# 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` |