Files
Bookra/apps/backend
Tomas DvorakandDevin 7509e82261 feat(reminders): SMS channel for reminder jobs
Tenants paying for the SMS add-on still got email-only reminders —
the channel column existed but nothing armed or dispatched sms jobs.
Booking creation now adds a second job when SMS is enabled and the
customer left a phone; dispatch routes sms jobs through an injected
sender adapter wired to the existing sms.Service, so monthly limits,
usage metering, and Stripe billing apply unchanged. Lifecycle handling
from the previous milestone clears and re-arms both channels together.

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

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-18 13:03:11 +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