feat: 드라이브 업로드·삭제 행위자 추적 추가

연동 프로젝트 폴더의 파일 업로드/삭제와 폴더 삭제를 활동 피드에 기록하고,
파일 삭제를 소프트 삭제(status=deleted + deletedBy/deletedAt 묘비)로 전환해
누가·언제 지웠는지 추적할 수 있게 한다. 실제 객체는 즉시 영구 삭제(복구 제외).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-30 21:54:17 +09:00
parent 2cbd19e791
commit ec54ba0e8d
7 changed files with 154 additions and 5 deletions
+24
View File
@@ -112,6 +112,30 @@ function toProjectActivityItem(api: ApiActivity): ProjectActivityItem {
}
case 'task.removed':
return { ...base, tone: 'task', icon: 'pencil', html: `<b>${actor}</b>님이 <span class="tgt">${title}</span> 업무를 삭제했습니다` }
case 'drive.file_uploaded':
return {
...base,
tone: 'setting',
icon: 'repo',
html: `<b>${actor}</b>님이 파일 <b>${escapeHtml(pstr(p, 'fileName'))}</b>을(를) 업로드했습니다`,
}
case 'drive.file_deleted':
return {
...base,
tone: 'setting',
icon: 'pencil',
html: `<b>${actor}</b>님이 파일 <b>${escapeHtml(pstr(p, 'fileName'))}</b>을(를) 삭제했습니다`,
}
case 'drive.folder_deleted': {
const cnt = typeof p.fileCount === 'number' ? p.fileCount : 0
const suffix = cnt > 0 ? ` (파일 ${cnt}개 포함)` : ''
return {
...base,
tone: 'setting',
icon: 'pencil',
html: `<b>${actor}</b>님이 폴더 <b>${escapeHtml(pstr(p, 'folderName'))}</b>을(를) 삭제했습니다${suffix}`,
}
}
default:
return { ...base, tone: 'task', icon: 'check', html: `<b>${actor}</b>님의 활동` }
}
+3
View File
@@ -19,6 +19,9 @@ export type ApiActivityType =
| 'task.checkpoint_reported'
| 'task.file_removed'
| 'task.removed'
| 'drive.file_uploaded'
| 'drive.file_deleted'
| 'drive.folder_deleted'
// 활동(API 원시) — 표시 문구/아이콘/톤은 프론트가 type+payload 로 조립한다
export interface ApiActivity {