fix(upload): clean up S3 objects when attachments are deleted

- Add Delete/DeleteKeys/KeyFromURL methods to S3Storage
- DeleteAttachment handler now removes the S3 object after DB delete
- DeleteComment collects attachment URLs before CASCADE, then cleans S3
- DeleteIssue collects all attachment URLs (issue + comment level) before CASCADE, then cleans S3

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
yushen 2026-03-31 16:34:47 +08:00
parent 2c76a0b905
commit acba0b8139
6 changed files with 131 additions and 0 deletions

View file

@ -101,6 +101,57 @@ func (q *Queries) GetAttachment(ctx context.Context, arg GetAttachmentParams) (A
return i, err
}
const listAttachmentURLsByCommentID = `-- name: ListAttachmentURLsByCommentID :many
SELECT url FROM attachment
WHERE comment_id = $1
`
func (q *Queries) ListAttachmentURLsByCommentID(ctx context.Context, commentID pgtype.UUID) ([]string, error) {
rows, err := q.db.Query(ctx, listAttachmentURLsByCommentID, commentID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []string{}
for rows.Next() {
var url string
if err := rows.Scan(&url); err != nil {
return nil, err
}
items = append(items, url)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listAttachmentURLsByIssueOrComments = `-- name: ListAttachmentURLsByIssueOrComments :many
SELECT a.url FROM attachment a
WHERE a.issue_id = $1
OR a.comment_id IN (SELECT c.id FROM comment c WHERE c.issue_id = $1)
`
func (q *Queries) ListAttachmentURLsByIssueOrComments(ctx context.Context, issueID pgtype.UUID) ([]string, error) {
rows, err := q.db.Query(ctx, listAttachmentURLsByIssueOrComments, issueID)
if err != nil {
return nil, err
}
defer rows.Close()
items := []string{}
for rows.Next() {
var url string
if err := rows.Scan(&url); err != nil {
return nil, err
}
items = append(items, url)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listAttachmentsByComment = `-- name: ListAttachmentsByComment :many
SELECT id, workspace_id, issue_id, comment_id, uploader_type, uploader_id, filename, url, content_type, size_bytes, created_at FROM attachment
WHERE comment_id = $1 AND workspace_id = $2