Implement initial scan tracking for one-time setup

- Add SystemSettings model to track setup completion status
- Create SystemSettingsService for managing setup flags
- Modify fastapi_app startup to check and set initial_scan_completed flag
- Anime folder scanning now only runs on first startup
- Update DATABASE.md with new system_settings table documentation
- Add unit test for SystemSettingsService functionality

This ensures expensive one-time operations like scanning the entire anime
directory only occur during initial setup, not on every application restart.
This commit is contained in:
2026-01-21 19:22:50 +01:00
parent 35c82e68b7
commit bf3cfa00d5
8 changed files with 383 additions and 45 deletions

View File

@@ -186,7 +186,34 @@ async def lifespan(_application: FastAPI):
# Subscribe to progress events
progress_service.subscribe("progress_updated", progress_event_handler)
# Sync series from data files to database FIRST (one-time setup)
# Check if initial setup has been completed
try:
from src.server.database.connection import get_db_session
from src.server.database.system_settings_service import (
SystemSettingsService,
)
async with get_db_session() as db:
is_initial_scan_done = (
await SystemSettingsService.is_initial_scan_completed(db)
)
if is_initial_scan_done:
logger.info(
"Initial scan already completed, skipping data file sync"
)
else:
logger.info(
"Initial scan not completed, "
"performing first-time setup"
)
except Exception as e:
logger.warning(
"Failed to check system settings: %s, assuming first run", e
)
is_initial_scan_done = False
# Sync series from data files to database (only on first run)
# This must happen before SeriesApp initialization
try:
logger.info(
@@ -195,13 +222,33 @@ async def lifespan(_application: FastAPI):
)
if settings.anime_directory:
# Sync series from data files to database (one-time setup)
sync_count = await sync_series_from_data_files(
settings.anime_directory
)
logger.info(
"Data file sync complete. Added %d series.", sync_count
)
# Only sync from data files on first run
if not is_initial_scan_done:
logger.info("Performing initial anime folder scan...")
sync_count = await sync_series_from_data_files(
settings.anime_directory
)
logger.info(
"Data file sync complete. Added %d series.", sync_count
)
# Mark initial scan as completed
try:
async with get_db_session() as db:
await (
SystemSettingsService
.mark_initial_scan_completed(db)
)
logger.info("Marked initial scan as completed")
except Exception as e:
logger.warning(
"Failed to mark initial scan as completed: %s", e
)
else:
logger.info(
"Skipping initial scan - "
"already completed on previous run"
)
# Load series from database into SeriesApp's in-memory cache
from src.server.utils.dependencies import get_anime_service