From 2a5b8e3806be445b0f954c0e9df725552da8a911 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Thu, 26 Sep 2024 10:10:06 +0200 Subject: [PATCH 1/2] chore: use joins instead of left joins --- .../personal-dashboard-read-model.ts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/lib/features/personal-dashboard/personal-dashboard-read-model.ts b/src/lib/features/personal-dashboard/personal-dashboard-read-model.ts index 9225a96f5433..ce761f24e952 100644 --- a/src/lib/features/personal-dashboard/personal-dashboard-read-model.ts +++ b/src/lib/features/personal-dashboard/personal-dashboard-read-model.ts @@ -28,15 +28,11 @@ export class PersonalDashboardReadModel implements IPersonalDashboardReadModel { }>('projects') .join('role_user', 'projects.id', 'role_user.project') .join('roles', 'role_user.role_id', 'roles.id') - .leftJoin('group_user', (join) => { + .join('group_user', (join) => { join.on('group_user.user_id', '=', this.db.raw('?', [userId])); }) - .leftJoin( - 'group_role', - 'group_role.group_id', - 'group_user.group_id', - ) - .leftJoin( + .join('group_role', 'group_role.group_id', 'group_user.group_id') + .join( 'roles as group_roles', 'group_role.role_id', 'group_roles.id', From 488078223b5664c537e35c6830aeda3ca66dd389 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Thu, 26 Sep 2024 10:10:22 +0200 Subject: [PATCH 2/2] wip: start messing around --- .../fake-personal-dashboard-read-model.ts | 6 +++ .../personal-dashboard-read-model-type.ts | 5 ++ .../personal-dashboard-read-model.ts | 51 +++++++++++++++++++ .../personal-dashboard-service.ts | 14 +++++ src/lib/services/index.ts | 5 ++ 5 files changed, 81 insertions(+) diff --git a/src/lib/features/personal-dashboard/fake-personal-dashboard-read-model.ts b/src/lib/features/personal-dashboard/fake-personal-dashboard-read-model.ts index 1df56844b030..0e77df4a0f6c 100644 --- a/src/lib/features/personal-dashboard/fake-personal-dashboard-read-model.ts +++ b/src/lib/features/personal-dashboard/fake-personal-dashboard-read-model.ts @@ -7,6 +7,12 @@ import type { export class FakePersonalDashboardReadModel implements IPersonalDashboardReadModel { + enrichProjectIds( + userId: number, + projectIds: string[], + ): Promise { + throw new Error('Method not implemented.'); + } async getPersonalFeatures(userId: number): Promise { return []; } diff --git a/src/lib/features/personal-dashboard/personal-dashboard-read-model-type.ts b/src/lib/features/personal-dashboard/personal-dashboard-read-model-type.ts index b3db032ff8a7..55f4156b39d4 100644 --- a/src/lib/features/personal-dashboard/personal-dashboard-read-model-type.ts +++ b/src/lib/features/personal-dashboard/personal-dashboard-read-model-type.ts @@ -17,4 +17,9 @@ export type PersonalProjectWithOwners = PersonalProject & { export interface IPersonalDashboardReadModel { getPersonalFeatures(userId: number): Promise; getPersonalProjects(userId: number): Promise; + + enrichProjectIds( + userId: number, + projectIds: string[], + ): Promise; } diff --git a/src/lib/features/personal-dashboard/personal-dashboard-read-model.ts b/src/lib/features/personal-dashboard/personal-dashboard-read-model.ts index ce761f24e952..3202ee009e37 100644 --- a/src/lib/features/personal-dashboard/personal-dashboard-read-model.ts +++ b/src/lib/features/personal-dashboard/personal-dashboard-read-model.ts @@ -116,4 +116,55 @@ export class PersonalDashboardReadModel implements IPersonalDashboardReadModel { project: row.project, })); } + + async enrichProjectIds( + userId: number, + projectIds: string[], + ): Promise { + const T = { + ROLE_USER: 'role_user', + ROLES: 'roles', + GROUPS: 'groups', + GROUP_ROLE: 'group_role', + GROUP_USER: 'group_user', + ROLE_PERMISSION: 'role_permission', + PERMISSIONS: 'permissions', + PERMISSION_TYPES: 'permission_types', + CHANGE_REQUEST_SETTINGS: 'change_request_settings', + PERSONAL_ACCESS_TOKENS: 'personal_access_tokens', + PUBLIC_SIGNUP_TOKENS_USER: 'public_signup_tokens_user', + }; + + const roles = await this.db + .select(['id', 'name', 'type', 'project', 'description']) + .from(T.ROLES) + .innerJoin(`${T.ROLE_USER} as ru`, 'ru.role_id', 'id') + .where('ru.user_id', '=', userId) + .andWhere((builder) => { + builder + .whereIn('ru.project', projectIds) + .orWhere('type', '=', 'root'); + }) + .union([ + this.db + .select(['id', 'name', 'type', 'project', 'description']) + .from(T.ROLES) + .innerJoin(`${T.GROUP_ROLE} as gr`, 'gr.role_id', 'id') + .innerJoin( + `${T.GROUP_USER} as gu`, + 'gu.group_id', + 'gr.group_id', + ) + .where('gu.user_id', '=', userId) + .andWhere((builder) => { + builder + .whereIn('gr.project', projectIds) + .orWhere('type', '=', 'root'); + }), + ]); + + console.log(roles); + + return []; + } } diff --git a/src/lib/features/personal-dashboard/personal-dashboard-service.ts b/src/lib/features/personal-dashboard/personal-dashboard-service.ts index f4aa5fccba79..43953ce965b8 100644 --- a/src/lib/features/personal-dashboard/personal-dashboard-service.ts +++ b/src/lib/features/personal-dashboard/personal-dashboard-service.ts @@ -1,4 +1,5 @@ import type { IProjectOwnersReadModel } from '../project/project-owners-read-model.type'; +import type { IProjectReadModel } from '../project/project-read-model-type'; import type { IPersonalDashboardReadModel, PersonalFeature, @@ -10,12 +11,16 @@ export class PersonalDashboardService { private projectOwnersReadModel: IProjectOwnersReadModel; + private projectReadModel: IProjectReadModel; + constructor( personalDashboardReadModel: IPersonalDashboardReadModel, projectOwnersReadModel: IProjectOwnersReadModel, + projectReadModel: IProjectReadModel, ) { this.personalDashboardReadModel = personalDashboardReadModel; this.projectOwnersReadModel = projectOwnersReadModel; + this.projectReadModel = projectReadModel; } getPersonalFeatures(userId: number): Promise { @@ -25,6 +30,15 @@ export class PersonalDashboardService { async getPersonalProjects( userId: number, ): Promise { + const projectIds = + await this.projectReadModel.getProjectsByUser(userId); + + console.log('got these', projectIds.length, 'projects', projectIds); + const enriched = await this.personalDashboardReadModel.enrichProjectIds( + userId, + projectIds, + ); + // console.log('got these', enriched.length, 'projects', projectIds); const projects = await this.personalDashboardReadModel.getPersonalProjects(userId); diff --git a/src/lib/services/index.ts b/src/lib/services/index.ts index 40c517171b06..b9393ab41dd6 100644 --- a/src/lib/services/index.ts +++ b/src/lib/services/index.ts @@ -151,6 +151,8 @@ import { PersonalDashboardReadModel } from '../features/personal-dashboard/perso import { FakePersonalDashboardReadModel } from '../features/personal-dashboard/fake-personal-dashboard-read-model'; import { ProjectOwnersReadModel } from '../features/project/project-owners-read-model'; import { FakeProjectOwnersReadModel } from '../features/project/fake-project-owners-read-model'; +import { ProjectReadModel } from '../features/project/project-read-model'; +import { FakeProjectReadModel } from '../features/project/fake-project-read-model'; export const createServices = ( stores: IUnleashStores, @@ -412,6 +414,9 @@ export const createServices = ( : new FakePersonalDashboardReadModel(), db ? new ProjectOwnersReadModel(db) : new FakeProjectOwnersReadModel(), + db + ? new ProjectReadModel(db, config.eventBus, config.flagResolver) + : new FakeProjectReadModel(), ); return {