Files
inkreach-official-website/docs/superpowers/specs/2026-06-21-goods-redesign.md
T
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

4.0 KiB

Goods Management Redesign

Date: 2026-06-21

Problem

  1. Origin Good name not displayed: GoodsView doesn't show the origin product name/image/price
  2. Single tag per good: Current schema only allows one tag per good via goods.tag_id FK
  3. Easy to miss unconfigured origin products: Flat paginated table with no visibility into which origin products have been configured vs not

Solution

1. Multi-Tag Support (GoodTag Junction Table)

Schema change:

  • New good_tags junction table: (good_id, tag_id) composite PK
  • Migrate existing goods.tag_id data into good_tags
  • Set goods.tag_id to nullable (will be dropped in a future migration)

Backend:

  • CreateGoodDto: tagIds: number[] (replaces tagId)
  • UpdateGoodDto: tagIds?: number[] (replaces tagId)
  • BatchCreateGoodDto: tagIds?: number[] (replaces tagId)
  • QueryGoodDto: tagId filter queries tags.some instead of direct FK
  • GoodsService.create/update: manage good_tags records in transaction
  • GOOD_INCLUDE: include tags: { include: { tag: true } }

2. Origin Goods Tree API

New endpoint: GET /origin-goods/tree

Returns origin goods grouped by SDS category, with configuration status:

[
  {
    "sdsCategoryId": "4185",
    "categoryName": "(包邮)180g纯棉T恤-单面印花",
    "originGoods": [
      {
        "id": "123",
        "goodName": "产品A",
        "goodImage": "https://...",
        "goodPrice": "12.50",
        "sdsGoodId": "p-123",
        "configuredCount": 2,
        "configuredCountries": ["美国", "英国"]
      }
    ]
  }
]

Origin goods without sdsCategoryId are grouped under "未分类".

3. Admin UI: Dual Tree Layout

┌──────────────────────────────────────────────────────────┐
│  [搜索原产品]                          [210/439 已配置]   │
├───────────────────┬─────────────────────────────────────┤
│  首页分类树        │  原产品分类树                        │
│                   │                                     │
│  ▼ 美国            │  ▼ (包邮)180g纯棉T恤               │
│    ▼ T恤          │    ✓ 产品A [美国,英国]               │
│    ▼ 卫衣         │    ✗ 产品B [未配置]                  │
│  ▼ 英国            │  ▼ 未分类                           │
│  ▼ 韩国            │    ✗ 产品C [未配置]                  │
├───────────────────┴─────────────────────────────────────┤
│  详情/操作区域                                           │
│  - 选左侧分类: 该分类下所有 goods 表格                    │
│  - 选右侧原产品: 该原产品的配置详情 + 快捷配置按钮         │
│  - 多标签选择 (el-select multiple)                       │
└──────────────────────────────────────────────────────────┘

Key interactions:

  • Left tree click: filter goods by selected category
  • Right tree click: show origin good detail + all its goods configs
  • Right tree badges: ✓ configured / ✗ unconfigured
  • Quick configure: select country+category+tags, click origin goods to batch create
  • Statistics bar: configured/total count

4. Data Migration

-- Step 1: Create good_tags table
-- Step 2: Copy existing tag_id data
INSERT INTO good_tags (good_id, tag_id, created_at)
  SELECT good_id, tag_id, NOW() FROM goods WHERE tag_id IS NOT NULL;
-- Step 3: Good.tag_id becomes nullable (already nullable)