docs
This commit is contained in:
60
docs/architecture/website/CLIENT_STATE.md
Normal file
60
docs/architecture/website/CLIENT_STATE.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# Client State (Strict)
|
||||
|
||||
This document defines the only allowed usage of client state in `apps/website`.
|
||||
|
||||
Authoritative contract: [`WEBSITE_CONTRACT.md`](docs/architecture/website/WEBSITE_CONTRACT.md:1).
|
||||
|
||||
## 1) Core rule
|
||||
|
||||
Client state is allowed only for **UI concerns**.
|
||||
|
||||
The API remains the single source of truth.
|
||||
|
||||
## 2) Allowed client state
|
||||
|
||||
Client state MAY represent:
|
||||
|
||||
- selection (table rows, active tab)
|
||||
- open/closed dialogs and drawers
|
||||
- input values before submission
|
||||
- loading flags
|
||||
- best-effort optimistic flags
|
||||
|
||||
## 3) Forbidden client state
|
||||
|
||||
Client state MUST NOT be used as:
|
||||
|
||||
- business truth
|
||||
- security truth
|
||||
- permission truth
|
||||
|
||||
Examples of forbidden behavior:
|
||||
|
||||
- client code deciding that a user is allowed based on local flags
|
||||
- client code persisting an authoritative list state that overrides server truth
|
||||
|
||||
## 4) Conflict resolution rule (hard)
|
||||
|
||||
If client state and API truth disagree, **API truth wins**.
|
||||
|
||||
Correct handling is:
|
||||
|
||||
- show the API result
|
||||
- revalidate and reload server-rendered truth
|
||||
|
||||
## 5) Relationship to Blockers
|
||||
|
||||
Blockers exist to prevent UX mistakes.
|
||||
|
||||
- Blockers are not security.
|
||||
- Blockers may reduce unnecessary requests.
|
||||
- The API still enforces rules.
|
||||
|
||||
See [`BLOCKER_GUARDS.md`](docs/architecture/website/BLOCKER_GUARDS.md:1).
|
||||
|
||||
## 6) Canonical placement in this repo
|
||||
|
||||
- `apps/website/lib/blockers/**`
|
||||
- `apps/website/lib/hooks/**`
|
||||
- `apps/website/lib/command-models/**`
|
||||
|
||||
Reference in New Issue
Block a user