Files
rakuten-api/app/trading/worker/evidence.py
T
q792602257andClaude Opus 4.6 07107094a7 实现下单任务网关与本地 worker
按 docs/order-gateway.md 落地:第三个部署单元 app.gateway(:31109)承担任务队列
+ 状态镜像;本地 worker 在 app.trading.worker 内,按 RAKUTEN_ORDER_GATEWAY_URL
决定是否启动。规格 §5 最关键约束已守:租约过期绝不自动重投,恢复只能 reclaim,
worker 收到 lease_count>1 时先核对站点订单。

站点交互(加购/下单/付款/订单列表反查)按规格 §10 留接口缝,site_interact.py
全部 NotImplementedError,verify.py 恒返回 unknown——等真实账号实测后再填,
不写猜测的提交逻辑。

310 个测试全绿,覆盖规格 §9 验收清单 12 条;架构测试守住三方互不 import。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-27 16:25:20 +08:00

57 lines
1.8 KiB
Python

"""证据落盘:HTML 快照、截图与 meta.json
规格 §6.1:每个任务一个子目录,按步骤序号命名文件。report 里的 evidence_ref
填 `{task_id}/{序号}-{步骤名}`,不含扩展名。
证据**只留本地**(约束 4),网关只存 evidence_ref 这个相对路径字符串。
"""
from __future__ import annotations
import json
import logging
from pathlib import Path
from typing import Any
logger = logging.getLogger(__name__)
class EvidenceStore:
"""把每一步的页面快照、截图与 meta 落到 {evidence_dir}/{task_id}/ 下"""
def __init__(self, evidence_dir: Path):
self._root = evidence_dir
def step_dir(self, task_id: str) -> Path:
path = self._root / task_id
path.mkdir(parents=True, exist_ok=True)
return path
def write_step(
self,
task_id: str,
step_no: int,
step_name: str,
*,
html: str | None = None,
png: bytes | None = None,
meta: dict[str, Any] | None = None,
) -> str:
"""写入一步的证据文件
返回相对 evidence_dir 的引用路径(不含扩展名),用于 report 的 evidence_ref
字段。文件命名:`{序号:02d}-{步骤名}.{html|png|meta.json}`。
"""
step_dir = self.step_dir(task_id)
stem = f"{step_no:02d}-{step_name}"
rel_stem = f"{task_id}/{stem}"
if html is not None:
(step_dir / f"{stem}.html").write_text(html, encoding="utf-8")
if png is not None:
(step_dir / f"{stem}.png").write_bytes(png)
if meta is not None:
(step_dir / f"{stem}.meta.json").write_text(
json.dumps(meta, ensure_ascii=False, indent=2), encoding="utf-8"
)
return rel_stem