浅念
bfba76b5e6
fix(ads): 终审修复——staging 前缀+运行时上限核验/失效绑定编辑/白名单去 heic/杂项
...
- verifyStaging 硬化(services/api/src/ads/ads.service.ts):新增键前缀核验
(仅 OBJECT_KEY_ROOT/ads/staging/ 布局,防照片域任意键被提升为公开广告)
与运行时 2MB 上限(head.bytes > AD_UPLOAD_MAX_BYTES → 400 报文含限额值
——init 申明管不住实际 PUT 体,create/update 是唯一核验点);e2e ⑰ 以
测试 storage 直接 presignPut 真实对象覆盖两分支
- 失效绑定编辑 400(admin AdsFormDialog):PATCH 仅在 albumIds 实际变化时
携带(albumIdsChanged 序敏感深比较,纯函数落 adsLogic + vitest 用例);
preloadOptions 解析失败的绑定 ID 加「已失效,可移除」后缀(zh/en 新增
adsManage.form.staleAlbum)——软删绑定不再挡住其它字段保存
- 白名单去 heic(原图直出无变体兜底,Chromium/Firefox 不渲染=破图):
contracts 三处 enum 收窄 [image/jpeg, image/png] 并重生成类型;dto 定义
广告域独立 AD_IMAGE_CONTENT_TYPES(与照片域 UPLOAD_CONTENT_TYPES 分离),
AD_IMAGE_EXTENSIONS 由其派生;init 对 .heic 文件名以广告域集合二次核验
拒绝(共享 extOfFilename 仍认 heic,杜绝 init 放行→create 中段断裂);
e2e heic 矩阵 400;admin accept/文案/类型同步收窄
- searchAlbums 补 catch(http 层已弹 toast,本地静默保持旧选项)
- ActivityPage 关闭记忆测试补位(activity.spec):dismissed 不拉取不渲染、
close 写 sessionStorage 并清空轮播两用例(getPublicAds 入替身防真实 fetch)
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-29 02:20:21 +08:00
浅念
b3e89f7efb
fix(admin): 广告位排序并列簇修正——create 追加 max+1/move 纯逻辑抽取/相册下拉预载
...
评审跟进(C1/I1/M3/M5):
- C1 排序并列簇:新建此前不送 sortOrder(服务端缺省 0)→ 3+ 广告即全 0
并列,首次上移/下移即产出错误顺序且经 outbox 立即传导 ov。修复双管:
① 新建载荷带 sortOrder=父页 max(现有)+1(空列表=0,尾部追加保证全序,
并列簇从源头不再产生——无存量数据,评审选项 B);② 上移/下移目标值
计算抽取为纯函数 planAdjacentMove(异值互换/并列错开抬邻居避免负值),
≥3 并列簇局限以 spec 文档化用例登记(create 追加后为 dead insurance),
index.vue 改用纯函数并跳过值未变侧的 no-op PATCH
- I1 相册下拉:对话框每次打开均预载选项(新建态同样,对照 SlotBindDialog
打开即 searchAlbums('') 先例),消除未输入时误显「无匹配相册」;编辑态
绑定 ID 兜底回显逻辑合并入 preloadOptions
- M3 en 复数:scopeTargeted 用 vue-i18n 复数 "{n} album | {n} albums"
(t(key, n))
- M5 预览对象 URL 兜底:onUnmounted(releasePreview) 防非常规卸载路径泄漏
已登记暂缓(非本次):M2 move 时序守卫细化、M4 相册搜索与 SlotBindDialog
的同构抽取、M6 编辑 diff-only 载荷。
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-29 01:35:09 +08:00
浅念
239ef5648f
feat(admin): 广告位管理页——上传/链接/绑定相册/开关/排序
...
Task 11(广告位轮播):admin 后台广告位治理页。
- utils/ads/adsLogic:scopeKind/normalizeAlbumIds/isValidAdLinkUrl 纯逻辑
(与服务端 dto LINK_URL_PATTERN、albumIds 归一语义同源)+ vitest 6 例
- api/ads + types/api/ads.d.ts:list/create/update/delete/initUpload 五端点
(对照 embedSlots.ts 逐字风格;列表全量不分页、imageUrl 现签)
- views/system/ads:列表(缩略图/备注名/链接截断/投放范围标签/启停开关
失败重拉回滚/上移下移 sortOrder 互换/硬删确认)+ 新建编辑对话框
(staging 直传 init→裸 fetch PUT、Content-Type 与申明一致;相册多选
远程搜索复用 /v1/albums 分页+本地过滤,绑定 ID 超限/失效以裸 ID 兜底;
编辑换图才带 image 三字段;albumIds 归一空→null 转全局)
- 路由/菜单:system 组 ads 页(ri:advertisement-line,workspace 分组);
locales zh/en 补 menus.system.ads + adsManage 子树(键集一致入单测)
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-29 01:21:33 +08:00
浅念
aaea76b0e3
fix(admin): copy buttons dead on HTTP origin — execCommand fallback
...
navigator.clipboard 仅安全上下文(HTTPS/localhost)可用,测试服务器经
http://IP:32005 访问时为 undefined,四处复制按钮(公开令牌/分享链接/
嵌入代码/重置密码)点击即抛 TypeError 且无提示。统一 utils/clipboard
copyText:API 优先、失败降级隐藏 textarea + execCommand。
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-23 17:01:54 +08:00
浅念
4f6790d630
feat(ui06): B2 shared components + B3a core pages — album cards, photo grid, viewer, summary header
...
- 类型补齐契约字段:Summary.cover / AdminPhoto.preview(SignedUrl;服务端已返回,B0 核对)
- AlbumCoverCard:封面卡(公开/状态/上传 pill,无封面中性占位,不显示 owner 名)
- 相册列表:默认封面卡片网格(3列/1700+4列)+ 表格切换 + 已加载内搜索 + 公开状态筛选 + 摘要行
- AlbumSummaryHeader:300×144 封面 + 两列紧凑资料 + 高级折叠(ownerId/统计时间收敛)
- 详情页壳:页头(编辑/分享固定主操作)替换 ElDescriptions 大区;banner 区 B3c 收纳
- PhotoGrid + PhotoPreviewDialog:照片网格默认(preview.thumb 签名 URL)+ 深色大图(browse URL、
行内隐藏/恢复/软删除复用表格状态机);网格勾选与表格 selection 合并批量目标
- e2e 适配默认网格视图(albums/governance 断言前切表格);batchHide fixture 补 preview
- typecheck/lint/vitest 87 项全绿
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-22 23:19:21 +08:00
浅念
8c4906c2f2
feat(embed,ui04): E07 acceptance — matrix completion, hostile-CSS hardening, measurements and record closure
...
- E07 e2e (7 cases): 4-viewport fixed size, narrow shrink + dual-slot 12px stack, single/static + empty state + two-photo loop copies, broken-thumb drop, reducedMotion stop with manual arrows, forged postMessage rejected, hostile CSS (!important box-sizing/border) with inline-important countermeasures + duplicate script dedup
- loader v2: geometry-critical properties upgraded to inline !important (beats host stylesheet !important)
- pre-existing fixes: likes.spec view-count assertion vs concurrent session's AlbumHeader unicode icons (toContainText); embed-v2 host port moved to 3998 (3999 collides with embed-crossorigin under parallel full runs); prettier formatting of two concurrent-session files (formatting-only)
- evidence: matrix EMB-A01..A16 closed in acceptance record (mechanism-level items honestly marked), measurements (loader v2 9885B/gzip 3959B, first-load 1 GET + 1 WS, DOM<=16), refreshed screenshots/recordings, master plan UI-04 note
- regression: root lint/typecheck/test 12 packages green; embed suites 43/43; admin embed-slots 5/5; journey pre-existing env failure reproduced at clean HEAD (registered)
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-22 18:56:38 +08:00
浅念
eebf3b3334
feat(admin): standard pagination + synced profile columns on users list
...
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-22 18:10:53 +08:00
浅念
1d1979f540
feat(viewer,ui04): E02 static fidelity — real photo fixtures, measured shell/photo/collapse specs, edge fade
...
- fixtures: 8 picsum-seeded real photos (mixed ratios); seedPhoto thumbBytes/browseBytes injection
- e2e E02 block: wrapper shell (195x280/radius/border/#10161E), photo strip (193w, ratio-height, 3px gap), collapse (44/44 hit, 24 visual, sole button), desktop+mobile screenshots
- EmbedStream: top/bottom 12px dark fade (0.12, §2.3 optional item)
- fix(admin): pre-existing eslint globals gap for ElNotification (template drift, blocks lint gate)
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-22 13:01:34 +08:00
浅念
66d1eb3e9f
feat(embed,ui04): E01 v2 contract skeleton — displayMode/scrollSpeed/reactionsEnabled, v2 loader entry and fixed 195x280 shell
...
- contracts: EmbedSlotSettings optional v2 fields (carousel default) + SlotSettingsPayload; gen + redocly green
- api: DTO validation + normalization full-set (cn manage + ov public projection share normalizeStoredSettings)
- embed-loader: params v2 parse/merge/url family, loader-v2.js fixed shell (border/radius/#10161E/safe-area, resize ignored, stack gap 12), dual-artifact build+sync; v1 source frozen
- viewer: EmbedPage v=2 branch, EmbedStream (viewport/track/real anchors/collapse/empty), stream.ts pure fns, i18n zh/en
- admin: types + utils (create default vertical-stream, clampScrollSpeed, v1/v2 snippet selection)
- tests: loader 36 (+9 v2), viewer 222, admin 82, api unit 51, v1 embed e2e 20, v2 E01 gate 2 (195x280 desktop+mobile cross-origin, no footer)
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-22 12:50:28 +08:00
浅念
ac23a4c40e
feat(admin): UI-01 embed slot config form and live preview
...
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-21 19:26:48 +08:00
浅念
7385785504
feat(i18n): T15 full-stack language audit with coverage assertions
...
- viewer/admin 错误码→文案映射按契约 ErrorCodes 枚举全集登记(机器守护
spec 遍历枚举断言无缺漏 + 映射键在 zh/en 词条均存在 + locale 键集
递归相等);mobile 镜像补齐 DOWNLOAD_DISABLED(P4a 增补漏登)
- 漏译修复:viewer.photoRemoved en 侧缺失(审计测试捕获);
DOWNLOAD_DISABLED 观众侧专属文案 + useDownload 专属提示接线;
admin apiMsg 增 RATE_LIMITED/ALBUM_NOT_PUBLIC/DOWNLOAD_DISABLED/
SYNC_AUTH_FAILED 四码词条
- 运行时抽查:admin 主旅程 en 版 e2e(登录→相册管理全英文 + 偏好
持久);embed iframe lang=en 渲染与深链跟随 e2e(zh 侧既有用例覆盖)
- contracts 新增 ./errors 浏览器安全子路径(errors.ts 纯 TS);
admin 增 @photo/contracts devDep(仅测试消费)
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-20 23:44:27 +08:00
浅念
0238f505c4
feat(admin): embed slot management with code snippet
...
P4b Task 5:/system/embed-slots 管理页(Task 8/9 页面模式:useCursorList
游标累积 + 对话框治理)。列表(名称/绑定相册/启停/configVersion/更新时间,
启停开关行内 PATCH → configVersion+1 toast 提示)+ 新建/编辑对话框
(设置表单位置/尺寸/间隔/语言/默认收起,intervalMs 契约区间夹取;编辑按
整体替换语义提交完整 settings)+ 绑定相册对话框(相册标题/ID 搜索选中 →
确认框携带 A22 文案「configVersion 将递增,官网无需改动」;清空即解绑)+
嵌入代码卡({EMBED_ORIGIN}/embed/v1/loader.js + data-slot 令牌,一键复制;
EMBED_ORIGIN=VITE_EMBED_ORIGIN 缺省本机 viewer dev,.env.example 登记)。
- API 层 src/api/embedSlots.ts + types/api/embedSlot.d.ts(契约镜像)
- vitest 9 例:表单→载荷(缺省+夹取)、编辑载荷收敛、snippet 拼接、
环境基址兜底、绑定变更分类、zh/en 键一致 + A22 短语断言
- Playwright e2e(真实 cn+ov 后端):新建→绑定(gov-photos 直种 +
seed-fixture 新增 sync-flush 模式经 bootstrap/真实发送管线投影 photos_ov)
→嵌入代码卡含 token→ov 公开 feed 返回相册照片→换绑 configVersion+1 +
feed 切换(A22)→停用 feed 404;admin playwright 配置补 ov webServer
- i18n zh/en(embedSlotsManage.* + menus.system.embedSlots)
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-20 23:25:59 +08:00
浅念
f08d68bebf
feat(admin): batch ops, transfer, watermark, usage and qr share pages
...
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-20 21:10:30 +08:00
浅念
618d1d796c
feat(admin): account governance and user sync pages
...
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-20 20:26:53 +08:00
浅念
50c59ca9d4
feat(admin): album management pages with members and categories
...
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-18 12:33:46 +08:00
浅念
a6cc190751
feat(admin): art-design-pro integration with local session auth
...
P1b Task 9: apps/admin based on art-design-pro v3.0.2 (tag, commit
d224dd4; source recorded in apps/admin/SOURCE.md), trimmed to
layout/login/i18n/request/table-form core. Login wired to real
POST /v1/auth/password (single-token session), Bearer header on all
requests, 401 interceptor logout+redirect, request-driven sliding
renewal (refresh at ~80% TTL, single-flight), best-effort
POST /v1/auth/logout on user-menu logout. One protected stub page
(相册管理). Dev port 5176 strictPort + /v1 proxy to 8080. Admin keeps
its own eslint9 flat config; root eslint ignores apps/admin/**.
vitest unit tests for renewal pacing + Playwright e2e (guard redirect,
localized wrong-password error, login lands on stub, token persists
across reload, logout clears session).
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-18 11:47:32 +08:00