feat(server): add comment-attachment storage (#12911)

close CLOUD-230












#### PR Dependency Tree


* **PR #12911** 👈
  * **PR #12761**
    * **PR #12924**
      * **PR #12925**

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**
* Added support for uploading and retrieving comment attachments in
workspace documents via a new API endpoint.
* Introduced a service for managing comment attachments, including
storage, retrieval, deletion, and URL generation.
* Implemented localized error messages and improved error handling for
missing comment attachments.

* **Bug Fixes**
  * Improved error feedback when comment attachments are not found.

* **Tests**
* Added comprehensive tests for comment attachment storage, retrieval,
deletion, API endpoint behavior, and permission checks.

* **Documentation**
* Updated GraphQL schema and localization files to include new error
types for comment attachments.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
fengmk2
2025-07-01 15:04:52 +08:00
committed by GitHub
parent 6e034185cf
commit e8bc8f2d63
12 changed files with 456 additions and 7 deletions
@@ -917,4 +917,8 @@ export const USER_FRIENDLY_ERRORS = {
type: 'resource_not_found',
message: 'Reply not found.',
},
comment_attachment_not_found: {
type: 'resource_not_found',
message: 'Comment attachment not found.',
},
} satisfies Record<string, UserFriendlyErrorOptions>;
@@ -1079,6 +1079,12 @@ export class ReplyNotFound extends UserFriendlyError {
super('resource_not_found', 'reply_not_found', message);
}
}
export class CommentAttachmentNotFound extends UserFriendlyError {
constructor(message?: string) {
super('resource_not_found', 'comment_attachment_not_found', message);
}
}
export enum ErrorNames {
INTERNAL_SERVER_ERROR,
NETWORK_ERROR,
@@ -1216,7 +1222,8 @@ export enum ErrorNames {
INVALID_SEARCH_PROVIDER_REQUEST,
INVALID_INDEXER_INPUT,
COMMENT_NOT_FOUND,
REPLY_NOT_FOUND
REPLY_NOT_FOUND,
COMMENT_ATTACHMENT_NOT_FOUND
}
registerEnumType(ErrorNames, {
name: 'ErrorNames'