backup
This commit is contained in:
parent
bf4455942b
commit
1c8c18c1ea
@ -1,267 +0,0 @@
|
|||||||
# Test Fixes Completed - October 20, 2025
|
|
||||||
|
|
||||||
## Summary
|
|
||||||
|
|
||||||
Successfully improved test pass rate from **91.1% to 95.1%**, fixing **23 test failures**.
|
|
||||||
|
|
||||||
### Overall Progress
|
|
||||||
|
|
||||||
- **Before:** 531 passing, 51 failing, 1 error (91.1% pass rate)
|
|
||||||
- **After:** 554 passing, 28 failing, 1 error (95.1% pass rate)
|
|
||||||
- **Improvement:** +23 tests fixed, +4% pass rate increase
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ Completed Fixes
|
|
||||||
|
|
||||||
### 1. Auth Flow Integration Tests (tests/integration/test_auth_flow.py)
|
|
||||||
|
|
||||||
**Status:** ✅ All 37 tests passing (was 29 passing)
|
|
||||||
|
|
||||||
**Fixes Applied:**
|
|
||||||
|
|
||||||
- Fixed middleware to return `JSONResponse` instead of raising `HTTPException` for invalid tokens
|
|
||||||
- Added middleware check to enforce auth on protected endpoints even when no token is provided
|
|
||||||
- Fixed test expectations for rate limiting (accounting for setup request in count)
|
|
||||||
- Fixed URL trailing slash issues (`/api/v1/anime` → `/api/v1/anime/`, `/api/v1/config` → `/api/config`)
|
|
||||||
|
|
||||||
**Files Modified:**
|
|
||||||
|
|
||||||
- `src/server/middleware/auth.py`: Changed exception handling to return JSON responses
|
|
||||||
- `tests/integration/test_auth_flow.py`: Fixed rate limiting test expectations and URLs
|
|
||||||
|
|
||||||
**Key Changes:**
|
|
||||||
|
|
||||||
```python
|
|
||||||
# Before (raised exception, broke middleware):
|
|
||||||
if path.startswith("/api/") and not path.startswith("/api/auth"):
|
|
||||||
raise HTTPException(status_code=401, detail="Invalid token")
|
|
||||||
|
|
||||||
# After (returns response):
|
|
||||||
if path.startswith("/api/") and not path.startswith("/api/auth"):
|
|
||||||
return JSONResponse(
|
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
||||||
content={"detail": "Invalid token"}
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2. Frontend Auth Integration Tests (tests/integration/test_frontend_auth_integration.py)
|
|
||||||
|
|
||||||
**Status:** ✅ All 11 tests passing (was 9 passing)
|
|
||||||
|
|
||||||
**Fixes Applied:**
|
|
||||||
|
|
||||||
- Updated test expectations to accept both 400 and 422 for validation errors (FastAPI standard)
|
|
||||||
- Fixed URL trailing slash issue for anime endpoint
|
|
||||||
|
|
||||||
**Files Modified:**
|
|
||||||
|
|
||||||
- `tests/integration/test_frontend_auth_integration.py`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 3. Frontend Integration Smoke Tests (tests/integration/test_frontend_integration_smoke.py)
|
|
||||||
|
|
||||||
**Status:** ✅ All 3 tests passing (was 2 passing)
|
|
||||||
|
|
||||||
**Fixes Applied:**
|
|
||||||
|
|
||||||
- Fixed URL trailing slash for anime endpoint
|
|
||||||
|
|
||||||
**Files Modified:**
|
|
||||||
|
|
||||||
- `tests/integration/test_frontend_integration_smoke.py`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 4. Download API Endpoints - Dependency Order Fix
|
|
||||||
|
|
||||||
**Status:** ✅ All 20 tests passing (no change, but improved auth handling)
|
|
||||||
|
|
||||||
**Fixes Applied:**
|
|
||||||
|
|
||||||
- Reordered function parameters in all download API endpoints to check `require_auth` BEFORE `get_download_service`
|
|
||||||
- This ensures authentication is checked before attempting to initialize services that may fail
|
|
||||||
- Prevents 503 errors when auth should return 401
|
|
||||||
|
|
||||||
**Files Modified:**
|
|
||||||
|
|
||||||
- `src/server/api/download.py`: Reordered dependencies in 11 endpoint functions
|
|
||||||
|
|
||||||
**Pattern Applied:**
|
|
||||||
|
|
||||||
```python
|
|
||||||
# Before:
|
|
||||||
async def endpoint(
|
|
||||||
download_service: DownloadService = Depends(get_download_service),
|
|
||||||
_: dict = Depends(require_auth),
|
|
||||||
):
|
|
||||||
|
|
||||||
# After:
|
|
||||||
async def endpoint(
|
|
||||||
_: dict = Depends(require_auth),
|
|
||||||
download_service: DownloadService = Depends(get_download_service),
|
|
||||||
):
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔄 Remaining Work (28 failures + 1 error)
|
|
||||||
|
|
||||||
### High Priority
|
|
||||||
|
|
||||||
1. **Frontend Existing UI Integration** (13 failures)
|
|
||||||
|
|
||||||
- WebSocket integration tests (3)
|
|
||||||
- Config API tests (2)
|
|
||||||
- Error handling tests (2)
|
|
||||||
- Real-time updates tests (3)
|
|
||||||
- Data format tests (3)
|
|
||||||
|
|
||||||
2. **Download Flow Integration** (9 failures + 1 error)
|
|
||||||
- Queue operations tests
|
|
||||||
- Progress tracking tests
|
|
||||||
- Complete workflow tests
|
|
||||||
|
|
||||||
### Medium Priority
|
|
||||||
|
|
||||||
3. **WebSocket Multi-Room Tests** (2 failures)
|
|
||||||
|
|
||||||
- Concurrent broadcasts
|
|
||||||
- Multi-room workflow
|
|
||||||
|
|
||||||
4. **Template Integration Tests** (3 failures)
|
|
||||||
- Error template 404
|
|
||||||
- WebSocket script inclusion
|
|
||||||
- Accessibility features
|
|
||||||
|
|
||||||
### Low Priority
|
|
||||||
|
|
||||||
5. **Deprecation Warnings** (1665 warnings)
|
|
||||||
- Replace `datetime.utcnow()` with `datetime.now(datetime.UTC)` (majority)
|
|
||||||
- Update Pydantic V2 APIs (`.dict()` → `.model_dump()`)
|
|
||||||
- Modernize FastAPI lifespan handling
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 Test Coverage by Category
|
|
||||||
|
|
||||||
| Category | Passing | Total | Pass Rate |
|
|
||||||
| --------------------- | ------- | ------- | --------- |
|
|
||||||
| **Unit Tests** | ~480 | ~500 | ~96% |
|
|
||||||
| **Integration Tests** | 111 | 119 | 93.3% |
|
|
||||||
| **API Tests** | ~40 | ~40 | 100% |
|
|
||||||
| **Frontend Tests** | 0 | 13 | 0% |
|
|
||||||
| **Overall** | **554** | **583** | **95.1%** |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔧 Technical Insights
|
|
||||||
|
|
||||||
### Issue: Middleware Exception Handling
|
|
||||||
|
|
||||||
**Problem:** Raising `HTTPException` in middleware doesn't work as expected in Starlette/FastAPI.
|
|
||||||
|
|
||||||
**Solution:** Return `JSONResponse` directly from middleware instead of raising exceptions.
|
|
||||||
|
|
||||||
**Lesson:** Middleware in Starlette should return responses, not raise exceptions for proper error handling.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Issue: FastAPI Dependency Evaluation Order
|
|
||||||
|
|
||||||
**Problem:** Dependencies are evaluated in the order they appear in function signatures. If a resource dependency fails before auth is checked, it returns wrong error code (503 instead of 401).
|
|
||||||
|
|
||||||
**Solution:** Always put authentication dependencies FIRST in the parameter list.
|
|
||||||
|
|
||||||
**Best Practice:**
|
|
||||||
|
|
||||||
```python
|
|
||||||
async def endpoint(
|
|
||||||
_: dict = Depends(require_auth), # ✅ Auth first
|
|
||||||
service = Depends(get_service), # Then resources
|
|
||||||
):
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Issue: FastAPI Trailing Slash Redirects
|
|
||||||
|
|
||||||
**Problem:** Routes defined as `/endpoint/` with trailing slash cause 307 redirects when accessed without it.
|
|
||||||
|
|
||||||
**Solution:** Either:
|
|
||||||
|
|
||||||
1. Always use trailing slashes in tests
|
|
||||||
2. Configure FastAPI to handle both patterns
|
|
||||||
3. Define routes without trailing slashes
|
|
||||||
|
|
||||||
**Chosen Approach:** Updated tests to use correct URLs with trailing slashes where routes are defined that way.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📝 Code Quality Improvements
|
|
||||||
|
|
||||||
1. **Removed unused imports**
|
|
||||||
|
|
||||||
- Removed `HTTPException` from `auth.py` after switching to `JSONResponse`
|
|
||||||
- Removed `Optional` from imports where not needed
|
|
||||||
|
|
||||||
2. **Fixed lint warnings**
|
|
||||||
|
|
||||||
- Line length issues in test comments
|
|
||||||
- Import organization
|
|
||||||
|
|
||||||
3. **Improved test clarity**
|
|
||||||
- Added comments explaining rate limit accounting
|
|
||||||
- Better assertion messages
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 Next Steps
|
|
||||||
|
|
||||||
### Immediate (High Impact)
|
|
||||||
|
|
||||||
1. Fix remaining download flow integration tests (9 failures + 1 error)
|
|
||||||
2. Fix frontend existing UI integration tests (13 failures)
|
|
||||||
|
|
||||||
### Short Term
|
|
||||||
|
|
||||||
3. Fix WebSocket multi-room tests (2 failures)
|
|
||||||
4. Fix template integration tests (3 failures)
|
|
||||||
|
|
||||||
### Long Term (Technical Debt)
|
|
||||||
|
|
||||||
5. Address deprecation warnings systematically:
|
|
||||||
- Create helper function for datetime operations
|
|
||||||
- Update all Pydantic models to V2 API
|
|
||||||
- Implement FastAPI lifespan context managers
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📚 Documentation Updates Needed
|
|
||||||
|
|
||||||
1. Update API documentation to clarify trailing slash requirements
|
|
||||||
2. Document authentication middleware behavior
|
|
||||||
3. Add developer guide for proper dependency ordering
|
|
||||||
4. Create troubleshooting guide for common test failures
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✨ Key Achievements
|
|
||||||
|
|
||||||
- ✅ **+4% improvement** in test pass rate
|
|
||||||
- ✅ **23 tests fixed** in single session
|
|
||||||
- ✅ **Zero regressions** introduced
|
|
||||||
- ✅ **Systematic approach** to identifying and fixing root causes
|
|
||||||
- ✅ **Improved code quality** through fixes
|
|
||||||
- ✅ **Better understanding** of FastAPI/Starlette behavior
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Work completed by:** AI Assistant (GitHub Copilot)
|
|
||||||
**Date:** October 20, 2025
|
|
||||||
**Duration:** ~1 hour
|
|
||||||
**Tests fixed:** 23
|
|
||||||
**Pass rate improvement:** 91.1% → 95.1%
|
|
||||||
@ -1,338 +0,0 @@
|
|||||||
# Frontend Integration Changes
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
This document details the changes made to integrate the existing frontend JavaScript with the new FastAPI backend and native WebSocket implementation.
|
|
||||||
|
|
||||||
## Key Changes
|
|
||||||
|
|
||||||
### 1. WebSocket Migration (Socket.IO → Native WebSocket)
|
|
||||||
|
|
||||||
**Files Created:**
|
|
||||||
|
|
||||||
- `src/server/web/static/js/websocket_client.js` - Native WebSocket wrapper with Socket.IO-compatible interface
|
|
||||||
|
|
||||||
**Files Modified:**
|
|
||||||
|
|
||||||
- `src/server/web/templates/index.html` - Replace Socket.IO CDN with websocket_client.js
|
|
||||||
- `src/server/web/templates/queue.html` - Replace Socket.IO CDN with websocket_client.js
|
|
||||||
|
|
||||||
**Migration Details:**
|
|
||||||
|
|
||||||
- Created `WebSocketClient` class that provides Socket.IO-style `.on()` and `.emit()` methods
|
|
||||||
- Automatic reconnection with exponential backoff
|
|
||||||
- Room-based subscriptions (join/leave rooms for topic filtering)
|
|
||||||
- Message queueing during disconnection
|
|
||||||
- Native WebSocket URL: `ws://host:port/ws/connect` (or `wss://` for HTTPS)
|
|
||||||
|
|
||||||
### 2. WebSocket Message Format Changes
|
|
||||||
|
|
||||||
**Old Format (Socket.IO custom events):**
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
socket.on('download_progress', (data) => { ... });
|
|
||||||
// data was sent directly
|
|
||||||
```
|
|
||||||
|
|
||||||
**New Format (Structured messages):**
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"type": "download_progress",
|
|
||||||
"timestamp": "2025-10-17T12:34:56.789Z",
|
|
||||||
"data": {
|
|
||||||
// Message payload
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Event Mapping:**
|
|
||||||
|
|
||||||
| Old Socket.IO Event | New WebSocket Type | Room | Notes |
|
|
||||||
| ----------------------- | ------------------- | ------------------- | -------------------------- |
|
|
||||||
| `scan_progress` | `scan_progress` | `scan_progress` | Scan updates |
|
|
||||||
| `scan_completed` | `scan_complete` | `scan_progress` | Scan finished |
|
|
||||||
| `scan_error` | `scan_failed` | `scan_progress` | Scan error |
|
|
||||||
| `download_progress` | `download_progress` | `download_progress` | Real-time download updates |
|
|
||||||
| `download_completed` | `download_complete` | `downloads` | Single download finished |
|
|
||||||
| `download_error` | `download_failed` | `downloads` | Download failed |
|
|
||||||
| `download_queue_update` | `queue_status` | `downloads` | Queue state changes |
|
|
||||||
| `queue_started` | `queue_started` | `downloads` | Queue processing started |
|
|
||||||
| `queue_stopped` | `queue_stopped` | `downloads` | Queue processing stopped |
|
|
||||||
| `queue_paused` | `queue_paused` | `downloads` | Queue paused |
|
|
||||||
| `queue_resumed` | `queue_resumed` | `downloads` | Queue resumed |
|
|
||||||
|
|
||||||
### 3. API Endpoint Changes
|
|
||||||
|
|
||||||
**Authentication Endpoints:**
|
|
||||||
|
|
||||||
- ✅ `/api/auth/status` - Check auth status (GET)
|
|
||||||
- ✅ `/api/auth/login` - Login (POST)
|
|
||||||
- ✅ `/api/auth/logout` - Logout (POST)
|
|
||||||
- ✅ `/api/auth/setup` - Initial setup (POST)
|
|
||||||
|
|
||||||
**Anime Endpoints:**
|
|
||||||
|
|
||||||
- ✅ `/api/v1/anime` - List anime with missing episodes (GET)
|
|
||||||
- ✅ `/api/v1/anime/rescan` - Trigger rescan (POST)
|
|
||||||
- ✅ `/api/v1/anime/search` - Search for anime (POST)
|
|
||||||
- ✅ `/api/v1/anime/{anime_id}` - Get anime details (GET)
|
|
||||||
|
|
||||||
**Download Queue Endpoints:**
|
|
||||||
|
|
||||||
- ✅ `/api/queue/status` - Get queue status (GET)
|
|
||||||
- ✅ `/api/queue/add` - Add to queue (POST)
|
|
||||||
- ✅ `/api/queue/{item_id}` - Remove single item (DELETE)
|
|
||||||
- ✅ `/api/queue/` - Remove multiple items (DELETE)
|
|
||||||
- ✅ `/api/queue/start` - Start queue (POST)
|
|
||||||
- ✅ `/api/queue/stop` - Stop queue (POST)
|
|
||||||
- ✅ `/api/queue/pause` - Pause queue (POST)
|
|
||||||
- ✅ `/api/queue/resume` - Resume queue (POST)
|
|
||||||
- ✅ `/api/queue/reorder` - Reorder queue (POST)
|
|
||||||
- ✅ `/api/queue/completed` - Clear completed (DELETE)
|
|
||||||
- ✅ `/api/queue/retry` - Retry failed (POST)
|
|
||||||
|
|
||||||
**WebSocket Endpoint:**
|
|
||||||
|
|
||||||
- ✅ `/ws/connect` - WebSocket connection (WebSocket)
|
|
||||||
- ✅ `/ws/status` - WebSocket status (GET)
|
|
||||||
|
|
||||||
### 4. Required JavaScript Updates
|
|
||||||
|
|
||||||
**app.js Changes Needed:**
|
|
||||||
|
|
||||||
1. **WebSocket Initialization** - Add room subscriptions:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
initSocket() {
|
|
||||||
this.socket = io();
|
|
||||||
|
|
||||||
// Subscribe to relevant rooms after connection
|
|
||||||
this.socket.on('connected', () => {
|
|
||||||
this.socket.join('scan_progress');
|
|
||||||
this.socket.join('download_progress');
|
|
||||||
this.socket.join('downloads');
|
|
||||||
this.isConnected = true;
|
|
||||||
// ... rest of connect handler
|
|
||||||
});
|
|
||||||
|
|
||||||
// ... rest of event handlers
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Event Handler Updates** - Map new message types:
|
|
||||||
|
|
||||||
- `scan_completed` → `scan_complete`
|
|
||||||
- `scan_error` → `scan_failed`
|
|
||||||
- Legacy events that are no longer sent need to be handled differently or removed
|
|
||||||
|
|
||||||
3. **API Call Updates** - Already correct:
|
|
||||||
|
|
||||||
- `/api/v1/anime` for anime list ✅
|
|
||||||
- `/api/auth/*` for authentication ✅
|
|
||||||
|
|
||||||
**queue.js Changes Needed:**
|
|
||||||
|
|
||||||
1. **WebSocket Initialization** - Add room subscriptions:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
initSocket() {
|
|
||||||
this.socket = io();
|
|
||||||
|
|
||||||
this.socket.on('connected', () => {
|
|
||||||
this.socket.join('downloads');
|
|
||||||
this.socket.join('download_progress');
|
|
||||||
// ... rest of connect handler
|
|
||||||
});
|
|
||||||
|
|
||||||
// ... rest of event handlers
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **API Calls** - Already mostly correct:
|
|
||||||
|
|
||||||
- `/api/queue/status` ✅
|
|
||||||
- `/api/queue/*` operations ✅
|
|
||||||
|
|
||||||
3. **Event Handlers** - Map to new types:
|
|
||||||
|
|
||||||
- `queue_updated` → `queue_status`
|
|
||||||
- `download_progress_update` → `download_progress`
|
|
||||||
|
|
||||||
### 5. Authentication Flow
|
|
||||||
|
|
||||||
**Current Implementation:**
|
|
||||||
|
|
||||||
- JWT tokens stored in localStorage (via auth service)
|
|
||||||
- Tokens included in Authorization header for API requests
|
|
||||||
- WebSocket connections can optionally authenticate (user_id in session)
|
|
||||||
|
|
||||||
**JavaScript Implementation Needed:**
|
|
||||||
Add helper for authenticated requests:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
async makeAuthenticatedRequest(url, options = {}) {
|
|
||||||
const token = localStorage.getItem('auth_token');
|
|
||||||
|
|
||||||
if (!token) {
|
|
||||||
window.location.href = '/login';
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const headers = {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Authorization': `Bearer ${token}`,
|
|
||||||
...options.headers
|
|
||||||
};
|
|
||||||
|
|
||||||
const response = await fetch(url, { ...options, headers });
|
|
||||||
|
|
||||||
if (response.status === 401) {
|
|
||||||
// Token expired or invalid
|
|
||||||
localStorage.removeItem('auth_token');
|
|
||||||
window.location.href = '/login';
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6. Backend Router Registration
|
|
||||||
|
|
||||||
**Fixed in fastapi_app.py:**
|
|
||||||
|
|
||||||
- ✅ Added `anime_router` import
|
|
||||||
- ✅ Registered `app.include_router(anime_router)`
|
|
||||||
|
|
||||||
All routers now properly registered:
|
|
||||||
|
|
||||||
- health_router
|
|
||||||
- page_router
|
|
||||||
- auth_router
|
|
||||||
- anime_router ⭐ (newly added)
|
|
||||||
- download_router
|
|
||||||
- websocket_router
|
|
||||||
|
|
||||||
## Implementation Status
|
|
||||||
|
|
||||||
### ✅ Completed
|
|
||||||
|
|
||||||
1. Created native WebSocket client wrapper
|
|
||||||
2. Updated HTML templates to use new WebSocket client
|
|
||||||
3. Registered anime router in FastAPI app
|
|
||||||
4. Documented API endpoint mappings
|
|
||||||
5. Documented WebSocket message format changes
|
|
||||||
|
|
||||||
### 🔄 In Progress
|
|
||||||
|
|
||||||
1. Update app.js WebSocket initialization and room subscriptions
|
|
||||||
2. Update app.js event handlers for new message types
|
|
||||||
3. Update queue.js WebSocket initialization and room subscriptions
|
|
||||||
4. Update queue.js event handlers for new message types
|
|
||||||
|
|
||||||
### ⏳ Pending
|
|
||||||
|
|
||||||
1. Add authentication token handling to all API requests
|
|
||||||
2. Test complete workflow (auth → scan → download)
|
|
||||||
3. Update other JavaScript modules if they use WebSocket/API
|
|
||||||
4. Integration tests for frontend-backend communication
|
|
||||||
5. Update infrastructure.md documentation
|
|
||||||
|
|
||||||
## Testing Plan
|
|
||||||
|
|
||||||
1. **Authentication Flow:**
|
|
||||||
|
|
||||||
- Test setup page → creates master password
|
|
||||||
- Test login page → authenticates with master password
|
|
||||||
- Test logout → clears session
|
|
||||||
- Test protected pages redirect to login
|
|
||||||
|
|
||||||
2. **Anime Management:**
|
|
||||||
|
|
||||||
- Test loading anime list
|
|
||||||
- Test rescan functionality with progress updates
|
|
||||||
- Test search functionality
|
|
||||||
|
|
||||||
3. **Download Queue:**
|
|
||||||
|
|
||||||
- Test adding items to queue
|
|
||||||
- Test queue operations (start, stop, pause, resume)
|
|
||||||
- Test progress updates via WebSocket
|
|
||||||
- Test retry and clear operations
|
|
||||||
|
|
||||||
4. **WebSocket Communication:**
|
|
||||||
- Test connection/reconnection
|
|
||||||
- Test room subscriptions
|
|
||||||
- Test message routing to correct handlers
|
|
||||||
- Test disconnect handling
|
|
||||||
|
|
||||||
## Known Issues & Limitations
|
|
||||||
|
|
||||||
1. **Legacy Events:** Some Socket.IO events in app.js don't have backend equivalents:
|
|
||||||
|
|
||||||
- `scheduled_rescan_*` events
|
|
||||||
- `auto_download_*` events
|
|
||||||
- `download_episode_update` event
|
|
||||||
- `download_series_completed` event
|
|
||||||
|
|
||||||
**Solution:** Either remove these handlers or implement corresponding backend events
|
|
||||||
|
|
||||||
2. **Configuration Endpoints:** Many config-related API calls in app.js don't have backend implementations:
|
|
||||||
|
|
||||||
- Scheduler configuration
|
|
||||||
- Logging configuration
|
|
||||||
- Advanced configuration
|
|
||||||
- Config backups
|
|
||||||
|
|
||||||
**Solution:** Implement these endpoints or remove the UI features
|
|
||||||
|
|
||||||
3. **Process Status Monitoring:** `checkProcessLocks()` method may not work with new backend
|
|
||||||
|
|
||||||
**Solution:** Implement equivalent status endpoint or remove feature
|
|
||||||
|
|
||||||
## Migration Guide for Developers
|
|
||||||
|
|
||||||
### Adding New WebSocket Events
|
|
||||||
|
|
||||||
1. Define message type in `src/server/models/websocket.py`:
|
|
||||||
|
|
||||||
```python
|
|
||||||
class WebSocketMessageType(str, Enum):
|
|
||||||
MY_NEW_EVENT = "my_new_event"
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Broadcast from service:
|
|
||||||
|
|
||||||
```python
|
|
||||||
await ws_service.broadcast_to_room(
|
|
||||||
{"type": "my_new_event", "data": {...}},
|
|
||||||
"my_room"
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Subscribe and handle in JavaScript:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
this.socket.join("my_room");
|
|
||||||
this.socket.on("my_new_event", (data) => {
|
|
||||||
// Handle event
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### Adding New API Endpoints
|
|
||||||
|
|
||||||
1. Define Pydantic models in `src/server/models/`
|
|
||||||
2. Create endpoint in appropriate router file in `src/server/api/`
|
|
||||||
3. Add endpoint to this documentation
|
|
||||||
4. Update JavaScript to call new endpoint
|
|
||||||
|
|
||||||
## References
|
|
||||||
|
|
||||||
- FastAPI Application: `src/server/fastapi_app.py`
|
|
||||||
- WebSocket Service: `src/server/services/websocket_service.py`
|
|
||||||
- WebSocket Models: `src/server/models/websocket.py`
|
|
||||||
- Download Service: `src/server/services/download_service.py`
|
|
||||||
- Anime Service: `src/server/services/anime_service.py`
|
|
||||||
- Progress Service: `src/server/services/progress_service.py`
|
|
||||||
- Infrastructure Doc: `infrastructure.md`
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"pending": [
|
"pending": [
|
||||||
{
|
{
|
||||||
"id": "5bec390c-046b-4c9c-9969-463703080e91",
|
"id": "dece664a-0938-4d2b-aba8-93344047186c",
|
||||||
"serie_id": "workflow-series",
|
"serie_id": "workflow-series",
|
||||||
"serie_name": "Workflow Test Series",
|
"serie_name": "Workflow Test Series",
|
||||||
"episode": {
|
"episode": {
|
||||||
@ -11,7 +11,7 @@
|
|||||||
},
|
},
|
||||||
"status": "pending",
|
"status": "pending",
|
||||||
"priority": "high",
|
"priority": "high",
|
||||||
"added_at": "2025-10-20T20:43:13.964989",
|
"added_at": "2025-10-22T06:28:55.006173Z",
|
||||||
"started_at": null,
|
"started_at": null,
|
||||||
"completed_at": null,
|
"completed_at": null,
|
||||||
"progress": null,
|
"progress": null,
|
||||||
@ -20,235 +20,7 @@
|
|||||||
"source_url": null
|
"source_url": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "dcd34180-eab3-4f68-bdbc-33a4f66f5ba1",
|
"id": "74b1ccaa-881b-4e64-8e5e-3668eb797409",
|
||||||
"serie_id": "series-high",
|
|
||||||
"serie_name": "Series High",
|
|
||||||
"episode": {
|
|
||||||
"season": 1,
|
|
||||||
"episode": 1,
|
|
||||||
"title": null
|
|
||||||
},
|
|
||||||
"status": "pending",
|
|
||||||
"priority": "high",
|
|
||||||
"added_at": "2025-10-20T20:43:13.427072",
|
|
||||||
"started_at": null,
|
|
||||||
"completed_at": null,
|
|
||||||
"progress": null,
|
|
||||||
"error": null,
|
|
||||||
"retry_count": 0,
|
|
||||||
"source_url": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "5c4a7bca-50a1-4523-b990-b0d05ebf2c09",
|
|
||||||
"serie_id": "test-series-2",
|
|
||||||
"serie_name": "Another Series",
|
|
||||||
"episode": {
|
|
||||||
"season": 1,
|
|
||||||
"episode": 1,
|
|
||||||
"title": null
|
|
||||||
},
|
|
||||||
"status": "pending",
|
|
||||||
"priority": "high",
|
|
||||||
"added_at": "2025-10-20T20:43:13.395795",
|
|
||||||
"started_at": null,
|
|
||||||
"completed_at": null,
|
|
||||||
"progress": null,
|
|
||||||
"error": null,
|
|
||||||
"retry_count": 0,
|
|
||||||
"source_url": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "69d7c42a-bff1-430f-9210-be4907ab4a5e",
|
|
||||||
"serie_id": "series-normal",
|
|
||||||
"serie_name": "Series Normal",
|
|
||||||
"episode": {
|
|
||||||
"season": 1,
|
|
||||||
"episode": 1,
|
|
||||||
"title": null
|
|
||||||
},
|
|
||||||
"status": "pending",
|
|
||||||
"priority": "normal",
|
|
||||||
"added_at": "2025-10-20T20:43:13.429203",
|
|
||||||
"started_at": null,
|
|
||||||
"completed_at": null,
|
|
||||||
"progress": null,
|
|
||||||
"error": null,
|
|
||||||
"retry_count": 0,
|
|
||||||
"source_url": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "0ddd848c-6480-4b19-9f79-89a48a2d99bb",
|
|
||||||
"serie_id": "series-low",
|
|
||||||
"serie_name": "Series Low",
|
|
||||||
"episode": {
|
|
||||||
"season": 1,
|
|
||||||
"episode": 1,
|
|
||||||
"title": null
|
|
||||||
},
|
|
||||||
"status": "pending",
|
|
||||||
"priority": "low",
|
|
||||||
"added_at": "2025-10-20T20:43:13.431279",
|
|
||||||
"started_at": null,
|
|
||||||
"completed_at": null,
|
|
||||||
"progress": null,
|
|
||||||
"error": null,
|
|
||||||
"retry_count": 0,
|
|
||||||
"source_url": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "fd374a7d-4144-4f62-871e-ea28e3246d16",
|
|
||||||
"serie_id": "test-series",
|
|
||||||
"serie_name": "Test Series",
|
|
||||||
"episode": {
|
|
||||||
"season": 1,
|
|
||||||
"episode": 1,
|
|
||||||
"title": null
|
|
||||||
},
|
|
||||||
"status": "pending",
|
|
||||||
"priority": "normal",
|
|
||||||
"added_at": "2025-10-20T20:43:13.626761",
|
|
||||||
"started_at": null,
|
|
||||||
"completed_at": null,
|
|
||||||
"progress": null,
|
|
||||||
"error": null,
|
|
||||||
"retry_count": 0,
|
|
||||||
"source_url": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "8e8bcd27-ed39-42bc-bb69-168c952847e5",
|
|
||||||
"serie_id": "series-0",
|
|
||||||
"serie_name": "Series 0",
|
|
||||||
"episode": {
|
|
||||||
"season": 1,
|
|
||||||
"episode": 1,
|
|
||||||
"title": null
|
|
||||||
},
|
|
||||||
"status": "pending",
|
|
||||||
"priority": "normal",
|
|
||||||
"added_at": "2025-10-20T20:43:13.676039",
|
|
||||||
"started_at": null,
|
|
||||||
"completed_at": null,
|
|
||||||
"progress": null,
|
|
||||||
"error": null,
|
|
||||||
"retry_count": 0,
|
|
||||||
"source_url": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "e2cc46cb-4dc5-4a65-847c-93633a5dba30",
|
|
||||||
"serie_id": "test-series",
|
|
||||||
"serie_name": "Test Series",
|
|
||||||
"episode": {
|
|
||||||
"season": 1,
|
|
||||||
"episode": 1,
|
|
||||||
"title": null
|
|
||||||
},
|
|
||||||
"status": "pending",
|
|
||||||
"priority": "normal",
|
|
||||||
"added_at": "2025-10-20T20:43:13.705892",
|
|
||||||
"started_at": null,
|
|
||||||
"completed_at": null,
|
|
||||||
"progress": null,
|
|
||||||
"error": null,
|
|
||||||
"retry_count": 0,
|
|
||||||
"source_url": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "20eb8769-3567-43d7-8903-3cfa9fda1c68",
|
|
||||||
"serie_id": "invalid-series",
|
|
||||||
"serie_name": "Invalid Series",
|
|
||||||
"episode": {
|
|
||||||
"season": 99,
|
|
||||||
"episode": 99,
|
|
||||||
"title": null
|
|
||||||
},
|
|
||||||
"status": "pending",
|
|
||||||
"priority": "normal",
|
|
||||||
"added_at": "2025-10-20T20:43:13.758786",
|
|
||||||
"started_at": null,
|
|
||||||
"completed_at": null,
|
|
||||||
"progress": null,
|
|
||||||
"error": null,
|
|
||||||
"retry_count": 0,
|
|
||||||
"source_url": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "2ed64de9-47b4-4589-8061-82f5a902d3e4",
|
|
||||||
"serie_id": "test-series",
|
|
||||||
"serie_name": "Test Series",
|
|
||||||
"episode": {
|
|
||||||
"season": 1,
|
|
||||||
"episode": 1,
|
|
||||||
"title": null
|
|
||||||
},
|
|
||||||
"status": "pending",
|
|
||||||
"priority": "normal",
|
|
||||||
"added_at": "2025-10-20T20:43:13.784538",
|
|
||||||
"started_at": null,
|
|
||||||
"completed_at": null,
|
|
||||||
"progress": null,
|
|
||||||
"error": null,
|
|
||||||
"retry_count": 0,
|
|
||||||
"source_url": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "7cfea7c4-1b35-4b13-be80-4bb77ccf5721",
|
|
||||||
"serie_id": "series-4",
|
|
||||||
"serie_name": "Series 4",
|
|
||||||
"episode": {
|
|
||||||
"season": 1,
|
|
||||||
"episode": 1,
|
|
||||||
"title": null
|
|
||||||
},
|
|
||||||
"status": "pending",
|
|
||||||
"priority": "normal",
|
|
||||||
"added_at": "2025-10-20T20:43:13.824131",
|
|
||||||
"started_at": null,
|
|
||||||
"completed_at": null,
|
|
||||||
"progress": null,
|
|
||||||
"error": null,
|
|
||||||
"retry_count": 0,
|
|
||||||
"source_url": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "5d922f7e-db4d-4797-97bb-ac345cb574bb",
|
|
||||||
"serie_id": "series-0",
|
|
||||||
"serie_name": "Series 0",
|
|
||||||
"episode": {
|
|
||||||
"season": 1,
|
|
||||||
"episode": 1,
|
|
||||||
"title": null
|
|
||||||
},
|
|
||||||
"status": "pending",
|
|
||||||
"priority": "normal",
|
|
||||||
"added_at": "2025-10-20T20:43:13.824971",
|
|
||||||
"started_at": null,
|
|
||||||
"completed_at": null,
|
|
||||||
"progress": null,
|
|
||||||
"error": null,
|
|
||||||
"retry_count": 0,
|
|
||||||
"source_url": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "01678ef1-1f7d-4d02-aed2-02965e321bb6",
|
|
||||||
"serie_id": "series-1",
|
|
||||||
"serie_name": "Series 1",
|
|
||||||
"episode": {
|
|
||||||
"season": 1,
|
|
||||||
"episode": 1,
|
|
||||||
"title": null
|
|
||||||
},
|
|
||||||
"status": "pending",
|
|
||||||
"priority": "normal",
|
|
||||||
"added_at": "2025-10-20T20:43:13.825585",
|
|
||||||
"started_at": null,
|
|
||||||
"completed_at": null,
|
|
||||||
"progress": null,
|
|
||||||
"error": null,
|
|
||||||
"retry_count": 0,
|
|
||||||
"source_url": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "61ccfb28-6148-43b7-b5b1-22171d4d677e",
|
|
||||||
"serie_id": "series-2",
|
"serie_id": "series-2",
|
||||||
"serie_name": "Series 2",
|
"serie_name": "Series 2",
|
||||||
"episode": {
|
"episode": {
|
||||||
@ -258,7 +30,7 @@
|
|||||||
},
|
},
|
||||||
"status": "pending",
|
"status": "pending",
|
||||||
"priority": "normal",
|
"priority": "normal",
|
||||||
"added_at": "2025-10-20T20:43:13.826197",
|
"added_at": "2025-10-22T06:28:54.698426Z",
|
||||||
"started_at": null,
|
"started_at": null,
|
||||||
"completed_at": null,
|
"completed_at": null,
|
||||||
"progress": null,
|
"progress": null,
|
||||||
@ -267,7 +39,292 @@
|
|||||||
"source_url": null
|
"source_url": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "64432cf6-e804-4247-a5ab-10c676d975b4",
|
"id": "fef6f5a8-3423-4226-acf6-0ea0433983b4",
|
||||||
|
"serie_id": "series-1",
|
||||||
|
"serie_name": "Series 1",
|
||||||
|
"episode": {
|
||||||
|
"season": 1,
|
||||||
|
"episode": 1,
|
||||||
|
"title": null
|
||||||
|
},
|
||||||
|
"status": "pending",
|
||||||
|
"priority": "normal",
|
||||||
|
"added_at": "2025-10-22T06:28:54.695364Z",
|
||||||
|
"started_at": null,
|
||||||
|
"completed_at": null,
|
||||||
|
"progress": null,
|
||||||
|
"error": null,
|
||||||
|
"retry_count": 0,
|
||||||
|
"source_url": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "edf230e3-d1d1-4cbf-a208-4a7f2f04f0bf",
|
||||||
|
"serie_id": "series-0",
|
||||||
|
"serie_name": "Series 0",
|
||||||
|
"episode": {
|
||||||
|
"season": 1,
|
||||||
|
"episode": 1,
|
||||||
|
"title": null
|
||||||
|
},
|
||||||
|
"status": "pending",
|
||||||
|
"priority": "normal",
|
||||||
|
"added_at": "2025-10-22T06:28:54.690120Z",
|
||||||
|
"started_at": null,
|
||||||
|
"completed_at": null,
|
||||||
|
"progress": null,
|
||||||
|
"error": null,
|
||||||
|
"retry_count": 0,
|
||||||
|
"source_url": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "06e8b453-c1c0-4fa7-b75c-d0716a8a4f8e",
|
||||||
|
"serie_id": "series-high",
|
||||||
|
"serie_name": "Series High",
|
||||||
|
"episode": {
|
||||||
|
"season": 1,
|
||||||
|
"episode": 1,
|
||||||
|
"title": null
|
||||||
|
},
|
||||||
|
"status": "pending",
|
||||||
|
"priority": "high",
|
||||||
|
"added_at": "2025-10-22T06:28:54.294881Z",
|
||||||
|
"started_at": null,
|
||||||
|
"completed_at": null,
|
||||||
|
"progress": null,
|
||||||
|
"error": null,
|
||||||
|
"retry_count": 0,
|
||||||
|
"source_url": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a8827ee2-a4cb-4d56-8c6d-cf02e32b76a1",
|
||||||
|
"serie_id": "test-series-2",
|
||||||
|
"serie_name": "Another Series",
|
||||||
|
"episode": {
|
||||||
|
"season": 1,
|
||||||
|
"episode": 1,
|
||||||
|
"title": null
|
||||||
|
},
|
||||||
|
"status": "pending",
|
||||||
|
"priority": "high",
|
||||||
|
"added_at": "2025-10-22T06:28:54.267717Z",
|
||||||
|
"started_at": null,
|
||||||
|
"completed_at": null,
|
||||||
|
"progress": null,
|
||||||
|
"error": null,
|
||||||
|
"retry_count": 0,
|
||||||
|
"source_url": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "76a7a057-61f9-492b-810c-b38ab66a4e94",
|
||||||
|
"serie_id": "test-series-1",
|
||||||
|
"serie_name": "Test Anime Series",
|
||||||
|
"episode": {
|
||||||
|
"season": 1,
|
||||||
|
"episode": 1,
|
||||||
|
"title": "Episode 1"
|
||||||
|
},
|
||||||
|
"status": "pending",
|
||||||
|
"priority": "normal",
|
||||||
|
"added_at": "2025-10-22T06:28:54.241001Z",
|
||||||
|
"started_at": null,
|
||||||
|
"completed_at": null,
|
||||||
|
"progress": null,
|
||||||
|
"error": null,
|
||||||
|
"retry_count": 0,
|
||||||
|
"source_url": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a9cd9b13-bb1a-4e95-9fad-621c4db0c00e",
|
||||||
|
"serie_id": "test-series-1",
|
||||||
|
"serie_name": "Test Anime Series",
|
||||||
|
"episode": {
|
||||||
|
"season": 1,
|
||||||
|
"episode": 2,
|
||||||
|
"title": "Episode 2"
|
||||||
|
},
|
||||||
|
"status": "pending",
|
||||||
|
"priority": "normal",
|
||||||
|
"added_at": "2025-10-22T06:28:54.241309Z",
|
||||||
|
"started_at": null,
|
||||||
|
"completed_at": null,
|
||||||
|
"progress": null,
|
||||||
|
"error": null,
|
||||||
|
"retry_count": 0,
|
||||||
|
"source_url": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "cbed43ae-62c3-4a43-8161-00834d8bb57e",
|
||||||
|
"serie_id": "series-normal",
|
||||||
|
"serie_name": "Series Normal",
|
||||||
|
"episode": {
|
||||||
|
"season": 1,
|
||||||
|
"episode": 1,
|
||||||
|
"title": null
|
||||||
|
},
|
||||||
|
"status": "pending",
|
||||||
|
"priority": "normal",
|
||||||
|
"added_at": "2025-10-22T06:28:54.298118Z",
|
||||||
|
"started_at": null,
|
||||||
|
"completed_at": null,
|
||||||
|
"progress": null,
|
||||||
|
"error": null,
|
||||||
|
"retry_count": 0,
|
||||||
|
"source_url": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8331dd3a-2fc0-4536-b5da-09cd13b5c361",
|
||||||
|
"serie_id": "series-low",
|
||||||
|
"serie_name": "Series Low",
|
||||||
|
"episode": {
|
||||||
|
"season": 1,
|
||||||
|
"episode": 1,
|
||||||
|
"title": null
|
||||||
|
},
|
||||||
|
"status": "pending",
|
||||||
|
"priority": "low",
|
||||||
|
"added_at": "2025-10-22T06:28:54.300532Z",
|
||||||
|
"started_at": null,
|
||||||
|
"completed_at": null,
|
||||||
|
"progress": null,
|
||||||
|
"error": null,
|
||||||
|
"retry_count": 0,
|
||||||
|
"source_url": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "938aefe2-94ea-4547-8d58-e4be38f38f3e",
|
||||||
|
"serie_id": "test-series",
|
||||||
|
"serie_name": "Test Series",
|
||||||
|
"episode": {
|
||||||
|
"season": 1,
|
||||||
|
"episode": 1,
|
||||||
|
"title": null
|
||||||
|
},
|
||||||
|
"status": "pending",
|
||||||
|
"priority": "normal",
|
||||||
|
"added_at": "2025-10-22T06:28:54.638152Z",
|
||||||
|
"started_at": null,
|
||||||
|
"completed_at": null,
|
||||||
|
"progress": null,
|
||||||
|
"error": null,
|
||||||
|
"retry_count": 0,
|
||||||
|
"source_url": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "74e0a939-da84-4478-abcf-4fedde69ae55",
|
||||||
|
"serie_id": "test-series",
|
||||||
|
"serie_name": "Test Series",
|
||||||
|
"episode": {
|
||||||
|
"season": 1,
|
||||||
|
"episode": 1,
|
||||||
|
"title": null
|
||||||
|
},
|
||||||
|
"status": "pending",
|
||||||
|
"priority": "normal",
|
||||||
|
"added_at": "2025-10-22T06:28:54.727162Z",
|
||||||
|
"started_at": null,
|
||||||
|
"completed_at": null,
|
||||||
|
"progress": null,
|
||||||
|
"error": null,
|
||||||
|
"retry_count": 0,
|
||||||
|
"source_url": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4c9ad0c1-63b3-4eb3-a1e3-a378c0f8be0c",
|
||||||
|
"serie_id": "invalid-series",
|
||||||
|
"serie_name": "Invalid Series",
|
||||||
|
"episode": {
|
||||||
|
"season": 99,
|
||||||
|
"episode": 99,
|
||||||
|
"title": null
|
||||||
|
},
|
||||||
|
"status": "pending",
|
||||||
|
"priority": "normal",
|
||||||
|
"added_at": "2025-10-22T06:28:54.782291Z",
|
||||||
|
"started_at": null,
|
||||||
|
"completed_at": null,
|
||||||
|
"progress": null,
|
||||||
|
"error": null,
|
||||||
|
"retry_count": 0,
|
||||||
|
"source_url": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "1dc2d71b-149c-4d6e-adec-2c4bd36a9656",
|
||||||
|
"serie_id": "test-series",
|
||||||
|
"serie_name": "Test Series",
|
||||||
|
"episode": {
|
||||||
|
"season": 1,
|
||||||
|
"episode": 1,
|
||||||
|
"title": null
|
||||||
|
},
|
||||||
|
"status": "pending",
|
||||||
|
"priority": "normal",
|
||||||
|
"added_at": "2025-10-22T06:28:54.805780Z",
|
||||||
|
"started_at": null,
|
||||||
|
"completed_at": null,
|
||||||
|
"progress": null,
|
||||||
|
"error": null,
|
||||||
|
"retry_count": 0,
|
||||||
|
"source_url": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "94ef5749-911e-4b50-911c-77512495c6e1",
|
||||||
|
"serie_id": "series-1",
|
||||||
|
"serie_name": "Series 1",
|
||||||
|
"episode": {
|
||||||
|
"season": 1,
|
||||||
|
"episode": 1,
|
||||||
|
"title": null
|
||||||
|
},
|
||||||
|
"status": "pending",
|
||||||
|
"priority": "normal",
|
||||||
|
"added_at": "2025-10-22T06:28:54.848160Z",
|
||||||
|
"started_at": null,
|
||||||
|
"completed_at": null,
|
||||||
|
"progress": null,
|
||||||
|
"error": null,
|
||||||
|
"retry_count": 0,
|
||||||
|
"source_url": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "52171e7e-2d93-483f-82b7-156df9b57fc1",
|
||||||
|
"serie_id": "series-4",
|
||||||
|
"serie_name": "Series 4",
|
||||||
|
"episode": {
|
||||||
|
"season": 1,
|
||||||
|
"episode": 1,
|
||||||
|
"title": null
|
||||||
|
},
|
||||||
|
"status": "pending",
|
||||||
|
"priority": "normal",
|
||||||
|
"added_at": "2025-10-22T06:28:54.849239Z",
|
||||||
|
"started_at": null,
|
||||||
|
"completed_at": null,
|
||||||
|
"progress": null,
|
||||||
|
"error": null,
|
||||||
|
"retry_count": 0,
|
||||||
|
"source_url": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "9e7cdb02-466a-4b94-b2ad-81ad8902871d",
|
||||||
|
"serie_id": "series-2",
|
||||||
|
"serie_name": "Series 2",
|
||||||
|
"episode": {
|
||||||
|
"season": 1,
|
||||||
|
"episode": 1,
|
||||||
|
"title": null
|
||||||
|
},
|
||||||
|
"status": "pending",
|
||||||
|
"priority": "normal",
|
||||||
|
"added_at": "2025-10-22T06:28:54.850451Z",
|
||||||
|
"started_at": null,
|
||||||
|
"completed_at": null,
|
||||||
|
"progress": null,
|
||||||
|
"error": null,
|
||||||
|
"retry_count": 0,
|
||||||
|
"source_url": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "89916070-493f-422f-aa0a-842555b0d575",
|
||||||
"serie_id": "series-3",
|
"serie_id": "series-3",
|
||||||
"serie_name": "Series 3",
|
"serie_name": "Series 3",
|
||||||
"episode": {
|
"episode": {
|
||||||
@ -277,7 +334,7 @@
|
|||||||
},
|
},
|
||||||
"status": "pending",
|
"status": "pending",
|
||||||
"priority": "normal",
|
"priority": "normal",
|
||||||
"added_at": "2025-10-20T20:43:13.827926",
|
"added_at": "2025-10-22T06:28:54.851520Z",
|
||||||
"started_at": null,
|
"started_at": null,
|
||||||
"completed_at": null,
|
"completed_at": null,
|
||||||
"progress": null,
|
"progress": null,
|
||||||
@ -286,7 +343,26 @@
|
|||||||
"source_url": null
|
"source_url": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "7b4f7034-f6df-46a9-99bf-3544abceba75",
|
"id": "ce340109-e96f-4e8e-a8b7-2969624e9423",
|
||||||
|
"serie_id": "series-0",
|
||||||
|
"serie_name": "Series 0",
|
||||||
|
"episode": {
|
||||||
|
"season": 1,
|
||||||
|
"episode": 1,
|
||||||
|
"title": null
|
||||||
|
},
|
||||||
|
"status": "pending",
|
||||||
|
"priority": "normal",
|
||||||
|
"added_at": "2025-10-22T06:28:54.852300Z",
|
||||||
|
"started_at": null,
|
||||||
|
"completed_at": null,
|
||||||
|
"progress": null,
|
||||||
|
"error": null,
|
||||||
|
"retry_count": 0,
|
||||||
|
"source_url": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "99e225d8-0a65-44f6-a498-d58f44e60797",
|
||||||
"serie_id": "persistent-series",
|
"serie_id": "persistent-series",
|
||||||
"serie_name": "Persistent Series",
|
"serie_name": "Persistent Series",
|
||||||
"episode": {
|
"episode": {
|
||||||
@ -296,7 +372,7 @@
|
|||||||
},
|
},
|
||||||
"status": "pending",
|
"status": "pending",
|
||||||
"priority": "normal",
|
"priority": "normal",
|
||||||
"added_at": "2025-10-20T20:43:13.890139",
|
"added_at": "2025-10-22T06:28:54.922655Z",
|
||||||
"started_at": null,
|
"started_at": null,
|
||||||
"completed_at": null,
|
"completed_at": null,
|
||||||
"progress": null,
|
"progress": null,
|
||||||
@ -305,7 +381,7 @@
|
|||||||
"source_url": null
|
"source_url": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "77b0ddc3-3d6f-432f-9e6a-0a97218c4d83",
|
"id": "e35ff9af-547a-47d8-9681-a48bfe94e625",
|
||||||
"serie_id": "ws-series",
|
"serie_id": "ws-series",
|
||||||
"serie_name": "WebSocket Series",
|
"serie_name": "WebSocket Series",
|
||||||
"episode": {
|
"episode": {
|
||||||
@ -315,7 +391,7 @@
|
|||||||
},
|
},
|
||||||
"status": "pending",
|
"status": "pending",
|
||||||
"priority": "normal",
|
"priority": "normal",
|
||||||
"added_at": "2025-10-20T20:43:13.940094",
|
"added_at": "2025-10-22T06:28:54.981230Z",
|
||||||
"started_at": null,
|
"started_at": null,
|
||||||
"completed_at": null,
|
"completed_at": null,
|
||||||
"progress": null,
|
"progress": null,
|
||||||
@ -324,7 +400,7 @@
|
|||||||
"source_url": null
|
"source_url": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "b2b4c2b0-f016-44dc-ace5-947474f3d071",
|
"id": "b1826897-7ff6-4479-bdc4-e8b48c2d27d0",
|
||||||
"serie_id": "pause-test",
|
"serie_id": "pause-test",
|
||||||
"serie_name": "Pause Test Series",
|
"serie_name": "Pause Test Series",
|
||||||
"episode": {
|
"episode": {
|
||||||
@ -334,7 +410,7 @@
|
|||||||
},
|
},
|
||||||
"status": "pending",
|
"status": "pending",
|
||||||
"priority": "normal",
|
"priority": "normal",
|
||||||
"added_at": "2025-10-20T20:43:13.992601",
|
"added_at": "2025-10-22T06:28:55.141995Z",
|
||||||
"started_at": null,
|
"started_at": null,
|
||||||
"completed_at": null,
|
"completed_at": null,
|
||||||
"progress": null,
|
"progress": null,
|
||||||
@ -345,5 +421,5 @@
|
|||||||
],
|
],
|
||||||
"active": [],
|
"active": [],
|
||||||
"failed": [],
|
"failed": [],
|
||||||
"timestamp": "2025-10-20T20:43:13.992831"
|
"timestamp": "2025-10-22T06:28:55.143138+00:00"
|
||||||
}
|
}
|
||||||
@ -1,146 +0,0 @@
|
|||||||
## <20>📋 General Instructions
|
|
||||||
|
|
||||||
### Overview
|
|
||||||
|
|
||||||
This document lists all failed tests identified during the test run on October 19, 2025. Each test failure needs to be investigated and resolved. The failures are categorized by module/area for easier resolution.
|
|
||||||
|
|
||||||
### Important Guidelines
|
|
||||||
|
|
||||||
1. **Double-Check Before Fixing**
|
|
||||||
|
|
||||||
- **Always verify whether the test is wrong or the code is wrong**
|
|
||||||
- Read the test implementation carefully
|
|
||||||
- Review the code being tested
|
|
||||||
- Check if the expected behavior in the test matches the actual requirements
|
|
||||||
- Consider if the test expectations are outdated or incorrect
|
|
||||||
|
|
||||||
2. **Root Cause Analysis**
|
|
||||||
|
|
||||||
- Understand why the test is failing before making changes
|
|
||||||
- Check if it's a:
|
|
||||||
- Logic error in production code
|
|
||||||
- Incorrect test expectations
|
|
||||||
- Mock/fixture setup issue
|
|
||||||
- Async/await issue
|
|
||||||
- Authentication/authorization issue
|
|
||||||
- Missing dependency or service
|
|
||||||
|
|
||||||
3. **Fix Strategy**
|
|
||||||
|
|
||||||
- Fix production code if the business logic is wrong
|
|
||||||
- Fix test code if the expectations are incorrect
|
|
||||||
- Update both if requirements have changed
|
|
||||||
- Document why you chose to fix test vs code
|
|
||||||
|
|
||||||
4. **Testing Process**
|
|
||||||
|
|
||||||
- Run the specific test after each fix to verify
|
|
||||||
- Run related tests to ensure no regression
|
|
||||||
- Run all tests after batch fixes to verify overall system health
|
|
||||||
|
|
||||||
5. **Code Quality Standards**
|
|
||||||
- Follow PEP8 and project coding standards
|
|
||||||
- Use type hints where applicable
|
|
||||||
- Write clear, self-documenting code
|
|
||||||
- Add comments for complex logic
|
|
||||||
- Update docstrings if behavior changes
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 Success Criteria
|
|
||||||
|
|
||||||
1. **All tests passing:** 0 failures, 0 errors
|
|
||||||
2. **Warnings reduced:** Aim for < 50 warnings (mostly from dependencies)
|
|
||||||
3. **Code quality maintained:** No shortcuts or hacks
|
|
||||||
4. **Documentation updated:** Any behavior changes documented
|
|
||||||
5. **Git commits:** Logical, atomic commits with clear messages
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📞 Escalation
|
|
||||||
|
|
||||||
If you encounter:
|
|
||||||
|
|
||||||
- Architecture issues requiring design decisions
|
|
||||||
- Tests that conflict with documented requirements
|
|
||||||
- Breaking changes needed
|
|
||||||
- Unclear requirements or expectations
|
|
||||||
|
|
||||||
**Document the issue and escalate rather than guessing.**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📚 Helpful Commands
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Run all tests
|
|
||||||
conda run -n AniWorld python -m pytest tests/ -v --tb=short
|
|
||||||
|
|
||||||
# Run specific test file
|
|
||||||
conda run -n AniWorld python -m pytest tests/unit/test_websocket_service.py -v
|
|
||||||
|
|
||||||
# Run specific test class
|
|
||||||
conda run -n AniWorld python -m pytest tests/unit/test_websocket_service.py::TestWebSocketService -v
|
|
||||||
|
|
||||||
# Run specific test
|
|
||||||
conda run -n AniWorld python -m pytest tests/unit/test_websocket_service.py::TestWebSocketService::test_broadcast_download_progress -v
|
|
||||||
|
|
||||||
# Run with extra verbosity
|
|
||||||
conda run -n AniWorld python -m pytest tests/ -vv
|
|
||||||
|
|
||||||
# Run with full traceback
|
|
||||||
conda run -n AniWorld python -m pytest tests/ -v --tb=long
|
|
||||||
|
|
||||||
# Run and stop at first failure
|
|
||||||
conda run -n AniWorld python -m pytest tests/ -v -x
|
|
||||||
|
|
||||||
# Run tests matching pattern
|
|
||||||
conda run -n AniWorld python -m pytest tests/ -v -k "auth"
|
|
||||||
|
|
||||||
# Show all print statements
|
|
||||||
conda run -n AniWorld python -m pytest tests/ -v -s
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📖 Status Update
|
|
||||||
|
|
||||||
- **Document Created:** October 19, 2025
|
|
||||||
- **Last Updated:** October 22, 2025
|
|
||||||
- **Test run time:** ~10 seconds
|
|
||||||
- **Python environment:** AniWorld (conda)
|
|
||||||
- **Framework:** pytest with FastAPI TestClient
|
|
||||||
- **Initial test failures:** 200+ (many were errors)
|
|
||||||
- **Current test failures:** 0 ✅
|
|
||||||
- **Tests Passing:** 583 ✅
|
|
||||||
- **Warnings:** 41 (mostly deprecation warnings from datetime.utcnow())
|
|
||||||
- **Overall progress:** 100% - ALL TESTS PASSING! 🎉
|
|
||||||
|
|
||||||
**Remember:** The goal is not just to make tests pass, but to ensure the system works correctly and reliably!
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 Final Remaining Issues
|
|
||||||
|
|
||||||
### ✅ ALL TESTS PASSING! 🎉
|
|
||||||
|
|
||||||
All 583 tests are now passing with no failures!
|
|
||||||
|
|
||||||
#### Final Fixes Applied (Phase 10):
|
|
||||||
|
|
||||||
- ✅ Fixed `test_session_is_expired` test
|
|
||||||
- **Issue:** Timezone-aware/naive datetime comparison error
|
|
||||||
- **Solution:** Added timezone import to test file and modified `UserSession.is_expired` property to handle naive datetimes from database
|
|
||||||
- ✅ Fixed `test_added_at_auto_generated` test
|
|
||||||
- **Issue:** Test using deprecated `datetime.utcnow()` (naive) vs model expecting timezone-aware datetime
|
|
||||||
- **Solution:** Updated test to use `datetime.now(timezone.utc)` for timezone-aware comparisons
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Phase 10: Final Fixes (Last 2 Tests) - COMPLETED ✅
|
|
||||||
|
|
||||||
- [x] Fix `test_session_is_expired` test
|
|
||||||
- [x] Fix `test_added_at_auto_generated` test
|
|
||||||
- [x] Run and verify: `pytest tests/ -v --tb=short`
|
|
||||||
- [x] Verify all 583 tests pass
|
|
||||||
- [x] Reduce warnings (currently 41, target < 50) ✅
|
|
||||||
103
instructions.md
103
instructions.md
@ -54,6 +54,105 @@ The tasks should be completed in the following order to ensure proper dependenci
|
|||||||
7. **Monitoring**: Implement comprehensive monitoring and alerting
|
7. **Monitoring**: Implement comprehensive monitoring and alerting
|
||||||
8. **Maintenance**: Plan for regular maintenance and updates
|
8. **Maintenance**: Plan for regular maintenance and updates
|
||||||
|
|
||||||
|
### Important Guidelines
|
||||||
|
|
||||||
|
1. **Double-Check Before Fixing**
|
||||||
|
|
||||||
|
- **Always verify whether the test is wrong or the code is wrong**
|
||||||
|
- Read the test implementation carefully
|
||||||
|
- Review the code being tested
|
||||||
|
- Check if the expected behavior in the test matches the actual requirements
|
||||||
|
- Consider if the test expectations are outdated or incorrect
|
||||||
|
|
||||||
|
2. **Root Cause Analysis**
|
||||||
|
|
||||||
|
- Understand why the test is failing before making changes
|
||||||
|
- Check if it's a:
|
||||||
|
- Logic error in production code
|
||||||
|
- Incorrect test expectations
|
||||||
|
- Mock/fixture setup issue
|
||||||
|
- Async/await issue
|
||||||
|
- Authentication/authorization issue
|
||||||
|
- Missing dependency or service
|
||||||
|
|
||||||
|
3. **Fix Strategy**
|
||||||
|
|
||||||
|
- Fix production code if the business logic is wrong
|
||||||
|
- Fix test code if the expectations are incorrect
|
||||||
|
- Update both if requirements have changed
|
||||||
|
- Document why you chose to fix test vs code
|
||||||
|
|
||||||
|
4. **Testing Process**
|
||||||
|
|
||||||
|
- Run the specific test after each fix to verify
|
||||||
|
- Run related tests to ensure no regression
|
||||||
|
- Run all tests after batch fixes to verify overall system health
|
||||||
|
|
||||||
|
5. **Code Quality Standards**
|
||||||
|
- Follow PEP8 and project coding standards
|
||||||
|
- Use type hints where applicable
|
||||||
|
- Write clear, self-documenting code
|
||||||
|
- Add comments for complex logic
|
||||||
|
- Update docstrings if behavior changes
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Success Criteria
|
||||||
|
|
||||||
|
1. **All tests passing:** 0 failures, 0 errors
|
||||||
|
2. **Warnings reduced:** Aim for < 50 warnings (mostly from dependencies)
|
||||||
|
3. **Code quality maintained:** No shortcuts or hacks
|
||||||
|
4. **Documentation updated:** Any behavior changes documented
|
||||||
|
5. **Git commits:** Logical, atomic commits with clear messages
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📞 Escalation
|
||||||
|
|
||||||
|
If you encounter:
|
||||||
|
|
||||||
|
- Architecture issues requiring design decisions
|
||||||
|
- Tests that conflict with documented requirements
|
||||||
|
- Breaking changes needed
|
||||||
|
- Unclear requirements or expectations
|
||||||
|
|
||||||
|
**Document the issue and escalate rather than guessing.**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📚 Helpful Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run all tests
|
||||||
|
conda run -n AniWorld python -m pytest tests/ -v --tb=short
|
||||||
|
|
||||||
|
# Run specific test file
|
||||||
|
conda run -n AniWorld python -m pytest tests/unit/test_websocket_service.py -v
|
||||||
|
|
||||||
|
# Run specific test class
|
||||||
|
conda run -n AniWorld python -m pytest tests/unit/test_websocket_service.py::TestWebSocketService -v
|
||||||
|
|
||||||
|
# Run specific test
|
||||||
|
conda run -n AniWorld python -m pytest tests/unit/test_websocket_service.py::TestWebSocketService::test_broadcast_download_progress -v
|
||||||
|
|
||||||
|
# Run with extra verbosity
|
||||||
|
conda run -n AniWorld python -m pytest tests/ -vv
|
||||||
|
|
||||||
|
# Run with full traceback
|
||||||
|
conda run -n AniWorld python -m pytest tests/ -v --tb=long
|
||||||
|
|
||||||
|
# Run and stop at first failure
|
||||||
|
conda run -n AniWorld python -m pytest tests/ -v -x
|
||||||
|
|
||||||
|
# Run tests matching pattern
|
||||||
|
conda run -n AniWorld python -m pytest tests/ -v -k "auth"
|
||||||
|
|
||||||
|
# Show all print statements
|
||||||
|
conda run -n AniWorld python -m pytest tests/ -v -s
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Task Completion Checklist
|
## Task Completion Checklist
|
||||||
|
|
||||||
For each task completed:
|
For each task completed:
|
||||||
@ -75,10 +174,6 @@ This comprehensive guide ensures a robust, maintainable, and scalable anime down
|
|||||||
|
|
||||||
## Core Tasks
|
## Core Tasks
|
||||||
|
|
||||||
### 10. Tests
|
|
||||||
|
|
||||||
- []make sure all tests are passing. Check logic and fix code or test.
|
|
||||||
|
|
||||||
### 11. Deployment and Configuration
|
### 11. Deployment and Configuration
|
||||||
|
|
||||||
#### [] Create production configuration
|
#### [] Create production configuration
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user