From 6832e856b2fae2e286555176807a55e051140327 Mon Sep 17 00:00:00 2001 From: yml2213 Date: Thu, 8 Oct 2026 14:14:56 +0800 Subject: [PATCH] =?UTF-8?q?docs(=E6=8A=96=E9=9F=B3-=E7=A0=81=E9=80=9F?= =?UTF-8?q?=E8=BE=BE):=20=E4=BF=AE=E6=AD=A3=E6=B7=B1=E5=BA=A6=E5=88=86?= =?UTF-8?q?=E6=9E=90=E9=87=8C=E7=9A=84=E7=AB=A0=E8=8A=82=E4=BA=A4=E5=8F=89?= =?UTF-8?q?=E5=BC=95=E7=94=A8=E4=B8=8E=E6=8E=AA=E8=BE=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - §1.3 / Phase 1 / 测试方案里的「§3.5」统一改为「§3.4」(幂等键小节已重排编号); - D9 的失败重试依据由误写的「§5 D2」改为「§8.1 第 8 条」(幂等优先于必成功); - §0 的待确认项计数改为与 §9 实际条目一致(外部 6 条 + 业务 3 条)。 仅文档改动,无代码变更。 --- docs/抖音-码速达/04-结合本项目的深度分析.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/抖音-码速达/04-结合本项目的深度分析.md b/docs/抖音-码速达/04-结合本项目的深度分析.md index 62262331..ffa518f4 100644 --- a/docs/抖音-码速达/04-结合本项目的深度分析.md +++ b/docs/抖音-码速达/04-结合本项目的深度分析.md @@ -17,7 +17,7 @@ (`grep -riE "码速达|doudian|抖店|jinritemai"` 仅命中本次新增的 `docs/抖音-码速达/`),属于全新接入,不存在「改造旧实现」的迁移风险。 初步规模判断(推断):协议层 + 进单 + 回执打通 **约 6~10 人日**;卡券全链路 + 售后 + 后台面板 **再加 8~12 人日**; -必须在联调前确认的**外部阻塞项 5 个**(见 §9),其中「抖店商户号 uid / 用户秘钥 secret 由谁分配」「我们扮演商家还是服务商」是**最高优先级**。 +必须在联调前确认的**外部问题 6 条 + 业务口径 3 条**(见 §9),其中「抖店商户号 uid / 用户秘钥 secret 由谁分配」「我们扮演商家还是服务商」是**最高优先级**。 --- @@ -64,7 +64,7 @@ | 执行器契约 | `FulfillmentExecutor` | `fulfillment/executors/types.ts:53-57` | 实现 `preparePaidTask` / `resolveDeliveryLink` 并注册进 `registry.ts:15-20` | | 执行器白名单 | `ROUTABLE_EXECUTOR_KEYS` | `fulfillment/routing-config-service.ts:64-69` | **必须加**,否则 `normalizeExecutorKey`(:470)会把新 key 清空,后台路由规则选不中 | | 履约档案 | `CORE_PROFILES` | `bootstrap/fulfillment-bootstrap-service.ts:22-39` | 加一个 profile(key/executor_key/requires_claim) | -| 入站幂等 | `insertWebhookEventOnce` | `repositories/webhook-event-repo.ts:9-43`,表 `webhook_events(provider,event_id)` 唯一(迁移 `013_*.sql:12`);**全仓只有 affiliate_dash 一个调用点**(`notify-service.ts:70`) | 直接用,但**码速达推送没有 `event_id` 字段**,需自行派生(见 §3.5) | +| 入站幂等 | `insertWebhookEventOnce` | `repositories/webhook-event-repo.ts:9-43`,表 `webhook_events(provider,event_id)` 唯一(迁移 `013_*.sql:12`);**全仓只有 affiliate_dash 一个调用点**(`notify-service.ts:70`) | 直接用,但**码速达推送没有 `event_id` 字段**,需自行派生(见 §3.4) | | 可观测 | `logIntegration` / `logExternalHttpPacket` / `task_events` / `admin_notifications`(dedupe_key) / `publishRealtimeEvent`(SSE) | `utils/logger.ts:96/122`、`repositories/task-event-repo.ts:16`、`repositories/admin-notification-repo.ts:25`、`services/realtime/realtime-event-service.ts:92` | 消息流水 + 回执失败 + 仲裁告警都要往这里写 | | 数据保留 | `data-retention-job.ts:21/39-48` | 定期清理 `webhook_events`/`task_events`/原始报文 | 新平台的报文留痕自动纳入保留策略,无需额外处理 | | 配置 | `app_config_entries(config_key, config_json JSONB)` | 表 `001_init.sql:45-62`;`config/app-config-keys.ts:1-15`、`services/config/app-config-store.ts:20/43`、`repositories/app-config-repo.ts:20/32` | 加配置键 + `platforms` 块;**凭据脱敏照抄快手**(见 G8) | @@ -225,7 +225,7 @@ | **D6** | 买家隐私边界 | 抖店会给我们 `post_tel`/`post_receiver`/`doudian_open_id` | **必须遵守既有约定**:`doudian_open_id` 只留内部,不写进工单 `material`、不下发打手;充值账号单独用专用字段承载(现有项目已有「退库后不再带出上一单买家资料」等约束,见 commit `250c456a`/`eae78aae`) | | **D7** | 密钥存储 | 现有 affiliate_dash 的 `appSecret`/`callbackSecret` 是**明文存在 `app_config_entries.config_json`**(`source-config-service.ts:16-24`,事实);**只有快手链路做了脱敏 + 只写不读**(`kuaishou-industry-service.ts:17/216/233` + `utils/masking.ts:10`) | **照抄快手模式**(出参 `secret:''` + `secretMasked` + `hasSecret`,掩码回写不覆盖真值),不要照抄 affiliate-dash 的明文回传;全库加密改造另立优化项 | | **D8** | 命名约定(避免各写各的) | `provider` / config key / 目录名 / 路由前缀 / 前端 Tab key 需统一 | 建议:`provider = 'douyin_mashida'`、`APP_CONFIG_KEYS.douyinMashida = 'douyin_mashida'`、后端目录 `services/platforms/douyin-mashida/`、路由 `/api/v1/open/douyin-mashida`、前端 Tab key `douyinMashida`(**统一用 `douyin_mashida`,不要混用 `codespeed`/`masuda`/`doudian`**) | -| **D9** | 入站响应格式 | 现有三种并存:affiliate-dash `{code:0}`、91 `{message,code,data}`、快手行业 `result` 风格;内部管理端是 `buildSuccessPayload`(`utils/http.ts:21`,`{code,msg,time,data}`) | **按码速达规范返回**(文档只要求「返回成功即可」,实际以联调为准);**绝不要**套用内部 `buildSuccessPayload`;建议统一返回 HTTP 200 + `{code:0}` 之类的简单体,且失败时按 §5 D2 的策略决定是否 4xx 触发重推 | +| **D9** | 入站响应格式 | 现有三种并存:affiliate-dash `{code:0}`、91 `{message,code,data}`、快手行业 `result` 风格;内部管理端是 `buildSuccessPayload`(`utils/http.ts:21`,`{code,msg,time,data}`) | **按码速达规范返回**(文档只要求「返回成功即可」,实际以联调为准);**绝不要**套用内部 `buildSuccessPayload`;建议统一返回 HTTP 200 + `{code:0}` 之类的简单体,且「未能处理」时按 §8.1 第 8 条(幂等优先于必成功:未匹配返 4xx 让上游重推)决定状态码 | --- @@ -237,7 +237,7 @@ - 交付物:`docs/抖音-码速达/05-接入开发设计.md`(对齐 `docs/91卡券/6.开发设计.md` 的写法)+ 联调清单。 ### Phase 1 · 只读接入(2~3 人日) -- 新增 `routes/douyin-mashida.ts`(`POST /api/v1/open/douyin-mashida/message`,query + body 混合取值可参照 `routes/kuaishou-industry.ts:176 mergeRequestParams`)+ `notify-service.ts`:验签(**用 `req.rawBody` 原始串**,`app.ts:41`)+ `insertWebhookEventOnce` 去重(§3.5 的 event_id 方案)+ 原始报文落库。 +- 新增 `routes/douyin-mashida.ts`(`POST /api/v1/open/douyin-mashida/message`,query + body 混合取值可参照 `routes/kuaishou-industry.ts:176 mergeRequestParams`)+ `notify-service.ts`:验签(**用 `req.rawBody` 原始串**,`app.ts:41`)+ `insertWebhookEventOnce` 去重(§3.4 的 event_id 方案)+ 原始报文落库。 - 新增出网层 `services/platforms/douyin-mashida/{sign,http,openapi-client}.ts`(`AbortSignal.timeout` + `logExternalHttpPacket` + `createHttpError`,**不要**改 `affiliate-dash/http-client.ts`),实现 `order.orderDetail`。 - `trade_TradePaid` → 拉详情 → `upsertOrderFromSource`(**先不派单**,观察数据质量)。 - 后台配置:`app-config-keys.ts` 加 key → `routes/admin/platform-config/douyin-mashida.ts`(挂在 `routes/admin/platform-config.ts:14` 的 admin 守卫**之后**)+ 出参脱敏(照抄 `kuaishou-industry-service.ts`)+ `audit`(action `platform_douyin_mashida_config_updated`、targetType `platform_config`)+ 前端 `AdminPlatformShopsPage.tsx` 加 Tab(`:72 PlatformTab`、`:85 platformTabs`、`:164-203 Tabs items`、`:1541 normalizePlatformTab`)。