- Add debug logging to checkActiveScanStatus() for better tracing
- Update status indicator before showing overlay for faster feedback
- Add warning logs when DOM elements are not found
- Ensure idle state is explicitly set when no scan is running
- Add debug logging to AnimeService.get_scan_status()
- Added defensive check for rescan-status element before adding event listener
- Added e.stopPropagation() to prevent click event bubbling issues
- Added console logging for debugging click events
- Call checkActiveScanStatus() directly in init() method, not just on socket connect
This ensures scan status is checked immediately on page load even if WebSocket
connection is delayed
- Show overlay immediately when rescan is clicked (before API response)
- Add click-outside-to-close on overlay background
- Add click on rescan-status indicator to reopen overlay
- Add cursor pointer to rescan-status for clickability feedback
- All 1024 tests passing
- Add _scan_lock asyncio.Lock to AnimeService
- Check if lock is held before starting rescan
- Use async with to ensure lock is released on completion or exception
- All 1024 tests passing
- Add is_scanning state tracking in AnimeService
- Add get_scan_status method to AnimeService
- Add /api/anime/scan/status endpoint to check scan state
- Add checkActiveScanStatus in JS to restore overlay on reconnect
- All 1024 tests passing
- Add total_items parameter to broadcast_scan_started and broadcast_scan_progress
- Pass total from SeriesApp to WebSocket broadcasts in AnimeService
- Update JS overlay to show progress bar and current/total count
- Add CSS for progress bar styling
- Add unit tests for new total_items parameter
- All 1024 tests passing
- Add broadcast_scan_started, broadcast_scan_progress, broadcast_scan_completed to WebSocketService
- Inject WebSocketService into AnimeService for real-time scan progress broadcasts
- Add CSS styles for scan progress overlay with spinner, stats, and completion state
- Update app.js to handle scan events and display progress overlay
- Add unit tests for new WebSocket broadcast methods
- All 1022 tests passing
- Fixed room name mismatch: ProgressService was broadcasting to
'download_progress' but JS clients join 'downloads' room
- Added _get_room_for_progress_type() mapping function
- Updated all progress methods to use correct room names
- Added 13 new tests for room name mapping and broadcast verification
- Updated existing tests to expect correct room names
- Fixed JS clients to join valid rooms (downloads, queue, scan)
- Update _update_series_in_db to sync missing episodes bidirectionally
- Add delete_by_series_and_episode method to EpisodeService
- Remove downloaded episodes from DB after successful download
- Clear anime service cache when episodes are removed
- Fix tests to use 'message' instead of 'detail' in API responses
- Mock DB operations in rescan tests
- Remove db_session parameter from SeriesApp, SerieList, SerieScanner
- Move all database operations to AnimeService (service layer)
- Add add_series_to_db, contains_in_db methods to AnimeService
- Update sync_series_from_data_files to use inline DB operations
- Remove obsolete test classes for removed DB methods
- Fix pylint issues: add broad-except comments, fix line lengths
- Core layer (src/core/) now has zero database imports
722 unit tests pass
- Add documentation warnings for in-memory rate limiting and failed login attempts
- Consolidate duplicate health endpoints into api/health.py
- Fix CLI to use correct async rescan method names
- Update download.py and anime.py to use custom exception classes
- Add WebSocket room validation and rate limiting
- Update SeriesApp.rescan() to use database storage by default (use_database=True)
- Use SerieScanner.scan_async() for database mode, which saves directly to DB
- Fall back to legacy file-based scan() when use_database=False (for CLI compatibility)
- Reinitialize SerieList from database after scan when in database mode
- Update unit tests to use use_database=False for mocked tests
- Add parameter to control storage mode for backward compatibility
- Fix return type annotation in SetupRedirectMiddleware.dispatch() to use Response instead of RedirectResponse
- Replace broad 'except Exception' with specific exception types (FileNotFoundError, ValueError, OSError, etc.)
- Rename AppConfig.validate() to validate_config() to avoid shadowing BaseModel.validate()
- Fix ValidationResult.errors field to use List[str] with default_factory
- Add pylint disable comments for intentional broad exception catches during shutdown
- Rename lifespan parameter to _application to indicate unused variable
- Update all callers to use new validate_config() method name
- Use folder name as fallback when series name is empty
- Skip series with both empty name and folder
- Add try/catch for individual series to prevent one failure
from stopping the entire sync
- Moved _sync_series_to_database from fastapi_app.py to anime_service.py
- Renamed to sync_series_from_data_files for better clarity
- Updated all imports and test references
- Removed completed TODO tasks from instructions.md
- Add get_all_series_from_data_files() to SeriesApp
- Sync series from data files to DB on startup
- Add unit tests for new SeriesApp method
- Add integration tests for sync functionality
- Update documentation
- Created QueueRepository adapter in src/server/services/queue_repository.py
- Refactored DownloadService to use repository pattern instead of JSON
- Updated application startup to initialize download service from database
- Updated all test fixtures to use MockQueueRepository
- All 1104 tests passing
Task 9: Clean up legacy code
- Added deprecation warnings to Serie.save_to_file() and load_from_file()
- Updated infrastructure.md with Data Storage section documenting:
- SQLite database as primary storage
- Legacy file storage as deprecated
- Data migration process
- Added deprecation warning tests for Serie class
- Updated existing tests to handle new warnings
- All 1012 tests pass (872 unit + 55 API + 85 integration)
- Added db_session parameter to SeriesApp.__init__()
- Added db_session property and set_db_session() method
- Added init_from_db_async() for async database initialization
- Pass db_session to SerieList and SerieScanner during construction
- Added get_series_app_with_db() dependency for FastAPI endpoints
- All 815 unit tests and 55 API tests pass
Task 6: Update Anime API endpoints to use database
- Modified add_series endpoint to save series to database when available
- Added get_optional_database_session dependency for graceful fallback
- Falls back to file-based storage when database unavailable
- All 55 API tests and 809 unit tests pass
- Enhanced infrastructure.md with identifier convention table, format requirements, migration notes
- Updated docs/README.md with series identifier convention section
- Updated docs/api_reference.md with key-based API examples and notes
- Added deprecation warnings to SerieList.get_by_folder()
- Added deprecation warnings to anime.py folder fallback lookup
- Added deprecation warnings to validate_series_key_or_folder()
- All warnings include v3.0.0 removal timeline
- All 1006 tests pass
- Updated AnimeSeries model docstring to clarify key is primary identifier
- Updated folder field to indicate metadata-only usage
- Updated AnimeSeriesService docstring and get_by_key method
- Updated infrastructure.md with database identifier documentation
- All 996 tests passing
- Updated app.js to use 'key' as primary series identifier
- selectedSeries Set now uses key instead of folder
- createSerieCard() uses data-key attribute for identification
- toggleSerieSelection() uses key for lookups
- downloadSelected() iterates with key values
- updateSelectionUI() and toggleSelectAll() use key
- Updated WebSocket service tests
- Tests now include key and folder in broadcast data
- Verified both fields are included in messages
- No changes needed for queue.js and other JS files
- They use download item IDs correctly, not series identifiers
- No template changes needed
- Series cards rendered dynamically in app.js
All 996 tests passing
- Add series context helpers: prepare_series_context, get_series_by_key, filter_series_by_missing_episodes
- Update module docstring with identifier convention documentation
- Add unit tests for new series context helper functions
- Update infrastructure.md with template helpers documentation
- Mark Phase 4 (API Layer) as complete
- Add validate_series_key() function that validates URL-safe, lowercase,
hyphen-separated series keys (e.g., 'attack-on-titan')
- Add validate_series_key_or_folder() for backward compatibility during
transition from folder-based to key-based identification
- Create comprehensive test suite with 99 test cases for all validators
- Update infrastructure.md with validation utilities documentation
- Mark Task 4.6 as complete in instructions.md
Test: conda run -n AniWorld python -m pytest tests/unit/test_validators.py -v
All 99 validator tests pass, 718 total unit tests pass
- Updated AnimeSeriesResponse and SearchResult models in anime.py:
- Changed 'id' field to 'key' as the primary series identifier
- Added 'folder' as optional metadata field
- Added field validator to normalize key to lowercase and strip whitespace
- Added comprehensive docstrings explaining identifier usage
- Updated DownloadItem and DownloadRequest models in download.py:
- Added field validator for serie_id normalization (lowercase, stripped)
- Improved documentation for serie_id (primary identifier) vs serie_folder (metadata)
- Updated test_anime_models.py with comprehensive tests:
- Tests for key normalization and whitespace stripping
- Tests for folder as optional metadata
- Reorganized tests into proper class structure
- Updated test_download_models.py with validator tests:
- Tests for serie_id normalization in DownloadItem
- Tests for serie_id normalization in DownloadRequest
All 885 tests pass.
- Updated src/server/api/websocket.py docstrings to document key as primary series identifier
- Updated src/server/models/websocket.py with detailed docstrings explaining key and folder fields in message payloads
- Updated src/server/services/websocket_service.py broadcast method docstrings to document key field usage
- Added WebSocket message example with key in infrastructure.md
- All 83 WebSocket tests pass
- Task 4.4 marked as complete in instructions.md
- Updated DownloadRequest and DownloadItem models with comprehensive
docstrings explaining serie_id (key as primary identifier) vs
serie_folder (filesystem metadata)
- Updated add_to_queue() endpoint docstring to document request parameters
- Updated all test files to include required serie_folder field:
- tests/api/test_download_endpoints.py
- tests/api/test_queue_features.py
- tests/frontend/test_existing_ui_integration.py
- tests/integration/test_download_flow.py
- Updated infrastructure.md with Download Queue request/response models
- All 869 tests pass
This is part of the Series Identifier Standardization effort (Phase 4.2)
to ensure key is used as the primary identifier throughout the codebase.