mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 21:27:20 +00:00
feat(server): add comment-attachment model (#12909)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Introduced support for comment attachments, allowing users to add, view, and manage attachments linked to comments within documents. * **Tests** * Added comprehensive tests to ensure correct behavior for adding, updating, deleting, listing, and retrieving comment attachments. <!-- end of auto-generated comment: release notes by coderabbit.ai --> #### PR Dependency Tree * **PR #12909** 👈 * **PR #12911** * **PR #12761** * **PR #12924** * **PR #12925** This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal)
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
import test from 'ava';
|
||||
|
||||
import { createModule } from '../../__tests__/create-module';
|
||||
import { Mockers } from '../../__tests__/mocks';
|
||||
import { Models } from '..';
|
||||
|
||||
const module = await createModule();
|
||||
const models = module.get(Models);
|
||||
|
||||
test.after.always(async () => {
|
||||
await module.close();
|
||||
});
|
||||
|
||||
test('should upsert comment attachment', async t => {
|
||||
const workspace = await module.create(Mockers.Workspace);
|
||||
|
||||
// add
|
||||
const item = await models.commentAttachment.upsert({
|
||||
workspaceId: workspace.id,
|
||||
docId: 'test-doc-id',
|
||||
key: 'test-key',
|
||||
name: 'test-name',
|
||||
mime: 'text/plain',
|
||||
size: 100,
|
||||
});
|
||||
|
||||
t.is(item.workspaceId, workspace.id);
|
||||
t.is(item.docId, 'test-doc-id');
|
||||
t.is(item.key, 'test-key');
|
||||
t.is(item.mime, 'text/plain');
|
||||
t.is(item.size, 100);
|
||||
t.truthy(item.createdAt);
|
||||
|
||||
// update
|
||||
const item2 = await models.commentAttachment.upsert({
|
||||
workspaceId: workspace.id,
|
||||
docId: 'test-doc-id',
|
||||
name: 'test-name',
|
||||
key: 'test-key',
|
||||
mime: 'text/html',
|
||||
size: 200,
|
||||
});
|
||||
|
||||
t.is(item2.workspaceId, workspace.id);
|
||||
t.is(item2.docId, 'test-doc-id');
|
||||
t.is(item2.key, 'test-key');
|
||||
t.is(item2.mime, 'text/html');
|
||||
t.is(item2.size, 200);
|
||||
|
||||
// make sure only one blob is created
|
||||
const items = await models.commentAttachment.list(workspace.id);
|
||||
t.is(items.length, 1);
|
||||
t.deepEqual(items[0], item2);
|
||||
});
|
||||
|
||||
test('should delete comment attachment', async t => {
|
||||
const workspace = await module.create(Mockers.Workspace);
|
||||
const item = await models.commentAttachment.upsert({
|
||||
workspaceId: workspace.id,
|
||||
docId: 'test-doc-id',
|
||||
key: 'test-key',
|
||||
name: 'test-name',
|
||||
mime: 'text/plain',
|
||||
size: 100,
|
||||
});
|
||||
|
||||
await models.commentAttachment.delete(workspace.id, item.docId, item.key);
|
||||
|
||||
const item2 = await models.commentAttachment.get(
|
||||
workspace.id,
|
||||
item.docId,
|
||||
item.key
|
||||
);
|
||||
|
||||
t.is(item2, null);
|
||||
});
|
||||
|
||||
test('should list comment attachments', async t => {
|
||||
const workspace = await module.create(Mockers.Workspace);
|
||||
const item1 = await models.commentAttachment.upsert({
|
||||
workspaceId: workspace.id,
|
||||
docId: 'test-doc-id',
|
||||
name: 'test-name',
|
||||
key: 'test-key',
|
||||
mime: 'text/plain',
|
||||
size: 100,
|
||||
});
|
||||
|
||||
const item2 = await models.commentAttachment.upsert({
|
||||
workspaceId: workspace.id,
|
||||
docId: 'test-doc-id2',
|
||||
name: 'test-name2',
|
||||
key: 'test-key2',
|
||||
mime: 'text/plain',
|
||||
size: 200,
|
||||
});
|
||||
|
||||
const items = await models.commentAttachment.list(workspace.id);
|
||||
|
||||
t.is(items.length, 2);
|
||||
items.sort((a, b) => a.key.localeCompare(b.key));
|
||||
t.is(items[0].key, item1.key);
|
||||
t.is(items[1].key, item2.key);
|
||||
});
|
||||
|
||||
test('should get comment attachment', async t => {
|
||||
const workspace = await module.create(Mockers.Workspace);
|
||||
const item = await models.commentAttachment.upsert({
|
||||
workspaceId: workspace.id,
|
||||
docId: 'test-doc-id',
|
||||
name: 'test-name',
|
||||
key: 'test-key',
|
||||
mime: 'text/plain',
|
||||
size: 100,
|
||||
});
|
||||
|
||||
const item2 = await models.commentAttachment.get(
|
||||
workspace.id,
|
||||
item.docId,
|
||||
item.key
|
||||
);
|
||||
|
||||
t.truthy(item2);
|
||||
t.is(item2?.key, item.key);
|
||||
});
|
||||
70
packages/backend/server/src/models/comment-attachment.ts
Normal file
70
packages/backend/server/src/models/comment-attachment.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Prisma } from '@prisma/client';
|
||||
|
||||
import { BaseModel } from './base';
|
||||
|
||||
export type CreateCommentAttachmentInput =
|
||||
Prisma.CommentAttachmentUncheckedCreateInput;
|
||||
|
||||
/**
|
||||
* Comment Attachment Model
|
||||
*/
|
||||
@Injectable()
|
||||
export class CommentAttachmentModel extends BaseModel {
|
||||
async upsert(input: CreateCommentAttachmentInput) {
|
||||
return await this.db.commentAttachment.upsert({
|
||||
where: {
|
||||
workspaceId_docId_key: {
|
||||
workspaceId: input.workspaceId,
|
||||
docId: input.docId,
|
||||
key: input.key,
|
||||
},
|
||||
},
|
||||
update: {
|
||||
name: input.name,
|
||||
mime: input.mime,
|
||||
size: input.size,
|
||||
},
|
||||
create: {
|
||||
workspaceId: input.workspaceId,
|
||||
docId: input.docId,
|
||||
key: input.key,
|
||||
name: input.name,
|
||||
mime: input.mime,
|
||||
size: input.size,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async delete(workspaceId: string, docId: string, key: string) {
|
||||
await this.db.commentAttachment.deleteMany({
|
||||
where: {
|
||||
workspaceId,
|
||||
docId,
|
||||
key,
|
||||
},
|
||||
});
|
||||
this.logger.log(`deleted comment attachment ${workspaceId}/${key}`);
|
||||
}
|
||||
|
||||
async get(workspaceId: string, docId: string, key: string) {
|
||||
return await this.db.commentAttachment.findUnique({
|
||||
where: {
|
||||
workspaceId_docId_key: {
|
||||
workspaceId,
|
||||
docId,
|
||||
key,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async list(workspaceId: string, docId?: string) {
|
||||
return await this.db.commentAttachment.findMany({
|
||||
where: {
|
||||
workspaceId,
|
||||
docId,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import { ModuleRef } from '@nestjs/core';
|
||||
|
||||
import { ApplyType } from '../base';
|
||||
import { CommentModel } from './comment';
|
||||
import { CommentAttachmentModel } from './comment-attachment';
|
||||
import { AppConfigModel } from './config';
|
||||
import { CopilotContextModel } from './copilot-context';
|
||||
import { CopilotJobModel } from './copilot-job';
|
||||
@@ -50,6 +51,7 @@ const MODELS = {
|
||||
copilotJob: CopilotJobModel,
|
||||
appConfig: AppConfigModel,
|
||||
comment: CommentModel,
|
||||
commentAttachment: CommentAttachmentModel,
|
||||
};
|
||||
|
||||
type ModelsType = {
|
||||
@@ -102,6 +104,7 @@ const ModelsSymbolProvider: ExistingProvider = {
|
||||
export class ModelsModule {}
|
||||
|
||||
export * from './comment';
|
||||
export * from './comment-attachment';
|
||||
export * from './common';
|
||||
export * from './copilot-context';
|
||||
export * from './copilot-job';
|
||||
|
||||
Reference in New Issue
Block a user