3 Commits

Author SHA1 Message Date
Claude 449ffcd62d Bambuddy sync: match the real spools API
Checked against Greg's Bambuddy: the key goes in X-API-Key, colors are
color_name (often null on RFID spools) and rgba, grams left is
label_weight minus weight_used, and archived spools carry archived_at.
Unnamed spools get the nearest plain color name.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012aSbo2D1qP8cMFQCykf7kx
2026-10-12 02:47:48 +00:00
Claude 754c6482be Phase 7: Cosmos deployment
- Dockerfile with a check target (typecheck and tests) and one image per
  service on a pinned Node 22.20 Alpine base, each with only its own
  production dependencies and a health check.
- deploy/compose.yaml: gk-content, gk-admin and gk-site on homelab_network
  with no host ports, read-only root filesystems, no capabilities, the vault's
  Site folder mounted into the content service, and backup.dump=sqlite on it.
- deploy/deploy.sh builds and checks the commit, restarts the stack, and goes
  back to the last good tag if it doesn't come up healthy; rollback.sh swaps
  tags. .gitea/workflows/deploy.yml runs it on a host runner on Cosmos.
- docs/deploy.md runbook (settings, runner, mirror, NPM hosts, Turnstile,
  Healthchecks, backups, cutover) and the stack's inventory note in vault-kit.
- Site: trusts X-Forwarded-Host/Proto for gregkilmer.com hosts so form posts
  pass Astro's origin check behind the proxy; rate limits read
  CF-Connecting-IP; site URL set for absolute links.
- Content service: the held-change webhook carries a Discord-ready message;
  .env.example lists the core settings.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012aSbo2D1qP8cMFQCykf7kx
2026-10-12 00:43:03 +00:00
Claude e3b0cf60c5 Phase 6: sync jobs, inquiry and order forms
- Sync scheduler in the content service with a per-job cache (sync_cache),
  sync_runs reporting and Healthchecks pings. Jobs: Archidekt, BoardGameGeek,
  cover art (Open Library, TMDB, AniList), Suwayomi and Kavita reading
  progress, Bambuddy filament and Homebox material stock. A note's own value
  always wins over a synced one.
- PersonalReader: updates only Library notes with a matching anilistId,
  changes to Greg's notes are held for review; Reading series with no note
  show as suggestions on the admin Overview.
- /api/inquiries and /api/orders: Turnstile, rate limits, a saved copy in the
  content service (intake token) plus email over SMTP. Orders are re-checked
  against the live notes: accepted only when the category's ordersOpen is
  true and the line has capacity.
- Admin Inbox for saved submissions. Options' inStock is optional so synced
  stock can fill it. All settings from process.env; .env.example per service.
- Sources could not be reached from the build environment; parsers are tested
  against fixtures labelled as not live.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012aSbo2D1qP8cMFQCykf7kx
2026-10-11 23:50:06 +00:00