Files
Bookra/apps/backend
Tomas DvorakandDevin 65a693cf38 feat: series-aware schedule edits + waitlist ledger removal (M32)
PATCH /v1/catalog/class-schedules/:id patches a recurring rule and,
with applyToFuture, retimes materialized future sessions to the new
local start time on their existing dates — moving confirmed and
waitlisted bookings with them and re-arming reminders. Zones-page
schedule rows gain an inline editor (CS/EN).

Also drops the vestigial waitlist_entries table (migration 00020):
positions derive from bookings.created_at, so the ledger was written
but never read.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 20:59:34 +02:00
..
2026-05-05 09:48:15 +02:00
2026-05-05 09:48:15 +02:00
2026-05-05 09:48:07 +02:00
2026-05-05 09:48:15 +02:00

Bookra Backend

Go + Gin API for Bookra, designed for Railway deployment with Neon Auth, Neon Postgres, and Stripe billing.

Commands

go run ./cmd/api
go build ./...
go test ./...
npm run db:migrate:status
npm run db:migrate:up

Environment

  • BOOKRA_FRONTEND_URL allowed browser origin
  • BOOKRA_DATABASE_URL Neon pooled connection
  • BOOKRA_DATABASE_DIRECT_URL Neon direct connection for migrations/admin tasks
  • BOOKRA_NEON_AUTH_URL Neon Auth base URL used for JWKS verification
  • BOOKRA_AUTH_JWT_SECRET local JWT secret for the password-auth endpoints
  • BOOKRA_JOB_RUNNER_KEY shared secret for remote job-runner calls
  • BOOKRA_EMAIL_FROM sender identity for email reminders
  • BOOKRA_SMTP_* optional SMTP transport for email delivery
  • BOOKRA_STRIPE_API_KEY Stripe secret API key
  • BOOKRA_STRIPE_WEBHOOK_SECRET Stripe webhook signing secret
  • BOOKRA_STRIPE_{STARTER,PRO,BUSINESS}_{CZK,USD}_{MONTHLY,YEARLY}_PRICE_ID Stripe price IDs
  • BOOKRA_STRIPE_SMS_{CZK,USD,...}_PRICE_ID Stripe SMS usage price IDs
  • BOOKRA_SMSMANAGER_API_KEY optional SMS Manager.cz key
  • BOOKRA_UMAMI_API_URL and BOOKRA_UMAMI_API_KEY optional analytics integration
  • BOOKRA_ADMIN_EMAIL and BOOKRA_ADMIN_KEY optional platform admin API credentials
  • BOOKRA_SENTRY_DSN optional error monitoring

See .env.example for the full list.

Notes

  • Auth verification is isolated in internal/auth.
  • OpenAPI lives in openapi/bookra.openapi.yaml.
  • SQL migrations live in migrations/ (goose).
  • Repositories are handwritten pgx in internal/db/; there is no generated query layer.
  • Goose migrations are wired through npm run db:migrate:* and use the Neon direct connection URL.
  • Reminder dispatch runs through POST /v1/internal/jobs/reminders/dispatch with X-Bookra-Job-Key.
  • BOOKRA_DEMO_MODE=true swaps the repository for deterministic in-memory demo data and authenticates all requests as demo-owner.

Production Auth

Bookra production auth uses Neon Auth directly:

  • frontend uses VITE_NEON_AUTH_URL
  • backend verifies Neon JWTs with BOOKRA_NEON_AUTH_URL

Trusted redirect domains in Neon Auth should include your frontend origin such as https://bookra.eu, plus local dev origins when needed.

Stripe Setup

Get these values from the Stripe dashboard:

  • BOOKRA_STRIPE_API_KEY: Developers -> API keys -> secret key
  • BOOKRA_STRIPE_WEBHOOK_SECRET: Developers -> Webhooks -> destination signing secret
  • BOOKRA_STRIPE_*_PRICE_ID: Product catalog -> recurring price IDs

Create one recurring price per plan/currency/interval you support:

  • starter / pro / business × czk / usd × monthly / yearly

Set the webhook destination to:

POST /v1/webhooks/stripe

Subscribe to at least: checkout.session.completed, customer.subscription.created, customer.subscription.updated, customer.subscription.deleted, invoice.payment_succeeded, invoice.payment_failed.

For local testing:

stripe listen --forward-to http://localhost:8080/v1/webhooks/stripe