Files
ryan 471cc3ad8c Switch to phone auth via Twilio SMS and add feature flag system
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>
2026-05-18 08:45:15 -04:00

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 (default 8080)
  • BBQ_DB — SQLite database path (default bbq.db)
  • BBQ_BASE_URL — Absolute URL for OG images (e.g. https://bbq.torrtle.co)
  • HOST_PORT — Compose host-side port mapping (default 8090)

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 form
  • POST /events — creates event + slots, redirects to admin URL
  • GET /e/{slug} — guest view
  • POST /e/{slug}/claim / DELETE /e/{slug}/claim/{claimID} — HTMX claim/unclaim
  • POST /e/{slug}/rsvp / DELETE /e/{slug}/rsvp/{rsvpID} — HTMX RSVP
  • GET /e/{slug}/sse — SSE stream for live updates
  • GET /e/{slug}/og.png — dynamic OG image
  • GET /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.