refactor(douyin-mashida)!: 纠偏——删掉自建的皮肤通道,改回复用 affiliate_dash
上一轮我把皮肤交付做成了「另建一套执行器 + 独立领取接口 + 只提交账号就结束」, 跟买家实际要走的过程不一致(真正的完成信号是「扫码绑定后的 UID == 买家填的 UID」), 而且核销还触发了老通知逻辑,给买家**又发了一条 /redeem** —— 买家收到两条链接。 本次按用户要求改回**完全复用仓库现成的 affiliate_dash 通道**(= 旧的快手皮肤自动发货)。 **删掉** - 执行器 `douyin_mashida_skin`(含 registry/types/planner/bootstrap/路由白名单注册) - `services/claim/claim-skin-service.ts`、`routes/claim-skin.ts`、`/api/v1/claim-skin` 挂载 - 迁移 096 的 `claim_submission_json` 全链路(task-repo / rows / inputs / task-detail / admin-read-service 的 claimSubmission),并新增 **097 兜底迁移**把该列 DROP 掉 - 顺带清掉上一轮专为已删接口加的死代码(utils/http.ts 的 buildMessageSuccessPayload 等) **改回复用** - `resolveOrderItemClaimLink`:通用解析(只看订单项、不看执行器)→ `buildConfiguredClaimUrl(claimLinkBase, token)`;多履约单元取 task id 最小并告警; **绝不回退** hash 形态的 `buildClaimUrl` - `cert_link` 与付款后那条**唯一**消息共用同一个解析结果 - **核销后不再给抖音买家发第二条消息**(`shouldNotifyBuyerAfterVerify` 只放行非抖音 provider) - 买家侧走既有流程:输 UID → 二维码 → 扫码绑定 → 比对 UID → delivered/REDEEMED; 在 delivered 分支 best-effort 核销平台券(幂等、失败只 warn,不拖慢买家响应) - 后台回显链接改按 **order.provider** 判断(抖音用 `claimLinkBase`) **SQL 守卫**:允许「删除历史迁移」,但强制要求「同时新增兜底迁移」配对 (修改历史迁移仍禁止),并把改动来源换成 `git status --porcelain`(否则未跟踪的新迁移看不见) `npm run check`:tests 671 / pass 668 / fail 0 / skipped 3(含新增的物品图回退用例)
This commit is contained in:
@@ -27,18 +27,6 @@ export function buildSuccessPayload(data: unknown, msg: string = 'ok') {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 与 `buildSuccessPayload` 同源,但用 `message` 作为文案字段(抖音入站/皮肤领取页等对外契约要求)。
|
||||
* 不额外带 `time`,严格贴合这些接口的响应契约。
|
||||
*/
|
||||
export function buildMessageSuccessPayload(data: unknown, message: string = 'success') {
|
||||
return {
|
||||
code: 0,
|
||||
message,
|
||||
data: normalizeResponseDateTime(data),
|
||||
}
|
||||
}
|
||||
|
||||
export function buildErrorPayload(error: unknown, fallbackMessage: string) {
|
||||
const classification = classifyRouteError(error)
|
||||
const errorMessage = error instanceof Error ? String(error.message || '').trim() : ''
|
||||
@@ -66,7 +54,6 @@ export function sendRouteError(
|
||||
error: unknown,
|
||||
fallbackMessage = '服务内部错误',
|
||||
scope = '[route]',
|
||||
options: { messageAlias?: boolean } = {},
|
||||
): void {
|
||||
const classification = classifyRouteError(error)
|
||||
const logLevel = resolveRouteErrorLogLevel(classification)
|
||||
@@ -77,12 +64,7 @@ export function sendRouteError(
|
||||
// 4xx 属预期失败(鉴权过期、参数错误等),带上完整错误对象只会刷十几行堆栈;仅 5xx 保留排查所需详情。
|
||||
...(classification.statusCode >= 500 ? { error } : {}),
|
||||
})
|
||||
const payload = buildErrorPayload(error, fallbackMessage)
|
||||
// 个别对外接口(皮肤领取页)约定用 `message` 而非仓库通用的 `msg`;
|
||||
// 这里只做别名追加,不改变 `msg` / `errorCode`,老调用方行为不受影响。
|
||||
res
|
||||
.status(classification.statusCode)
|
||||
.json(options.messageAlias ? { ...payload, message: payload.msg } : payload)
|
||||
res.status(classification.statusCode).json(buildErrorPayload(error, fallbackMessage))
|
||||
}
|
||||
|
||||
export function resolveRouteErrorLogLevel(classification: {
|
||||
|
||||
Reference in New Issue
Block a user