# Auto Crossposter Architecture

## Pipeline

1. `ScrapeQueue` receives a profile URL or platform username.
2. The scraper discovers up to ten latest video URLs, processes each independently, downloads an authenticated browser stream, creates a thumbnail, and writes one metadata file per video.
3. `AiCaptionQueue` rewrites the caption with Gemini. Any timeout, quota, or API error returns the original caption unchanged.
4. `PublishQueue` stores ready items as durable delayed jobs. At 00:00, 06:00, and 17:00 Asia/Jakarta, the scheduler promotes exactly one oldest item.
5. The publish worker opens the destination studio using the latest cookie JSON, uploads through Playwright, verifies success, and immediately removes the MP4 and thumbnail.
6. Daily housekeeping removes stale download and metadata artifacts older than 24 hours.

## Persistence

Redis uses append-only persistence through `docker-compose.yml`. Video state is stored as JSON under `storage/metadata`. PM2 runs one process to prevent duplicate cron execution and duplicate Telegram polling.

## Session JSON

Cookie files accept either a Playwright `storageState` object or an array of browser cookies. The web settings page writes updates atomically and every browser task reloads the file, so no process restart is required.
