Skip to content

Commit

Permalink
refactor: reduce complexity in project owners read model
Browse files Browse the repository at this point in the history
  • Loading branch information
Tymek committed Apr 24, 2024
1 parent 26a9581 commit 0232537
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 32 deletions.
7 changes: 0 additions & 7 deletions src/lib/features/project/project-owners-read-model.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ describe('integration tests', () => {
projectId,
);

// fetch project owners
const owners = await readModel.getAllProjectOwners();

expect(owners).toMatchObject({
Expand All @@ -111,10 +110,6 @@ describe('integration tests', () => {
const projectId = randomId();
await db.stores.projectStore.create({ id: projectId, name: projectId });

const ownerRole = await db.stores.roleStore.getRoleByName(
RoleName.OWNER,
);

const memberRole = await db.stores.roleStore.getRoleByName(
RoleName.MEMBER,
);
Expand All @@ -130,7 +125,6 @@ describe('integration tests', () => {
projectId,
);

// fetch project owners
const owners = await readModel.getAllProjectOwners();

expect(owners).toMatchObject({
Expand All @@ -149,7 +143,6 @@ describe('integration tests', () => {
projectId,
);

// fetch project owners
const owners = await readModel.getAllProjectOwners();

expect(owners).toMatchObject({
Expand Down
60 changes: 35 additions & 25 deletions src/lib/features/project/project-owners-read-model.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import type { Db } from '../../db/db';
import { RoleName, type IProjectWithCount, type IRoleStore } from '../../types';

export type SystemOwner = { ownerType: 'system' };
const T = {
ROLE_USER: 'role_user',
GROUP_ROLE: 'group_role',
ROLES: 'roles',
USERS: 'users',
};

type SystemOwner = { ownerType: 'system' };
type UserProjectOwner = {
ownerType: 'user';
name: string;
Expand All @@ -12,7 +19,6 @@ type GroupProjectOwner = {
ownerType: 'group';
name: string;
};

type ProjectOwners =
| [SystemOwner]
| Array<UserProjectOwner | GroupProjectOwner>;
Expand Down Expand Up @@ -43,17 +49,9 @@ export class ProjectOwnersReadModel {
return [];
}

async getAllProjectOwners(): Promise<ProjectOwnersDictionary> {
// Query both user and group owners
const T = {
ROLE_USER: 'role_user',
GROUP_ROLE: 'group_role',
ROLES: 'roles',
USERS: 'users',
};

const ownerRole = await this.roleStore.getRoleByName(RoleName.OWNER);

private async getAllProjectUsersByRole(
roleId: number,
): Promise<Record<string, UserProjectOwner[]>> {
const usersResult = await this.db
.select(
'user.username',
Expand All @@ -65,19 +63,9 @@ export class ProjectOwnersReadModel {
)
.from(`${T.ROLE_USER} as ru`)
.join(`${T.ROLES} as r`, 'ru.role_id', 'r.id')
.where('r.id', ownerRole.id)
.where('r.id', roleId)
.join(`${T.USERS} as user`, 'ru.user_id', 'user.id');

const groupsResult = await this.db
.select('groups.name', 'gr.created_at', 'gr.project')
.from(`${T.GROUP_ROLE} as gr`)
.join(`${T.ROLES} as r`, 'gr.role_id', 'r.id')
.where('r.id', ownerRole.id)
.join('groups', 'gr.group_id', 'groups.id');

// Map results into project owners format
const usersDict: Record<string, UserProjectOwner[]> = {};
const groupsDict: Record<string, GroupProjectOwner[]> = {};

usersResult.forEach((user) => {
const project = user.project as string;
Expand All @@ -96,6 +84,21 @@ export class ProjectOwnersReadModel {
}
});

return usersDict;
}

private async getAllProjectGroupsByRole(
roleId: number,
): Promise<Record<string, GroupProjectOwner[]>> {
const groupsResult = await this.db
.select('groups.name', 'gr.created_at', 'gr.project')
.from(`${T.GROUP_ROLE} as gr`)
.join(`${T.ROLES} as r`, 'gr.role_id', 'r.id')
.where('r.id', roleId)
.join('groups', 'gr.group_id', 'groups.id');

const groupsDict: Record<string, GroupProjectOwner[]> = {};

groupsResult.forEach((group) => {
const project = group.project as string;

Expand All @@ -111,7 +114,14 @@ export class ProjectOwnersReadModel {
}
});

// Combine user and group owners
return groupsDict;
}

async getAllProjectOwners(): Promise<ProjectOwnersDictionary> {
const ownerRole = await this.roleStore.getRoleByName(RoleName.OWNER);
const usersDict = await this.getAllProjectUsersByRole(ownerRole.id);
const groupsDict = await this.getAllProjectGroupsByRole(ownerRole.id);

const projects = [
...new Set([...Object.keys(usersDict), ...Object.keys(groupsDict)]),
];
Expand Down

0 comments on commit 0232537

Please sign in to comment.