MovieMapper/docs/FEATURES.md
Jarian Cottingham 1a35eb346e chore: reorganize repo layout, remove dead files
- Move phase/plan docs into docs/
- Move legacy node:test files into tests/legacy/ with README
- Remove .backup file, test audit artifacts, and unused AI prompt/skill files
- Remove broken iOS GitHub workflows (reference missing MovieMapper-iOS/)
2026-08-20 20:11:57 +00:00

320 lines
8.3 KiB
Markdown

# MovieMapper Feature Specification
## Project Overview
A desktop application for organizing and managing movie and TV show collections with intelligent file mapping using TheTVDB API.
## Current State
- Electron-based application (v40.4.1)
- TheTVDB v4 API integration with bearer token authentication
- FFmpeg-based media file metadata extraction
- Basic file renaming and directory navigation
- Audit logging to `.audit` files
## Target Architecture
- **Main Process**: Rust backend with Node.js Electron bridge
- **Renderer Process**: Electron web UI (unchanged)
- **Performance**: Native Rust for CPU-intensive operations
## Core Features
### 1. Directory Scanning (Rust Implementation)
**Priority**: High
**Status**: Current - Node.js, Target - Rust
**Requirements**:
- Non-recursive directory scanning
- Media file detection (mp4, mkv, avi, mov, flv, webm)
- FFmpeg metadata extraction (duration, quality, FPS)
- Progress callback support for UI updates
- Permission error handling
**API**:
```rust
pub struct FileMetadata {
pub path: String,
pub name: String,
pub size: u64,
pub modified: SystemTime,
pub duration: String,
pub quality: String,
pub fps: String,
pub is_folder: bool,
}
pub fn scan_directory(
directory_path: &str,
progress_callback: Option<Box<dyn Fn(u32, u32, &str) + Send>>
) -> Result<Vec<FileMetadata>, ScanError>;
```
### 2. FFmpeg Integration (Rust Implementation)
**Priority**: High
**Status**: Current - fluent-ffmpeg, Target - ffmpeg-kit or rust-ffmpeg
**Requirements**:
- ffprobe for metadata extraction
- Duration calculation (mm:ss format)
- Video quality detection (4K, 1440p, 1080p, 720p, 480p)
- Frame rate extraction
- Graceful error handling for corrupted files
**API**:
```rust
pub struct VideoStreamInfo {
pub width: u32,
pub height: u32,
pub codec: String,
pub frame_rate: f64,
}
pub struct AudioStreamInfo {
pub codec: String,
pub channels: u32,
pub sample_rate: u32,
}
pub struct MediaInfo {
pub duration: f64, // seconds
pub format: String,
pub video_streams: Vec<VideoStreamInfo>,
pub audio_streams: Vec<AudioStreamInfo>,
}
pub fn probe_file(path: &str) -> Result<MediaInfo, ProbeError>;
```
### 3. TheTVDB API Integration (Rust Implementation)
**Priority**: High
**Status**: Current - axios, Target - reqwest with async/await
**Requirements**:
- TVDB v4 API authentication (apikey → token)
- Show search with query
- Show details with seasons
- Episode listing per season
- Token caching (30-day validity)
- Rate limiting handling
**API**:
```rust
pub struct Show {
pub id: u64,
pub name: String,
pub status: Option<String>,
pub first_aired: Option<String>,
pub overview: Option<String>,
pub image: Option<String>,
pub slug: Option<String>,
}
pub struct Season {
pub id: u64,
pub number: u32,
pub episode_count: u32,
}
pub struct Episode {
pub id: u64,
pub name: String,
pub number: u32,
pub season_number: u32,
pub aired: Option<String>,
pub overview: Option<String>,
}
pub struct TVDBClient {
token: Option<String>,
api_key: String,
}
impl TVDBClient {
pub fn new(api_key: String) -> Self;
pub async fn search(&self, query: &str) -> Result<Vec<Show>, TVDBError>;
pub async fn get_show_details(&self, show_id: u64) -> Result<Show, TVDBError>;
pub async fn get_seasons(&self, show_id: u64) -> Result<Vec<Season>, TVDBError>;
pub async fn get_episodes(&self, show_id: u64, season_number: u32) -> Result<Vec<Episode>, TVDBError>;
}
```
### 4. File Operations (Rust Implementation)
**Priority**: High
**Status**: Current - Node.js fs, Target - std::fs + tokio
**Requirements**:
- File renaming with atomic operations
- Directory creation (recursive)
- File movement to folder (extras, commentary, etc.)
- Audit log writing
- Conflict detection (duplicate files)
**API**:
```rust
pub struct AuditLogEntry {
pub timestamp: String,
pub action: AuditAction,
pub details: HashMap<String, String>,
}
pub enum AuditAction {
RenameFile { old_path: String, new_path: String },
MoveFile { original_path: String, new_path: String, folder: String },
}
pub struct FileManager {
base_path: String,
}
impl FileManager {
pub fn new(base_path: &str) -> Self;
pub async fn rename_file(&self, old_path: &str, new_name: &str) -> Result<(), FileError>;
pub async fn move_to_folder(&self, file_path: &str, folder_name: &str) -> Result<String, FileError>;
pub async fn write_audit_log(&self, action: AuditAction) -> Result<(), FileError>;
}
```
### 5. File Mapping/Batch Rename (Rust Implementation)
**Priority**: High
**Status**: Current - Node.js, Target - Rust
**Requirements**:
- Parse show name from folder
- Extract season number (multiple formats: "Season 01", "S01", etc.)
- Map files to episodes using TVDB data
- Handle single episodes and episode ranges (1-3)
- Quality suffix support
- Folder naming with TVDB ID
**API**:
```rust
pub struct EpisodeMapping {
pub show_name: String,
pub season_number: u32,
pub episodes: Vec<EpisodeRange>,
pub quality: Option<String>,
}
pub struct EpisodeRange {
pub start: u32,
pub end: u32,
}
pub struct MappingResult {
pub success_count: u32,
pub error_count: u32,
pub renamed_files: Vec<String>,
}
pub async fn begin_mapping(
directory: &str,
files: Vec<MediaFile>,
tvdb_id: u64,
client: &TVDBClient
) -> Result<MappingResult, MappingError>;
```
### 6. IPC Bridge (Rust Implementation)
**Priority**: Medium
**Status**: Current - Direct ipcMain/handle, Target - Node.js addon or IPC socket
**Requirements**:
- Node.js native addon or IPC interface
- Async message handling
- Progress event streaming
- Error propagation
**API**:
```rust
#[repr(C)]
pub struct IpcMessage {
pub channel: *const c_char,
pub data: *const c_char,
}
pub type IpcCallback = extern "C" fn(channel: *const c_char, data: *const c_char);
#[no_mangle]
pub extern "C" fn init_ipc(callback: IpcCallback);
#[no_mangle]
pub extern "C" fn handle_request(channel: *const c_char, data: *const c_char) -> *const c_char;
```
## Implementation Phases
### Phase 1: Core Foundation (Weeks 1-2)
- [ ] Set up Rust project structure
- [ ] Implement FileMetadata and scan_directory
- [ ] Integrate FFmpeg for metadata extraction
- [ ] Create basic error types
- [ ] Write unit tests for core utilities
### Phase 2: API Integration (Weeks 2-3)
- [ ] Implement TVDBClient with authentication
- [ ] Add show search functionality
- [ ] Implement show details and episode fetching
- [ ] Add token caching mechanism
- [ ] Write integration tests
### Phase 3: File Operations (Weeks 3-4)
- [ ] Implement FileManager with async operations
- [ ] Add audit logging
- [ ] Implement file movement and renaming
- [ ] Add conflict detection
- [ ] Write integration tests
### Phase 4: File Mapping (Weeks 4-5)
- [ ] Implement begin_mapping logic
- [ ] Add episode range handling
- [ ] Implement quality suffix logic
- [ ] Add folder naming with TVDB ID
- [ ] Write integration tests
### Phase 5: IPC Bridge (Weeks 5-6)
- [ ] Create Node.js native addon
- [ ] Implement message handling
- [ ] Add progress streaming
- [ ] Handle async callbacks
- [ ] Write integration tests
### Phase 6: Testing & Documentation (Weeks 6-7)
- [ ] Comprehensive integration tests
- [ ] Performance benchmarks
- [ ] Documentation
- [ ] Migration guide
## Technical Decisions
### FFmpeg Integration
**Option A**: ffmpeg-kit (prebuilt binaries)
- Pros: Easy setup, cross-platform
- Cons: Larger binary size
**Option B**: rust-ffmpeg (FFmpeg C bindings)
- Pros: Full control, smaller binary
- Cons: Build complexity, dependency management
**Decision**: ffmpeg-kit for rapid development and reliability
### Async Runtime
- tokio for async operations
- Standard library for sync operations
- Cross-platform async file I/O
### Error Handling
- Custom error types with meaningful messages
- Consistent error propagation
- Detailed logging for debugging
### Testing Strategy
- Unit tests for pure functions
- Integration tests for file operations
- Mock TVDB API for API tests
- Benchmark tests for performance-critical paths
## Success Criteria
- [ ] All features work identically to Node.js version
- [ ] Performance improvement for large directories
- [ ] Memory usage below Node.js baseline
- [ ] No crashes or memory leaks
- [ ] All tests passing
- [ ] Documentation complete