website refactor
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
This document defines **Blockers** as UX-only prevention mechanisms in the website.
|
||||
|
||||
**IMPORTANT**: Blockers are **optional UX helpers**. They are NOT enforced by ESLint rules and do not belong in the strict architecture contract.
|
||||
|
||||
Shared contract: [`docs/architecture/shared/BLOCKERS_AND_GUARDS.md`](docs/architecture/shared/BLOCKERS_AND_GUARDS.md:1)
|
||||
|
||||
## 1) Definition
|
||||
@@ -10,42 +12,64 @@ A Blocker is a website mechanism that prevents an action from being executed.
|
||||
|
||||
Blockers exist solely to improve UX and reduce unnecessary requests.
|
||||
|
||||
Blockers are not security.
|
||||
**Blockers are not security.** They are best-effort helpers that can be bypassed.
|
||||
|
||||
## 2) Responsibilities
|
||||
## 2) Purpose
|
||||
|
||||
Blockers MAY:
|
||||
Use Blockers to:
|
||||
- Prevent multiple form submissions
|
||||
- Debounce rapid button clicks
|
||||
- Temporarily disable actions during loading
|
||||
- Show/hide UI elements based on state
|
||||
|
||||
- prevent multiple submissions
|
||||
- disable actions temporarily
|
||||
- debounce or throttle interactions
|
||||
- hide or disable UI elements
|
||||
- prevent navigation under certain conditions
|
||||
**Do NOT use Blockers for:**
|
||||
- Authorization checks
|
||||
- Security enforcement
|
||||
- Permanent access control
|
||||
|
||||
Blockers MUST:
|
||||
## 3) Placement
|
||||
|
||||
- be reversible
|
||||
- be local to the website
|
||||
- be treated as best-effort helpers
|
||||
Since Blockers are UX-only, they belong in:
|
||||
- `apps/website/components/**` (component-specific blockers)
|
||||
- `apps/website/hooks/**` (shared blocker hooks)
|
||||
- `apps/website/utils/**` (blocker utilities)
|
||||
|
||||
## 3) Restrictions
|
||||
**NOT in `lib/`** - `lib/` is for business logic and architecture contracts.
|
||||
|
||||
Blockers MUST NOT:
|
||||
## 4) Example
|
||||
|
||||
- enforce security
|
||||
- claim authorization
|
||||
- block access permanently
|
||||
- replace API Guards
|
||||
- make assumptions about backend state
|
||||
```typescript
|
||||
// ✅ OK: Component-level blocker
|
||||
export function useSubmitBlocker() {
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
return {
|
||||
isSubmitting,
|
||||
block: () => setIsSubmitting(true),
|
||||
release: () => setIsSubmitting(false),
|
||||
};
|
||||
}
|
||||
|
||||
## 4) Common Blockers
|
||||
// Usage
|
||||
const blocker = useSubmitBlocker();
|
||||
|
||||
- SubmitBlocker
|
||||
- ThrottleBlocker
|
||||
- NavigationBlocker
|
||||
- FeatureBlocker
|
||||
async function handleSubmit() {
|
||||
if (blocker.isSubmitting) return;
|
||||
|
||||
blocker.block();
|
||||
await submitForm();
|
||||
blocker.release();
|
||||
}
|
||||
```
|
||||
|
||||
## 5) Canonical placement
|
||||
## 5) Key Principle
|
||||
|
||||
- `apps/website/lib/blockers/**`
|
||||
**Blockers are optional.** The backend must never rely on them.
|
||||
|
||||
If a blocker prevents a submission, the backend should still:
|
||||
- Validate the request
|
||||
- Return appropriate errors
|
||||
- Handle duplicate submissions gracefully
|
||||
|
||||
This is why Blockers don't need ESLint enforcement - they're just UX sugar.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user