From b800158648d65f88c2883dfef8fa29b42adaa737 Mon Sep 17 00:00:00 2001 From: Lukas Date: Sun, 7 Jun 2026 20:02:51 +0200 Subject: [PATCH] refactor(docs): restructure navigation as state machine Replaced linear flow diagram with explicit state definitions and transition table. Removes MIGRATION_GUIDE.md (merged into main docs). --- Docs/MIGRATION_GUIDE.md | 111 ----------------------- Docs/NAVIGATION.md | 195 +++++++++++++++++++++++----------------- 2 files changed, 111 insertions(+), 195 deletions(-) delete mode 100644 Docs/MIGRATION_GUIDE.md diff --git a/Docs/MIGRATION_GUIDE.md b/Docs/MIGRATION_GUIDE.md deleted file mode 100644 index 5a5e91b..0000000 --- a/Docs/MIGRATION_GUIDE.md +++ /dev/null @@ -1,111 +0,0 @@ -# Migration Guide: File-Based to Database Storage - -## Overview - -This guide covers the transition from file-based series metadata storage to the new database-backed system introduced in v2.0. - -## What Changed - -**Before v2.0**: Series metadata stored in `key` and `data` files alongside anime folders. - -**After v2.0**: All metadata stored in SQLite database (`aniworld.db`). Files are deprecated but still supported for backward compatibility during migration. - -## Automated Migration - -The application automatically migrates on first startup: - -1. Scans anime directory for `key` and `data` files -2. Parses legacy files into `AnimeSeries` and `Episode` records -3. Loads series into in-memory cache -4. Logs migration results - -**No manual action required.** - -## Manual Verification - -After first startup with the new version: - -1. **Check logs** for: `"Migrated X series from files to DB"` -2. **Verify series count**: UI shows same number of series as before -3. **Confirm episodes**: Episode counts match expected totals - -```bash -# Check migration log -grep "Migrated" logs/app.log - -# Verify series via API -curl http://localhost:8000/api/anime | jq '.total' -``` - -## After Migration - -### Safe to Delete - -Once verified, these files can be removed: - -``` -/ -├── Attack on Titan (2013)/ -│ ├── key # ❌ Can delete -│ ├── data # ❌ Can delete -│ └── Season 1/ -│ └── ... -``` - -**Deleting these files does not affect the database.** The metadata now lives in `aniworld.db`. - -### Backup (Recommended) - -Before deleting, backup the files: - -```bash -# Create backup directory -mkdir -p backup/legacy_series_files - -# Copy all key and data files -find /path/to/anime -name "key" -o -name "data" | while read f; do - cp "$f" "backup/legacy_series_files/" -done -``` - -## Reverting (Not Recommended) - -If you must revert to file-based storage: - -1. **Restore from database backup** (if available) -2. **Export manually** (no export script exists) - -**Warning**: File-based storage is deprecated and will be removed in v3.0.0. - -## Troubleshooting - -### Series Not Appearing After Migration - -1. Check logs for migration errors: `grep -i error logs/app.log` -2. Verify `key` and `data` files exist and are readable -3. Manually trigger rescan: `POST /api/scheduler/trigger-rescan` - -### Duplicate Series - -1. Check for duplicate `key` files (same series in multiple folders) -2. Verify series key uniqueness in database: - -```bash -sqlite3 aniworld.db "SELECT key, COUNT(*) FROM anime_series GROUP BY key HAVING COUNT(*) > 1;" -``` - -### Missing Episodes - -1. Trigger targeted scan for affected series -2. Check episode sync logs -3. Verify file permissions on anime directory - -## Deprecation Timeline - -| Version | Status | -|---------|--------| -| v2.0.x | Legacy files supported, migration automated | -| v2.1.x | Legacy files still supported, warnings in logs | -| v3.0.0 | **Legacy files removed** - database only | - -Upgrade to v3.0.0 before legacy file support ends. \ No newline at end of file diff --git a/Docs/NAVIGATION.md b/Docs/NAVIGATION.md index 1b51190..a5b36fd 100644 --- a/Docs/NAVIGATION.md +++ b/Docs/NAVIGATION.md @@ -4,54 +4,56 @@ This document describes the setup flow navigation, covering how users progress f ## Overview -The application uses a middleware-based redirect system to ensure users complete setup before accessing the main app. The flow involves multiple pages handling setup completion, unresolved folder detection, and initialization. +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. -## Setup Flow +## State Machine ``` -┌─────────────────────────────────────────────────────────────────────┐ -│ SETUP FLOW │ -├─────────────────────────────────────────────────────────────────────┤ -│ │ -│ /setup ──► /loading ──► /setup/unresolved ──► /loading ──► /login │ -│ │ │ │ │ │ -│ │ │ │ │ │ -│ ▼ ▼ ▼ ▼ │ -│ (first (Series Scan + (has folders) (all resolved) │ -│ time) NFO Scan) │ │ -│ │ │ │ -│ │ │ │ -│ │ ▼ │ -│ │ [Done button] ──► marks complete │ -│ │ │ │ -│ │ ▼ │ -│ │ /loading (NFO phase runs again) │ -│ │ │ │ -│ └────────┴─────────────────────────────────────┘ -│ │ -└─────────────────────────────────────────────────────────────────────┘ +┌─────────────────────────────────────────────────────────────────────────┐ +│ 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 │ +│ │ +└─────────────────────────────────────────────────────────────────────────┘ ``` -**New Navigation Order:** -1. `/setup` → Initial configuration -2. `/loading` → Series scan + NFO scan -3. `/setup/unresolved` → Resolve folders (if any) -4. `/loading` → NFO scan runs again -5. `/login` → Authentication +## State Definitions -**Key Changes:** -- After `/setup/unresolved`, the "Done" button marks the phase as complete -- Revisiting `/setup/unresolved` after completion → redirects to `/loading` -- `/loading` always goes to `/setup/unresolved` if unresolved folders exist -- NFO scan runs as a separate phase after series sync during initialization +| 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 redirects to `/setup` if: -- No master password is configured -- Configuration file is missing or invalid +The middleware intercepts all requests and enforces the state machine. ### Exempt Paths (always accessible) @@ -68,13 +70,47 @@ The middleware intercepts all requests and redirects to `/setup` if: ### Middleware Logic -1. **Setup incomplete** → Redirect to `/setup` -2. **Setup complete, accessing `/setup`** → Redirect to `/login` -3. **Setup complete, accessing `/loading`** → Allow access (page handles its own redirect) -4. **Setup complete, accessing `/setup/unresolved`**: - - If `unresolved_completed` flag is set → Redirect to `/loading` - - Otherwise → Allow access -5. **API requests during setup** → Return 503 with `setup_url` +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 | +| `unresolved_completed` | User clicked "Done" on unresolved page | +| `loading_complete` | Series scan + initial loading finished | +| `nfo_scan_complete` | Final NFO scan finished | ## Pages @@ -87,8 +123,11 @@ Handles initial configuration: - Anime directory selection - Database initialization -**Post-completion flow:** -- Redirects to `/loading` to begin initialization +**Allowed in states:** `NO_SETUP` + +**Post-completion:** +- Sets `setup_complete` flag +- Redirects to `/loading` ### 2. Loading Page (`/loading`) @@ -99,25 +138,28 @@ Shows initialization progress via WebSocket: - Database population - Logo/image loading -**Post-initialization flow:** +**Allowed in states:** `SETUP_COMPLETE`, `UNRESOLVED_DONE`, `NFO_SCAN_PENDING` + +**Post-initialization (series scan complete):** ```javascript async function checkUnresolvedAndProceed() { - // Fetch unresolved folders via API const res = await fetch('/api/setup/unresolved', { headers: { 'Authorization': `Bearer ${token}` } }); const folders = await res.json(); if (folders.length > 0) { - // Has unresolved folders → go to resolution page window.location.href = '/setup/unresolved'; } else { - // No unresolved folders → go to login 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` @@ -127,24 +169,16 @@ Allows manual resolution of folders that couldn't be auto-matched: - Provides search suggestions - Input field for entering provider key - Resolve/delete actions -- **Done button** at top to complete the phase without resolving all folders +- **Done button** to complete the phase without resolving all folders -**Post-resolution flow:** -```javascript -// After clicking "Done" button -async function handleDone() { - // Call API to mark phase as complete - await fetch('/api/setup/unresolved/done', { method: 'POST' }); - // Redirect to loading for final NFO scan - window.location.href = '/loading'; -} -``` +**Allowed in states:** `UNRESOLVED_PENDING` **Done button behavior:** -- Marks all remaining folders as handled -- Sets `unresolved_completed` flag in config -- Redirects to `/loading` to run final NFO scan -- After completion, `/setup/unresolved` becomes inaccessible (redirects to `/loading`) +- Sets `unresolved_completed` flag +- Redirects to `/loading` for final NFO scan + +**After completion:** +- Any access redirects to `/loading` ### 4. Login Page (`/login`) @@ -152,6 +186,8 @@ async function handleDone() { Authentication page. After successful login → redirect to `/` (main app). +**Allowed in states:** `COMPLETE` + ## API Endpoints ### Unresolved Folders API @@ -177,7 +213,7 @@ Authentication page. After successful login → redirect to `/` (main app). | File | Purpose | |------|---------| -| `src/server/middleware/setup_redirect.py` | Redirect middleware | +| `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 | @@ -185,22 +221,13 @@ Authentication page. After successful login → redirect to `/` (main app). | `src/server/api/setup_endpoints.py` | Unresolved folders API | | `src/server/database/service.py` | UnresolvedFolderService | -## Common Issues +## Navigation Summary -### Redirect Loop - -**Symptom:** Browser keeps redirecting between pages. - -**Causes:** -1. `loading.html` always redirected to `/setup/unresolved` without checking if any exist -2. `unresolved.html` redirected to `/` which middleware redirected back to `/login` - -**Fix:** See the navigation logic updates in loading.html and unresolved.html. - -### Can't Access Unresolved Page After Setup - -**Symptom:** Middleware redirects to `/login` instead of allowing access to `/setup/unresolved`. - -**Cause:** `/setup/unresolved` is in the exempt paths but the request may not be reaching it due to completion check timing. - -**Fix:** The middleware allows access to `/loading` which handles the redirect to `/setup/unresolved` after initialization. \ No newline at end of file +| 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` | \ No newline at end of file