74 lines
3.3 KiB
Markdown
74 lines
3.3 KiB
Markdown
# Quality gates — web client
|
|
|
|
LLM-verified gates for `architecture/web-client.md`. Automatic tests:
|
|
`cbd-web/src/{state,keymap}.rs` (native target),
|
|
`crabidy-server/src/web.rs`, plus the existing auth-layer suite.
|
|
|
|
## Parity
|
|
|
|
- [x] Every TUI binding has a web equivalent (keyboard *and*
|
|
clickable): browse/ascend/dive, marks, `%`/`e`/`d`, `w`/`W`,
|
|
queue replace/append/queue-next/insert-here, queue select/play/
|
|
remove/clear(s)/save, play/pause/restart/next/prev, volume,
|
|
mute, shuffle, repeat, help overlay.
|
|
- [x] Semantics ported, not approximated: tracks before children,
|
|
empty non-creatable nodes not entered, marks win over cursor,
|
|
per-path cursor memory, capture-progress lines identical, skipped
|
|
tracks red and flagged, capture deletes ask y/N, cheap deletes do
|
|
not, mutable roots never cached (`state::is_cacheable` mirrors
|
|
the TUI rule).
|
|
- [x] The update stream feeds queue/play-state/volume/mute/mods/
|
|
position/capture progress; a broken stream reconnects with
|
|
backoff and shows a disconnected banner until then.
|
|
|
|
## Security
|
|
|
|
- [x] The auth layer wraps the gRPC route in both transports: a
|
|
gRPC-web call without credentials is `UNAUTHENTICATED`, with
|
|
insufficient role `PERMISSION_DENIED` — verified against a live
|
|
server.
|
|
- [x] Static assets are served without auth (public shell), and only
|
|
via GET/HEAD; nothing under `/crabidy.v1.CrabidyService/` is
|
|
served statically.
|
|
- [x] Credentials live in `localStorage` only; never in URLs, never
|
|
logged to the console; the login form is the only place that
|
|
reads them back.
|
|
- [x] `UNAUTHENTICATED` responses open the login dialog instead of a
|
|
silent failure loop.
|
|
|
|
## Build & packaging
|
|
|
|
- [x] `cargo build`/`test` (no wasm toolchain) succeeds with the
|
|
default `web-ui` feature: missing `cbd-web/dist` embeds the
|
|
placeholder page with the build hint, a present dist embeds the
|
|
real bundle on the next build (`rerun-if-changed`).
|
|
- [x] `--no-default-features` yields a gRPC-only server (no embedded
|
|
assets, no tonic-web), and it still compiles and passes tests.
|
|
- [x] `devenv shell -- build-web` produces `cbd-web/dist` (RUSTFLAGS
|
|
cleared: mold breaks rust-lld); `cargo check -p cbd-web --target
|
|
wasm32-unknown-unknown` and native `cargo test -p cbd-web` both
|
|
pass.
|
|
- [x] The TUI's native gRPC still works through the axum server (h2c
|
|
prior knowledge) — verified live alongside gRPC-web.
|
|
|
|
## Styling
|
|
|
|
- [x] Pure CSS, no framework, no external requests (fonts, CDNs);
|
|
everything ships in the bundle.
|
|
- [x] Light and dark themes: `color-scheme` + `light-dark()` following
|
|
the OS by default, manual toggle persisted; both themes keep
|
|
readable contrast for dim text, accent, and the red
|
|
skipped/danger tones.
|
|
- [x] The crab orange-red accent is a single custom property
|
|
(`--accent`), derived tones via `color-mix` — no hard-coded
|
|
copies.
|
|
- [x] Usable on a phone viewport (panes stack/switch) and desktop.
|
|
|
|
## Code shape
|
|
|
|
- [x] Components stay thin; logic lives in `state.rs`/`keymap.rs` with
|
|
native unit tests.
|
|
- [x] No panics on server errors: every RPC result is handled (status
|
|
surfaces in the UI or the console at worst); stream reconnect
|
|
never busy-loops.
|