Tomas DvorakandDevin 5c860a1264 feat: data surfacing — intake labels, service metrics, honest capacity
- booking views gain intakeLabels (declared key→label join); dashboard
  modal + manage view render real question labels with slug fallback
- GET /v1/metrics/services aggregates bookings/completed/cancelled/
  revenue per service + classBookings; service-report.csv delegates to
  the same ServiceMetrics aggregation and gains a completed column
- services page gains a Service performance card (per-service stat grid,
  locale CZK revenue, class-bookings footer); demo rows match the
  fabricated service list
- staff capacity utilization subtracts blocked days — tenant-wide and
  staff-scoped blocks remove that day's rule minutes via blockedAt
- tests: blocked-day capacity (tenant + staff scope), service aggregation

Authored By: TDvorak <[email protected]>

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

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 20:25:32 +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%