Tomáš DvořákandDevin 1cd14046de chore(tooling): oxlint + oxfmt frontend, lefthook gate, govulncheck (#21)
- apps/frontend: oxlint 1.85 (typescript/unicorn/oxc — no react rules,
  SolidJS), oxfmt scripts; lint script now oxlint && tsc --noEmit
- backend: gofmt; bump x/text 0.39.0, quic-go 0.59.1, pgx 5.9.2
  (govulncheck 0 reachable vulns, was 3)
- ci: go vet + govulncheck in Go job (frontend job already gates via
  lint:frontend)
- lefthook pre-push: frontend lint + gofmt + vet/test + gitleaks

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-26 16:41:35 +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 — bookra-frontend serves www.bookra.eu (landing only, pre-launch: signup CTAs are mailto and app routes redirect to /); bookrademo serves demo.bookra.eu (full app). The split is enforced by hostname in apps/frontend/src/lib/app-host.ts.
  • 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%