From 1a8130b8fd6085feb02a0e558d217802eb8f7f9e Mon Sep 17 00:00:00 2001 From: KernelDeimos <7225168+KernelDeimos@users.noreply.github.com> Date: Tue, 23 Dec 2025 14:14:28 -0500 Subject: [PATCH] dev(data-access): add owner object to app select --- .../src/modules/data-access/AppService.js | 15 ++++++++++++- .../src/modules/data-access/lib/filter.js | 10 +++++++++ .../src/modules/data-access/lib/sqlutil.js | 21 +++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 src/backend/src/modules/data-access/lib/filter.js create mode 100644 src/backend/src/modules/data-access/lib/sqlutil.js diff --git a/src/backend/src/modules/data-access/AppService.js b/src/backend/src/modules/data-access/AppService.js index 200f9a314..2b337215b 100644 --- a/src/backend/src/modules/data-access/AppService.js +++ b/src/backend/src/modules/data-access/AppService.js @@ -3,6 +3,8 @@ import { DB_READ } from '../../services/database/consts.js'; import { Context } from '../../util/context.js'; import AppRepository from './AppRepository.js'; import { as_bool } from './lib/coercion.js'; +import { user_to_client } from './lib/filter.js'; +import { extract_from_prefix } from './lib/sqlutil.js'; /** * AppService contains an instance using the repository pattern @@ -43,7 +45,13 @@ export default class AppService extends BaseService { const userCanEditOnly = Array.prototype.includes.call(predicate, 'user-can-edit'); - const stmt = `SELECT * FROM apps ${userCanEditOnly ? 'WHERE owner_user_id=?' : ''} LIMIT 5000`; + const stmt = 'SELECT *, ' + + 'owner_user.username AS owner_user_username, ' + + 'owner_user.uuid AS owner_user_uuid ' + + 'FROM apps ' + + 'LEFT JOIN user owner_user ON owner_user_id = owner_user.id ' + + `${userCanEditOnly ? 'WHERE owner_user_id=?' : ''} ` + + 'LIMIT 5000'; const values = userCanEditOnly ? [Context.get('user').id] : []; const rows = await db.read(stmt, values); @@ -75,6 +83,11 @@ export default class AppService extends BaseService { // app.filetype_associations = row.filetype_associations; // app.owner = row.owner; + { + const owner_user = extract_from_prefix(row, 'owner_user_'); + app.owner_user = user_to_client(owner_user); + } + // REFINED BY OTHER DATA // app.icon; diff --git a/src/backend/src/modules/data-access/lib/filter.js b/src/backend/src/modules/data-access/lib/filter.js new file mode 100644 index 000000000..8adddaf2f --- /dev/null +++ b/src/backend/src/modules/data-access/lib/filter.js @@ -0,0 +1,10 @@ +// These utility functions describe how to produce an object safe +// for transfer that came from a "raw" object. + +export const user_to_client = raw_user => { + return { + username: raw_user.username, + // This `uuid` is not an internal-only ID. + uuid: raw_user.uuid, + }; +}; diff --git a/src/backend/src/modules/data-access/lib/sqlutil.js b/src/backend/src/modules/data-access/lib/sqlutil.js new file mode 100644 index 000000000..6c146b6db --- /dev/null +++ b/src/backend/src/modules/data-access/lib/sqlutil.js @@ -0,0 +1,21 @@ +/** + * When columns are selected from a joined table and prefixed: + * + * SELECT joined_table.* AS joined_table_ + * + * This function is able to extract the object from the result: + * + * extract_from_prefix(row, 'joined_table_') // columns of joined_table + * + * @param {*} row + * @param {*} prefix + */ +export const extract_from_prefix = (row, prefix) => { + const result = {}; + for ( const [key, value] of Object.entries(row) ) { + if ( key.startsWith(prefix) ) { + result[key.replace(prefix, '')] = value; + } + } + return result; +};