fix(server): add user id to comment-attachment model (#13113)

close AF-2723



#### PR Dependency Tree


* **PR #13113** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Comment attachments now track and display the user who uploaded them.

* **Tests**
* Updated tests to verify that the uploader’s information is correctly
stored and retrieved with comment attachments.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
fengmk2
2025-07-09 20:16:09 +08:00
committed by GitHub
parent d4c905600b
commit 45c016af8b
6 changed files with 26 additions and 10 deletions

View File

@@ -73,7 +73,8 @@ e2e('should get comment attachment body', async t => {
docId, docId,
key, key,
'test.txt', 'test.txt',
Buffer.from('test') Buffer.from('test'),
owner.id
); );
const res = await app.GET( const res = await app.GET(

View File

@@ -361,7 +361,8 @@ export class CommentResolver {
docId, docId,
key, key,
attachment.filename ?? key, attachment.filename ?? key,
buffer buffer,
me.id
); );
return this.commentAttachmentStorage.getUrl(workspaceId, docId, key); return this.commentAttachmentStorage.getUrl(workspaceId, docId, key);
} }

View File

@@ -24,11 +24,12 @@ test.after.always(async () => {
test('should put comment attachment', async t => { test('should put comment attachment', async t => {
const workspace = await module.create(Mockers.Workspace); const workspace = await module.create(Mockers.Workspace);
const user = await module.create(Mockers.User);
const docId = randomUUID(); const docId = randomUUID();
const key = randomUUID(); const key = randomUUID();
const blob = Buffer.from('test'); const blob = Buffer.from('test');
await storage.put(workspace.id, docId, key, 'test.txt', blob); await storage.put(workspace.id, docId, key, 'test.txt', blob, user.id);
const item = await models.commentAttachment.get(workspace.id, docId, key); const item = await models.commentAttachment.get(workspace.id, docId, key);
@@ -39,15 +40,17 @@ test('should put comment attachment', async t => {
t.is(item?.mime, 'text/plain'); t.is(item?.mime, 'text/plain');
t.is(item?.size, blob.length); t.is(item?.size, blob.length);
t.is(item?.name, 'test.txt'); t.is(item?.name, 'test.txt');
t.is(item?.createdBy, user.id);
}); });
test('should get comment attachment', async t => { test('should get comment attachment', async t => {
const workspace = await module.create(Mockers.Workspace); const workspace = await module.create(Mockers.Workspace);
const user = await module.create(Mockers.User);
const docId = randomUUID(); const docId = randomUUID();
const key = randomUUID(); const key = randomUUID();
const blob = Buffer.from('test'); const blob = Buffer.from('test');
await storage.put(workspace.id, docId, key, 'test.txt', blob); await storage.put(workspace.id, docId, key, 'test.txt', blob, user.id);
const item = await storage.get(workspace.id, docId, key); const item = await storage.get(workspace.id, docId, key);
@@ -62,11 +65,12 @@ test('should get comment attachment', async t => {
test('should get comment attachment with access url', async t => { test('should get comment attachment with access url', async t => {
const workspace = await module.create(Mockers.Workspace); const workspace = await module.create(Mockers.Workspace);
const user = await module.create(Mockers.User);
const docId = randomUUID(); const docId = randomUUID();
const key = randomUUID(); const key = randomUUID();
const blob = Buffer.from('test'); const blob = Buffer.from('test');
await storage.put(workspace.id, docId, key, 'test.txt', blob); await storage.put(workspace.id, docId, key, 'test.txt', blob, user.id);
const url = storage.getUrl(workspace.id, docId, key); const url = storage.getUrl(workspace.id, docId, key);
@@ -79,11 +83,12 @@ test('should get comment attachment with access url', async t => {
test('should delete comment attachment', async t => { test('should delete comment attachment', async t => {
const workspace = await module.create(Mockers.Workspace); const workspace = await module.create(Mockers.Workspace);
const user = await module.create(Mockers.User);
const docId = randomUUID(); const docId = randomUUID();
const key = randomUUID(); const key = randomUUID();
const blob = Buffer.from('test'); const blob = Buffer.from('test');
await storage.put(workspace.id, docId, key, 'test.txt', blob); await storage.put(workspace.id, docId, key, 'test.txt', blob, user.id);
await storage.delete(workspace.id, docId, key); await storage.delete(workspace.id, docId, key);
@@ -94,11 +99,12 @@ test('should delete comment attachment', async t => {
test('should handle comment.attachment.delete event', async t => { test('should handle comment.attachment.delete event', async t => {
const workspace = await module.create(Mockers.Workspace); const workspace = await module.create(Mockers.Workspace);
const user = await module.create(Mockers.User);
const docId = randomUUID(); const docId = randomUUID();
const key = randomUUID(); const key = randomUUID();
const blob = Buffer.from('test'); const blob = Buffer.from('test');
await storage.put(workspace.id, docId, key, 'test.txt', blob); await storage.put(workspace.id, docId, key, 'test.txt', blob, user.id);
await storage.onCommentAttachmentDelete({ await storage.onCommentAttachmentDelete({
workspaceId: workspace.id, workspaceId: workspace.id,
@@ -113,14 +119,15 @@ test('should handle comment.attachment.delete event', async t => {
test('should handle workspace.deleted event', async t => { test('should handle workspace.deleted event', async t => {
const workspace = await module.create(Mockers.Workspace); const workspace = await module.create(Mockers.Workspace);
const user = await module.create(Mockers.User);
const docId = randomUUID(); const docId = randomUUID();
const key1 = randomUUID(); const key1 = randomUUID();
const key2 = randomUUID(); const key2 = randomUUID();
const blob1 = Buffer.from('test'); const blob1 = Buffer.from('test');
const blob2 = Buffer.from('test2'); const blob2 = Buffer.from('test2');
await storage.put(workspace.id, docId, key1, 'test.txt', blob1); await storage.put(workspace.id, docId, key1, 'test.txt', blob1, user.id);
await storage.put(workspace.id, docId, key2, 'test.txt', blob2); await storage.put(workspace.id, docId, key2, 'test.txt', blob2, user.id);
const count = module.event.count('comment.attachment.delete'); const count = module.event.count('comment.attachment.delete');

View File

@@ -59,7 +59,8 @@ export class CommentAttachmentStorage {
docId: string, docId: string,
key: string, key: string,
name: string, name: string,
blob: Buffer blob: Buffer,
userId: string
) { ) {
const meta = autoMetadata(blob); const meta = autoMetadata(blob);
@@ -75,6 +76,7 @@ export class CommentAttachmentStorage {
name, name,
mime: meta.contentType ?? 'application/octet-stream', mime: meta.contentType ?? 'application/octet-stream',
size: blob.length, size: blob.length,
createdBy: userId,
}); });
} }

View File

@@ -13,6 +13,7 @@ test.after.always(async () => {
test('should upsert comment attachment', async t => { test('should upsert comment attachment', async t => {
const workspace = await module.create(Mockers.Workspace); const workspace = await module.create(Mockers.Workspace);
const user = await module.create(Mockers.User);
// add // add
const item = await models.commentAttachment.upsert({ const item = await models.commentAttachment.upsert({
@@ -22,6 +23,7 @@ test('should upsert comment attachment', async t => {
name: 'test-name', name: 'test-name',
mime: 'text/plain', mime: 'text/plain',
size: 100, size: 100,
createdBy: user.id,
}); });
t.is(item.workspaceId, workspace.id); t.is(item.workspaceId, workspace.id);
@@ -30,6 +32,7 @@ test('should upsert comment attachment', async t => {
t.is(item.mime, 'text/plain'); t.is(item.mime, 'text/plain');
t.is(item.size, 100); t.is(item.size, 100);
t.truthy(item.createdAt); t.truthy(item.createdAt);
t.is(item.createdBy, user.id);
// update // update
const item2 = await models.commentAttachment.upsert({ const item2 = await models.commentAttachment.upsert({
@@ -46,6 +49,7 @@ test('should upsert comment attachment', async t => {
t.is(item2.key, 'test-key'); t.is(item2.key, 'test-key');
t.is(item2.mime, 'text/html'); t.is(item2.mime, 'text/html');
t.is(item2.size, 200); t.is(item2.size, 200);
t.is(item2.createdBy, user.id);
// make sure only one blob is created // make sure only one blob is created
const items = await models.commentAttachment.list(workspace.id); const items = await models.commentAttachment.list(workspace.id);

View File

@@ -32,6 +32,7 @@ export class CommentAttachmentModel extends BaseModel {
name: input.name, name: input.name,
mime: input.mime, mime: input.mime,
size: input.size, size: input.size,
createdBy: input.createdBy,
}, },
}); });
} }