feat: keep track of page contributors (#959)

* WIP

* feat: store and retrieve page contributors
This commit is contained in:
Philip Okugbe
2025-04-04 13:03:57 +01:00
committed by GitHub
parent 8aa604637e
commit 64f0531093
7 changed files with 82 additions and 7 deletions

View File

@ -47,7 +47,7 @@ types.setTypeParser(types.builtins.INT8, (val) => Number(val));
log: (event: LogEvent) => {
if (environmentService.getNodeEnv() !== 'development') return;
const logger = new Logger(DatabaseModule.name);
if (event.level === 'query') {
if (event.level) {
if (process.env.DEBUG_DB?.toLowerCase() === 'true') {
logger.debug(event.query.sql);
logger.debug('query time: ' + event.queryDurationMillis + ' ms');

View File

@ -0,0 +1,12 @@
import { type Kysely, sql } from 'kysely';
export async function up(db: Kysely<any>): Promise<void> {
await db.schema
.alterTable('pages')
.addColumn('contributor_ids', sql`uuid[]`, (col) => col.defaultTo("{}"))
.execute();
}
export async function down(db: Kysely<any>): Promise<void> {
await db.schema.alterTable('pages').dropColumn('contributor_ids').execute();
}

View File

@ -10,9 +10,9 @@ import {
import { PaginationOptions } from '@docmost/db/pagination/pagination-options';
import { executeWithPagination } from '@docmost/db/pagination/pagination';
import { validate as isValidUUID } from 'uuid';
import { ExpressionBuilder } from 'kysely';
import { ExpressionBuilder, sql } from 'kysely';
import { DB } from '@docmost/db/types/db';
import { jsonObjectFrom } from 'kysely/helpers/postgres';
import { jsonArrayFrom, jsonObjectFrom } from 'kysely/helpers/postgres';
import { SpaceMemberRepo } from '@docmost/db/repos/space/space-member.repo';
@Injectable()
@ -38,6 +38,7 @@ export class PageRepo {
'createdAt',
'updatedAt',
'deletedAt',
'contributorIds',
];
async findById(
@ -48,6 +49,7 @@ export class PageRepo {
includeSpace?: boolean;
includeCreator?: boolean;
includeLastUpdatedBy?: boolean;
includeContributors?: boolean;
withLock?: boolean;
trx?: KyselyTransaction;
},
@ -68,6 +70,10 @@ export class PageRepo {
query = query.select((eb) => this.withLastUpdatedBy(eb));
}
if (opts?.includeContributors) {
query = query.select((eb) => this.withContributors(eb));
}
if (opts?.includeSpace) {
query = query.select((eb) => this.withSpace(eb));
}
@ -189,6 +195,15 @@ export class PageRepo {
).as('lastUpdatedBy');
}
withContributors(eb: ExpressionBuilder<DB, 'pages'>) {
return jsonArrayFrom(
eb
.selectFrom('users')
.select(['users.id', 'users.name', 'users.avatarUrl'])
.whereRef('users.id', '=', sql`ANY(${eb.ref('pages.contributorIds')})`),
).as('contributors');
}
async getPageAndDescendants(parentPageId: string) {
return this.db
.withRecursive('page_hierarchy', (db) =>

View File

@ -161,6 +161,7 @@ export interface PageHistory {
export interface Pages {
content: Json | null;
contributorIds: Generated<string[] | null>;
coverPhoto: string | null;
createdAt: Generated<Timestamp>;
creatorId: string | null;