摘要
FR-3.2-02(溯源 AI-3.2-02)要求:企业通过深度资质认证、业务信息补全、交易权限开通后,获得深度权益。PRD 验收要点原文:「发布、交易、开店等深度权益仅在资质通过后开放;资料退回—补正—重提闭环可用 」。现状判定为部分实现 :资质提交/重提/维护全套在、资格通道迁移在;差距 = 两阶段分层未成型 + 权益门控执行点缺失 + 零 AI 辅助。
本卡方案 = 流程产品化 (两阶段分层注册向导:阶段一最小集注册复用既有六步工作流零改动 → 阶段二向导补全深度资质走差异改造后的重提闭环)+ 权益门控 (统一 assertSellerApprovedStep 门控原语,判定条件 APPROVED && trade_profile 非空,插入发布/报价/结算三个执行点,feature flag 两阶段灰度)。AI 辅助(OCR/智能填单/材料预审)为后续增强段,只预留接入位、不阻塞本条。全程零 schema migration。
深度权益口径
6 项
发布产品 / 参与 B2B 集采报价 / 开启线上交易 / 结算对账 / 开通数字店铺 / 启用数字员工
注册向导
4 步
企业基础信息 → 执照上传与归属核验 → 行业资质+验厂资料 → 提交与预检
门控执行点
G1–G6
现状可插桩 4 点(发布/报价/交易/结算)+ 从零新建预留 2 点(数字店铺/数字员工)
数据模型变更
0
零 schema migration;深度判定复用 approval_data JSON 既有 trade_profile 键;草稿仅存 localStorage
关键概念
两阶段分层注册
阶段一(信息层,对齐 FR-3.2-01):最小集字段快速注册、轻审过审即开放展示/浏览权益;阶段二(深度层,本卡主体):向导补全行业资质与验厂资料,深审通过开放深度权益六项。
approval_status 三态机
seller-profile 的 PENDING / APPROVED / REJECTED 三态 + approval_data JSON 快照 + reviewed_at/reviewed_by/rejection_reason 留痕(seller-profile.ts:16-37)。本卡不改三态机。
深度资质判定
entitlementGranted = (approval_status === "APPROVED") && (approval_data?.trade_profile != null)——语义即 PRD 口径「资质通过」= 深度资质过审;单点判定,全部执行点复用。
register-vendor 六步工作流
register-vendor.ts:232(复核精确命中)六步串行:auth 创建 → 内联建 seller → 建 profile(PENDING)→ 建 distribution policy → 推荐码绑定 → 执照 nonce 校验;全链带补偿。
退回—补正—重提闭环
resubmit-qualification/route.ts:54-65:守卫 → 重置 PENDING → 清空审核留痕 → 重新人工审核;配套商家端表单与资料维护展示。本卡做三项差异改造(R1/R2/R3)。
执照 nonce 防伪(M-16)
注册前端生成 registration_nonce 随执照上传(guest+nonce 持有私有文件),注册成功时 verifyLicenseOwnershipStep 校验归属并转移给新 seller,防执照盗用。
资格通道迁移(不混同)
apply-btob-reseller.ts / apply-btoc-shell-store.ts 是已入驻商家在渠道体系内的资格切换(H2B 买家 → B2B reseller → B2C shell store),不是 注册分层,本卡不改造。
灰度开关 deep_entitlement_gate
featureFlags 新增配置:false(阶段1)= 违规仅 warn 留痕,行为同现状;true(阶段2)= step 内抛错强制拒绝;切换无需发版。
草稿候选 B(localStorage)
分步草稿仅存商家本人浏览器,提交动作才落库——红线不破:资质/审核/权益以后端 approval_data 单一数据源为准,草稿丢失可重填。
方案设计
设计红线(强制验收)
AGENTS.md §0.1 红线
Workflow 承载业务逻辑 :全部数据变更(注册/资质提交/状态迁移)走 Workflow,守卫在 step 内实现;现状 resubmit-qualification route 直写 module 的瑕疵一并收敛;
不修改上游源码 :全部改动在本地 workflows/api/vendor-panel,无上游包内改动;
后端是单一数据源 :资质快照、审核状态、权益判定以后端 seller_profile 为准,向导草稿仅前端便利载体;
参数化 SQL :本卡无新增裸 SQL(发布校验既有 knex 查询已参数化,publish-vendor-product.ts:21-33 范式沿用)。
现状底座与复用边界
判定部分实现 的证据链(全部经复核,漂移处双写标注):
模块 锚点(file:line) 结论
① 注册工作流(复用主体) backend/src/workflows/vendor-registration/register-vendor.ts(291 行)registerVendorWorkflow = createWorkflow("register-vendor", …) :232 (复核精确命中),六步串行 + 补偿范式(profile 创建 step 的 compensation 删除 profile :221-230),详见图2
② 资质字段三类型(契约) backend/src/types/seller-approval.ts(50 行)SellerQualificationData :35-50 / SupplierTradeDocument :10-15 / SupplierTradeProfile :17-31——字段级契约见数据模型与 API 契约 ;validator「仅 company_name 必填」(validators.ts:15)天然支持最小集注册
③ 审核状态机(权益门控锚) backend/src/modules/seller-profile/models/seller-profile.ts:16-37三态枚举(复核常量 :8-12)+ approval_data 快照(:31)+ 审核留痕三元组(:32-34)+ sales_channel_id(:21)/business_type(:22-25)/capabilities(:26);patch 构造器 approval-policy.ts:22-55;admin 审核端 approve/reject 链带补偿(reject-seller.ts:81-92 Saga 范式)
④ 退回—补正—重提闭环(沿用主体) backend/src/api/auth/vendor/resubmit-qualification/route.ts(78 行)状态守卫 :54-60 (复核)+ 更新 :62-69 :重提即重置 PENDING 并清空留痕;前端配套 resubmit-qualification.tsx:136-159、维护展示 qualification-section.tsx:130-191
⑤ 执照 nonce 防伪(M-16) verify-license-ownership.ts(38 行)归属校验+转移调用 :33-37 (复核),StepResponse :38;nonce 生成 register.tsx:55 → 上传 :87 → upload-license/route.ts:14-20(requireRegistrationNonce;private storage + opaque reference,audit H-15)
⑥ 商家端界面(重构对象) vendor-panel/src/routes/register/register.tsx 等603 行单页表单(wc -l 复核);:111 handleSubmit(复核命中)、:148-163 mutateAsync 一次性提交全量 qualification_data——「一次性提交全部资料」的直接证据
⑦ 资格通道迁移(边界证据) backend/src/workflows/vendor-registration/apply-btob-reseller.ts(61 行,来源锚点路径漂移双写)apply-btob-reseller :30-47(复核:createWorkflow :29-31)与 apply-btoc-shell-store.ts :30-53——经白名单键的渠道资格迁移 ,文件头注释自述仅记录资格状态,非注册分层 ,不改造(§4.4)
⑧ 深度权益执行点现状(门控插入位盘点)
权益 现有代码位 现状是否校验 approval_status
发布产品 publish-vendor-product.ts:25-135(校验函数 :90-117、step 包装 :119-128、workflow :130)❌ 仅校验 ownership/shipping/image/variants/inventory,不查 seller 审核态 (PENDING 商家可提交发布 → listing review)
参与 B2B 集采报价 merchant-send-quote.ts:12 + create-request-for-quote.ts(客户侧 RFQ)❌ 无 seller 资格校验
线上交易 下单/购物车链路(validate-add-to-cart.ts 等) ❌ 无(交易准入 = 渠道分发 + listing review,非资质门控)
结算对账 upsert-seller-manual-payout-profile.ts:26-40(:31-37 仅校验 country_code === "CN")❌ 仅国别校验,不查资质态
数字店铺 全库负证据 :rg -i "数字店铺|digital.?store|ai.?store" → 0 命中—(从零新建,门控原语由本卡供给)
数字员工 同上(AI-3.6-03 范围,规划中) —(同上)
⑨ 负证据(AI 辅助零实现)
rg "智能填单|材料预审|证照识别|智能识别"(六端排除 node_modules)→ 0 命中 ;
rg "OCR"(区分大小写)→ 仅 countries.ts 国家名「DEMOCRATIC」误报(admin-panel/vendor-panel 各 3 处),无任何 OCR 实现;
结论:AI 辅助 = 从零新建 ,按后续增强段处理(预留接入位见向导设计 ),不阻塞本条 TDD。
类别 项
已存在可复用 register-vendor 六步工作流(:232)与全补偿链;资质三类型 JSON 字段契约;approval_status 三态机 + 审核留痕 + ApprovalPolicy patch 构造器;退回—补正—重提闭环(route + 前端 + patch 构造器);执照 nonce 防伪链;validator「仅 company_name 必填」弹性
需扩展 register.tsx 单页表单 → 分步向导(旧表单保留为回滚路由);重提闭环的 APPROVED 态深度资质补全通道 + route 直写 module 收敛为 Workflow;四项深度权益执行点插入门控校验(publish/quote/payout + 交易)
从零新建 共享门控 step 原语 assertSellerApprovedStep(或含深度资质判定的 assertDeepEntitlementStep);AI 辅助全套(后续增强段);数字店铺/数字员工开通入口(归 AI-3.2-04 / AI-3.6-03,本卡只供给门控原语)
sequenceDiagram
autonumber
participant FE as vendor-panel 注册表单
participant API as POST /auth/vendor/register
participant WF as registerVendorWorkflow(六步串行)
participant SP as seller-profile
FE->>API: 提交最小集字段 + registration_nonce
API->>API: VendorRegistrationSchema.parse + sanitizeObject
API->>WF: 事务内执行工作流
WF->>WF: 1 registerSellerAuthStep(auth_identity 创建,含僵尸号治理)
WF->>WF: 2 createSellerWorkflow.runAsStep(内联子工作流保证原子性,失败触发补偿清除)
WF->>SP: 3 createSellerProfileStep(写 PENDING + handle 兜底)
WF->>WF: 4 ensureStoreDistributionPolicyWorkflow(注册即建 distribution policy,防未审先发)
WF->>WF: 5 bindReferralOnRegistrationStep(推荐码绑定,无效降级不阻断)
WF->>SP: 6 verifyLicenseOwnershipStep(M-16 执照 nonce 校验 + 归属转移)
WF-->>FE: Registration submitted for approval
图1. register-vendor 六步工作流时序(现状复用主体,阶段一零改动;来源 register-vendor.ts:232 起)
缺口与目标状态
PRD 验收要点(原文逐字) 技术目标转译
「发布、交易、开店等深度权益仅在资质通过后开放」 深度权益六项的每个执行点插入统一门控:APPROVED 且深度资质完备(approval_data.trade_profile 非空)方可执行;PENDING/REJECTED/无深度资质一律拒绝;门控守卫在 Workflow step 内实现;以两阶段灰度开关控制生效(阶段1 warn → 阶段2 强制)
「资料退回—补正—重提闭环可用」 沿用重提闭环本体 + 维护界面;差异改造 = ①放开 APPROVED 态的深度资质补全提交(两阶段第二阶段入口)②提交动作 Workflow 化(红线)③向导分步录入复用同一数据契约
# 缺口(证据) 目标状态
① 两阶段分层注册流程未成型:现有是资格通道迁移不是分层注册;register.tsx 一次性提交全部资料 分步向导四步制(见下 ):阶段一最小集注册快速过审,阶段二复用重提闭环补全
② 零 AI 辅助(rg 0 命中) 后续增强段 :不阻塞本条 TDD;接入位预留 step2(OCR 证照识别)/ step3(材料预审)
③ 深度权益门控执行点缺失:publish 校验不查审核态、quote/payout 无资格校验——PRD 验收要点当前无技术强制 统一 assertSellerApprovedStep 门控原语 + 四执行点插入清单,feature flag 两阶段灰度
④ 信息层/深度层无区分:现状 APPROVED 即全权益,无法表达「阶段一过审但深度资质未交」 深度权益门控条件 = APPROVED && approval_data.trade_profile 非空(沿用 3 态机不扩状态)
⑤ 重提闭环守卫拒绝 APPROVED 态提交(route.ts:56-60)——「阶段一已过审商家补交深度资质」无通道 守卫放宽为 PENDING / REJECTED / (APPROVED && 无深度资质),提交动作收敛进 Workflow
FR-3.2-01 对照声明(不越界)
信息层基础注册(FR-3.2-01)PRD 判定「已实现」;本卡阶段一即对该链路的流程显式化(最小集字段 + 快速过审),不改其权益语义(企业信息展示/公开浏览注册即可用)。FR-3.2-01 差距栏「一次性提交全部资料 → 两阶段显式呈现(列入 P1 配套优化)」由本卡承接。AI 检索收录/基础智能咨询两项信息层 AI 权益分别归 AI-3.3-02 / AI-3.6-03·3.7-02,本卡不涉及。
两阶段分层注册向导
flowchart TB
subgraph P1["阶段一(信息层,FR-3.2-01 对齐)"]
S1["向导 step1 企业基础信息(最小集注册)"] --> REG["register-vendor 六步工作流(复用零改动)"]
REG --> PEN1["profile = PENDING"]
PEN1 -->|"轻审"| A1["APPROVED(无 trade_profile)"]
A1 --> INFO["信息层权益开放(企业展示 / 公开浏览 / 检索收录)"]
end
subgraph P2["阶段二(深度层,本卡主体)"]
S234["向导 step2 执照上传与归属核验 + step3 行业资质与验厂资料 + step4 提交与预检"] --> RESUB["重提闭环通道(差异改造 R1/R2)"]
RESUB --> PEN2["profile = PENDING(approval_data 全量快照)"]
PEN2 -->|"深审"| A2["APPROVED(trade_profile 在)"]
A2 --> DEEP["深度权益六项开放(门控通过)"]
end
INFO -->|"商家中心向导进入阶段二"| S234
REJ["任一环节 REJECTED"] -.-> LOOP["退回—补正—重提闭环(既有)"]
LOOP -.-> PEN2
图2. 两阶段分层注册总流程(阶段一复用既有链路零改动;阶段二走差异改造后的重提通道;虚线为既有退回闭环)
阶段一复用 register-vendor.ts:232 六步工作流零改动 :validator 本就「仅 company_name 必填」,向导 step1 只收集最小集即满足;registration_nonce 机制保留(无执照时 business_license_url 可选,nonce 仅在有上传时消费——:33-37 仅在有 reference 时 claim);
阶段二提交走差异改造后的重提通道 (见退回—补正—重提闭环 ),approval_data 仍为 SellerQualificationData 全量快照(契约不变)。
四步字段级设计(向导步骤划分定稿)
步骤 字段清单(沿用既有契约字段名) 服务端校验点 Workflow 边界
step1 企业基础信息 (阶段一字段集)
email / password / confirmPassword(:111-148 现有提交对象);company_name* / representative_name / country_code / contact_phone / website_url / business_description(SellerQualificationData :36-45;*=必填,对齐 validators.ts:15-56)
步骤级:email 查重(ERR_EMAIL_ALREADY_REGISTERED,register/route.ts:44-46)、country_code 白名单(validators.ts:53/:71-73);提交级:VendorRegistrationSchema.parse(route.ts:14)+ sanitizeObject(:19-23)
register-vendor 六步工作流复用(:232);守卫全部已在 step 内
step2 执照上传与归属核验
business_license_number / business_license_url(SellerQualificationData :38-39)+ registration_nonce(register.tsx:55 生成、:87 上传携带、:147 提交携带)
上传时 requireRegistrationNonce(upload-license/route.ts:14);提交时 verifyLicenseOwnershipStep nonce 归属校验+转移(M-16 防伪);未上传则本步可跳过(阶段一最小集语义)
执照文件落 private storage(opaque reference,audit H-15);nonce 消费在 register-vendor 第 6 步内
step3 行业资质 + 验厂资料 (阶段二主体)
tax_id(:41);trade_profile: factory_video_url / factory_photo_urls[] / production_line / annual_capacity / equipment_summary / quality_system / export_experience / customer_cases / after_sales_capability(SupplierTradeProfile :18-26)+ documents[]: type / title / url / expires_at(SupplierTradeDocument :11-14)
步骤级:documents 数组结构校验(type/title/url 必填,expires_at 可空);提交级:sanitizeObject 递归清洗(resubmit route.ts:30 范式沿用)
数据变更经 Workflow(改造后的提交流程),守卫在 step
step4 提交与预检
无新字段;预检清单 = ①必填齐备(按目标阶段判定:阶段一最小集/阶段二全量)②执照归属预检(nonce 未消费提示)③trade_profile 结构预检
预检为前端只读预检 ,服务端仍以 Workflow step 校验为准(不信任前端)
阶段一提交 = 现有 POST /auth/vendor/register;阶段二提交 = 改造后重提 Workflow
AI 接入位预留(不设计实现)
step2 预留 OCR 证照识别 位(上传后自动回填 business_license_number 等字段);step3 预留材料预审 位(documents 完整性/清晰度预检);step1/step3 预留智能填单 。预留约束:识别/预审结果仅作建议,用户确认后才写入,失败/服务不可用回退手工流程——NFR-3.8-01「未配置/故障即跳过不阻断主业务」;未来若走 LLM 通路必须复用平台唯一 AI 通路(backend/src/modules/translation/client.ts)与 isAIConfigured 预检+降级范式(translation-config.ts:49-66),不新建平行通路。
草稿持久化候选与选定(断点续填)
候选 说明 评估
A. vendor 侧草稿实体(新表 vendor_registration_draft) 后端持久化草稿,跨设备续填 ❌ 否决(本期) :新增 migration + 清理 job + PII 保存期限合规面(APPI),成本与「续填便利」不成比例;草稿非业务数据、不承载权益
B. 前端 localStorage + 提交落库 分步草稿存 vendor-panel localStorage;仅提交动作落库(approval_data) ✅ 选定 :零 migration、零新增后端攻击面;红线不破——草稿仅为前端便利,资质/审核/权益以后端 approval_data 单一数据源为准 ,草稿丢失可重填
候选 B 字段级约定:localStorage key vendor-registration-wizard/{seller_id|anonymous};存 JSON { step, form: {…step1-3 字段}, updatedAt };排除项 :business_license_url/执照文件不入草稿(文件已走 upload-license 私有存储,草稿仅存 opaque reference 以便回显);tax_id 等敏感文本字段允许入草稿(仅存于用户本人浏览器,不后端落库);提交成功即清除该 key。
权益门控与 approval_status 对齐
门控锚 :seller-profile.ts:16-37 的 approval_status 三态 + approval_data 快照 + 审核留痕。深度权益开放判定(单一函数,全部执行点复用,不改 3 态机) :
entitlementGranted = (approval_status === "APPROVED") && (approval_data?.trade_profile != null)
语义即 PRD 口径「资质通过」=深度资质过审 :阶段一 APPROVED 无 trade_profile → 深度权益关;阶段二提交置 PENDING(重提闭环既有语义)→ 关;深审 APPROVED 且快照含 trade_profile → 开;REJECTED → 关。信息层权益(企业展示/公开浏览)不挂此门控(注册即可用,FR-3.2-01 现状口径)。
stateDiagram-v2
state "APPROVED · 无 trade_profile(信息层权益)" as A1
state "APPROVED · 含 trade_profile(深度权益开放)" as A2
[*] --> PENDING: 注册(阶段一最小集提交)
PENDING --> A1: 轻审通过
PENDING --> REJECTED: 驳回
REJECTED --> PENDING: 退回—补正—重提(既有闭环)
A1 --> PENDING: 阶段二深度资质提交(守卫 R1 放宽通道)
note right of A2: 深审通过后快照含 trade_profile,深度权益六项门控通过
note left of A2: APPROVED 且已有 trade_profile 的再提交仍被拒绝(防过审后偷改资质)
图3. approval_status 三态机与深度资质维度(状态机不扩状态,深度权益由「APPROVED × trade_profile」组合判定)
门控执行点清单(逐点 file:line 与插入方式)
# 权益 执行点(现状代码位) 插入方式
G1 发布产品 publish-vendor-product.ts:130 publishVendorProductWorkflow(step 链 :133 validateProductForPublishStep → :134 submitProductListingReviewStep)step 链首插入 assertSellerApprovedStep({ seller_id })(新增共享 step,读 seller_profile 判定上文条件;违规抛 MedusaError(NOT_ALLOWED, "deep entitlement requires approved qualification"));守卫在 step 内 (红线),不改上游 mercurjs 路由
G2 参与 B2B 集采报价 merchant-send-quote.ts:12 merchantSendQuoteWorkflow(商家报价动作);RFQ 创建(客户侧)不设门控同一共享 step 插入该 workflow 链首;集采参与资格若另需 h2b 渠道校验,复用 assertH2BBuyerApprovedStep 范式(apply-btob-reseller.ts:32-34 已示范)叠加,不在本卡展开
G3 线上交易 交易链路(下单/履约)现状无资质门控;准入实际由「listing review 通过 + 渠道分发」承载 G1 生效即传递性封锁未审商品上线;交易执行点不单独插桩 (避免在 @medusajs cart/order 上游链路加本地守卫的耦合),在验收中标注该设计取舍
G4 结算对账 upsert-seller-manual-payout-profile.ts:26-40 resolveSellerManualPayoutOwnerStep(:31-37 现仅校验 CN)在该 step 内并列追加 判定(同 step 两守卫,错误码区分 seller_manual_payout_country_not_allowed / seller_not_approved);Stripe payout 通道同范式
G5 开通数字店铺 0 实现 (负证据;归 AI-3.2-04 工具适配器)本卡交付共享门控原语;AI-3.2-04 entitlement 机制落地时消费(交叉引用,P2)
G6 启用数字员工 0 实现 (归 AI-3.6-03)同 G5
flowchart TB
REQ["深度权益执行点请求(G1 发布 / G2 报价 / G4 结算…)"] --> CHK{"assertSellerApprovedStep 判定"}
CHK -->|"APPROVED 且 approval_data.trade_profile 非空"| PASS["放行(权益开放)"]
CHK -->|"不满足(PENDING / REJECTED / 无 trade_profile)"| FLAG{"feature flag deep_entitlement_gate"}
FLAG -->|"false(阶段1 观察期)"| WARN["logger.warn 留痕,行为同现状"]
FLAG -->|"true(阶段2 强制)"| DENY["抛 MedusaError NOT_ALLOWED,拒绝执行"]
图4. 深度权益门控判定与灰度行为(守卫在 Workflow step 内实现,阶段切换无需发版)
权益-状态判定矩阵(验收对照表)
状态 信息层权益(展示/浏览) 深度权益六项
PENDING(阶段一注册后) ✅(FR-3.2-01 注册即可用) ❌
APPROVED 且无 trade_profile(阶段一过审) ✅ ❌
PENDING(阶段二资质提交后) ✅ ❌
APPROVED 且 trade_profile 在(阶段二深审通过) ✅ ✅
REJECTED(任一环节驳回) ✅(展示不停,PRD 未约束下线) ❌
灰度与行为变化声明
门控上线使 PENDING 商家不能再提交发布 (现状可提交 → listing review)——行为变化以 feature flag deep_entitlement_gate 两阶段灰度控制:阶段1 = 违规仅 logger.warn 留痕(观察期);阶段2 = step 内抛错强制拒绝;medusa-config.ts:55-58 featureFlags 区新增 deep_entitlement_gate: false(默认关 = 阶段1)。
退回—补正—重提闭环(沿用 + 差异改造点)
沿用本体 :resubmit-qualification/route.ts:54-65(守卫 + 重置 PENDING + 清空审核留痕)+ resubmit-qualification.tsx:136-159(提交入口)+ qualification-section.tsx:130-191(资料维护展示)+ approval-policy.ts:48-55(resubmitProfilePatch 构造器)。
# 改造 依据
R1 守卫放宽:currentStatus 允许集由 {REJECTED, PENDING} 扩为 {REJECTED, PENDING} ∪ {APPROVED && !hasDeepQualification}(阶段一过审商家的深度资质补全通道);APPROVED 且已有 trade_profile 的提交仍拒绝(防过审后偷改资质) route.ts:56-60 现守卫;缺口⑤
R2 提交动作 Workflow 化:新增 submit-deep-qualification workflow(steps:① assertResubmitAllowedStep(承载 R1 守卫,读 profile 快照返回 previous)→ ② updateQualificationStep(写 PENDING + approval_data + 清审核留痕,compensation 回写 previous 快照));route 收敛为校验 + 调 workflow(红线:数据变更走 Workflow,守卫在 step) 现状 route 直写 module(:62-69)为红线瑕疵;补偿范式对照 reject-seller.ts:81-92
R3 向导 UI 复用:step2/step3 表单组件与 resubmit-qualification.tsx 表单共用同一 zod schema 源(validators.ts 契约),qualification-section.tsx 展示区增加 trade_profile 分组渲染(字段来自 SupplierTradeProfile :18-27,展示逻辑沿用 :162-191 FieldRow 范式) 单页 → 分步重构中消除双份 schema 漂移
边界声明(不混同、不改造)
apply-btob-reseller.ts:30-47 与 apply-btoc-shell-store.ts:30-53 是资格通道迁移 (H2B 买家 → B2B reseller → B2C shell store,经 transitionChannelQualificationWorkflow 白名单键迁移)——属已入驻商家在渠道体系内的权益/资格切换,不是 注册分层,本卡不将其改造为注册阶段、不在其内插注册逻辑。两阶段向导与通道迁移的唯一交点 = G2 门控同样适用于迁移后的商家(共享原语自然覆盖)。
迁移与回滚
变更 回滚路径
向导重构 旧单页表单路由保留 ,vendor-panel 路由级 feature flag(register_wizard,env 驱动)一键切回 register.tsx 单页入口;草稿 localStorage 数据无回滚需求(提交前不落库)
权益门控 deep_entitlement_gate 置 false 即回阶段1(warn 不拦截)= 现状行为等价;移除插桩 step 属代码回滚,无数据回滚(门控只读不写)
重提闭环 R1/R2 route 恢复直调 module 的旧实现(保留在 git 历史);approval_data 为整快照覆写语义,无增量迁移数据
零 schema migration :无新表、无列变更、状态机不变;若后续复审改判草稿为后端实体(候选 A),migration 必须走 medusa db:generate 规范并另行评审。pnpm db:reset / db:reset:demo 兼容:seed 流程零影响;既有 demo 商家(APPROVED + 有/无 trade_profile)在门控开启后的权益表现按判定矩阵可预期。
上线顺序建议 :W3 闭环改造先行(为阶段二提供通道)→ 向导灰度放量(旧表单并存)→ 门控阶段1 观察(warn 日志盘点 PENDING 发布量)→ 门控阶段2 强制。
flowchart LR
W12["W1+W2 向导重构 + 草稿 localStorage + schema 共享(3d)"] --> V["V1 集成验收 + e2e(1.5d,覆盖 A1-A6)"]
W3["W3 重提闭环改造 R1/R2/R3(1.5d,与 W1 并行,schema 先行对齐)"] --> V
G1["G1 门控原语 + G1/G2/G4 三点插桩 + 灰度开关(2d)"] --> V
图5. 子任务 DAG 与估时(向导线/闭环线/门控线并行,汇于集成验收;交叉引用 AI-3.2-04 消费门控底座、AI-3.9-04 把关框架 references_only)
数据模型与 API 契约
数据模型变更汇总(字段级)
对象 变更 说明
seller_profile(现有表)无 schema 变更 深度资质判定复用 approval_data JSON 内既有 trade_profile 键(SellerQualificationData :49);状态机 3 态不变
草稿载体 无新表 候选 B(localStorage),见草稿持久化
门控开关 medusa-config.ts featureFlags 新增 deep_entitlement_gate配置项非 schema,见权益门控
资质字段契约(阶段二字段集的既有契约,JSON 可扩展)
SellerQualificationData(注册资质数据总容器,落库于 seller_profile.approval_data)— :35-50
字段 说明
company_name*企业名称(注册唯一必填,validators.ts:15)
representative_name法定代表人/代表者姓名
business_license_number营业执照号(step2)
business_license_url执照文件(private storage opaque reference,step2,可空)
registered_address注册地址
contact_phone联系电话
tax_id税号(step3)
country_code国别(白名单校验)
website_url企业网站
business_description业务描述
referral_code推荐码(绑定推荐关系,无效降级不阻断)
joint_store_intent联合开店意向
trade_profile?验厂/产能/贸易画像(SupplierTradeProfile,可空——深度资质判定键)
SupplierTradeProfile(验厂/产能/贸易画像九字段 + 单证数组)— :17-31
字段 说明
factory_video_url工厂视频
factory_photo_urls[]工厂照片数组
production_line产线说明
annual_capacity年产能
equipment_summary设备概要
quality_system质量体系
export_experience出口经验
customer_cases客户案例
after_sales_capability售后能力
documents: SupplierTradeDocument[]资质单证数组(type / title / url / expires_at? 四字段,:11-14)
校验入口:backend/src/api/vendor/register/validators.ts:15-56(注释 :15「Only company_name is required at registration; other fields are optional」;:53 country_code 白名单正则、:72 支持国别校验报错)。
API 契约汇总
路由 方法 变更 权限域 要点
/auth/vendor/registerPOST 无改动 public 阶段一提交入口(validators 最小集既有);响应语义不变
/auth/vendor/resubmit-qualificationPOST 行为变化(R1/R2) seller 认证 守卫放宽 + 内部改调 submit-deep-qualification workflow;请求/响应 schema 不变(VendorResubmitQualificationSchema 沿用,route.ts:16-18)
/admin/sellers/[id]/approve、/rejectPOST 无改动 admin 深审动作复用(approve-seller.ts:278 / reject-seller.ts:31);「深审」与「轻审」由审核员按 approval_data 内 trade_profile 有无自判,本期不拆双审核队列(运营口径,避免过度设计)
/vendor/* 其余— 无改动 vendor 门控在 workflow step 内生效,路由层无感
Workflow 设计汇总
Workflow 状态 steps 链 补偿逻辑
register-vendor既有复用零改动 registerSellerAuthStep → createSellerWorkflow.runAsStep → createSellerProfileStep → ensureStoreDistributionPolicyWorkflow.runAsStep → bindReferralOnRegistrationStep → verifyLicenseOwnershipStep profile 创建 step 的 compensation 删除 profile(:221-230);内联子工作流失败触发内部 step 补偿清除僵尸 seller/member/auth 元数据(:247-252)
submit-deep-qualification新增 ① assertResubmitAllowedStep(R1 守卫四分支:PENDING / REJECTED / APPROVED-无深度 / APPROVED-有深度)→ ② updateQualificationStep(写 PENDING + approval_data + 清审核留痕) update 补偿回写 previous 快照(对照 reject-seller.ts:81-92 范式)
publishVendorProductWorkflow(插桩)新增守卫 step 链首插入 assertSellerApprovedStep → validateProductForPublishStep → submitProductListingReviewStep 门控只读不写,无补偿需求
merchantSendQuoteWorkflow / resolveSellerManualPayoutOwnerStep(插桩)新增守卫 同一共享 step 插入链首 / step 内并列追加两守卫(错误码区分) 同上
前端改动面与 i18n
前端触点(逐端)
端 改动 依据
vendor-panel ① register.tsx(603 行单页)重构为四步向导(新路由组件组,旧单页路由保留挂 feature flag 作回滚);② resubmit-qualification.tsx 表单与 step2/3 共用 schema(R3);③ qualification-section.tsx 增 trade_profile 分组展示;④ 草稿 localStorage 工具;⑤ step2 执照上传沿用 uploadLicenseQuery(:87) 向导 / 闭环改造
admin-panel 无改动(审核工作台既有:approve/reject 路由 + seller-status-cards 审核卡片;「轻审/深审」由审核员按资料自判) API 契约
influencer / referrer panel 无改动 无注册/资质触点
storefront / b2b / h2b 无改动 信息层权益展示链路现状已可用,本卡不改前台
i18n 三语言 key 规划(en / zhCN / ja,仅 vendor-panel)
改动面仅 vendor-panel:vendor-panel/src/i18n/translations/{en.json, zhCN.json, ja.json} 三文件同步新增(register.wizard.* 命名空间):
新增 key 用途
register.wizard.step1.title / step2.title / step3.title / step4.title四步标题(企业基础信息/执照上传与归属核验/行业资质与验厂资料/提交与预检)
register.wizard.draft.saved / draft.restored / draft.cleared草稿保存/恢复/清除提示
register.wizard.step3.tradeProfile.*(factoryVideo / productionLine / annualCapacity / qualitySystem / exportExperience / customerCases / afterSales)step3 验厂资料字段标签(对应 SupplierTradeProfile 九字段,:18-26)
register.wizard.step3.documents.type / .title / .expiresAt / .addDocument单证四字段 + 新增单证按钮(SupplierTradeDocument :11-14)
register.wizard.step4.precheck.passed / precheck.licenseUnclaimed / precheck.missingFields预检结果文案
store.qualification.deepStatus.notSubmitted / .underReview / .granted深度权益状态徽标(配合判定矩阵,挂 qualification-section)
admin-panel / storefront 系 i18n 无新增 key(无 UI 改动)。
验收与测试
验收标准
# 验收标准 映射
A1 深度权益仅在资质通过后开放:门控负向测试 ——PENDING 态、REJECTED 态、APPROVED-无 trade_profile 态三种身份逐一尝试六项深度权益执行点,全部被拒(G1 发布 / G2 报价 / G4 结算可自动化断言;G5/G6 随 AI-3.2-04 / 3.6-03 落地补验)PRD 验收要点①;判定矩阵
A2 资料退回—补正—重提闭环可用 :REJECTED → 重提 → PENDING → APPROVED 全链回归(既有闭环零回归缺陷)+ R1 新通道(APPROVED-无深度资质 → 补交 → PENDING)可用 + R2 守卫拒绝「APPROVED 且已有 trade_profile」的再提交PRD 验收要点②;闭环改造
A3 两阶段分层可用 :阶段一最小集(仅 company_name 必填)注册 → 轻审 → 信息层权益生效;阶段二向导补全 → 深审 → 深度权益生效;全程无断点(向导步骤间状态可恢复,草稿丢失不阻塞)两阶段向导
A4 向导分步可用性 :四步字段校验逐步生效(步骤级不放过无效数据);断点续填测试(中途退出 → 重进 → 草稿恢复);执照 nonce 链回归(上传 → 注册 → 归属转移,M-16 不被向导重构破坏)四步设计 / 草稿
A5 灰度行为正确 :deep_entitlement_gate 关 = 现状行为(warn 留痕不拦截);开 = 强制拒绝;两阶段切换无需发版(featureFlags/env)灰度声明
A6 量化指标埋点就位 :注册转化率 / 两阶段转化漏斗事件可采集;数值一律「基线立项定(DEC-5)」 ,本 TDD 不预设前置决策点
测试策略(分层)与 L0 门禁
L0 门禁 :本文档十要素齐备、关键 code anchor 可 rg 命中、既有注册/审核域单测回归通过(实现期复跑)。
层 范围 明细
既有回归 注册/审核域 register-vendor 工作流六步与补偿、resubmit 闭环(route 守卫 + 状态重置)、license nonce 转移(verify-license-ownership)、approval-policy patch 构造器、seller-profile 契约单测(modules/seller-profile/__tests__/merchant-qualification-contract.unit.spec.ts 等)、workflows/seller-approval/__tests__/approval-logic.unit.spec.ts
新增单测 门控原语 assertSellerApprovedStep:三态 × 有无 trade_profile 判定矩阵全分支;G1/G2/G4 插桩后 workflow 级拒绝断言;灰度两阶段行为(warn vs throw)
新增单测 重提改造 submit-deep-qualification workflow:R1 守卫四分支、update 补偿回写 previous 快照(对照 reject-seller.ts:81-92 范式)
新增单测 向导(vendor-panel) 向导表单步骤校验、草稿存取/清除、schema 共享(R3)不漂移(vitest/RTL)
集成 / e2e 关键旅程 阶段一注册 → 轻审 → 信息层权益;阶段二补全 → 深审 → 发布成功;PENDING 发布被拒(负向);e2e 挂 e2e/ Playwright(涉及 e2e 前先加载 playwright-cli skill)
降级路径测试 NFR-3.8-01 后续增强段(OCR/预审)立项时补——本卡预留位验收 =「无 AI 服务时向导全流程可用」(即现状行为,天然满足)
风险与开放问题
已识别风险
publish 校验不查审核态(publish-vendor-product.ts:90-117)、quote/payout 无资格校验——PENDING 商家可发布商品进入 listing review,PRD「仅在资质通过后开放」不成立。缓解 :本卡 G1/G2/G4 插桩 + 共享门控原语 + 灰度上线。
PENDING 商家将不能再提交发布(现状可提交)。缓解 :feature flag 两阶段灰度——阶段1 仅 warn 留痕观察(盘点 PENDING 发布量),阶段2 强制拒绝,切换无需发版。
注册转化率、审核时效、两阶段转化漏斗等量化指标的基线与目标值待管理层决策+法务。缓解 :仅阻塞验收数值,不阻塞向导+门控设计与开发;指标采集埋点随开发落地,数值后补(占位「基线立项定(DEC-5)」)。
换设备/清浏览器缓存即丢草稿,且敏感字段仅存本地。缓解 :草稿仅为前端便利载体、可重填;资质/审核/权益以后端 approval_data 单一数据源为准;执照文件不入草稿(仅存 opaque reference 回显)。
避免在 @medusajs cart/order 上游链路加本地守卫的耦合,依赖 G1 传递性封锁未审商品上线。缓解 :在验收中显式标注该取舍;若后续复审要求交易侧强校验,另行评审。
前提与假设
假设
「深审/轻审」由审核员按 approval_data 内 trade_profile 有无自判,本期不拆双审核队列(运营口径,避免过度设计);
PRD 双层口径声明:本条属「底座已建成」;「AI 服务未接入」与本条关系仅体现为 AI 辅助为零——按后续增强段处理,不阻塞本条流程产品化设计;
入驻审批人工审核状态机仅复用不重设计(AI-3.9-04 边界,references_only)。
前置决策点
Blocker 二分表(禁止因阻塞点否定整条 TDD)
Blocker 类型 阻塞什么 可并行做什么
blocker D-dec5 (验收指标基线与目标值,PRD 2.5 DEC-5 / 7.6)
管理层决策 + 法务
仅阻塞验收数值 :注册转化率跟踪、审核时效、两阶段转化漏斗等全部量化指标的基线与目标值——本卡一律「基线立项定(DEC-5)」占位
不阻塞向导+门控设计 :四步向导字段级设计、草稿取舍、门控原语与四执行点插桩、重提闭环改造、测试用例全部可立即开工;指标采集埋点(转化事件)可随开发一并落地,数值后补
依赖与下游消费
内部依赖:无硬前置 TDD(模板为结构契约非业务依赖);
AI-3.2-04 (P2,智能工具试用期与付费开通):消费本条权益门控底座(门控原语 + approved 判定)叠加工具 entitlement——两层边界:本卡 = 资质权益门控,3.2-04 = 工具付费 entitlement,不混建;
AI-3.9-04 (P1):把关框架引用本条审核状态机为既有底座(references_only 互相声明,禁止两套状态机);
FR-3.2-01 配套优化(两阶段显式化)由本卡阶段一承接。
外部资源:无(本卡不依赖法务/机构/场地)。
待决问题清单
D-dec5:验收指标基线与目标值——何时由管理层/法务给出数值基线?(仅阻塞验收数值,开发不受阻)
数字店铺 / 数字员工开通入口的产品化时点(归 AI-3.2-04 / AI-3.6-03,本卡只供给门控原语 G5/G6)。
集采参与资格若另需 h2b 渠道校验,是否在 G2 之上叠加 assertH2BBuyerApprovedStep 范式——不在本卡展开,待 AI-3.3-05/3.6-03 侧明确。
草稿持久化若后续复审改判候选 A(后端实体),需 migration 评审与 PII 保存期限合规面评估(APPI)。
附录:溯源对照
本文档由 docs/reports/ai-module-prd/tdd/AI-3.2-02-deep-commerce-registration.md(文档版本 v1.0,2026-10-26)转换生成。输出章节与源章节映射如下(Preserved = 保留原文内容;Summarized = 摘要化重组;Inferred = 转换侧推断标注):
本文档章节 源章节 处理方式
摘要 元数据表 + §1 溯源与现状 + §4 方案概览 Summarized
关键概念 头部口径声明 + §1.2/§2.1/§4.1/§4.2/§4.3 术语 Summarized
方案设计 · 设计红线 §4.0 设计红线(AGENTS.md §0.1) Preserved
方案设计 · 现状底座与复用边界 §1.3 三态判定 + §2.1 涉及模块清单 ①~⑨ + §2.2 三类标注 Preserved (file:line 锚点与负证据逐条保留)
方案设计 · 缺口与目标状态 §3.1 验收要点转译 + §3.2 缺口清单 + §3.3 FR-3.2-01 对照声明 Preserved
方案设计 · 两阶段分层注册向导 §4.1(含四步字段级设计表、AI 接入位预留) Preserved
方案设计 · 草稿持久化 §4.1.3 候选与选定 Preserved
方案设计 · 权益门控 §4.2(判定条件 / 执行点清单 G1-G6 / 判定矩阵 / 灰度声明) Preserved
方案设计 · 退回—补正—重提闭环 §4.3(沿用本体 + R1/R2/R3)+ §4.4 边界声明 Preserved
方案设计 · 迁移与回滚 §10(含上线顺序建议) Preserved
数据模型与 API 契约 §4.5 数据模型汇总 + §2.1② 资质字段契约 + §4.6 API 契约 + §4.3 R2 Workflow(汇总表) Preserved
前端改动面与 i18n §4.7 前端触点 + §4.8 i18n key 规划 Preserved
验收与测试 §8.1 验收标准 A1-A6 + §8.2 测试策略与 L0 门禁 Preserved
风险与开放问题 §3.2 缺口③⑤ + §4.2.4 行为变化 + §7 D-dec5 + §4.6/§6 假设(风险分级为转换侧判定) Inferred
前置决策点 §7 Blocker 二分表 + 依赖与下游消费 Preserved
图1 / 图2 / 图3 / 图4 / 图5 §2.1① / §4.1.1 / §4.2.1+§4.2.4 / §9 子任务 DAG Inferred (依源表格与文字绘制的可视化视图)
溯源说明
源文档所有锚点在执行 run 以 rg/sed 逐条复核(Windows Git Bash,仅扫 backend/src、vendor-panel/src、admin-panel/src),上游卡内锚点与复核实际行号漂移处已按「来源锚点(复核:实际行号)」双写标注保留。内部流程标识(任务批次号、执行 run 标识)属过程元数据,不影响任何契约性内容(资质字段契约、API 契约、Workflow step 链、错误码、验收标准均完整保留)。