feat(albums): soft-delete albums (admin+owner, hidden & irreversible, both app entries)

契约 deleteAlbum(DELETE /albums/{albumId} → 204 幂等)+ status enum 'deleted':
- 服务端:softDelete(canView 404→canManage 403 防枚举;乐观锁 claim +
  outbox album.updated priority=high + audit album.delete);列表/详情/更新/
  成员/资产/分类/水印/照片/展示位绑定全部 deleted→404;公开端 cn
  (status!=='active')与 ov(isAlbumVisibleOv)天然屏蔽;ov 副本经
  album.updated 载荷 status 直投自动下线
- Admin:列表表格操作「删除」+ 详情页头「删除相册」(确认含不可恢复说明)
- App:操作面板「删除相册」(红字、二次确认、成功退回列表并刷新)
- 验证:API 56/56、App 397/397(analyze 0)、admin typecheck/lint/test/build 绿

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-09-23 10:13:08 +08:00
parent 9cb960c27a
commit 8e674a902e
31 changed files with 995 additions and 258 deletions
+6 -2
View File
@@ -316,7 +316,10 @@
"viewTable": "Table view",
"loadedCount": "{n} albums loaded",
"cursorNote": "Sorted by creation time · cursor-based loading",
"emptyFiltered": "No albums match these filters"
"emptyFiltered": "No albums match these filters",
"actionDelete": "Delete",
"deleteConfirm": "Delete album \"{title}\"? It becomes invisible immediately and cannot be restored (data retained; ops-only recovery).",
"deleted": "Album deleted"
},
"form": {
"createTitle": "New Album",
@@ -385,7 +388,8 @@
"fieldOwnerId": "Owner",
"subtitle": "Album workspace · Manage the moments that matter",
"share": "Share album",
"tabAssets": "Branding assets"
"tabAssets": "Branding assets",
"delete": "Delete album"
},
"banner": {
"kind": "Asset Kind",
+6 -2
View File
@@ -316,7 +316,10 @@
"viewTable": "表格视图",
"loadedCount": "已加载 {n} 个相册",
"cursorNote": "按创建时间排序 · 游标加载",
"emptyFiltered": "没有符合筛选条件的相册"
"emptyFiltered": "没有符合筛选条件的相册",
"actionDelete": "删除",
"deleteConfirm": "确定删除相册「{title}」?删除后立即不可见且不可恢复(数据保留,仅运维可恢复)。",
"deleted": "相册已删除"
},
"form": {
"createTitle": "新建相册",
@@ -385,7 +388,8 @@
"fieldOwnerId": "负责人",
"subtitle": "相册工作区 · 管理活动中的精彩瞬间",
"share": "分享相册",
"tabAssets": "品牌资产"
"tabAssets": "品牌资产",
"delete": "删除相册"
},
"banner": {
"kind": "资产类型",