13 KiB
Series Identifier Standardization - Validation Instructions
Overview
This document provides comprehensive instructions for AI agents to validate the Series Identifier Standardization change across the Aniworld codebase. The change standardizes key as the primary identifier for series and relegates folder to metadata-only status.
Summary of the Change
| Field | Purpose | Usage |
|---|---|---|
key |
Primary Identifier - Provider-assigned, URL-safe (e.g., attack-on-titan) |
All lookups, API operations, database queries, WebSocket events |
folder |
Metadata Only - Filesystem folder name (e.g., Attack on Titan (2013)) |
Display purposes, filesystem operations only |
id |
Database Primary Key - Internal auto-increment integer | Database relationships only |
Validation Checklist
Phase 2: Application Layer Services
Files to validate:
-
src/server/services/anime_service.py- Class docstring explains
keyvsfolderconvention - All public methods accept
keyparameter for series identification - No methods accept
folderas an identifier parameter - Event handler methods document key/folder convention
- Progress tracking uses
keyin progress IDs where possible
- Class docstring explains
-
src/server/services/download_service.pyDownloadItemusesserie_id(which should be thekey)serie_folderis documented as metadata only- Queue operations look up series by
keynotfolder - Persistence format includes
serie_idas the key identifier
-
src/server/services/websocket_service.py- Module docstring explains key/folder convention
- Broadcast methods include
keyin message payloads folderis documented as optional/display only- Event broadcasts use
keyas primary identifier
-
src/server/services/scan_service.py- Scan operations use
keyfor identification - Progress events include
keyfield
- Scan operations use
-
src/server/services/progress_service.py- Progress tracking includes
keyin metadata where applicable
- Progress tracking includes
Validation Commands:
# Check service layer for folder-based lookups
grep -rn "by_folder\|folder.*=.*identifier\|folder.*lookup" src/server/services/ --include="*.py"
# Verify key is used in services
grep -rn "serie_id\|series_key\|key.*identifier" src/server/services/ --include="*.py"
Phase 3: API Endpoints and Responses
Files to validate:
-
src/server/api/anime.pyAnimeSummarymodel haskeyfield with proper descriptionAnimeDetailmodel haskeyfield with proper description- API docstrings explain
keyis the primary identifier folderfield descriptions state "metadata only"- Endpoint paths use
keyparameter (e.g.,/api/anime/{key}) - No endpoints use
folderas path parameter for lookups
-
src/server/api/download.py- Download endpoints use
serie_id(key) for operations - Request models document key/folder convention
- Response models include
keyas primary identifier
- Download endpoints use
-
src/server/models/anime.py- Module docstring explains identifier convention
AnimeSeriesResponsehaskeyfield properly documentedSearchResulthaskeyfield properly documented- Field validators normalize
keyto lowercase folderfields document metadata-only purpose
-
src/server/models/download.pyDownloadItemhasserie_iddocumented as the keyserie_folderdocumented as metadata only- Field descriptions are clear about primary vs metadata
-
src/server/models/websocket.py- Module docstring explains key/folder convention
- Message models document
keyas primary identifier folderdocumented as optional display metadata
Validation Commands:
# Check API endpoints for folder-based paths
grep -rn "folder.*Path\|/{folder}" src/server/api/ --include="*.py"
# Verify key is used in endpoints
grep -rn "/{key}\|series_key\|serie_id" src/server/api/ --include="*.py"
# Check model field descriptions
grep -rn "Field.*description.*identifier\|Field.*description.*key\|Field.*description.*folder" src/server/models/ --include="*.py"
Phase 4: Frontend Integration
Files to validate:
-
src/server/web/static/js/app.jsselectedSeriesSet useskeyvalues, notfolderseriesDataarray comments indicatekeyas primary identifier- Selection operations use
keyproperty - API calls pass
keyfor series identification - WebSocket message handlers extract
keyfrom data - No code uses
folderfor series lookups
-
src/server/web/static/js/queue.js- Queue items reference series by
keyorserie_id - WebSocket handlers extract
keyfrom messages - UI operations use
keyfor identification serie_folderused only for display
- Queue items reference series by
-
src/server/web/static/js/websocket_client.js- Message handling preserves
keyfield - No transformation that loses
keyinformation
- Message handling preserves
-
HTML Templates (
src/server/web/templates/)- Data attributes use
keyfor identification (e.g.,data-key) - No
data-folderused for identification purposes - Display uses
folderornameappropriately
- Data attributes use
Validation Commands:
# Check JavaScript for folder-based lookups
grep -rn "\.folder\s*==\|folder.*identifier\|getByFolder" src/server/web/static/js/ --include="*.js"
# Check data attributes in templates
grep -rn "data-key\|data-folder\|data-series" src/server/web/templates/ --include="*.html"
Phase 5: Database Operations
Files to validate:
-
src/server/database/models.pyAnimeSeriesmodel haskeycolumn with unique constraintkeycolumn is indexed- Model docstring explains identifier convention
foldercolumn docstring states "metadata only"- Validators check
keyis not empty - No
folderuniqueness constraint (unless intentional)
-
src/server/database/service.pyAnimeSeriesServicehasget_by_key()method- Class docstring explains lookup convention
- No
get_by_folder()without deprecation - All CRUD operations use
keyfor identification - Logging uses
keyin messages
Validation Commands:
# Check database models
grep -rn "unique=True\|index=True" src/server/database/models.py
# Check service lookups
grep -rn "get_by_key\|get_by_folder\|filter.*key\|filter.*folder" src/server/database/service.py
Phase 6: WebSocket Events
Files to validate:
-
All WebSocket broadcast calls should include
keyin payload:download_progress→ includeskeydownload_complete→ includeskeydownload_failed→ includeskeyscan_progress→ includeskey(where applicable)queue_status→ items includekey
-
Message format validation:
{ "type": "download_progress", "data": { "key": "attack-on-titan", // PRIMARY - always present "folder": "Attack on Titan (2013)", // OPTIONAL - display only "progress": 45.5, ... } }
Validation Commands:
# Check WebSocket broadcast calls
grep -rn "broadcast.*key\|send_json.*key" src/server/services/ --include="*.py"
# Check message construction
grep -rn '"key":\|"folder":' src/server/services/ --include="*.py"
Phase 7: Test Coverage
Test files to validate:
-
tests/unit/test_serie_class.py- Tests for key validation (empty, whitespace, None)
- Tests for key as primary identifier
- Tests for folder as metadata only
-
tests/unit/test_anime_service.py- Service tests use
keyfor operations - Mock objects have proper
keyattributes
- Service tests use
-
tests/unit/test_database_models.py- Tests for
keyuniqueness constraint - Tests for
keyvalidation
- Tests for
-
tests/unit/test_database_service.py- Tests for
get_by_key()method - No tests for deprecated folder lookups
- Tests for
-
tests/api/test_anime_endpoints.py- API tests use
keyin requests - Mock
FakeSeriehas properkeyattribute - Comments explain key/folder convention
- API tests use
-
tests/unit/test_websocket_service.py- WebSocket tests verify
keyin messages - Broadcast tests include
keyin payload
- WebSocket tests verify
Validation Commands:
# Run all tests
conda run -n AniWorld python -m pytest tests/ -v --tb=short
# Run specific test files
conda run -n AniWorld python -m pytest tests/unit/test_serie_class.py -v
conda run -n AniWorld python -m pytest tests/unit/test_database_models.py -v
conda run -n AniWorld python -m pytest tests/api/test_anime_endpoints.py -v
# Search tests for identifier usage
grep -rn "key.*identifier\|folder.*metadata" tests/ --include="*.py"
Common Issues to Check
1. Inconsistent Naming
Look for inconsistent parameter names:
serie_keyvsseries_keyvskeyserie_idshould refer tokey, not databaseidserie_foldervsfolder
2. Missing Documentation
Check that ALL models, services, and APIs document:
- What
keyis and how to use it - That
folderis metadata only
3. Legacy Code Patterns
Search for deprecated patterns:
# Bad - using folder for lookup
series = get_by_folder(folder_name)
# Good - using key for lookup
series = get_by_key(series_key)
4. API Response Consistency
Verify all API responses include:
keyfield (primary identifier)folderfield (optional, for display)
5. Frontend Data Flow
Verify the frontend:
- Stores
keyin selection sets - Passes
keyto API calls - Uses
folderonly for display
Deprecation Warnings
The following should have deprecation warnings (for removal in v3.0.0):
- Any
get_by_folder()orGetByFolder()methods - Any API endpoints that accept
folderas a lookup parameter - Any frontend code that uses
folderfor identification
Example deprecation:
import warnings
def get_by_folder(self, folder: str):
"""DEPRECATED: Use get_by_key() instead."""
warnings.warn(
"get_by_folder() is deprecated, use get_by_key(). "
"Will be removed in v3.0.0",
DeprecationWarning,
stacklevel=2
)
# ... implementation
Automated Validation Script
Run this script to perform automated checks:
#!/bin/bash
# identifier_validation.sh
echo "=== Series Identifier Standardization Validation ==="
echo ""
echo "1. Checking core entities..."
grep -rn "PRIMARY IDENTIFIER\|metadata only" src/core/entities/ --include="*.py" | head -20
echo ""
echo "2. Checking for deprecated folder lookups..."
grep -rn "get_by_folder\|GetByFolder" src/ --include="*.py"
echo ""
echo "3. Checking API models for key field..."
grep -rn 'key.*Field\|Field.*key' src/server/models/ --include="*.py" | head -20
echo ""
echo "4. Checking database models..."
grep -rn "key.*unique\|key.*index" src/server/database/models.py
echo ""
echo "5. Checking frontend key usage..."
grep -rn "selectedSeries\|\.key\|data-key" src/server/web/static/js/ --include="*.js" | head -20
echo ""
echo "6. Running tests..."
conda run -n AniWorld python -m pytest tests/unit/test_serie_class.py -v --tb=short
echo ""
echo "=== Validation Complete ==="
Expected Results
After validation, you should confirm:
- ✅ All core entities use
keyas primary identifier - ✅ All services look up series by
key - ✅ All API endpoints use
keyfor operations - ✅ All database queries use
keyfor lookups - ✅ Frontend uses
keyfor selection and API calls - ✅ WebSocket events include
keyin payload - ✅ All tests pass
- ✅ Documentation clearly explains the convention
- ✅ Deprecation warnings exist for legacy patterns
Sign-off
Once validation is complete, update this section:
- Phase 1: Core Entities - Validated by: AI Agent Date: 28 Nov 2025
- Phase 2: Services - Validated by: AI Agent Date: 28 Nov 2025
- Phase 3: API - Validated by: ___ Date: ___
- Phase 4: Frontend - Validated by: ___ Date: ___
- Phase 5: Database - Validated by: ___ Date: ___
- Phase 6: WebSocket - Validated by: ___ Date: ___
- Phase 7: Tests - Validated by: ___ Date: ___
Final Approval: ******___****** Date: **_**