Skip to content

docs(architecture): correct the ops method, the transaction types and the API list scope - #203

Merged
argszero merged 1 commit into
mainfrom
docs/architecture-current-state-accuracy
Sep 13, 2026
Merged

argszero merged 1 commit into
mainfrom
docs/architecture-current-state-accuracy

Conversation

@argszero

Copy link
Copy Markdown
Owner

Summary

docs/architecture.md describes itself as documenting the current state, but its §5/§6 enumerations had drifted from the code in four places. This PR re-aligns the doc with what src/routes/mod.rs::router() and the schema actually contain, and — following the project's preference for pointing at an authority rather than re-typing a roster that will rot on the next change — names the arbiters instead of writing new snapshots.

Found by diffing the registered routes against the doc (a "reverse route matrix"), each item then confirmed against the code:

# Where Was Really is
1 §6 `GET /api/ops/runtime` / `credits` / `users` /api/ops/credits is POST (src/routes/mod.rs:569) — following the doc gives 405
2 §6 (absent) the departments API and the raise-requests API are implemented, and §5 already documents their tables
3 §5 transactions type: consume|earn|topup|gift the real set is TX_FILTER_TYPES (6 values) — expire is written (src/gift.rs:49), withdraw is accepted by the filter
4 §5 table list (absent) email_verifications (src/db.rs:220) and schema_version

Item 3 is the one with a copy-paste consequence: a reader implementing against the 4-value list silently drops expired-gift rows — the same bug class fixed earlier in ops.rs.

Related Issue

None — the repository carries no open issues; this is maintenance of the documented current state.

Changes

  • docs/architecture.md
    • §5 transactions row: the type values now defer to src/routes/wallet.rs 的 TX_FILTER_TYPES instead of enumerating a stale subset.
    • §5 table list: added email_verifications (with users.verified) and schema_version (pointing at SCHEMA_VERSION).
    • §6: added the two formerly-missing surfaces —
      GET/POST /api/admin/departments + PATCH/DELETE /api/admin/departments/:id,
      POST/GET /api/raise-requests + POST /api/admin/raise-requests/:id/{approve,reject}.
    • §6: fixed the ops line to GET /api/ops/runtime / users,POST /api/ops/credits.
    • §6: added a note that the list is grouped by feature surface, not by route, and that router() is the authority.
  • README.md:58: 「API 全清单见 docs/architecture.md」 → 「API 一览见 …,权威清单以 src/routes/mod.rs 的 router() 为准」 (the doc is an overview, so the completeness claim was the thing making the omissions matter).
  • 涉及配置/数据结构的改动已同步示例文件 — N/A: no config or data-structure change.

Tests

  • cargo test 全部通过 — 190 passed / 0 failed, i.e. unchanged from main; the count staying put is itself the evidence that no behaviour moved.
  • cargo fmt --check 通过
  • cargo clippy --all-targets -- -D warnings 通过
  • 新增/更新了单元测试 — N/A: a documentation-only change has no behaviour to assert, and the repo deliberately carries no doc-linting gate.

Independent verification (not just "the prose reads correctly")

A checker derives the §6 method+path claims (including its shorthand chains such as runtime / credits / users) and compares them with the routes actually registered in router(), and asserts the §5 transaction-type cell against TX_FILTER_TYPES:

doc result
main (pre-change) FAIL — 5: GET /api/ops/credits (registered methods: ['post']), the stale 4-value type list, both missing surfaces, and §6 not marked as an overview
this branch PASS

⚠️ The checker itself was wrong twice before it was trustworthy (it first reported a blanket "every path is unregistered" — its .route() parser only matched multi-line calls and it missed the Markdown \| escape; then it silently skipped the abbreviation chain that hid item 1). Both were caught by running it against the pre-change file, and it now self-checks its parse and aborts instead of reporting doc failures when the instrument is broken.

Checklist

  • 分支命名符合约定(docs/)
  • Commit message 使用 Conventional Commits 格式(docs(architecture): …)
  • 单一职责,改动最小化(2 files, +9/−3; no route roster added, no gate introduced, no console feature touched)

… the API list scope

The "current state" section of docs/architecture.md had drifted from the code in
four places, all found by diffing the doc against the routes actually registered in
src/routes/mod.rs::router():

- §6 stated `GET /api/ops/runtime` / `credits` / `users`, but /api/ops/credits is
  registered as POST (src/routes/mod.rs:569), so following the doc yields 405.
- §6 omitted two whole API surfaces that §5 already documents tables for: the
  departments API and the raise-requests API.
- §5's `transactions` row enumerated the type values as consume/earn/topup/gift,
  omitting `expire` (which really is written, src/gift.rs:49) and `withdraw`.
- §5's table list omitted `email_verifications` and `schema_version`.

Rather than re-typing rosters that rot on the next change, the doc now names the
authority: the type values defer to `TX_FILTER_TYPES` (src/routes/wallet.rs), the
table list gained the two missing tables with a pointer to `SCHEMA_VERSION`, and §6
is explicitly marked as an overview pointing at `router()`. README.md:58 likewise
stops claiming the doc is a 「全清单」 and points at `router()`.

Docs only: no production code, no i18n key, no schema change — `cargo test` stays at
190 passed.
@argszero
argszero merged commit cabe4c6 into main Sep 13, 2026
1 check passed
@argszero
argszero deleted the docs/architecture-current-state-accuracy branch September 13, 2026 08:52
argszero added a commit that referenced this pull request Sep 27, 2026
…#318)

`cabe4c6` (#203) changed only the Chinese half of the sentence that says where
the API list lives: `README.md` now reads "API 一览见 docs/architecture.md,
权威清单以 `src/routes/mod.rs` 的 `router()` 为准", while `README.en.md` kept
its pre-#203 wording ("Full API reference: docs/architecture.md."). That sends
the English reader to a document #203 was downgrading to an overview, and the
Chinese reader to the code — two answers to one question, from one document
whose two halves declare each other as translations on line 3.

Fix the value and give the pair an enforcer:

- `README.en.md`: say the same thing as the Chinese half — an overview link
  plus the authoritative source in code (`router()` in `src/routes/mod.rs`).
- `src/readme_gate.rs` (test-only, `#[cfg(test)] mod readme_gate`): assert the
  two carriers hold the same facts. The compared positions are the
  language-independent ones only — inline code spans, markdown link targets,
  bare URLs, numeric literals — compared as sets, with the expected value
  derived from the files on both sides (no snapshot). Prose, headings, table
  headers, emphasis, line order and line count are deliberately not compared.
  Positive control: every family must be non-empty on both sides and the four
  together must yield enough items, so an extractor that returns empty sets
  cannot pass vacuously. Teeth: a fact dropped on one side is reported for each
  of the four families.

Scope, stated where the gate is: it is lexical — it proves the two sides carry
the same structural positions, not that the translation is faithful, and a
"delete the Chinese sentence instead" fix would pass it.

`cargo test`: 417 passed / 0 failed (baseline 413; +4 new).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant