Files
pay/docs/pay-v2-execution-overview.html
T
2026-07-10 19:44:38 +08:00

133 lines
11 KiB
HTML

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pay v2 · 执行总览与评审</title>
<style>
:root{--bg:#0d1117;--card:#161b22;--card-2:#1c2330;--border:#283041;--fg:#e6edf3;--fg-soft:#aeb9c7;--muted:#7d8896;--accent:#58a6ff;--ok:#3fb950;--warn:#d29922;--bad:#f85149;--radius:14px;--mono:"SF Mono",ui-monospace,Menlo,Consolas,monospace}
*{box-sizing:border-box}
body{margin:0;background:radial-gradient(1200px 600px at 80% -10%,rgba(88,166,255,.08),transparent 60%),var(--bg);color:var(--fg);font:15px/1.7 -apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei",sans-serif}
.wrap{max-width:1000px;margin:0 auto;padding:44px 24px 96px}
.eyebrow{color:var(--accent);font-weight:600;letter-spacing:.12em;font-size:12px;text-transform:uppercase}
h1{font-size:28px;margin:8px 0 8px}
.lead{color:var(--fg-soft);margin:0 0 20px}
h2{font-size:19px;margin:38px 0 12px;color:var(--accent);border-bottom:1px solid var(--border);padding-bottom:8px}
h3{font-size:15px;margin:20px 0 8px;color:var(--fg)}
a{color:var(--accent);text-decoration:none}
code{font-family:var(--mono);font-size:.85em;background:var(--card-2);padding:1px 6px;border-radius:5px;color:#cdd9e5}
b{color:#fff}
table{width:100%;border-collapse:collapse;margin:12px 0;font-size:13.5px}
th,td{text-align:left;padding:9px 12px;border-bottom:1px solid var(--border);vertical-align:top}
th{color:var(--fg-soft);font-weight:600;font-size:13px}
table.fields td:first-child{font-family:var(--mono);font-size:12px;color:#cdd9e5;white-space:nowrap;width:1%}
.lead-box{background:linear-gradient(180deg,rgba(88,166,255,.10),transparent);border:1px solid var(--border);border-radius:var(--radius);padding:16px 20px;margin:0 0 8px}
.tag{display:inline-block;font-size:11.5px;font-weight:600;padding:2px 9px;border-radius:999px}
.tag.ok{background:rgba(63,185,80,.16);color:var(--ok)}
.tag.par{background:rgba(210,153,34,.16);color:var(--warn)}
.tag.info{background:rgba(88,166,255,.16);color:var(--accent)}
.svgwrap{overflow-x:auto;background:#0a0e14;border:1px solid var(--border);border-radius:12px;padding:10px 6px;margin:14px 0}
.decision{background:var(--card);border:1px solid var(--border);border-left:3px solid var(--warn);border-radius:10px;padding:12px 16px;margin:10px 0}
.decision b{color:#fff}
.grid{display:grid;grid-template-columns:1fr 1fr;gap:14px}
@media(max-width:760px){.grid{grid-template-columns:1fr}}
.col{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:16px 18px}
.col h3{margin-top:0;color:var(--accent)}
ol{padding-left:20px;margin:6px 0}
ol li{margin:3px 0;font-size:13.5px}
</style>
</head>
<body>
<div class="wrap">
<div class="eyebrow">pay v2 · Execution</div>
<h1>pay v2 · 执行总览与评审</h1>
<p class="lead">2026-07-10 · 一页看全:当前进度 + 依赖 DAG + P2/P7 待审计划 + 你要拍的决策点。详见 <a href="pay-v2-unified-gateway-design.html">设计</a> · <a href="pay-v2-p1-plan.html">P1</a> · <a href="pay-v2-p2-plan.html">P2</a> · <a href="pay-v2-p7-codes-lib.html">P7</a> · <a href="pay-v2-roadmap-dag.html">DAG</a></p>
<div class="lead-box">
<b>现状(2026-07-10 全部收官)</b>:<span class="tag ok">P1-P8 八阶段全部完成 ✅</span> —— pay 仓 <code>design/pay-v2</code> @ da8bbef(84 提交)已含全部八阶段 + jiu 反馈波(端型透传/alipay qr/单号增熵/限流加固),每阶段逐任务复审 + 整支 opus 终审 + 修复闭环;codes 库已 push Gitea 并完成 pangolin 宿主集成验证(合并前清单待用户执行)。累计抓修 4 Critical(索引升级/订阅无付款激活/限流 XFF 绕过/SubscriptionRef 断链)+ 20+ Important 全部闭环。<b>design/pay-v2 未合 main 未部署,等你验收;部署前清单见台账。</b>
</div>
<h2>1. 8 阶段进度</h2>
<table class="fields">
<thead><tr><th>阶段</th><th>内容</th><th>状态</th></tr></thead>
<tbody>
<tr><td>P1</td><td>核心数据模型(Order/Attempt/Account/Refund)+ money + 账户注册表</td><td><span class="tag ok">✅ 完成</span></td></tr>
<tr><td>P2</td><td>Provider 抽象 + 一次性收款管线 + 统一入账 + webhook v2</td><td><span class="tag ok">✅ 完成</span></td></tr>
<tr><td>P3</td><td>首批渠道 adapter:crypto 自托管 / 支付宝 / Stripe</td><td><span class="tag ok">✅ 完成</span></td></tr>
<tr><td>P4</td><td>退款 POST /refunds + 三向</td><td><span class="tag ok">✅ 完成</span></td></tr>
<tr><td>P5</td><td>多账户路由策略</td><td><span class="tag ok">✅ 完成</span></td></tr>
<tr><td>P6</td><td>对账 job</td><td><span class="tag ok">✅ 完成</span></td></tr>
<tr><td>P7</td><td>codes 共享库(独立仓,A 嵌入各产品)</td><td><span class="tag ok">✅ 完成</span></td></tr>
<tr><td>P8</td><td>订阅/recurring + 拒付</td><td><span class="tag ok">✅ 完成</span></td></tr>
</tbody>
</table>
<h2>2. 依赖 DAG 与波次</h2>
<div class="svgwrap">
<svg viewBox="0 0 940 400" style="width:100%;min-width:820px;height:auto;display:block" font-family="'SF Mono',ui-monospace,'PingFang SC',sans-serif" role="img" aria-label="P2-P8 依赖 DAG">
<defs><marker id="a" markerWidth="9" markerHeight="9" refX="7" refY="3" orient="auto"><path d="M0,0 L7,3 L0,6 Z" fill="#58a6ff"/></marker></defs>
<style>
.n{fill:#161b22;stroke:#283041;stroke-width:1.2}.nd{fill:#12251a;stroke:#2ea043;stroke-width:1.4}.npar{fill:#231d10;stroke:#9e7016;stroke-width:1.4}
.t{fill:#e6edf3;font-size:12.5px;font-weight:600}.ts{fill:#8aa0b8;font-size:10px}.e{stroke:#3d5578;stroke-width:1.6;fill:none}
</style>
<line class="e" x1="150" y1="60" x2="248" y2="90" marker-end="url(#a)"/>
<line class="e" x1="378" y1="88" x2="470" y2="66" marker-end="url(#a)"/>
<line class="e" x1="378" y1="104" x2="470" y2="196" marker-end="url(#a)"/>
<line class="e" x1="600" y1="52" x2="690" y2="40" marker-end="url(#a)"/>
<line class="e" x1="600" y1="66" x2="690" y2="128" marker-end="url(#a)"/>
<line class="e" x1="600" y1="78" x2="690" y2="214" marker-end="url(#a)"/>
<rect class="nd" x="24" y="34" width="126" height="52" rx="9"/><text class="t" x="38" y="56">P1 数据模型</text><text class="ts" x="38" y="72">✅ 已完成</text>
<rect class="n" x="250" y="66" width="130" height="56" rx="9"/><text class="t" x="264" y="88">P2 Provider 抽象</text><text class="ts" x="264" y="104">收款管线+webhook</text><text class="ts" x="264" y="116">关键路径起点</text>
<rect class="n" x="472" y="30" width="130" height="52" rx="9"/><text class="t" x="486" y="52">P3 渠道 adapter</text><text class="ts" x="486" y="68">crypto/支付宝/Stripe</text>
<rect class="n" x="472" y="176" width="130" height="52" rx="9"/><text class="t" x="486" y="198">P5 多账户路由</text><text class="ts" x="486" y="214">∥ P3</text>
<rect class="n" x="692" y="16" width="128" height="48" rx="9"/><text class="t" x="706" y="37">P4 退款</text><text class="ts" x="706" y="53">三向</text>
<rect class="n" x="692" y="104" width="128" height="48" rx="9"/><text class="t" x="706" y="125">P6 对账 job</text><text class="ts" x="706" y="141">query 兜底</text>
<rect class="n" x="692" y="192" width="128" height="48" rx="9"/><text class="t" x="706" y="213">P8 订阅/拒付</text><text class="ts" x="706" y="229">later</text>
<rect class="npar" x="24" y="300" width="300" height="64" rx="9"/><text class="t" x="40" y="324">P7 codes 共享库(独立仓)</text><text class="ts" x="40" y="342">零依赖 pay · 全程可并行(worktree)</text><text class="ts" x="40" y="356">▶ Wave0 与 P2 同步起跑</text>
</svg>
</div>
<p><b>关键路径</b> P2→P3→P4/P6(硬串行);<b>波次</b>:Wave0 P7 ∥ Wave1 P2 → Wave2 P3∥P5 → Wave3 P4∥P6 → Wave4 P8。</p>
<h2>3. 待审计划</h2>
<div class="grid">
<div class="col">
<h3>P2 收款管线(pay 仓,7 任务)</h3>
<ol>
<li>Provider 接口 + 6 render_type + PaidEvent + 注册表</li>
<li>fake provider(测试用)</li>
<li>OrderStore 扩展(GetOrder/AttemptByProviderRef…)</li>
<li>一次性收款管线 gateway(建单/查单/重试/取消)</li>
<li>统一入账/开通 settle(先幂等入队再幂等翻转,崩溃安全)</li>
<li>webhook v2 outbox + Notifier(event_type + HMAC + 已付门禁)</li>
<li>HTTP /api/v2 接线(D3:与旧版统一 /api 前缀)</li>
</ol>
<p style="font-size:12.5px;color:var(--muted)"><a href="pay-v2-p2-plan.html">P2 详细阅读版</a></p>
</div>
<div class="col">
<h3>P7 codes 共享库(新仓 ~/code/codes,8 任务)</h3>
<ol>
<li>模块脚手架 + 通用权益描述符 Entitlement + 状态机</li>
<li>Crockford Base32 生成器(移植 pangolin)</li>
<li>Dialect + 内嵌迁移 + Store CRUD</li>
<li>Mint(批次生成,明文只现一次)</li>
<li><b>Redeem[T] 兑换事务骨架</b>(宿主本地事务 + grant 回调)</li>
<li>RateLimiter/NonceChecker 接口 + GuardedRedeem</li>
<li>redisx 可选子包(唯一 import Redis 处)</li>
<li>webhook 灌码(pay-contract 式 HMAC)</li>
</ol>
<p style="font-size:12.5px;color:var(--muted)"><a href="pay-v2-p7-codes-lib.html">P7 详细阅读版</a></p>
</div>
</div>
<h2>4. 决策点(2026-07-10 评审:D2/D3/D4 已拍,余 D1)</h2>
<div class="decision"><b>D1 · 是否开跑大执行波</b> —— P2(7)+P7(8)≈15 任务、~40 次 SDD agent 调用,多小时工程;P7 要<b>新建仓 <code>~/code/codes</code></b>。开跑 / 先只跑 P7 / 暂缓?<b>【待拍】</b></div>
<div class="decision" style="border-left-color:var(--ok)"><b>D2 · P7 独立新仓</b> —— <span class="tag ok">✅ 已拍:认可</span> <code>github.com/wangjia/codes</code> 独立仓,核心零第三方依赖。</div>
<div class="decision" style="border-left-color:var(--ok)"><b>D3 · 路由统一</b> —— <span class="tag ok">✅ 已拍:统一 /api 前缀</span> v2 挂 <code>/api/v2</code>(<code>POST /api/v1/orders</code> 被旧契约占用,同前缀无法并存);旧 <code>/api/v1</code> 仅为存量当面付部署保留,P3 渠道迁入后整组删除,最终只剩一套。其余延后取舍(webhook 暂用 biz_ref、路由首账户延 P5、币种部署默认延 P3+)维持。</div>
<div class="decision" style="border-left-color:var(--ok)"><b>D4 · settle 资金链路 & Provider 接口</b> —— <span class="tag ok">✅ 已深讲并折入 3 处修订</span>:A1 先入队后翻转+投递门禁(消灭"已付但永不通知"窗口)/ A2 <code>Query(QueryRequest)</code> 带尝试上下文 / A3 <code>PaidEvent.PaidAt</code> 渠道支付时间。详见 <a href="pay-v2-p2-plan.html">P2 阅读版「评审修订」</a></div>
<h2>5. 建议下一步</h2>
<p>只剩 <b>D1</b>:说"开跑"即按 DAG 波次启动(P7 新仓 ∥ P2 关键路径,SDD 逐任务实现+复审,每波边界汇报);想稳则"先只跑 P7"。</p>
</div>
</body>
</html>