Skip to content

refactor(ui): zero mock data in logged-in views (v1.22) - #94

Merged
argszero merged 1 commit into
mainfrom
feat/zero-mock-logged-in
Aug 19, 2026
Merged

argszero merged 1 commit into
mainfrom
feat/zero-mock-logged-in

Conversation

@argszero

Copy link
Copy Markdown
Owner

Summary

Systematic cleanup per host rant 2026-08-19T15:54:06 (登录态零 mock — any view in logged-in state must not render data.js mock data; mock only for guest mode, and guest should be as real as possible).

Frontend (ui/js/app.js, ui/js/data.js, ui/js/i18n.js):

  • Deleted mock objects from data.js: TRANSACTIONS, SHARINGS, API_KEYS, EMPLOYEES, DEPARTMENTS, USAGE_MODEL, USAGE_EMP, OPERATOR_USERS, RAISE_REQUESTS; removed fictional multi/success from MARKET.
  • Uniform degradation for logged-in load failures: Live.x ? view(Live.x) : loadErrorHtml/loadErrorRow(empty state + retry) — never falls back to D.*. loadErrorRow (tbody-safe) added; retry buttons wired for all views (dash/sharings/market/tx/api-keys/admin-emp/usage/org/raise/ops).
  • Dashboard stats use /api/wallet + /api/dashboard (+ real /api/transactions total); sparkline/aggregation mock only in guest mode.
  • Marketplace: logged-in uses /api/models exclusively (failure → retry); provider filter rebuilt from live providers; multi = available_keys >= 2; success rate not shown (backend has no such field); guest mock rows no longer show fake success.
  • Transactions/CSV, API Keys (gen/rename/delete), admin members/usage/departments CRUD, ops runtime/users, raise requests submit/approve, share form submit: real API only, mock branches removed.
  • Chat mock (sendChat) no longer writes D.TRANSACTIONS (P2-D candidate pending); wallet mock topup keeps session balance only.

Backend (src/dao.rs, src/gateway.rs): GET /api/models now returns context_window (from models.context_window) so logged-in market ctx is real data; test updated.

Docs: ui/README.md v1.22 section 登录态零 mock 约定 (kept objects / deleted objects / degradation pattern / acceptance).

Related

Host rant 2026-08-19T15:54:06.168447+08:00 — 系统性清理 · 登录态零 mock(any page must not show data.js fake data in logged-in state).

Tests

  • cargo test: 111/111 passed
  • cargo fmt --check: clean
  • cargo clippy --all-targets -- -D warnings: clean
  • node --check on all ui/js files: clean
  • i18n key scan: 446 used keys, 0 missing (zh/en both 599)
  • Node smoke test (38 assertions): guest still sees mock; logged-in market/dash/tx/settings/admin/ops all real data or retry states; no mock numbers (32,800/100,000/+1,611/51,200/80,000) in logged-in views

@argszero
argszero merged commit 89963f3 into main Aug 19, 2026
1 check passed
@argszero
argszero deleted the feat/zero-mock-logged-in branch August 19, 2026 08:30
argszero added a commit that referenced this pull request Sep 15, 2026
A sharing key has three reachable statuses (`on` / `paused` / `off`): PATCH
/api/sharings/:id accepts all three, and GET /api/sharings applies no status
filter, so a soft-deleted row stays in the list. The row button labels the
transition from the CURRENT status (Pause / Resume / Re-list), while the
outcome toast picked it from the NEXT status with a two-valued ternary
(`s.status === "on" ? "paused" : "on"`) -- so `off -> on` (re-list) was
reported as a resume: button "Re-list", toast "Resumed sharing of ...".
The key naming that branch, `share.toggle.relisted`, is present in both
language packs and unreachable -- an unreachable key is the fingerprint of a
lost branch. Provenance is drift, not a trade-off: 68f9f70 (#86) introduced
the three-way button, 89963f3 (#94) replaced the mock's three-branch toggle
with the two-branch ternary.

- add `SHARE_TOGGLE` (status -> { label, next, outcome }): the button's action,
  its next status and its outcome text now come from the SAME entry, read by
  both consumers through `shareToggle(s.status)`.
- new static gate
  `state_gate::the_sharing_toggle_outcome_comes_from_the_same_entry_as_its_action`:
  share.toggle.* literals may only live inside the table; the table's key set
  must equal `SHARE_STATUS`'s (both derived from source); the label/outcome
  columns must be unique per entry; and the handler (derived as the endpoint
  that sends a NON-literal status to /api/sharings/) must not name a
  share.toggle.* key nor branch on a status literal, and must share exactly one
  accessor with the button markup. Extractor self-proofs use synthetic inputs.
- i18n positive controls recalibrated from what the gate reported:
  T() literals 542 -> 537, distinct 433 -> 428 (five literal call sites became
  table entries).
- ui/README.md: rule + measured scope; index.html cache-bust for app.js.
argszero added a commit that referenced this pull request Sep 15, 2026
…265)

A sharing key has three reachable statuses (`on` / `paused` / `off`): PATCH
/api/sharings/:id accepts all three, and GET /api/sharings applies no status
filter, so a soft-deleted row stays in the list. The row button labels the
transition from the CURRENT status (Pause / Resume / Re-list), while the
outcome toast picked it from the NEXT status with a two-valued ternary
(`s.status === "on" ? "paused" : "on"`) -- so `off -> on` (re-list) was
reported as a resume: button "Re-list", toast "Resumed sharing of ...".
The key naming that branch, `share.toggle.relisted`, is present in both
language packs and unreachable -- an unreachable key is the fingerprint of a
lost branch. Provenance is drift, not a trade-off: 68f9f70 (#86) introduced
the three-way button, 89963f3 (#94) replaced the mock's three-branch toggle
with the two-branch ternary.

- add `SHARE_TOGGLE` (status -> { label, next, outcome }): the button's action,
  its next status and its outcome text now come from the SAME entry, read by
  both consumers through `shareToggle(s.status)`.
- new static gate
  `state_gate::the_sharing_toggle_outcome_comes_from_the_same_entry_as_its_action`:
  share.toggle.* literals may only live inside the table; the table's key set
  must equal `SHARE_STATUS`'s (both derived from source); the label/outcome
  columns must be unique per entry; and the handler (derived as the endpoint
  that sends a NON-literal status to /api/sharings/) must not name a
  share.toggle.* key nor branch on a status literal, and must share exactly one
  accessor with the button markup. Extractor self-proofs use synthetic inputs.
- i18n positive controls recalibrated from what the gate reported:
  T() literals 542 -> 537, distinct 433 -> 428 (five literal call sites became
  table entries).
- ui/README.md: rule + measured scope; index.html cache-bust for app.js.
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