# Backup Feature

Complete backup and restore system for MotoVaultPro.

## Overview

This feature provides:
- Manual and scheduled backups of the PostgreSQL database and document files
- Multiple backup schedules with individual retention policies
- Restore functionality with safety backup creation
- Email notifications on backup success/failure

## Architecture

```
backup/
  api/                    # HTTP endpoints
    backup.routes.ts      # Route definitions
    backup.controller.ts  # Request handlers
    backup.validation.ts  # Zod schemas
  domain/                 # Business logic
    backup.types.ts       # TypeScript types and constants
    backup.service.ts     # Core backup operations
    backup-archive.service.ts      # Archive creation
    backup-restore.service.ts      # Restore operations
    backup-retention.service.ts    # Tiered retention enforcement
    backup-classification.service.ts  # Backup category classification
  data/                   # Data access
    backup.repository.ts  # Database queries
  jobs/                   # Scheduled jobs
    backup-scheduled.job.ts  # Scheduled backup execution
    backup-cleanup.job.ts    # Retention cleanup
  migrations/             # Database schema
    001_create_backup_tables.sql
    002_add_retention_categories.sql  # Tiered retention columns
  tests/                  # Test files
    unit/
      backup-classification.service.test.ts  # Classification tests
```

## API Endpoints

All endpoints require admin authentication.

### Backup Operations

| Method | Path | Description |
|--------|------|-------------|
| GET | `/api/admin/backups` | List backups with pagination |
| POST | `/api/admin/backups` | Create manual backup |
| GET | `/api/admin/backups/:id` | Get backup details |
| GET | `/api/admin/backups/:id/download` | Download backup file |
| DELETE | `/api/admin/backups/:id` | Delete backup |
| POST | `/api/admin/backups/upload` | Upload backup file |

### Restore Operations

| Method | Path | Description |
|--------|------|-------------|
| POST | `/api/admin/backups/:id/restore/preview` | Preview restore |
| POST | `/api/admin/backups/:id/restore` | Execute restore |
| GET | `/api/admin/backups/restore/status` | Get restore status |

### Schedule Operations

| Method | Path | Description |
|--------|------|-------------|
| GET | `/api/admin/backups/schedules` | List schedules |
| POST | `/api/admin/backups/schedules` | Create schedule |
| PUT | `/api/admin/backups/schedules/:id` | Update schedule |
| DELETE | `/api/admin/backups/schedules/:id` | Delete schedule |
| PATCH | `/api/admin/backups/schedules/:id/toggle` | Enable/disable |

### Settings

| Method | Path | Description |
|--------|------|-------------|
| GET | `/api/admin/backups/settings` | Get settings |
| PUT | `/api/admin/backups/settings` | Update settings |

## Backup Archive Format

Backups are `.tar.gz` archives containing:

```
motovaultpro_backup_YYYYMMDD_HHMMSS.tar.gz
  manifest.json           # Backup metadata
  database/
    motovaultpro.sql.gz   # Compressed PostgreSQL dump
  documents/
    <user_id>/            # User document files
```

## Schedule Frequencies

| Frequency | Cron | Default Time |
|-----------|------|--------------|
| hourly | `0 * * * *` | Every hour |
| daily | `0 3 * * *` | 3:00 AM |
| weekly | `0 3 * * 0` | Sunday 3:00 AM |
| monthly | `0 3 1 * *` | 1st of month 3:00 AM |

## Database Tables

- `backup_schedules` - Schedule configurations
- `backup_history` - Backup operation records
- `backup_settings` - Global settings

## Storage

Backups are stored in `/app/data/backups/` (mapped to `./data/backups/` on host).

## Integration

### Scheduler

Jobs are registered in `backend/src/core/scheduler/index.ts`:
- Backup check: Every minute
- Retention cleanup: Daily at 4 AM (also runs after each scheduled backup)

### Distributed Locking

Scheduled backups use Redis distributed locking to prevent duplicate backups when multiple backend containers are running (blue-green deployments).

**Lock behavior:**
- Lock key: `backup:schedule:{schedule_id}`
- Lock TTL: 5 minutes (auto-release if container crashes)
- Only one container creates the backup; others skip

**Retention cleanup (tiered):**
- Runs immediately after each successful scheduled backup
- Uses tiered classification: each backup can belong to multiple categories
- A backup is only deleted when it exceeds ALL applicable category quotas
- Also runs globally at 4 AM daily as a safety net

## Tiered Retention System

Backups are classified by their creation timestamp into categories:

| Category | Qualification | Retention Count |
|----------|--------------|-----------------|
| hourly | All backups | 8 |
| daily | First backup at midnight UTC | 7 |
| weekly | First backup on Sunday at midnight UTC | 4 |
| monthly | First backup on 1st of month at midnight UTC | 12 |

**Multi-category classification:**
- A backup can belong to multiple categories simultaneously
- Example: Backup at midnight on Sunday, January 1st qualifies as: hourly + daily + weekly + monthly

**Retention logic:**
```
For each category (hourly, daily, weekly, monthly):
  1. Get all backups with this category
  2. Keep top N (sorted by started_at DESC)
  3. Add to protected set

A backup is deleted ONLY if it's NOT in the protected set
(i.e., exceeds quota for ALL its categories)
```

**Expiration calculation:**
- Each backup's `expires_at` is calculated based on its longest retention period
- Monthly backup: 12 months from creation
- Weekly-only backup: 4 weeks from creation
- Daily-only backup: 7 days from creation
- Hourly-only backup: 8 hours from creation

See `backend/src/core/scheduler/README.md` for the distributed locking pattern.

### Admin Routes

Routes are registered in `backend/src/features/admin/api/admin.routes.ts`.
