Commit Graph
16 Commits
Author SHA1 Message Date
yeuimu ab79325ab0 perf(public): 公开读路径进程内分域缓存——meta/goods/matrix 版本域 + TTL 兜底 + in-flight 合并
- PublicCacheService:分域版本号失效(bump 即作废,不等 TTL)、loader 期间
  bump 的竞态防护(返回但不回写)、并发 miss 单飞、PUBLIC_CACHE_DISABLED
  /TTL_MS/MAX_ENTRIES 应急开关;@Global 模块
- PublicService 六端点接缓存:列表缓存全量物化(分页切片在缓存外按请求执行,
  修复'所有页返回第一页'的切片缓存错误)、详情/首页/树/标签组/树序元数据/
  族最低价聚合各按依赖域缓存
- 全写路径挂钩 bump:admin CRUD(goods/categories/countries/tags/tag-groups/
  positions/origin-goods 标签)、sync 三同步、族重算、整理全家桶——
  事务提交成功后失效对应域,product-families 经 recompute 天然覆盖
- 测试:PublicCacheService 单测 13 例 + 失效链路集成 8 例(读命中/写后立即可见
  端到端/每条写路径域断言);既有两套件测数据语义改为显式禁缓存
2026-09-03 03:40:20 +08:00
yeuimu c3be8ab979 fix(goods): 商品展示名统一「品名 SKU」——剥 ASCII 型号限定词、纯款号补描述
左栏商品名显示成光款号(如 PLTK016)的根因是双层解析不一致:api 写路径按
首括号对解析产出「童装…(DTG180) PLTK016」,admin 展示解析按末括号取品名
误显示成 PLTK016。

- admin parseLinkName 对齐 api 首括号对解析 + 无 SKU 段中文品名守卫,
  cleanLinkName 剥离 ASCII 型号限定词(中文括号内容保留)
- api 新增 cleanGoodDisplayName/describePureSkuGoodName,接入 create/update/
  batchCreate(batchCreate 补上缺失的 normalize);纯款号按 SDS 分类名补描述
- 新增幂等存量修复脚本 fix:good-names(默认 dry-run,--apply 写库)
- 已执行:V2 栈 34 条限定词名、V1 栈 213 条原始链接名规范化,复跑幂等 0

Tests: api 22 suites/199 passed, admin 27 passed, tsc clean
2026-09-03 01:04:22 +08:00
yeuimu a756c8c3c8 fix(admin,api): always show family composition badge N条链接·M个配置
按用户反馈(PLTM006 明明能查到配置数却不显示):左树徽标此前只在
同分类内 ≥2 个配置时才出现,单配置族一行上什么都不显示,而右树同族
链接都挂着绿色已配置徽标,两边数字对不上,反复造成「配置数没显示」
的误解。

- goods API:GOOD_INCLUDE 的 family 带 _count.originGoods,
  GoodDto.originGood.family 增加 memberCount(族成员链接数)
- admin:distinctByFamily 记录 linkCount;一族一行的徽标常显
  「N 条链接 · M 个配置」(链接数=族成员数,配置数=该族官网商品数),
  悬浮仍列出全部配置可打开
- 文档同步徽标语义

效果:PLTM006 行显示「4 条链接 · 1 个配置」(真值:4 条链接仅配了
1 个官网商品);PLTF026 的「4 条链接 · 4 个配置」同屏可对比,其中
4 个配置为历史同国家重复配置,建议另行清理。

验证:admin vue-tsc 干净 + vitest 22/22;api goods spec 18/18;
Prisma _count 查询实测返回 originGoods=4
2026-08-30 03:07:16 +08:00
yeuimu 93ac525c55 refactor(api): parsing out of runtime — pure-mirror sync, explicit organize, auto aggregate recompute
解析去运行时化(三层架构,plans/refactor/organize-script-refactor.md):
- 同步 = 纯镜像:upsertOriginGood 不再写解析列、不再自动挂族;详情同步仍触发重算
- 整理 = 显式人工动作(OrganizeService):解析列回填 → 派生标签(人工接管永不
  覆盖)→ auto-group 建族 → 全量重算;入口 CLI(pnpm --filter @inkreach/api
  organize)+ POST /product-families/organize + 后台「整理」按钮
