# SnapAPI Session Log ## Session 1 — 2026-02-18 **Goal:** Build core SnapAPI from scratch and deploy to cluster. ### What Was Done 1. **Studied DocFast patterns** — reviewed all key files (index.ts, db.ts, keys.ts, browser.ts, auth.ts, usage.ts, Dockerfile, CI/CD workflows) 2. **Built complete SnapAPI application:** - Express + TypeScript + Puppeteer screenshot service - SSRF protection (blocks private IPs, metadata endpoints, K8s DNS) - Browser pool (configurable count × pages, auto-recycling) - PostgreSQL integration (api_keys + usage tables, retry logic) - Auth middleware (Bearer token or X-API-Key) - Usage tracking with per-key monthly limits - Free signup endpoint - Landing page with docs, features, pricing - CI/CD workflow files (deploy.yml + promote.yml) 3. **Docker image built** on k3s-mgr (ARM64, ~1.2GB with Chromium) 4. **Deployed to staging** (snapapi-staging namespace, 1 replica) 5. **Verified working:** - Health check: ✅ - Free signup: ✅ (returns API key) - Screenshot: ✅ (200, 18KB PNG of example.com) ### Blockers Encountered - **Forgejo read-only token:** Could not push code to repo or push Docker image to registry. Had to build image directly on k3s-mgr and import via containerd (docker save | k3s ctr images import) - **No domain:** Can't set up Traefik IngressRoute or production deployment ### Image on workers - Imported manually via `docker save | ssh | k3s ctr images import` to both k3s-w1 and k3s-w2 - Uses `imagePullPolicy: IfNotPresent` since image is pre-loaded