feat(base): create() now allocates an is_base=true page via PageService

This commit is contained in:
Philipinho
2026-04-27 01:16:48 +01:00
parent ccdf2343f2
commit a2917bad6d
5 changed files with 45 additions and 31 deletions
+5 -1
View File
@@ -17,9 +17,13 @@ import { BasePresenceService } from './realtime/base-presence.service';
import { QueueName } from '../../integrations/queue/constants'; import { QueueName } from '../../integrations/queue/constants';
import { FormulaService } from './formula/formula.service'; import { FormulaService } from './formula/formula.service';
import { FormulaLockService } from './formula/formula-lock'; import { FormulaLockService } from './formula/formula-lock';
import { PageModule } from '../page/page.module';
@Module({ @Module({
imports: [BullModule.registerQueue({ name: QueueName.BASE_QUEUE })], imports: [
BullModule.registerQueue({ name: QueueName.BASE_QUEUE }),
PageModule,
],
controllers: [ controllers: [
BaseController, BaseController,
BasePropertyController, BasePropertyController,
@@ -1,22 +1,18 @@
import { IsNotEmpty, IsOptional, IsString, IsUUID } from 'class-validator'; import { IsOptional, IsString, IsUUID } from 'class-validator';
export class CreateBaseDto { export class CreateBaseDto {
@IsString() @IsString()
@IsNotEmpty()
name: string;
@IsOptional() @IsOptional()
@IsString() name?: string;
description?: string;
@IsOptional()
@IsString() @IsString()
@IsOptional()
icon?: string; icon?: string;
@IsOptional()
@IsUUID() @IsUUID()
pageId?: string; spaceId!: string;
@IsUUID() @IsUUID()
spaceId: string; @IsOptional()
parentPageId?: string;
} }
@@ -8,6 +8,8 @@ import { executeTx } from '@docmost/db/utils';
import { BaseRepo } from '@docmost/db/repos/base/base.repo'; import { BaseRepo } from '@docmost/db/repos/base/base.repo';
import { BasePropertyRepo } from '@docmost/db/repos/base/base-property.repo'; import { BasePropertyRepo } from '@docmost/db/repos/base/base-property.repo';
import { BaseViewRepo } from '@docmost/db/repos/base/base-view.repo'; import { BaseViewRepo } from '@docmost/db/repos/base/base-view.repo';
import { PageService } from '../../page/services/page.service';
import { PageRepo } from '@docmost/db/repos/page/page.repo';
import { CreateBaseDto } from '../dto/create-base.dto'; import { CreateBaseDto } from '../dto/create-base.dto';
import { UpdateBaseDto } from '../dto/update-base.dto'; import { UpdateBaseDto } from '../dto/update-base.dto';
import { BasePropertyType } from '../base.schemas'; import { BasePropertyType } from '../base.schemas';
@@ -21,20 +23,22 @@ export class BaseService {
private readonly baseRepo: BaseRepo, private readonly baseRepo: BaseRepo,
private readonly basePropertyRepo: BasePropertyRepo, private readonly basePropertyRepo: BasePropertyRepo,
private readonly baseViewRepo: BaseViewRepo, private readonly baseViewRepo: BaseViewRepo,
private readonly pageService: PageService,
private readonly pageRepo: PageRepo,
) {} ) {}
async create(userId: string, workspaceId: string, dto: CreateBaseDto) { async create(userId: string, workspaceId: string, dto: CreateBaseDto) {
return executeTx(this.db, async (trx) => { return executeTx(this.db, async (trx) => {
const base = await this.baseRepo.insertBase( const page = await this.pageService.create(
{ userId,
name: dto.name,
description: dto.description,
icon: dto.icon,
pageId: dto.pageId,
spaceId: dto.spaceId,
workspaceId, workspaceId,
creatorId: userId, {
}, title: dto.name ?? 'Untitled',
icon: dto.icon,
spaceId: dto.spaceId,
parentPageId: dto.parentPageId,
isBase: true,
} as any,
trx, trx,
); );
@@ -42,7 +46,7 @@ export class BaseService {
await this.basePropertyRepo.insertProperty( await this.basePropertyRepo.insertProperty(
{ {
baseId: base.id, pageId: page.id,
name: 'Title', name: 'Title',
type: BasePropertyType.TEXT, type: BasePropertyType.TEXT,
position: firstPosition, position: firstPosition,
@@ -54,17 +58,18 @@ export class BaseService {
await this.baseViewRepo.insertView( await this.baseViewRepo.insertView(
{ {
baseId: base.id, pageId: page.id,
name: 'Table View 1', name: 'Table',
type: 'table', type: 'table',
position: firstPosition, position: firstPosition,
config: {},
workspaceId, workspaceId,
creatorId: userId, creatorId: userId,
}, },
{ trx }, { trx },
); );
return this.baseRepo.findById(base.id, { return this.baseRepo.findById(page.id, {
includeProperties: true, includeProperties: true,
includeViews: true, includeViews: true,
trx, trx,
@@ -72,8 +77,8 @@ export class BaseService {
}); });
} }
async getBaseInfo(baseId: string) { async getBaseInfo(pageId: string) {
const base = await this.baseRepo.findById(baseId, { const base = await this.baseRepo.findById(pageId, {
includeProperties: true, includeProperties: true,
includeViews: true, includeViews: true,
}); });
@@ -91,11 +96,13 @@ export class BaseService {
throw new NotFoundException('Base not found'); throw new NotFoundException('Base not found');
} }
await this.baseRepo.updateBase(dto.baseId, { await this.pageRepo.updatePage(
...(dto.name !== undefined && { name: dto.name }), {
...(dto.description !== undefined && { description: dto.description }), ...(dto.name !== undefined && { title: dto.name }),
...(dto.icon !== undefined && { icon: dto.icon }), ...(dto.icon !== undefined && { icon: dto.icon }),
}); },
dto.baseId,
);
return this.baseRepo.findById(dto.baseId); return this.baseRepo.findById(dto.baseId);
} }
@@ -1,4 +1,5 @@
import { import {
IsBoolean,
IsIn, IsIn,
IsOptional, IsOptional,
IsString, IsString,
@@ -25,6 +26,10 @@ export class CreatePageDto {
@IsUUID() @IsUUID()
spaceId: string; spaceId: string;
@IsOptional()
@IsBoolean()
isBase?: boolean;
@IsOptional() @IsOptional()
content?: string | object; content?: string | object;
@@ -15,7 +15,7 @@ import {
executeWithCursorPagination, executeWithCursorPagination,
} from '@docmost/db/pagination/cursor-pagination'; } from '@docmost/db/pagination/cursor-pagination';
import { InjectKysely } from 'nestjs-kysely'; import { InjectKysely } from 'nestjs-kysely';
import { KyselyDB } from '@docmost/db/types/kysely.types'; import { KyselyDB, KyselyTransaction } from '@docmost/db/types/kysely.types';
import { generateJitteredKeyBetween } from 'fractional-indexing-jittered'; import { generateJitteredKeyBetween } from 'fractional-indexing-jittered';
import { MovePageDto } from '../dto/move-page.dto'; import { MovePageDto } from '../dto/move-page.dto';
import { generateSlugId } from '../../../common/helpers'; import { generateSlugId } from '../../../common/helpers';
@@ -90,6 +90,7 @@ export class PageService {
userId: string, userId: string,
workspaceId: string, workspaceId: string,
createPageDto: CreatePageDto, createPageDto: CreatePageDto,
trx?: KyselyTransaction,
): Promise<Page> { ): Promise<Page> {
let parentPageId = undefined; let parentPageId = undefined;
@@ -138,10 +139,11 @@ export class PageService {
creatorId: userId, creatorId: userId,
workspaceId: workspaceId, workspaceId: workspaceId,
lastUpdatedById: userId, lastUpdatedById: userId,
isBase: createPageDto.isBase ?? false,
content, content,
textContent, textContent,
ydoc, ydoc,
}); }, trx);
this.generalQueue this.generalQueue
.add(QueueJob.ADD_PAGE_WATCHERS, { .add(QueueJob.ADD_PAGE_WATCHERS, {