Commit Graph
82 Commits
Author SHA1 Message Date
QiuSW 3261561940 fix(web): decouple SYB sync feedback (#77) 2026-08-24 16:49:23 +08:00
QiuSW 791f90c6c5 docs(#76): 精简单人开发工作流 2026-08-24 16:27:55 +08:00
QiuSW a2cc9a144f feat(#75): 增加 SYB 每小时自动同步 2026-08-24 16:02:16 +08:00
QiuSW 0fccbc99c1 feat(#74): 优化 SYB 商品筛选和列表布局 2026-08-24 15:10:47 +08:00
QiuSW 634bd46729 fix(#73): speed up SYB purchase preview 2026-08-24 11:48:56 +08:00
QiuSW 476ca64616 fix(#72): wait for API and retry SYB load 2026-08-24 11:02:47 +08:00
QiuSW ca0c81b9f0 feat(#71): supervise GoAuto local services 2026-08-24 10:39:27 +08:00
QiuSW a439b0b77c docs(#70): archive user acceptance 2026-08-24 09:10:53 +08:00
QiuSW 1f2478ae9e docs(#70): record completed product import 2026-08-24 00:11:14 +08:00
QiuSW 166adc6fa8 feat(#70): import cmautobuy product catalog 2026-08-23 23:59:12 +08:00
QiuSW 67d8f32eaf feat(#69): add Shopee PDD specification mapping 2026-08-23 23:23:42 +08:00
QiuSW 9490bddf8f feat(#67): add Shopee order snapshots to purchase tasks 2026-08-22 10:41:05 +08:00
QiuSW 0ceb248233 fix(#66): recover from Android payment chooser 2026-08-22 10:11:29 +08:00
QiuSW 553dc46afa fix(#65): locate detailed address editor by label 2026-08-22 10:01:42 +08:00
QiuSW 340543936d fix(#65): preserve text anchors for purchase clicks 2026-08-22 09:52:14 +08:00
QiuSW 464a3b8abc fix(#65): tap exact purchase address entry 2026-08-22 09:46:05 +08:00
QiuSW f5ac7f6300 fix(#65): restore address entry within purchase panel 2026-08-22 09:31:20 +08:00
QiuSW 22a024be64 fix(#64): bound purchase spec selection retries 2026-08-22 09:07:13 +08:00
QiuSW 0e3be46c4c feat(#62): extend AI matching timeout 2026-08-21 17:23:02 +08:00
QiuSW 6181d97f39 feat(#62): add AI specification matching settings 2026-08-21 17:04:49 +08:00
QiuSW 5a94f4f8b4 docs(#61): record safe purchase spec entry 2026-08-21 16:09:47 +08:00
QiuSW aebe80f305 fix(#61): use safe purchase spec entry 2026-08-21 16:08:57 +08:00
QiuSW 36b11ece5d fix(#60): stabilize per-color price capture 2026-08-21 15:29:03 +08:00
QiuSW 37db89ce92 docs(#59): record Samsung device verification 2026-08-21 15:15:01 +08:00
QiuSW 2977edcd53 fix(#59): avoid PDD review page spec misclick 2026-08-21 15:04:06 +08:00
QiuSW 01d852011a feat(#58): batch retry failed purchase tasks 2026-08-21 14:20:40 +08:00
QiuSW 6a0dfed757 feat(#36): add guarded Android live purchase 2026-08-21 11:06:26 +08:00
QiuSW 7e4f404265 feat(#44): create purchase tasks from SYB products 2026-08-21 10:17:31 +08:00
QiuSW 09083c8e18 docs: record acceptance of #35 #55 #56 2026-08-21 09:44:34 +08:00
QiuSW 35dd3e0be5 docs(#35): clarify unknown-order guard 2026-08-20 23:56:50 +08:00
QiuSW c0c88bb43f feat(#35): add purchase task admin UI 2026-08-20 23:54:17 +08:00
QiuSW 182ef3940a feat(#55): add purchase admin query APIs 2026-08-20 23:31:23 +08:00
QiuSW e5b8d48856 docs(#54): record user acceptance 2026-08-20 23:22:48 +08:00
QiuSW dae9cb6aed docs(#42): record user acceptance 2026-08-20 23:14:16 +08:00
QiuSW b0f33bf679 fix(#54): unify device state across task domains 2026-08-20 22:53:15 +08:00
QiuSW 997f4e7463 docs(#53): record user acceptance 2026-08-20 18:04:40 +08:00
QiuSW afeb2723ea fix(#53): parameterize purchase rule actions 2026-08-20 17:53:10 +08:00
QiuSW dfa425ba5f docs(#34): record user acceptance 2026-08-20 17:31:30 +08:00
QiuSW 65ae41fd6f feat(#34): implement purchase task state machine 2026-08-20 17:22:52 +08:00
QiuSW 978f42806a feat(#33): define purchase task data and API contract 2026-08-20 16:49:43 +08:00
QiuSW 32edb91a31 fix(#52): expose SYB preflight failure stages 2026-08-20 16:09:28 +08:00
QiuSW badb78fa68 feat(#50): run SYB imports asynchronously 2026-08-20 15:24:50 +08:00
QiuSW 6c7a7298e3 feat(#49): complete SYB shop management 2026-08-20 11:54:11 +08:00
QiuSWandClaude Opus 5 e6f533b71e fix(#48): add the missing version-local migration for syb_session
Adding SYBSession to migrations.Migrate was not enough. Schema reaches an
existing database only through a version-local file; with the previous
version already recorded in sys_migration, Migrate never re-ran and the
table simply never appeared. The unit tests build a fresh database every
time, so they stayed green while the real database was missing a table —
which surfaced as "Error 1146: Table 'goauto.syb_session' doesn't exist"
on the first import attempt.

server/.gitignore was hiding these files. go-admin ignores version-local
because it is where generated local migrations land, but every GoAuto
migration belongs in version control; the existing ones had been forced
in with `git add -f`. Un-ignoring *.go there also recovers four migrations
that were never committed at all — 1786700000000 through 1786700300000,
covering the base schema, device registration, heartbeat and collection
execution. A fresh clone could not have built a working database.

Guard the class of mistake rather than just this instance:

  - migrations.VerifyTables checks every model's table after migrating and
    names what is missing along with the fix.
  - The migrate command runs it, so the failure lands at migrate time
    instead of at the first request that needs the table.
  - initDB no longer discards migrateModel's error. Upstream had
    `_ = migrateModel()` followed by an unconditional "初始化成功", so a
    failed migration reported success and the launcher believed it.

Also records the two-step rule in Common-Changes: a new model needs both
the model registration and a new version file.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 10:10:11 +08:00
QiuSWandClaude Opus 5 c86e98d0cb feat(#48): make one config work for both development and deployment
The repo already layered file defaults under environment overrides, on
both the backend (settings.yml < GOAUTO_*) and the frontend
(.env.production < process.env). What was missing was a translator for
production: config.yaml only ever existed for the PowerShell launchers,
so a packaged binary read none of it and had no database credentials
either — SYB was inheriting an existing gap, not creating one.

The server now reads config.yaml itself, between settings.yml and the
environment. Lookup is GOAUTO_CONFIG, then ./config.yaml, then beside the
executable, so a packaged binary works wherever it is started. An absent
file is not an error: containers supply everything through the
environment. Scalars are read by YAML type and coerced, so an unquoted
all-digit password cannot take startup down over a quoting detail.

This removed the need for a Read-SybConfig in PowerShell: the launcher
just hands over the path it already knows, rather than reimplementing a
YAML parser.

The server also serves the built frontend when dist is present, which is
what .env.production's empty VUE_APP_BASE_API already assumes. The
history fallback is restricted to non-API GETs, and is not installed at
all without dist, so development 404s stay 404s.

Precedence is mutation-tested: applying the local file after the
environment instead of before makes the layering test fail.

Not verified: the PowerShell change and any Windows deployment — both
need a run on the Windows side.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 09:28:45 +08:00
QiuSWandClaude Opus 5 7edb4e7b9f feat(#48): add SYB sync orchestration, import endpoint and page entry
Stage 2. Completes the path from the SYB API to the archive.

sybimport.Sync pages a date range day by day and folds each detail line
through the existing idempotent ApplyDetail. The paging loop is driven by
listTotal, never by the list response's own total, which live data
confirmed is the page's row count rather than the filtered total. A day
whose completeness cannot be proven — a short page, a total that drifted
while paging, a detail response missing an order — stops the run instead
of reporting a partial import as a whole one. Rows already written stay:
they are idempotent on (order_code, detail_id), so a re-run overwrites.

sybimport.Connect reuses the cached session and only discards it when SYB
explicitly says it is invalid. Caching the numeric user id alongside the
cookies is required, not incidental: session validation calls
/am/user/get?id=, and a wrong id comes back as a business error rather
than a logout, so cookies alone can never be revalidated.

The import endpoint is single-flight and detached from the request
context, so closing the tab cannot abandon a half-finished range. It
reads only; no SYB write endpoint is reachable from GoAuto.

The page swaps its "no import entry" warning for a date-range dialog that
warns when the span is wide — a single week held over 7000 orders — and
reports partial progress when a run fails midway.

Verified: go build, go vet, go test ./... all pass. The drift check was
mutation-tested. Not verified: the MySQL migration for syb_session, and
any browser walkthrough.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 16:56:00 +08:00
QiuSWandClaude Opus 5 a31c4776c4 feat(#48): port SYB ERP client, session store and config (Stage 1)
Port the SYB ERP HTTP client from the upstream cmautobuy project. The
package is stdlib-only (no DB, no gin), so client.go, columns.go, ocr.go
and their httptest suites carry over almost verbatim; only the package
name and doc references changed.

Add on top of the port:
  - models.SYBSession + gorm SessionStore, so a restart does not force a
    fresh captcha. Cookies are credential-equivalent and carry json:"-".
    Expired sessions read as absent because SYB has no rolling renewal.
  - config.Extend.SYB. Non-secret settings live in settings.yml;
    username and password come only from GOAUTO_SYB_* environment
    variables, so no credential lands in a tracked file.
  - docs/12-syb-erp-interface.md, the ported interface contract.

The guard tests were mutation-checked: reverting json:"-" and renaming a
settings.yml key each make their test fail.

No import endpoint yet — that needs real credentials and live network
verification, which is Stage 2 of #48.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 16:30:35 +08:00
QiuSWandClaude Opus 5 b4861f5073 docs(#48): scope OCR prohibition to Agent side, allow SYB login captcha OCR
The blanket "no OCR/VLM" rule was written for Android Agent collection.
Server-side SYB ERP login is a different domain and needs captcha OCR to
run unattended. Scope the prohibition to the Agent side and record the
SYB carve-out, including that captcha images leave the project.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 16:17:16 +08:00
QiuSWandClaude Opus 5 f53e6ba05b docs(#41): sync architecture, business rules and API contract for syb import
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 15:11:03 +08:00
QiuSWandClaude Opus 5 03f44a0dd2 docs(#40): sync architecture, business rules and API contract for shopee product
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 13:45:35 +08:00