Tomas DvorakandDevin e680e0c2b8 feat: scheduled report digests + per-session capacity (M33)
POST /v1/internal/jobs/reports/dispatch emails each tenant owner a
trailing-window digest (bookings, revenue, per-service and per-staff
breakdown) localized to the tenant locale; zero-activity tenants are
skipped. Metrics cores extracted to tenant-scoped variants so the job
needs no principal.

PATCH /v1/catalog/class-sessions/:id sets a session's seat count with
a confirmed-bookings floor — shrinking below it needs allowOverCapacity,
matching the waitlist-promotion convention. Session rows gain an inline
capacity editor with an overbook confirm state.

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

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

Bookra

Booking operating layer for small local service businesses. Public booking pages for customers, a dashboard for owners, and the scheduling, reminder, and billing machinery underneath.

Deployment targets:

  • frontend on Vercel
  • backend on Railway
  • Neon Postgres + Neon Auth
  • Stripe billing (checkout, customer portal, webhooks, SMS usage invoices)
  • no Docker-based local runtime

What it does

Public booking

  • Embeddable booking page per tenant (/book/:tenantSlug) — services, staff, locations, real availability
  • Customer self-service via manage token: view, reschedule, and cancel bookings
  • Class sessions with capacity and waitlists — customers see their waitlist position
  • Structured intake fields per service (text / yes-no, required flag), asked at booking time and shown to staff

Dashboard

  • Calendar with day-level booking modals, bookings, customers, staff, services, locations, working hours, blocked days
  • Recurring class schedules — weekly rules that materialize sessions 28 days ahead
  • Waitlist management — capacity-aware promotion, session-to-session moves
  • Staff performance metrics — bookings, completion/cancellation, revenue, capacity-based utilization
  • CSV exports — bookings, customers, staff and service reports
  • Activity feed — persistent notification center with a per-user read cursor
  • ICS calendar feeds — read-only tenant and staff feeds with token rotation
  • CS/EN localization throughout

Platform

  • Stripe subscriptions (monthly/yearly, CZK/USD), customer portal, webhooks
  • Email reminders; optional SMS add-on via SMS Manager.cz, metered through Stripe invoices
  • Admin API for tenant/plan operations

Workspace

  • apps/frontend — SolidJS frontend
  • apps/backend — Go API (Gin, pgx, Goose migrations)
  • packages/api-client — generated TypeScript client/types from OpenAPI
  • packages/shared-types — shared frontend constants and helpers

Local development

Frontend

npm install
npm run dev:frontend

Runs on http://localhost:3000.

Backend

cd apps/backend
go run ./cmd/api

Runs on http://localhost:8080.

Both apps expect remote services when not in demo mode:

  • Neon Postgres
  • Neon Auth
  • Stripe

See apps/frontend/.env.example and apps/backend/.env.example for the full variable list.

Demo mode

Set BOOKRA_DEMO_MODE=true to run the backend with an in-memory repository and pre-populated demo data — no database, Neon Auth, or Stripe required. All requests are authenticated as the demo-owner principal. Pair with VITE_BOOKRA_DEMO_MODE=true on the frontend. The seeded demo tenant slug is studio-atelier; its public page is /book/studio-atelier.

CI/CD

Backend database commands

npm run db:migrate:status
npm run db:migrate:up

db:migrate:* expects BOOKRA_DATABASE_DIRECT_URL to be exported in the shell.

The API client types are regenerated from the OpenAPI spec:

npm run generate:api-client

Verification

npm run verify

Runs API-client generation, frontend typecheck, backend tests, and both builds. Run this before pushing.

Design system

Bookra uses a warm, editorial palette implemented as CSS custom properties in apps/frontend/src/styles/index.css, with light and dark themes.

Surfaces

  • Canvas: warm cream hsl(40 25% 97%) light / dark counterpart per theme
  • Canvas elevated/subtle/sunken: stepped warm neutrals

Ink (text)

  • Ink: hsl(25 15% 12%) — primary text
  • Ink muted: hsl(25 10% 42%)
  • Ink subtle: hsl(25 8% 58%)

Accent

  • Accent: hsl(17 55% 42%) — deep warm terracotta
  • Accent hover/active/subtle/soft/muted: stepped variants

Semantic

  • Success hsl(145 45% 38%), Warning hsl(38 80% 50%), Error hsl(0 60% 52%), Info hsl(210 60% 50%)

Typography

  • Space Grotesk — display/headings
  • Newsreader — serif accents
  • DM Sans — UI body
  • JetBrains Mono — code/mono

Motion

  • Ease out expo: cubic-bezier(0.16, 1, 0.3, 1)
  • Ease spring: cubic-bezier(0.68, -0.55, 0.265, 1.55)

Roadmap

Milestone history and the curated future-phase shortlist live in project.md.

S
Description
No description provided
Readme
4.9 MiB
0 Stars 1 Watchers 0 Forks
Languages
TypeScript 55.3%
Go 43%
CSS 1%
JavaScript 0.5%
HTML 0.2%