# Addon Config Worker — Session Management Pattern

From the Unspooled addon-config-worker (May 2026). A Cloudflare Worker with Durable Objects that manages temporary addon configuration sessions.

## Architecture

```
┌──────────────┐     HTTP/HTTPS     ┌──────────────────────┐
│  Android App  │ ──────────────────→│ addon-config-worker  │
│  (QR code UI) │ ←──────────────────│  (Cloudflare Worker) │
└──────────────┘                    └──────────┬───────────┘
                                               │ Durable Object
                                               ▼
                                        ┌──────────────┐
                                        │ ConfigSession │
                                        │ (DO per code) │
                                        │ 30min TTL     │
                                        └──────────────┘
```

## API Endpoints

| Method | Route | Purpose | Called By |
|--------|-------|---------|-----------|
| POST | `/api/addons/config-sessions` | Create session | Android app |
| GET | `/api/addons/config-sessions/{code}` | Poll status | Android app |
| POST | `/api/addons/config-sessions/{code}/complete` | Submit configured URL | Android app |
| POST | `/api/addons/config-sessions/{code}/cancel` | Cancel session | Android app |
| GET | `/addons/config/{code}` | Config landing page | Phone browser (QR) |
| GET | `/addons/config/{code}/status` | Poll (phone page JS) | Phone browser |
| POST | `/addons/config/{code}/complete` | Submit URL from phone | Phone browser |
| POST | `/addons/config/{code}/cancel` | Cancel from phone | Phone browser |

## Session State Machine

```
pending ──(phone opens page)──→ active ──(user submits URL)──→ completed
   │                                │                             │
   └──(30min timeout)──→ cancelled  └──(user cancels)──→ cancelled  │
                                                                     │
                                                    completed ───────┘
```

## Durable Object Key Methods

- `createSession()` — stores session + sets 30min alarm
- `getStatus()` — returns session (checks expiry)
- `activate()` — transitions pending→active
- `complete(url)` — validates URL, transitions→completed
- `cancel()` — transitions→cancelled
- `alarm()` — auto-cancels on TTL expiry

## Validation Flow

1. User pastes configured manifest URL (e.g., `https://torrentio.strem.fun/DEBRID_TOKEN/manifest.json`)
2. Worker fetches the URL
3. Checks: `id`, `name`, `resources` array exist
4. Returns `validatedManifestOk: true/false` + `validationError` if failed

## Security

- Rate limit: 30 req/min/IP (in-memory per-isolate)
- Configured URLs are NOT stored in Worker KV — returned to app on completion
- App stores configured URL in Room database (not visible in logs)
- No secret token between app and worker (publicly accessible)
- Backend secret can be added via `wrangler secret put BACKEND_SECRET`

## Session Code Format

- 8-character alphanumeric (no 0,1,i,l,o for readability)
- Random via `crypto.getRandomValues()` (falls back to `Math.random()` in dev)
- Used as Durable Object `idFromName()` deterministic ID
