mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 21:05:19 +00:00
refactor(server): merge PageModel into DocModel (#10592)
This commit is contained in:
@@ -3,6 +3,7 @@ import { randomUUID } from 'node:crypto';
|
|||||||
import ava, { TestFn } from 'ava';
|
import ava, { TestFn } from 'ava';
|
||||||
|
|
||||||
import { Config } from '../../base/config';
|
import { Config } from '../../base/config';
|
||||||
|
import { PublicDocMode } from '../../models';
|
||||||
import { DocModel } from '../../models/doc';
|
import { DocModel } from '../../models/doc';
|
||||||
import { type User, UserModel } from '../../models/user';
|
import { type User, UserModel } from '../../models/user';
|
||||||
import { type Workspace, WorkspaceModel } from '../../models/workspace';
|
import { type Workspace, WorkspaceModel } from '../../models/workspace';
|
||||||
@@ -228,7 +229,7 @@ test('should upsert a doc', async t => {
|
|||||||
t.is(updatedSnapshot!.editorId, otherUser.id);
|
t.is(updatedSnapshot!.editorId, otherUser.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should get a doc meta', async t => {
|
test('should get a doc authors', async t => {
|
||||||
const snapshot = {
|
const snapshot = {
|
||||||
spaceId: workspace.id,
|
spaceId: workspace.id,
|
||||||
docId: randomUUID(),
|
docId: randomUUID(),
|
||||||
@@ -237,7 +238,7 @@ test('should get a doc meta', async t => {
|
|||||||
editorId: user.id,
|
editorId: user.id,
|
||||||
};
|
};
|
||||||
await t.context.doc.upsert(snapshot);
|
await t.context.doc.upsert(snapshot);
|
||||||
const meta = await t.context.doc.getMeta(snapshot.spaceId, snapshot.docId);
|
const meta = await t.context.doc.getAuthors(snapshot.spaceId, snapshot.docId);
|
||||||
t.truthy(meta);
|
t.truthy(meta);
|
||||||
t.deepEqual(meta!.createdByUser, {
|
t.deepEqual(meta!.createdByUser, {
|
||||||
id: user.id,
|
id: user.id,
|
||||||
@@ -262,7 +263,7 @@ test('should get a doc meta', async t => {
|
|||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
};
|
};
|
||||||
await t.context.doc.upsert(newSnapshot);
|
await t.context.doc.upsert(newSnapshot);
|
||||||
const updatedSnapshotMeta = await t.context.doc.getMeta(
|
const updatedSnapshotMeta = await t.context.doc.getAuthors(
|
||||||
snapshot.spaceId,
|
snapshot.spaceId,
|
||||||
snapshot.docId
|
snapshot.docId
|
||||||
);
|
);
|
||||||
@@ -282,7 +283,7 @@ test('should get a doc meta', async t => {
|
|||||||
t.deepEqual(updatedSnapshotMeta!.updatedAt, new Date(newSnapshot.timestamp));
|
t.deepEqual(updatedSnapshotMeta!.updatedAt, new Date(newSnapshot.timestamp));
|
||||||
|
|
||||||
// get null when doc not found
|
// get null when doc not found
|
||||||
const notFoundMeta = await t.context.doc.getMeta(
|
const notFoundMeta = await t.context.doc.getAuthors(
|
||||||
snapshot.spaceId,
|
snapshot.spaceId,
|
||||||
randomUUID()
|
randomUUID()
|
||||||
);
|
);
|
||||||
@@ -579,3 +580,93 @@ test('should detect doc exists on only updates exists', async t => {
|
|||||||
]);
|
]);
|
||||||
t.true(await t.context.doc.exists(workspace.id, docId));
|
t.true(await t.context.doc.exists(workspace.id, docId));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// #region DocMeta
|
||||||
|
|
||||||
|
test('should create doc meta with default mode and public false', async t => {
|
||||||
|
const docId = randomUUID();
|
||||||
|
const meta = await t.context.doc.upsertMeta(workspace.id, docId);
|
||||||
|
t.is(meta.workspaceId, workspace.id);
|
||||||
|
t.is(meta.docId, docId);
|
||||||
|
t.is(meta.mode, PublicDocMode.Page);
|
||||||
|
t.is(meta.public, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should update doc meta', async t => {
|
||||||
|
const docId = randomUUID();
|
||||||
|
const meta = await t.context.doc.upsertMeta(workspace.id, docId);
|
||||||
|
const data = {
|
||||||
|
mode: PublicDocMode.Edgeless,
|
||||||
|
public: true,
|
||||||
|
};
|
||||||
|
await t.context.doc.upsertMeta(workspace.id, docId, data);
|
||||||
|
const doc1 = await t.context.doc.getMeta(workspace.id, docId);
|
||||||
|
t.deepEqual(doc1, {
|
||||||
|
...meta,
|
||||||
|
...data,
|
||||||
|
});
|
||||||
|
|
||||||
|
// set to private
|
||||||
|
await t.context.doc.upsertMeta(workspace.id, docId, {
|
||||||
|
public: false,
|
||||||
|
});
|
||||||
|
const doc2 = await t.context.doc.getMeta(workspace.id, docId);
|
||||||
|
t.deepEqual(doc2, {
|
||||||
|
...meta,
|
||||||
|
...data,
|
||||||
|
public: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should get null when doc meta not exists', async t => {
|
||||||
|
const doc = await t.context.doc.getMeta(workspace.id, randomUUID());
|
||||||
|
t.is(doc, null);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should get doc meta with select', async t => {
|
||||||
|
const docId = randomUUID();
|
||||||
|
await t.context.doc.upsertMeta(workspace.id, docId);
|
||||||
|
const doc = await t.context.doc.getMeta(workspace.id, docId, {
|
||||||
|
select: {
|
||||||
|
mode: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
t.is(doc!.mode, PublicDocMode.Page);
|
||||||
|
// @ts-expect-error public is not in the select
|
||||||
|
t.is(doc!.public, undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should get public doc count', async t => {
|
||||||
|
const docId1 = randomUUID();
|
||||||
|
const docId2 = randomUUID();
|
||||||
|
const docId3 = randomUUID();
|
||||||
|
await t.context.doc.upsertMeta(workspace.id, docId1, {
|
||||||
|
public: true,
|
||||||
|
});
|
||||||
|
await t.context.doc.upsertMeta(workspace.id, docId2, {
|
||||||
|
public: true,
|
||||||
|
});
|
||||||
|
await t.context.doc.upsertMeta(workspace.id, docId3);
|
||||||
|
const count = await t.context.doc.getPublicsCount(workspace.id);
|
||||||
|
t.is(count, 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should get public docs of a workspace', async t => {
|
||||||
|
const docId1 = `1-${randomUUID()}`;
|
||||||
|
const docId2 = `2-${randomUUID()}`;
|
||||||
|
const docId3 = `3-${randomUUID()}`;
|
||||||
|
await t.context.doc.upsertMeta(workspace.id, docId1, {
|
||||||
|
public: true,
|
||||||
|
});
|
||||||
|
await t.context.doc.upsertMeta(workspace.id, docId2, {
|
||||||
|
public: true,
|
||||||
|
});
|
||||||
|
await t.context.doc.upsertMeta(workspace.id, docId3, {
|
||||||
|
public: false,
|
||||||
|
});
|
||||||
|
const docs = await t.context.doc.findPublics(workspace.id);
|
||||||
|
t.is(docs.length, 2);
|
||||||
|
t.deepEqual(docs.map(d => d.docId).sort(), [docId1, docId2]);
|
||||||
|
});
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|||||||
@@ -256,7 +256,7 @@ export class WorkspaceResolver {
|
|||||||
@Parent() workspace: WorkspaceType,
|
@Parent() workspace: WorkspaceType,
|
||||||
@Args('pageId') pageId: string
|
@Args('pageId') pageId: string
|
||||||
) {
|
) {
|
||||||
const metadata = await this.models.doc.getMeta(workspace.id, pageId);
|
const metadata = await this.models.doc.getAuthors(workspace.id, pageId);
|
||||||
if (!metadata) {
|
if (!metadata) {
|
||||||
throw new DocNotFound({ spaceId: workspace.id, docId: pageId });
|
throw new DocNotFound({ spaceId: workspace.id, docId: pageId });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { Transactional } from '@nestjs-cls/transactional';
|
import { Transactional } from '@nestjs-cls/transactional';
|
||||||
import type { Update } from '@prisma/client';
|
import type { Update } from '@prisma/client';
|
||||||
|
import { Prisma } from '@prisma/client';
|
||||||
|
|
||||||
import { BaseModel } from './base';
|
import { BaseModel } from './base';
|
||||||
import type { Doc, DocEditor } from './common';
|
import type { Doc, DocEditor } from './common';
|
||||||
@@ -31,6 +32,11 @@ export interface DocHistoryFilter {
|
|||||||
take?: number;
|
take?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type DocMetaUpsertInput = Omit<
|
||||||
|
Prisma.WorkspaceDocUncheckedCreateInput,
|
||||||
|
'workspaceId' | 'docId'
|
||||||
|
>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Workspace Doc Model
|
* Workspace Doc Model
|
||||||
*
|
*
|
||||||
@@ -38,6 +44,7 @@ export interface DocHistoryFilter {
|
|||||||
* - Updates: the changes made to the doc.
|
* - Updates: the changes made to the doc.
|
||||||
* - History: the doc history of the doc.
|
* - History: the doc history of the doc.
|
||||||
* - Doc: the doc itself.
|
* - Doc: the doc itself.
|
||||||
|
* - DocMeta: the doc meta.
|
||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DocModel extends BaseModel {
|
export class DocModel extends BaseModel {
|
||||||
@@ -338,7 +345,7 @@ export class DocModel extends BaseModel {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async getMeta(workspaceId: string, docId: string) {
|
async getAuthors(workspaceId: string, docId: string) {
|
||||||
return await this.db.snapshot.findUnique({
|
return await this.db.snapshot.findUnique({
|
||||||
where: {
|
where: {
|
||||||
workspaceId_id: {
|
workspaceId_id: {
|
||||||
@@ -461,4 +468,78 @@ export class DocModel extends BaseModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
||||||
|
// #region DocMeta
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create or update the doc meta.
|
||||||
|
*/
|
||||||
|
async upsertMeta(
|
||||||
|
workspaceId: string,
|
||||||
|
docId: string,
|
||||||
|
data?: DocMetaUpsertInput
|
||||||
|
) {
|
||||||
|
return await this.db.workspaceDoc.upsert({
|
||||||
|
where: {
|
||||||
|
workspaceId_docId: {
|
||||||
|
workspaceId,
|
||||||
|
docId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
...data,
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
...data,
|
||||||
|
workspaceId,
|
||||||
|
docId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the doc meta.
|
||||||
|
*/
|
||||||
|
async getMeta<Select extends Prisma.WorkspaceDocSelect>(
|
||||||
|
workspaceId: string,
|
||||||
|
docId: string,
|
||||||
|
options?: {
|
||||||
|
select?: Select;
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
return (await this.db.workspaceDoc.findUnique({
|
||||||
|
where: {
|
||||||
|
workspaceId_docId: {
|
||||||
|
workspaceId,
|
||||||
|
docId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: options?.select,
|
||||||
|
})) as Prisma.WorkspaceDocGetPayload<{ select: Select }> | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the workspace public doc metas.
|
||||||
|
*/
|
||||||
|
async findPublics(workspaceId: string) {
|
||||||
|
return await this.db.workspaceDoc.findMany({
|
||||||
|
where: {
|
||||||
|
workspaceId,
|
||||||
|
public: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the workspace public docs count.
|
||||||
|
*/
|
||||||
|
async getPublicsCount(workspaceId: string) {
|
||||||
|
return await this.db.workspaceDoc.count({
|
||||||
|
where: {
|
||||||
|
workspaceId,
|
||||||
|
public: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// #endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import { ApplyType } from '../base';
|
|||||||
import { DocModel } from './doc';
|
import { DocModel } from './doc';
|
||||||
import { DocUserModel } from './doc-user';
|
import { DocUserModel } from './doc-user';
|
||||||
import { FeatureModel } from './feature';
|
import { FeatureModel } from './feature';
|
||||||
import { PageModel } from './page';
|
|
||||||
import { MODELS_SYMBOL } from './provider';
|
import { MODELS_SYMBOL } from './provider';
|
||||||
import { SessionModel } from './session';
|
import { SessionModel } from './session';
|
||||||
import { UserModel } from './user';
|
import { UserModel } from './user';
|
||||||
@@ -27,7 +26,6 @@ const MODELS = {
|
|||||||
verificationToken: VerificationTokenModel,
|
verificationToken: VerificationTokenModel,
|
||||||
feature: FeatureModel,
|
feature: FeatureModel,
|
||||||
workspace: WorkspaceModel,
|
workspace: WorkspaceModel,
|
||||||
page: PageModel,
|
|
||||||
userFeature: UserFeatureModel,
|
userFeature: UserFeatureModel,
|
||||||
workspaceFeature: WorkspaceFeatureModel,
|
workspaceFeature: WorkspaceFeatureModel,
|
||||||
doc: DocModel,
|
doc: DocModel,
|
||||||
@@ -89,7 +87,6 @@ export * from './common';
|
|||||||
export * from './doc';
|
export * from './doc';
|
||||||
export * from './doc-user';
|
export * from './doc-user';
|
||||||
export * from './feature';
|
export * from './feature';
|
||||||
export * from './page';
|
|
||||||
export * from './session';
|
export * from './session';
|
||||||
export * from './user';
|
export * from './user';
|
||||||
export * from './user-doc';
|
export * from './user-doc';
|
||||||
|
|||||||
@@ -1,80 +0,0 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
|
||||||
import { type WorkspaceDoc as Page } from '@prisma/client';
|
|
||||||
|
|
||||||
import { BaseModel } from './base';
|
|
||||||
import { PublicDocMode } from './common';
|
|
||||||
export type { Page };
|
|
||||||
export type UpdatePageInput = {
|
|
||||||
mode?: PublicDocMode;
|
|
||||||
public?: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class PageModel extends BaseModel {
|
|
||||||
// #region page
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create or update the page.
|
|
||||||
*/
|
|
||||||
async upsert(workspaceId: string, docId: string, data?: UpdatePageInput) {
|
|
||||||
return await this.db.workspaceDoc.upsert({
|
|
||||||
where: {
|
|
||||||
workspaceId_docId: {
|
|
||||||
workspaceId,
|
|
||||||
docId,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
update: {
|
|
||||||
...data,
|
|
||||||
},
|
|
||||||
create: {
|
|
||||||
...data,
|
|
||||||
workspaceId,
|
|
||||||
docId,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the page.
|
|
||||||
* @param isPublic: if true, only return the public page. If false, only return the private page.
|
|
||||||
* If not set, return public or private both.
|
|
||||||
*/
|
|
||||||
async get(workspaceId: string, docId: string, isPublic?: boolean) {
|
|
||||||
return await this.db.workspaceDoc.findUnique({
|
|
||||||
where: {
|
|
||||||
workspaceId_docId: {
|
|
||||||
workspaceId,
|
|
||||||
docId,
|
|
||||||
},
|
|
||||||
public: isPublic,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the workspace public pages.
|
|
||||||
*/
|
|
||||||
async findPublics(workspaceId: string) {
|
|
||||||
return await this.db.workspaceDoc.findMany({
|
|
||||||
where: {
|
|
||||||
workspaceId,
|
|
||||||
public: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the workspace public pages count.
|
|
||||||
*/
|
|
||||||
async getPublicsCount(workspaceId: string) {
|
|
||||||
return await this.db.workspaceDoc.count({
|
|
||||||
where: {
|
|
||||||
workspaceId,
|
|
||||||
public: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// #endregion
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user