# Research: Backup Scheduler & Unified Task UI ## Decisions ### 1. Scheduler Implementation - **Decision**: Use `APScheduler` (Advanced Python Scheduler) with `BackgroundScheduler`. - **Rationale**: `APScheduler` is the industry standard for Python scheduling. It supports Cron-style scheduling (required by FR-001), runs in the background (FR-003), and handles thread management. It integrates well with FastAPI lifecycles. - **Alternatives Considered**: - `cron` (system level): Harder to manage from within the app, requires OS access. - `schedule` library: Simpler but lacks advanced Cron features and persistence robustness. - Custom thread loop: Error-prone and reinvents the wheel. ### 2. Task History Database - **Decision**: SQLite (`tasks.db`) accessed via `SQLAlchemy` (AsyncIO). - **Rationale**: The spec explicitly requests `tasks.db` (FR-009). SQLAlchemy provides a robust ORM for the `Task` entity. Using AsyncIO ensures non-blocking database operations within the FastAPI event loop, even if the actual backup tasks run in threads. - **Alternatives Considered**: - `JSON` files: Poor performance for filtering/sorting logs (FR-006). - `PostgreSQL`: Overkill for a local tool configuration. ### 3. Concurrency Handling - **Decision**: Skip scheduled backups if a backup is already running for the *same* environment. Allow concurrent backups for *different* environments. - **Rationale**: Prevents resource contention and potential corruption of the same target. - **Implementation**: The `SchedulerService` will check `TaskManager` for active jobs with the same `environment_id` before triggering. ### 4. Frontend Polling vs WebSockets - **Decision**: Polling (every 2-5 seconds) for the "Tasks" tab. - **Rationale**: Simpler to implement than WebSockets for this scale. The requirement is "near real-time" (SC-002: latency < 5s), which polling satisfies easily. - **Alternatives Considered**: - WebSockets: Better real-time, but higher complexity for connection management and state.