Replace email-based auth (Resend) with phone-based auth (Twilio SMS). Add BBQ_FEATURES env var for toggling features at deploy time — when auth is disabled, no login routes are registered and the app works as before. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3.0 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
What This Is
Potluck signup app. No accounts — share a link, people claim slots. Open like a shared Google Sheet.
Commands
# Build and run
go build -o bbq . && ./bbq
# Docker
docker compose up -d --build
# Regenerate DB layer after editing schema.sql or db/queries.sql
$(go env GOPATH)/bin/sqlc generate
Environment Variables
PORT— Go server listen port (default8080)BBQ_DB— SQLite database path (defaultbbq.db)BBQ_BASE_URL— Absolute URL for OG images (e.g.https://bbq.torrtle.co)HOST_PORT— Compose host-side port mapping (default8090)
Architecture
Stack: Go, chi router, sqlc + SQLite (mattn/go-sqlite3), html/template, HTMX + SSE
Design: Soft Brutalism — cream #f5f0e8, black borders/shadows, yellow #f5e642 accents, Bricolage Grotesque + DM Mono fonts
Data Flow
schema.sql defines tables (events, slots, claims, rsvps) → db/queries.sql has SQL queries → sqlc generate produces db/ package (models.go, queries.sql.go, db.go). Never edit generated files in db/ directly.
Server (main.go)
Server struct holds *db.Queries, *sql.DB, baseURL, and SSE client channels. SSE uses subscribe/unsubscribe/notify pattern — any mutation calls notify(slug) to push updates to all viewers.
Templates
Go template inheritance doesn't work with a single ParseFS, so each page is parsed separately into pageTmpl map:
pageTmpl["home"]/pageTmpl["event"]— full pages, rendered via.ExecuteTemplate(w, "layout", data)pageTmpl["slots"]— partial for HTMX responses, rendered via.ExecuteTemplate(w, "slots-inner", data)
Template files: layout.html (shell + all CSS/JS), slots.html (shared partial), event.html, home.html. All CSS is inline in layout.html.
Handlers (handlers.go)
loadEventPage() is the shared data loader — assembles EventPageData with event, slots+claims, rsvps, and counts. Used by both full page renders and HTMX partial responses.
OG Image (ogimage.go)
Dynamic PNG generation at /e/{slug}/og.png using Go's image package with a custom 5x7 bitmap font. Renders event title, date/time/location in the app's visual style.
Routes
GET /— create event formPOST /events— creates event + slots, redirects to admin URLGET /e/{slug}— guest viewPOST /e/{slug}/claim/DELETE /e/{slug}/claim/{claimID}— HTMX claim/unclaimPOST /e/{slug}/rsvp/DELETE /e/{slug}/rsvp/{rsvpID}— HTMX RSVPGET /e/{slug}/sse— SSE stream for live updatesGET /e/{slug}/og.png— dynamic OG imageGET /e/{slug}/admin/{token}— admin view (same template,IsAdmin=true)POST /e/{slug}/admin/{token}/slot/DELETE /e/{slug}/admin/{token}/slot/{slotID}— manage slots
Auth Model
No user auth. Admin access is via secret admin_token in the URL. Claims/RSVPs are open to anyone with the event link.