- 重算 = 纯结构化聚合:不再按名称重派生标签(防上游改名倒灌,回归测试覆盖);
  矩阵维度只认标签/CUSTOM 显式标签,未整理成员不进矩阵;工艺=不打印时
  印花数量以单面占位(纯结构化规则);「恢复自动」走整理的单链接派生
- 派生默认补齐(脚本层假设):名称无单/双面且工艺非不打印 → 印花数量单面印花
- goods 服务建品/更新后仅镜像标签+重算(不派生);含商品名入库规范化
  (normalizeGoodName,管理员输入边界质检)
- organize.service.spec 由 tag-sync spec 迁移 + 防倒灌回归;sync/recompute/
  public/families spec 全部适配;API 173/173,admin typecheck+22/22
2026-08-30 01:27:01 +08:00
yeuimu 1e07c62fc8 feat(admin): country drag-sort + always-available member detail sync
- Country 加 sort_order(默认 0 保持 id 序);PATCH /countries/sort 批量保存
  顺序(对齐 /tags/sort 模式);findAll 与公开 /public/countries 均按
  sortOrder 排序
- CountriesView 表格改为可拖拽行列表:拖动松开即全量保存新顺序,失败回滚
- 商品编辑弹窗成员展开面板:同步详情按钮常驻(已同步显示 重新同步详情),
  不再只在未同步态出现
- goods.service.spec 的 FamilyRecomputeService mock 补齐 syncFamilyTags 等
  方法(全量并行时其他套件的扫名归族会把本套件夹具收进族,create/update
  会调用到,mock 缺方法导致偶发 TypeError)
- api 164/164、admin typecheck+22/22+构建全绿
2026-08-28 20:00:56 +08:00
yeuimu ee336968a0 feat(product-family): derive tags per link name (印花数量/工艺/物流 rules) 2026-08-28 15:33:11 +08:00
yeuimu eedfbb344e feat(product-family): auto-derive logistics/craft tags from family members 2026-08-28 14:57:25 +08:00
yeuimu 4eadb67c36 feat(product-family): replace legacy good merge with family mechanism in config view and public detail 2026-08-28 14:14:58 +08:00
yeuimu 6418aa7302 feat(api): public good detail family block behind gray-release flag 2026-08-28 13:40:19 +08:00
yeuimu c8531bfe08 feat(api): category-based family grouping, tree family info and custom goods family attribution 2026-08-28 12:43:58 +08:00
yeuimu cbdb507be9 fix(api): allow pageSize up to 1000 so admin goods tree can load full list 2026-08-28 09:36:15 +08:00
yeuimu 9c279ae393 feat(goods): support merged secondary origin goods in create/update/detail 2026-08-27 18:15:56 +08:00
yeuimu 6c61a4e871 feat(deploy): production deployment setup and fixes
- Debian-based api image (bookworm-slim), docker/debian mirrors, prisma
  binaryTargets for openssl 3.0
- nginx: admin SPA under /admin, TLS via acme.sh (ZeroSSL) + auto-renewal
  cron, http->https redirect
- prisma: add origin_goods.delisted migration, sync missing schema
  (good_image/tag_font_color/good_tags), fix users.createdAt Timestamptz
- api: CORS wildcard reflection, helmet CORP cross-origin, price
  backfill in persistProductDetail, categoryIcon ancestor fallback,
  mediaByColor per-color gallery in public goods detail
- admin: /admin base path (vite + router)
- import-data.mjs: udt_name casting, serial sequence advance fix
2026-08-26 14:23:09 +08:00
yeuimu b04623ebdd feat(goods): add editable custom products 2026-08-21 14:45:42 +08:00
yeuimu d375df810d feat(admin): manage and sync product details 2026-08-21 10:18:57 +08:00
yeuimu 7e04877bb6 chore: migrate to pnpm workspaces monorepo with Turborepo
- Restructure directories: apps/api, apps/admin, apps/website
- Add root pnpm-workspace.yaml, turbo.json, .prettierrc, .gitignore
- Rename packages to @inkreach/api, @inkreach/admin, @inkreach/website
- Add shared packages: packages/tsconfig, packages/shared-types
- Add pnpm.onlyBuiltDependencies for native builds
- Update docs: README.md, structs.md
- All three projects build successfully
2026-07-11 16:54:05 +08:00