docs
This commit is contained in:
@@ -1,14 +1,20 @@
|
||||
# Login Flow State Machine Architecture
|
||||
# Login Flow State Machine (Strict)
|
||||
|
||||
## Problem
|
||||
The current login page has unpredictable behavior due to:
|
||||
- Multiple useEffect runs with different session states
|
||||
- Race conditions between session loading and redirect logic
|
||||
- Client-side redirects that interfere with test expectations
|
||||
This document defines the canonical, deterministic login flow controller for the website.
|
||||
|
||||
## Solution: State Machine Pattern
|
||||
Authoritative website contract:
|
||||
|
||||
### State Definitions
|
||||
- [`docs/architecture/website/WEBSITE_CONTRACT.md`](docs/architecture/website/WEBSITE_CONTRACT.md:1)
|
||||
|
||||
## 1) Core rule
|
||||
|
||||
Login flow logic MUST be deterministic.
|
||||
|
||||
The same inputs MUST produce the same state and the same next action.
|
||||
|
||||
## 2) State machine definition (strict)
|
||||
|
||||
### 2.1 State definitions
|
||||
|
||||
```typescript
|
||||
enum LoginState {
|
||||
@@ -19,7 +25,7 @@ enum LoginState {
|
||||
}
|
||||
```
|
||||
|
||||
### State Transition Table
|
||||
### 2.2 State transition table
|
||||
|
||||
| Current State | Session | ReturnTo | Next State | Action |
|
||||
|---------------|---------|----------|------------|--------|
|
||||
@@ -29,7 +35,7 @@ enum LoginState {
|
||||
| UNAUTHENTICATED | exists | any | POST_AUTH_REDIRECT | Redirect to returnTo |
|
||||
| AUTHENTICATED_WITHOUT_PERMISSIONS | exists | any | POST_AUTH_REDIRECT | Redirect to returnTo |
|
||||
|
||||
### Class-Based Controller
|
||||
### 2.3 Class-based controller
|
||||
|
||||
```typescript
|
||||
class LoginFlowController {
|
||||
@@ -57,7 +63,7 @@ class LoginFlowController {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
// Pure function - returns action, doesn't execute
|
||||
// Pure function - returns action, does not execute
|
||||
getNextAction(): LoginAction {
|
||||
switch (this.state) {
|
||||
case LoginState.UNAUTHENTICATED:
|
||||
@@ -71,7 +77,7 @@ class LoginFlowController {
|
||||
}
|
||||
}
|
||||
|
||||
// Called after authentication
|
||||
// Transition called after authentication
|
||||
transitionToPostAuth(): void {
|
||||
if (this.session) {
|
||||
this.state = LoginState.POST_AUTH_REDIRECT;
|
||||
@@ -80,15 +86,14 @@ class LoginFlowController {
|
||||
}
|
||||
```
|
||||
|
||||
### Benefits
|
||||
## 3) Non-negotiable rules
|
||||
|
||||
1. **Predictable**: Same inputs always produce same outputs
|
||||
2. **Testable**: Can test each state transition independently
|
||||
3. **No Race Conditions**: State determined once at construction
|
||||
4. **Clear Intent**: Each state has a single purpose
|
||||
5. **Maintainable**: Easy to add new states or modify transitions
|
||||
1. The controller MUST be constructed from explicit inputs only.
|
||||
2. The controller MUST NOT perform side effects.
|
||||
3. Side effects (routing) MUST be executed outside the controller.
|
||||
4. The controller MUST be unit-tested per transition.
|
||||
|
||||
### Usage in Login Page
|
||||
## 4) Usage in login page (example)
|
||||
|
||||
```typescript
|
||||
export default function LoginPage() {
|
||||
@@ -129,4 +134,4 @@ export default function LoginPage() {
|
||||
}
|
||||
```
|
||||
|
||||
This eliminates all the unpredictable behavior and makes the flow testable and maintainable.
|
||||
This pattern ensures deterministic behavior and makes the flow testable.
|
||||
|
||||
Reference in New Issue
Block a user