Documents the shift planning and closure/payroll modules (new tables,
routes, stores), the dark redesign, and the docker-compose-broken-host
workaround. Adds CLAUDE.md pointing agents at docs/. Translates README to
English and keeps host-specific infrastructure details out of the repo.
Bookable shift slots (a date + time range + headcount capacity), generated from a weekly template or created ad hoc by the admin.
backend/src/db/index.ts
data-model
sqlite
shift-planning
2026-08-16T00:00:00Z
shift_slots
Schema
Column
Type
Description
id
INTEGER PK
autoincrement
date
TEXT
YYYY-MM-DD
start_time / end_time
TEXT
HH:MM; end_time <= start_time means the slot rolls past midnight
capacity
INTEGER
headcount
status
TEXT
open | full | closed — recomputed from capacity vs. approved signups on every change
note
TEXT
free text
generated
INTEGER
1 if created by the weekly template, 0 if manually added by the admin
created_at / updated_at
TEXT
ISO 8601 UTC
UNIQUE (date, start_time, end_time) — this is what makes template
generation idempotent (INSERT OR IGNORE).
Weekly template
ensureSlotsForPeriod (backend/src/services/shiftPlanning.ts) generates a
whole calendar month lazily, the first time anyone (employee or admin)
requests that period — not on a cron schedule. There's no scheduler in this
app, and lazy + idempotent is simpler and just as reliable as the source
system's Apps Script monthly trigger
(createShiftPlanningTrigger_ in gscript/ShiftPlanningService.js, which
could only fire in a coarse hourly window).
Day
Slots
Sun–Thu
18:00–23:00, capacity 1
Fri, Sat
18:00–02:00, capacity 1 and 20:00–00:00, capacity 1
The two Friday/Saturday slots deliberately overlap in time — a real
scheduling choice from the source bistro (an early shift and a late shift),
not a bug. It's also exactly what the collision test in
backend/src/services/shiftPlanning.test.ts exercises.