Files
Bookra/README.md
T
Tomáš DvořákandDevin 7a31f55f81
CI / Frontend (push) Canceled after 0s
CI / Go - apps/backend (push) Canceled after 0s
CI / Docker publish - backend (push) Canceled after 0s
feat(site): landing-only on www, app gated to demo subdomain (#20)
* feat(site): landing-only on www host, app gated to demo subdomain

- RequireAppHost redirects app routes to / on non-demo hosts
- Signup CTAs swapped for launch-notification mailto on www
- Pricing marked as indicative pre-launch, no subscription purchasable
- SEO: OG/Twitter cards, og.png, JSON-LD, robots.txt, sitemap.xml,
  per-route document titles, SPA rewrite for Vercel

Authored By: TDvorak <[email protected]>

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

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore: ignore vercel link artifacts

Authored By: TDvorak <[email protected]>

* docs: document www/demo host split in deployment targets

Authored By: TDvorak <[email protected]>

---------

Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-25 16:20:05 +02:00

166 lines
4.7 KiB
Markdown

# 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
```bash
npm install
npm run dev:frontend
```
Runs on `http://localhost:3000`.
### Backend
```bash
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
- GitHub Actions CI lives in [`.github/workflows/ci.yml`](/home/tdvorak/Desktop/PROG+HTML/Bookra/.github/workflows/ci.yml:1)
- rollout notes and platform wiring live in [docs/ci-cd.md](/home/tdvorak/Desktop/PROG+HTML/Bookra/docs/ci-cd.md:1)
## Backend database commands
```bash
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:
```bash
npm run generate:api-client
```
## Verification
```bash
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](/home/tdvorak/Desktop/PROG+HTML/Bookra/project.md).