a56df9d908193d8f71773664fd267b365520b0df
1. recomputeFingerprint now hashes a JSON-serialized (not naive string-
concatenated, to avoid delimiter-collision) sorted list of
{id, direction, ruleId, ruleKind, ruleKeyword} per planned change — the
rule kind/keyword are exactly what gets written into
excluded_rule_kind/excluded_rule_keyword, so a plan that affects the
same ids/directions via a since-edited rule must now be rejected as
stale, not silently accepted. New tests:
TestRecomputeFingerprintChangesWhenRuleEvidenceChanges (edits the rule
row directly between preview and execute, since the API has no edit
endpoint, and asserts RECOMPUTE_PREVIEW_STALE with nothing written and
no log row) and TestRecomputeFingerprintStableAcrossUnchangedPreviews
(two previews of the same data yield the same fingerprint and execute
succeeds).
2. New server/app/goauto/sybproductfilter/recompute_mysql_integration_test.go,
gated on GOAUTO_IT_MYSQL_DSN (t.Skip when unset, so `go test` is
unaffected normally). It creates a uniquely named throwaway database
(zz_goauto_it_340_<ts>), migrates it, and drops it in t.Cleanup — never
touches an existing database. Two real-MySQL, two-connection scenarios
reproduce the exact race the phase-3 fix closes: connection A takes its
REPEATABLE-READ snapshot via the planning step, connection B takes the
row's FOR UPDATE lock and holds it (confirmed via a channel) while A's
write phase is proven to actually block on that same lock (asserted via
a wait window), B then inserts a purchase_task / active return_match
and commits, and A is asserted to unblock, see it, and skip the row.
Verified locally against the dev MySQL server (this session never
printed the password: read via a shell one-liner into an env var,
exported only for the go test invocation): both tests PASS with the
phase-3 fix in place. Temporarily reverted purchaseTaskLockedQuery to a
plain (non-locking) read (not committed) and reran —
TestRecomputeConcurrentPurchaseTaskUnderRealMySQL correctly FAILED
("expected A to skip the row ... got {PDDToExcluded:1 SkippedHasTask:0}"),
proving the test is meaningful; restored and diffed byte-identical
against a backup before rerunning to confirm both tests pass again.
Confirmed via `SHOW DATABASES LIKE 'zz_goauto_it_%'` (empty) that every
throwaway database, across all these runs, was actually dropped.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NTDbDcwbDw1TSAcE6wfh2F
GoAuto 移动采集管理平台
GoAuto 使用 go-admin、go-admin-ui 和 Android Portal/Agent 跑通 PDD 商品采集闭环:人工添加 PDD 链接、创建采集规则、创建任务、由 Android 执行并在任务详情查看结构化结果。
当前 MVP 只包含 PDD 商品、采集规则、采集任务、Android 执行和任务详情结果。顺云宝、Shopee、采购、批量任务、规则发布流程、全局停机和实时屏幕均不在当前范围。
阅读入口
旧版 ADB/Portal 验证代码、日志和诊断资料已归档到本机 demo/,该目录不进入 Git。
当前状态
- 需求和技术边界已确认。
- Harness Coding 文档和工单已建立。
- 服务端与 Android 端为可交互 HTML 原型。
server/已固定导入 go-adminv2.3.0。web/已固定导入 go-admin-uiv3.0.0。android/已建立 Kotlin/SDK 34 Agent 骨架。- 最小闭环 8 张业务表、迁移和唯一约束测试已经落地。
- 设备首次自注册、Token 认证、停用和吊销接口已经落地。
- Token 心跳、在线/离线、空闲/忙碌和离线任务失败已经落地。
验证
.\scripts\verify.ps1 -Component all
也可以把 all 改为 server、web 或 android 单独验证。
Languages
HTML
49.6%
Go
27.2%
Kotlin
10.3%
Vue
7.7%
JavaScript
2.2%
Other
2.9%