Users were incorrectly redirected to /login during the initial loading phase before the loading was actually complete. Added loading_started and loading_complete flags to properly track the initialization state so the setup redirect middleware knows when it's safe to redirect.
234 lines
9.4 KiB
Markdown
234 lines
9.4 KiB
Markdown
# Navigation & Redirect Logic
|
|
|
|
This document describes the setup flow navigation, covering how users progress from initial setup through to the main application.
|
|
|
|
## Overview
|
|
|
|
The application uses a middleware-based redirect system to enforce a strict state machine. Users must complete each phase before accessing the next. Attempting to bypass the current phase redirects to the appropriate page.
|
|
|
|
## State Machine
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────────┐
|
|
│ NAVIGATION STATES │
|
|
├─────────────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ NO_SETUP ──────────► SETUP_COMPLETE ──────────► UNRESOLVED_PENDING │
|
|
│ │ │ │ │
|
|
│ │ │ │ │
|
|
│ ▼ ▼ ▼ │
|
|
│ /setup /loading /setup/unresolved │
|
|
│ (series scan) (resolve folders) │
|
|
│ │
|
|
│ UNRESOLVED_DONE ───────┐
|
|
│ │ │
|
|
│ ▼ │
|
|
│ NFO_SCAN_PENDING │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ /loading │
|
|
│ (NFO scan) │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ COMPLETE │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ /login │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## State Definitions
|
|
|
|
| State | Condition | Target Page |
|
|
|-------|-----------|-------------|
|
|
| `NO_SETUP` | No master password configured | `/setup` |
|
|
| `SETUP_COMPLETE` | Initial config passed, loading not started | `/loading` |
|
|
| `UNRESOLVED_PENDING` | Setup done, unresolved exist, not marked done | `/setup/unresolved` |
|
|
| `UNRESOLVED_DONE` | Unresolved phase marked complete, NFO scan pending | `/loading` |
|
|
| `NFO_SCAN_PENDING` | Unresolved done, NFO scan incomplete | `/loading` |
|
|
| `COMPLETE` | All phases finished | `/login` |
|
|
|
|
## Middleware: SetupRedirectMiddleware
|
|
|
|
**File:** `src/server/middleware/setup_redirect.py`
|
|
|
|
The middleware intercepts all requests and enforces the state machine.
|
|
|
|
### Exempt Paths (always accessible)
|
|
|
|
| Path | Purpose |
|
|
|------|---------|
|
|
| `/setup` | Initial setup page |
|
|
| `/setup/unresolved` | Unresolved folder resolution |
|
|
| `/loading` | Initialization progress page |
|
|
| `/login` | Authentication |
|
|
| `/api/auth/*` | Auth endpoints |
|
|
| `/api/config/*` | Config API |
|
|
| `/api/health` | Health check |
|
|
| `/static/*` | Static assets |
|
|
|
|
### Middleware Logic
|
|
|
|
The middleware checks the current state and redirects accordingly:
|
|
|
|
```
|
|
1. NO_SETUP state:
|
|
→ Redirect ALL requests to /setup
|
|
→ Exception: /setup itself is accessible
|
|
|
|
2. SETUP_COMPLETE state:
|
|
→ Redirect /setup to /loading
|
|
→ Redirect any other page to /loading
|
|
|
|
3. UNRESOLVED_PENDING state (unresolved folders exist, not marked done):
|
|
→ Redirect /setup to /setup/unresolved
|
|
→ Redirect /loading to /setup/unresolved
|
|
→ Allow access to /setup/unresolved
|
|
→ Redirect any other page to /setup/unresolved
|
|
|
|
4. UNRESOLVED_DONE state (unresolved marked done, NFO scan pending):
|
|
→ Redirect /setup to /loading
|
|
→ Redirect /setup/unresolved to /loading
|
|
→ Redirect any other page to /loading
|
|
|
|
5. NFO_SCAN_PENDING state:
|
|
→ Redirect /setup to /loading
|
|
→ Redirect /setup/unresolved to /loading
|
|
→ Allow access to /loading (NFO phase runs)
|
|
→ Redirect any other page to /loading
|
|
|
|
6. COMPLETE state (loading finished):
|
|
→ Redirect /setup, /loading, /setup/unresolved to /login
|
|
→ Allow access to /login and main app
|
|
```
|
|
|
|
### Phase Tracking Flags
|
|
|
|
| Flag | Purpose |
|
|
|------|---------|
|
|
| `setup_complete` | Initial configuration was saved |
|
|
| `loading_started` | Loading phase has been initiated (redirected to /loading) |
|
|
| `unresolved_completed` | User clicked "Done" on unresolved page |
|
|
| `loading_complete` | Series scan + initial loading finished |
|
|
| `nfo_scan_complete` | Final NFO scan finished |
|
|
|
|
## Pages
|
|
|
|
### 1. Setup Page (`/setup`)
|
|
|
|
**File:** `src/server/web/templates/setup.html`
|
|
|
|
Handles initial configuration:
|
|
- Master password creation
|
|
- Anime directory selection
|
|
- Database initialization
|
|
|
|
**Allowed in states:** `NO_SETUP`
|
|
|
|
**Post-completion:**
|
|
- Sets `setup_complete` flag
|
|
- Redirects to `/loading`
|
|
|
|
### 2. Loading Page (`/loading`)
|
|
|
|
**File:** `src/server/web/templates/loading.html`
|
|
|
|
Shows initialization progress via WebSocket:
|
|
- Series scanning
|
|
- Database population
|
|
- Logo/image loading
|
|
|
|
**Allowed in states:** `SETUP_COMPLETE`, `UNRESOLVED_DONE`, `NFO_SCAN_PENDING`
|
|
|
|
**Post-initialization (series scan complete):**
|
|
```javascript
|
|
async function checkUnresolvedAndProceed() {
|
|
const res = await fetch('/api/setup/unresolved', {
|
|
headers: { 'Authorization': `Bearer ${token}` }
|
|
});
|
|
const folders = await res.json();
|
|
|
|
if (folders.length > 0) {
|
|
window.location.href = '/setup/unresolved';
|
|
} else {
|
|
window.location.href = '/login';
|
|
}
|
|
}
|
|
```
|
|
|
|
**Post-NFO scan:**
|
|
- Sets `nfo_scan_complete` flag
|
|
- Redirects to `/login`
|
|
|
|
### 3. Unresolved Folders Page (`/setup/unresolved`)
|
|
|
|
**File:** `src/server/web/templates/unresolved.html`
|
|
|
|
Allows manual resolution of folders that couldn't be auto-matched:
|
|
- Shows list of unresolved folders
|
|
- Provides search suggestions
|
|
- Input field for entering provider key
|
|
- Resolve/delete actions
|
|
- **Done button** to complete the phase without resolving all folders
|
|
|
|
**Allowed in states:** `UNRESOLVED_PENDING`
|
|
|
|
**Done button behavior:**
|
|
- Sets `unresolved_completed` flag
|
|
- Redirects to `/loading` for final NFO scan
|
|
|
|
**After completion:**
|
|
- Any access redirects to `/loading`
|
|
|
|
### 4. Login Page (`/login`)
|
|
|
|
**File:** `src/server/web/templates/login.html`
|
|
|
|
Authentication page. After successful login → redirect to `/` (main app).
|
|
|
|
**Allowed in states:** `COMPLETE`
|
|
|
|
## API Endpoints
|
|
|
|
### Unresolved Folders API
|
|
|
|
| Method | Endpoint | Description |
|
|
|--------|----------|-------------|
|
|
| `GET` | `/api/setup/unresolved` | List all unresolved folders |
|
|
| `GET` | `/api/setup/unresolved/{folder_name}` | Get specific folder details |
|
|
| `POST` | `/api/setup/unresolved/{folder_name}/resolve` | Resolve with provider key |
|
|
| `POST` | `/api/setup/unresolved/{folder_name}/search` | Re-search for matches |
|
|
| `DELETE` | `/api/setup/unresolved/{folder_name}` | Remove folder from tracking |
|
|
| `POST` | `/api/setup/unresolved/done` | Mark unresolved phase as complete |
|
|
|
|
### Auth API
|
|
|
|
| Method | Endpoint | Description |
|
|
|--------|----------|-------------|
|
|
| `POST` | `/api/auth/setup` | Create master password |
|
|
| `POST` | `/api/auth/login` | Authenticate |
|
|
| `POST` | `/api/auth/logout` | End session |
|
|
|
|
## Key Files
|
|
|
|
| File | Purpose |
|
|
|------|---------|
|
|
| `src/server/middleware/setup_redirect.py` | Redirect middleware (state machine) |
|
|
| `src/server/controllers/page_controller.py` | Page route handlers |
|
|
| `src/server/web/templates/setup.html` | Setup template |
|
|
| `src/server/web/templates/loading.html` | Loading template |
|
|
| `src/server/web/templates/unresolved.html` | Unresolved folders template |
|
|
| `src/server/api/setup_endpoints.py` | Unresolved folders API |
|
|
| `src/server/database/service.py` | UnresolvedFolderService |
|
|
|
|
## Navigation Summary
|
|
|
|
| Current State | Access `/setup` | Access `/loading` | Access `/setup/unresolved` |
|
|
|--------------|-----------------|-------------------|---------------------------|
|
|
| NO_SETUP | ✅ Allowed | ❌ → `/setup` | ❌ → `/setup` |
|
|
| SETUP_COMPLETE | ❌ → `/loading` | ✅ Allowed | ❌ → `/loading` |
|
|
| UNRESOLVED_PENDING | ❌ → `/setup/unresolved` | ❌ → `/setup/unresolved` | ✅ Allowed |
|
|
| UNRESOLVED_DONE | ❌ → `/loading` | ✅ Allowed (NFO phase) | ❌ → `/loading` |
|
|
| NFO_SCAN_PENDING | ❌ → `/loading` | ✅ Allowed (NFO phase) | ❌ → `/loading` |
|
|
| COMPLETE | ❌ → `/login` | ❌ → `/login` | ❌ → `/login` | |