Unified Sessions Model Deep Dive
1. One-Sentence Version
Voyage models appointments, walk-ins, and event registrations as one operational work unit: a service_sessions row with a polymorphic source_type, shared occupancy fields, and shared lifecycle semantics. workers/staff-feed/src/db/schema.sql:1-69; workers/staff-feed/src/engine/state-machine.ts:1-54; ../voyage-bank/docs/architecture/unified-session-architecture.md:5-20
2. The Problem JRNI Solved Imperfectly
JRNI has real scheduling machinery, but its concepts evolved as separate operational products rather than one staff-time model. ../bookingbug/app/models/slot.rb:5-38; ../bookingbug/app/models/event.rb:3-19; ../bookingbug/app/models/queuing/queuer.rb:1-20
JRNI appointments are centered on Slot and Space. ../bookingbug/app/models/slot.rb:5-38; ../bookingbug/app/models/space.rb:5-47
JRNI events are centered on Event and session-oriented event helpers. ../bookingbug/app/models/event.rb:3-19; ../bookingbug/app/models/event.rb:171-189
JRNI queueing is centered on Queuing::Queuer. ../bookingbug/app/models/queuing/queuer.rb:1-20
Those models touch staff time, but they do not expose one canonical occupancy row. ../bookingbug/app/models/person.rb:736-839; ../bookingbug/lib/scheduler/bookable.rb:37-46; ../bookingbug/app/models/queuing/queuer.rb:189-224
JRNI's appointment scheduler combines schedule and booked slot bitsets. ../bookingbug/lib/scheduler/bookable.rb:37-46
JRNI's appointment conflict scan checks overlapping Slot rows by person and resource. ../bookingbug/lib/services/validation/booking_conflicts.rb:81-133
JRNI's appointment persistence also checks slot space before accepting a booking. ../bookingbug/app/models/slot.rb:1596-1608; ../bookingbug/app/models/slot.rb:1674-1681
JRNI's queue runtime has its own current-serving implementation. ../bookingbug/app/models/queuing/queuer.rb:189-224; ../bookingbug/app/models/queuing/queuer.rb:273-314; ../bookingbug/app/models/queuing/queuer.rb:343-345
JRNI's queue runtime moves a staff member into a busy attendance state. ../bookingbug/app/models/queuing/queuer.rb:189-208
JRNI's appointment runtime uses generic Space multi-status timestamps. ../bookingbug/app/models/space.rb:2563-2612
JRNI's appointment model exposes current multi-status as metadata, not as a unified service-session lifecycle. ../bookingbug/app/models/space.rb:2628-2659
JRNI's Person object keeps queue-serving and booked-slot capacity as different queries. ../bookingbug/app/models/person.rb:736-839
JRNI's event model gets calendar booking details through slot helpers. ../bookingbug/app/models/event.rb:174-189
JRNI's event model still depends on the event-specific Event abstraction for event identity. ../bookingbug/app/models/event.rb:3-19
JRNI's slot status enum includes appointment, waitlist, held, queue, and externally-created states inside one legacy slot status space. ../bookingbug/app/models/slot.rb:44-73
That status enum is not the same thing as one operational lifecycle because queue serving still has queue-specific transitions. ../bookingbug/app/models/queuing/queuer.rb:189-224; ../bookingbug/app/models/queuing/queuer.rb:273-314
JRNI reports reflect the split. ../bookingbug/lib/tasks/report_templates.rake:1-70
JRNI booking reports export booking fields and multi-status fields. ../bookingbug/lib/tasks/report_templates.rake:1-23
JRNI queue reports export queue wait and service timings. ../bookingbug/lib/tasks/report_templates.rake:37-58
JRNI event reports export event/session ticket fields. ../bookingbug/lib/tasks/report_templates.rake:61-70
JRNI's richer queue analytics compute wait time, service time, and turnaround time from queue multi-status events. ../bookingbug/lib/search/payload_builder/queuer.rb:20-48; ../bookingbug/lib/search/payload_builder/queuer.rb:84-133
The operational pain is therefore not that JRNI lacks all overlap controls. ./docs/analysis/jrni-overlap-handling.md:7-12
The operational pain is that staff-time truth is distributed across appointments, event sessions, queue entries, attendance, and reports. ../bookingbug/app/models/person.rb:736-839; ../bookingbug/lib/tasks/report_templates.rake:1-70
An operator asking "what is this staff member doing now?" gets a queue answer from queue state. ../bookingbug/app/models/queuing/queuer.rb:189-224; ../bookingbug/app/models/person.rb:736-750
An operator asking "what is this staff member booked for?" gets a slot answer from scheduled bookings. ../bookingbug/lib/scheduler/bookable.rb:37-46; ../bookingbug/app/models/person.rb:791-839
An operator asking "what event work is this staff member supporting?" gets an event/session answer through event-specific data. ../bookingbug/app/models/event.rb:91-113; ../bookingbug/app/models/event.rb:174-189
Those answers can be reconciled, but they are not born reconciled. ../bookingbug/app/models/person.rb:736-839; ../bookingbug/lib/tasks/report_templates.rake:1-70
Voyage's differentiator is that the reconciliation step is removed from the operator's mental model. workers/staff-feed/src/db/schema.sql:1-69; workers/staff-feed/src/routes/feed.ts:29-123
3. The Voyage Model
Voyage makes service_sessions the canonical operational record for customer-facing work. workers/staff-feed/src/db/schema.sql:1-69; ../voyage-bank/docs/architecture/unified-session-architecture.md:5-20
The source records still exist. workers/booking/src/db/schema.sql:22-59; workers/events/src/db/schema.sql:1-58; workers/queue/src/db/schema.sql:1-35
The source records answer "how this interaction entered the system." ../voyage-bank/docs/architecture/unified-session-architecture.md:5-8
The session row answers "what occupies staff time now." workers/staff-feed/src/db/schema.sql:1-69; ../voyage-bank/docs/architecture/unified-session-architecture.md:5-8
The session row is polymorphic through source_type. workers/staff-feed/src/db/schema.sql:9-10; workers/staff-feed/src/types.ts:38-53
The accepted source types are appointment, walkin, and event. workers/staff-feed/src/db/schema.sql:9-10; workers/staff-feed/src/types.ts:38
Appointments point to bookings through source_type = 'appointment' and source_id = booking.id. workers/booking/src/routes/checkout.ts:400-432; workers/booking/src/routes/check-in.ts:192-235
Walk-ins point to queue_entries through source_type = 'walkin' and source_id = entry.id. workers/queue/src/routes/entries.ts:914-945
Event registrations point to event_registrations through source_type = 'event' and source_id = registration.id. workers/events/src/session-sync.ts:77-136
The session table carries customer identity, staff assignment, service identity, planned time, actual timestamps, queue position, status, notes, and priority in one row. workers/staff-feed/src/db/schema.sql:1-64
The session table indexes staff/status, company/date, source, queue position, and finish time. workers/staff-feed/src/db/schema.sql:65-69
The staff status table points at the current session. workers/staff-feed/src/db/schema.sql:71-89
The note table attaches notes to a session rather than to only bookings or only queue entries. workers/staff-feed/src/db/schema.sql:91-101
The audit table records session transitions, trigger identity, effects fired, effect results, context, duration, and version. workers/staff-feed/src/db/schema.sql:103-123
The session type includes the same operational fields in TypeScript. workers/staff-feed/src/types.ts:44-75
The staff feed response returns a current session, a feed, a schedule, and staff status together. workers/staff-feed/src/types.ts:117-122
The schedule block type is derived from source_type. workers/staff-feed/src/routes/feed.ts:15-19
The staff feed query reads from service_sessions, not from three independent APIs. workers/staff-feed/src/routes/feed.ts:29-53
The staff schedule query also reads from service_sessions. workers/staff-feed/src/routes/feed.ts:71-87
The staff schedule emits unified TimeBlock objects for appointments, walk-ins, and events. workers/staff-feed/src/routes/feed.ts:89-113
The transition engine validates all session transitions with one state machine. workers/staff-feed/src/engine/state-machine.ts:1-54; workers/staff-feed/src/engine/transition.ts:74-115
The transition engine writes status changes with optimistic version checks. workers/staff-feed/src/engine/transition.ts:117-132
The transition engine executes configured effects after the state update. workers/staff-feed/src/engine/transition.ts:134-214
The transition engine always writes a session audit log entry. workers/staff-feed/src/engine/transition.ts:219-259
Effects can synchronize the source record after a session transition. workers/staff-feed/src/engine/effects/update-source-record.ts:4-100
Effects can update staff busy/available state from the session transition. workers/staff-feed/src/engine/effects/update-staff-status.ts:3-54
This is the architectural merger: one session type, one occupancy vocabulary, one state machine, and source-specific edge records only where the business domain needs them. workers/staff-feed/src/db/schema.sql:1-123; workers/staff-feed/src/engine/state-machine.ts:1-54; workers/staff-feed/src/engine/effects/update-source-record.ts:27-86
4. Concrete Schema
4.1 Canonical Session Row
service_sessions.id is the primary key for the operational work unit. workers/staff-feed/src/db/schema.sql:1-2
company_id scopes the session to the tenant/company operational boundary. workers/staff-feed/src/db/schema.sql:2-4
staff_id is nullable because a session can be waiting before assignment. workers/staff-feed/src/db/schema.sql:3-4; workers/staff-feed/src/assignment-candidates.ts:73-80
customer_id is nullable because a walk-in can be anonymous at queue join. workers/staff-feed/src/db/schema.sql:4-8; workers/queue/src/routes/entries.ts:914-945
customer_name, customer_email, and customer_phone put staff-facing identity on the session row. workers/staff-feed/src/db/schema.sql:5-8
source_type is constrained to appointment, walk-in, or event. workers/staff-feed/src/db/schema.sql:9
source_id links back to the source record. workers/staff-feed/src/db/schema.sql:10
service_id and service_name normalize the staff-facing service label onto the session. workers/staff-feed/src/db/schema.sql:11-12
estimated_duration_minutes gives every source a comparable occupancy length. workers/staff-feed/src/db/schema.sql:13
scheduled_at captures scheduled work. workers/staff-feed/src/db/schema.sql:14
checked_in_at captures arrival. workers/staff-feed/src/db/schema.sql:15
called_at captures call-forward for assigned queue work. workers/staff-feed/src/db/schema.sql:16; workers/staff-feed/src/routes/assignment.ts:687-697
started_serving_at captures actual service start. workers/staff-feed/src/db/schema.sql:17; workers/staff-feed/src/routes/actions.ts:125-129
finished_at captures actual service completion. workers/staff-feed/src/db/schema.sql:18; workers/staff-feed/src/routes/actions.ts:201-205
token_number and queue_position support queue semantics without making queue the only session type. workers/staff-feed/src/db/schema.sql:19-20; workers/queue/src/routes/entries.ts:914-945
status is constrained to the shared lifecycle vocabulary. workers/staff-feed/src/db/schema.sql:21-36
start_utc, end_utc, and timezone carry calendar-grade time windows. workers/staff-feed/src/db/schema.sql:37-39
booking_ref and hold_id preserve appointment checkout context. workers/staff-feed/src/db/schema.sql:40-41; workers/booking/src/routes/checkout.ts:400-432
version supports optimistic concurrency. workers/staff-feed/src/db/schema.sql:42; workers/staff-feed/src/engine/transition.ts:101-132
booking_questions_json and outcome_questions_json attach configurable input/output answers to the session. workers/staff-feed/src/db/schema.sql:43-44
staff_notes attaches operational notes to the session. workers/staff-feed/src/db/schema.sql:45
arrived_via distinguishes entry channel without fragmenting the model. workers/staff-feed/src/db/schema.sql:46-54
booking_type carries modality. workers/staff-feed/src/db/schema.sql:55-59
priority gives assignment and feed sorting a cross-source ranking input. workers/staff-feed/src/db/schema.sql:60; workers/staff-feed/src/assignment-candidates.ts:90-100
wait_time_notified_at supports queue wait notifications without moving queue work out of sessions. workers/staff-feed/src/db/schema.sql:61
created_at and updated_at are present on the canonical row. workers/staff-feed/src/db/schema.sql:62-63
4.2 Occupancy Representation
Voyage represents occupancy as time intervals on sessions plus blocking status. workers/staff-feed/src/db/schema.sql:13-18; workers/staff-feed/src/routes/assignment.ts:310-347
For scheduled appointments, the interval comes from start_utc/end_utc or scheduled_at plus duration. workers/booking/src/routes/checkout.ts:400-432; workers/staff-feed/src/routes/feed.ts:89-113
For walk-ins being served, the interval comes from started_serving_at plus estimated duration until completion. workers/queue/src/routes/entries.ts:362-370; workers/staff-feed/src/routes/feed.ts:89-113
For event registrations, the interval comes from the event's start_utc and end_utc. workers/events/src/session-sync.ts:110-136; workers/events/src/session-sync.ts:167-191
The assignment code converts each session into a comparable window. workers/staff-feed/src/routes/assignment.ts:322-347
being_served sessions block from now or start through estimated duration. workers/staff-feed/src/routes/assignment.ts:330-333
Waiting and checked-in sessions can be treated as immediate candidate windows. workers/staff-feed/src/routes/assignment.ts:334-337
Assigned sessions use scheduled or start time. workers/staff-feed/src/routes/assignment.ts:338-341
Other scheduled sessions use start, scheduled, now, end, and duration fallback. workers/staff-feed/src/routes/assignment.ts:342-346
Staff assignment excludes candidates when the proposed window overlaps any blocking session for that staff member. workers/staff-feed/src/routes/assignment.ts:387-451
Auto-assignment uses the same overlap logic across source types. workers/staff-feed/src/routes/assignment.ts:516-620
The reporting utilization endpoint also constructs occupancy intervals from appointments, walk-ins, and events. workers/reporting/src/routes/reports.ts:836-950
The reporting endpoint computes peak concurrent sessions from those intervals with 5-minute buckets. workers/reporting/src/routes/reports.ts:986-1004
4.3 Source Records Still Exist
Bookings still have holds, customer references, staff/resource, status, check-in code, and booking reference. workers/booking/src/db/schema.sql:1-59
Event records still have event capacity, waitlist capacity, location, staff, status, and settings. workers/events/src/db/schema.sql:1-24
Event registrations still have ticket type, customer, registration status, attendance status, check-in code, and attendee count. workers/events/src/db/schema.sql:36-58
Queue records still have queue configuration. workers/queue/src/db/schema.sql:1-11
Queue entries still have ticket, position, queue status, staff, wait estimate, and timestamps. workers/queue/src/db/schema.sql:13-35
Those source records carry domain-specific facts. workers/booking/src/db/schema.sql:1-59; workers/events/src/db/schema.sql:1-58; workers/queue/src/db/schema.sql:1-35
The session row carries the operational timeline fact. workers/staff-feed/src/db/schema.sql:1-69
This is collapse of operational vocabulary, not deletion of domain data. workers/staff-feed/src/engine/effects/update-source-record.ts:27-86; workers/events/src/session-sync.ts:115-136; workers/queue/src/routes/entries.ts:896-945
5. The Scheduling Engine
Voyage's shared schedule engine uses 5-minute quanta. packages/schedule-engine/src/constants.ts:1-5
TIME_QUANTUM_MINUTES is 5. packages/schedule-engine/src/constants.ts:1
QUANTA_PER_DAY is 24 * (60 / 5), which is 288. packages/schedule-engine/src/constants.ts:1-5
The bitset implementation stores occupancy/availability in a compact Uint32Array. packages/schedule-engine/src/bitset.ts:1-8
The bitset supports setting and reading individual quanta. packages/schedule-engine/src/bitset.ts:44-58
The bitset supports and, or, not, and andNot operations. packages/schedule-engine/src/bitset.ts:60-100
The bitset supports contiguous chunk extraction. packages/schedule-engine/src/bitset.ts:130-146
The bitset supports conversion to and from binary strings. packages/schedule-engine/src/bitset.ts:10-18; packages/schedule-engine/src/bitset.ts:148-154
The schedule engine exports the constants and bitset primitives through the package entry point. packages/schedule-engine/src/index.ts:1-13
The availability slot finder imports Bitset, QUANTA_PER_DAY, TIME_QUANTUM_MINUTES, and buffer helpers from the shared package. workers/availability/src/services/slot-finder.ts:1-6
Time strings are converted to quanta by dividing minutes by TIME_QUANTUM_MINUTES. workers/availability/src/services/slot-finder.ts:39-45
Quanta are converted back to UTC timestamps for slot output. workers/availability/src/services/slot-finder.ts:47-52
Schedule segments become a day bitset with 288 possible quanta. workers/availability/src/services/slot-finder.ts:59-75
Overrides can remove availability from that bitset. workers/availability/src/services/slot-finder.ts:77-95
Overrides can also add availability into that bitset. workers/availability/src/services/slot-finder.ts:96-109
Bookings and active holds are converted into blocking bits. workers/availability/src/services/slot-finder.ts:112-146
Blocking booking statuses include confirmed, pending, completed, active, held, reserved, blocked, booked, and queued. workers/availability/src/services/slot-finder.ts:21-31
Available slots are extracted by scanning for contiguous true quanta for the requested duration. workers/availability/src/services/slot-finder.ts:148-178
Lead time removes early quanta before customer-facing slot extraction. workers/availability/src/services/slot-finder.ts:180-213
Service config supplies duration, granularity, lead time, horizon, buffers, staff/resource requirements, and slot capacity. workers/availability/src/services/slot-finder.ts:215-233
Schedule rules and segments are loaded from config DB. workers/availability/src/services/slot-finder.ts:235-267
Availability overrides are loaded from config DB and expanded across the requested date range. workers/availability/src/services/slot-finder.ts:269-360
Existing bookings are loaded from ops DB for the requested staff/resource and time range. workers/availability/src/services/slot-finder.ts:362-385
Active holds are loaded from ops DB for the requested staff/resource and time range. workers/availability/src/services/slot-finder.ts:387-415
Slot search caps requests at the service booking horizon. workers/availability/src/services/slot-finder.ts:430-442
Slot search converts duration, granularity, and buffers into quanta. workers/availability/src/services/slot-finder.ts:444-447
Slot search chooses staff, resource, or company as the schedule entity. workers/availability/src/services/slot-finder.ts:449-475
If a service requires staff and no staff is specified, slot search expands across active staff schedules. workers/availability/src/services/slot-finder.ts:454-467
For each entity and day, slot search builds schedule bits, applies overrides, subtracts bookings and holds, applies buffers, applies lead time, and extracts slots. workers/availability/src/services/slot-finder.ts:482-565
The buffer helper removes pre/post quanta from contiguous availability chunks. packages/schedule-engine/src/buffer-time.ts:9-40
The next-slot helper searches batches until it finds the first future available slot. workers/availability/src/services/slot-finder.ts:568-600
The scheduling engine is not appointment-only in its primitives. packages/schedule-engine/src/constants.ts:7-31
Its status constants include queue and external-calendar occupancy statuses. packages/schedule-engine/src/constants.ts:7-31
Its availability-affecting status set includes reserved, blocked, booked, held, queue, and externally created work. packages/schedule-engine/src/constants.ts:24-31
This matters because the occupancy model and the slot engine share the same scheduling vocabulary for blocking statuses and time-based occupancy windows. packages/schedule-engine/src/constants.ts:1-31; workers/staff-feed/src/routes/assignment.ts:322-345
6. Operational Flow A: Appointment Booking
Appointment booking starts with an availability-derived hold. workers/booking/src/routes/holds.ts:1-17
The hold table stores slot start, slot end, staff, resource, active status, and expiry. workers/booking/src/db/schema.sql:1-20
Hold creation rejects overlapping active holds. workers/booking/src/routes/holds.ts:44-63
Hold creation rejects overlapping non-terminal bookings. workers/booking/src/routes/holds.ts:64-82
Hold creation persists a time-bounded reservation_holds row. workers/booking/src/routes/holds.ts:90-126
Checkout converts holds into bookings. workers/booking/src/routes/checkout.ts:326-368
The booking row stores the customer, service, company, hold, start/end time, duration, staff/resource, status, reference, and check-in code. workers/booking/src/routes/checkout.ts:326-362
Checkout updates the hold to converted. workers/booking/src/routes/checkout.ts:364-368
Checkout creates a service_sessions row for the appointment immediately after creating the booking. workers/booking/src/routes/checkout.ts:400-432
The appointment session sets source_type = 'appointment'. workers/booking/src/routes/checkout.ts:403-410
The appointment session points source_id at the booking id. workers/booking/src/routes/checkout.ts:412-431
The appointment session carries scheduled start/end, timezone, status, arrival channel, booking reference, hold id, booking type, priority, and version. workers/booking/src/routes/checkout.ts:403-431
Confirmed appointment bookings queue booking notifications. workers/booking/src/routes/checkout.ts:525-551
Confirmed appointment bookings schedule reminders. workers/booking/src/routes/checkout.ts:552-578
Confirmed appointment bookings can notify calendar sync using the session id. workers/booking/src/routes/checkout.ts:583-590
Public check-in finds the booking by check-in code. workers/booking/src/routes/check-in.ts:85-100
Public check-in validates lifecycle transition into checked_in. workers/booking/src/routes/check-in.ts:103-116
Public check-in enforces a configurable check-in window. workers/booking/src/routes/check-in.ts:118-148
Public check-in updates the booking to checked in. workers/booking/src/routes/check-in.ts:150-154
Public check-in updates the existing appointment session if it exists. workers/booking/src/routes/check-in.ts:192-203
Public check-in creates the appointment session if the booking predates session creation. workers/booking/src/routes/check-in.ts:204-235
Staff start-serving updates the session to being_served. workers/staff-feed/src/routes/actions.ts:90-129
Staff start-serving prevents a staff member from serving two sessions at the same time. workers/staff-feed/src/routes/actions.ts:113-123
Staff start-serving syncs appointment sessions back to booking status. workers/staff-feed/src/routes/actions.ts:138-143
Staff finish-serving updates the session to completed. workers/staff-feed/src/routes/actions.ts:179-205
Staff finish-serving syncs appointment completion back to booking status. workers/staff-feed/src/routes/actions.ts:214-219
The shared transition effect layer can also sync appointment statuses back to bookings. workers/staff-feed/src/engine/effects/update-source-record.ts:27-48
The appointment flow therefore produces both a booking source record and a unified session record. workers/booking/src/routes/checkout.ts:335-432
The booking source record handles checkout, customer, reference, and booking-specific policy. workers/booking/src/db/schema.sql:22-59
The session record handles occupancy, assignment, serving, notes, and timeline. workers/staff-feed/src/db/schema.sql:1-101; workers/staff-feed/src/routes/feed.ts:71-123
7. Operational Flow B: Walk-In Queue Entry
Queue join begins with a public queue endpoint. workers/queue/src/routes/entries.ts:802-839
The queue must exist and be open. workers/queue/src/routes/entries.ts:809-823
The queue policy computes capacity before a new entry is accepted. workers/queue/src/routes/entries.ts:845-876; workers/queue/src/queue-policy.ts:163-244
The queue flow deduplicates recently recoverable active entries. workers/queue/src/routes/entries.ts:848-867
The queue flow assigns the next queue position. workers/queue/src/routes/entries.ts:878-885
The queue flow calculates an estimated wait from policy and current waiting count. workers/queue/src/routes/entries.ts:845-885
The queue flow creates a queue_entries row. workers/queue/src/routes/entries.ts:896-912
The queue flow immediately creates a service_sessions row. workers/queue/src/routes/entries.ts:914-945
The walk-in session sets source_type = 'walkin'. workers/queue/src/routes/entries.ts:914-945
The walk-in session points source_id at the queue entry id. workers/queue/src/routes/entries.ts:914-945
The walk-in session carries service label, estimated duration, check-in time, token number, queue position, status, arrival channel, and priority. workers/queue/src/routes/entries.ts:914-945
A queue entry can be assigned to staff. workers/queue/src/routes/entries.ts:629-676
Assignment validates staff eligibility for the service. workers/queue/src/routes/entries.ts:171-189; workers/queue/src/routes/entries.ts:283-315
Assignment rejects staff already serving or assigned active work. workers/queue/src/routes/entries.ts:191-217; workers/queue/src/routes/entries.ts:306-315
queue_next assignment updates the walk-in session to assigned. workers/queue/src/routes/entries.ts:317-341
serve_now assignment updates the queue entry and walk-in session to being_served. workers/queue/src/routes/entries.ts:342-370
Starting a called queue entry updates both queue entry and session to being_served. workers/queue/src/routes/entries.ts:383-436
Starting service updates staff status to busy and current session. workers/queue/src/routes/entries.ts:108-134; workers/queue/src/routes/entries.ts:438-443
Completing a walk-in updates queue entry and session completion timestamps. workers/queue/src/routes/entries.ts:457-499
Completing a walk-in clears staff status. workers/queue/src/routes/entries.ts:136-148; workers/queue/src/routes/entries.ts:495-499
Completing a priced walk-in can create an order and order item. workers/queue/src/routes/entries.ts:501-565
No-show updates both the queue entry and the walk-in session. workers/queue/src/routes/entries.ts:578-626
Returning a walk-in to the queue resets queue and session fields together. workers/queue/src/routes/entries.ts:678-748
Leaving a queue marks the queue entry as left and the walk-in session as cancelled. workers/queue/src/routes/entries.ts:751-799
Queue outcome answers write to service_sessions, not only to queue rows. workers/queue/src/routes/staff.ts:94-166
Queue availability windows combine bookings and active service sessions to find staff gaps. workers/queue/src/routes/availability-windows.ts:54-115
Queue availability windows emit "available for walk-ins" blocks between busy blocks. workers/queue/src/routes/availability-windows.ts:117-191
The walk-in flow therefore keeps the queue-specific ticket/position record while treating service delivery as the same session lifecycle used by appointments. workers/queue/src/db/schema.sql:13-35; workers/queue/src/routes/entries.ts:914-945; workers/staff-feed/src/engine/state-machine.ts:1-54
8. Operational Flow C: Event Registration
Events carry event-level capacity and waitlist capacity. workers/events/src/db/schema.sql:1-24
Event registrations carry customer, ticket, registration status, attendance status, check-in code, and attendee count. workers/events/src/db/schema.sql:36-58
Event registration preview prevents duplicate active registrations for the same customer and event. workers/events/src/registration-core.ts:94-107
Event registration preview reads computed event state before accepting capacity. workers/events/src/registration-core.ts:109-120
Computed event state reads ticket types, registrations, and active holds. workers/events/src/event-runtime.ts:173-182
Computed event state counts active confirmed and waitlisted registrations. workers/events/src/event-runtime.ts:184-187
Computed event state includes extra attendees when calculating consumed capacity. workers/events/src/event-runtime.ts:189-193
Computed event state calculates ticket-level availability. workers/events/src/event-runtime.ts:195-217
Computed event state calculates event-level remaining spots and waitlist spots. workers/events/src/event-runtime.ts:227-229
Computed event state decides whether registration is open, waitlist-only, full, closed, completed, cancelled, draft, or started. workers/events/src/event-runtime.ts:231-270
Registration creation inserts the event registration. workers/events/src/registration-core.ts:212-237
Registration creation verifies concurrent capacity after insert when batch support exists. workers/events/src/registration-core.ts:239-268
Registration creation creates an order and payment intent for paid confirmed tickets. workers/events/src/registration-core.ts:273-322
Registration creation then upserts the event session. workers/events/src/registration-core.ts:324-338
The event session status is derived from registration and attendance status. workers/events/src/session-sync.ts:17-23
Waitlisted registrations become waitlisted sessions. workers/events/src/session-sync.ts:17-23; workers/events/src/session-sync.ts:88-95
Confirmed registered attendees become scheduled sessions. workers/events/src/session-sync.ts:17-23
Checked-in or attended event registrations become checked-in sessions. workers/events/src/session-sync.ts:17-23
Cancelled or no-show event registrations become cancelled/no-show sessions. workers/events/src/session-sync.ts:17-23
Event session staff is resolved from per-registration staffing assignments or event fallback staff. workers/events/src/session-sync.ts:25-39
Event session upsert preserves explicitly assigned staff for assigned and being-served states. workers/events/src/session-sync.ts:41-59
Event session duration is computed from event start and end. workers/events/src/session-sync.ts:110-113
Event session metadata captures event id, registration ref, ticket type, registration status, attendance status, attendee count, and assignment source. workers/events/src/session-sync.ts:115-123
Event session upsert inserts or updates service_sessions using source_type = 'event' and source_id = registration.id. workers/events/src/session-sync.ts:128-191
Event waitlist promotion updates the registration, upserts the session, and notifies calendar sync. workers/events/src/event-runtime.ts:297-399
Event cancellation marks the related session cancelled. workers/events/src/session-sync.ts:227-244
Staff-feed event mutation sync can update registration attendance and event staffing assignments from a session. workers/staff-feed/src/event-sync.ts:3-63; workers/staff-feed/src/event-sync.ts:65-111
The shared transition effect can sync event sessions back to event registration and staffing state. workers/staff-feed/src/engine/effects/update-source-record.ts:71-86
The event flow therefore keeps event capacity and ticket semantics, but each attendee's operational occupancy is represented as a session. workers/events/src/db/schema.sql:1-58; workers/events/src/session-sync.ts:77-191
9. Operational Flow D: Reassignment And Overrun Handling
Voyage reassigns sessions, not just bookings. workers/staff-feed/src/routes/actions.ts:296-370; workers/staff-feed/src/routes/assignment.ts:808-913
The simple staff action reassigns a session by updating service_sessions.staff_id and setting status to assigned. workers/staff-feed/src/routes/actions.ts:300-343
The simple staff action rejects reassignment for completed, no-show, and cancelled sessions. workers/staff-feed/src/routes/actions.ts:322-337
The simple staff action syncs appointment reassignment to bookings.staff_id. workers/staff-feed/src/routes/actions.ts:345-351
The simple staff action syncs walk-in reassignment to queue_entries.staff_id. workers/staff-feed/src/routes/actions.ts:352-357
The simple staff action syncs event reassignment through event session mutation. workers/staff-feed/src/routes/actions.ts:358-364
The assignment console exposes assignable sessions across appointment, walk-in, and event sources. workers/staff-feed/src/routes/sessions.ts:9-29; workers/staff-feed/src/assignment-candidates.ts:38-83
Assignable statuses include waiting in queue, waiting, checked in, scheduled, and confirmed. workers/staff-feed/src/assignment-candidates.ts:4-12
Assignable sessions are selected from service_sessions with staff_id IS NULL. workers/staff-feed/src/assignment-candidates.ts:73-80
Assignable sessions can be filtered by source types, defaulting to all three. workers/staff-feed/src/assignment-candidates.ts:38-49
Assignable appointment sessions are filtered out when the backing booking is already staff-locked. workers/staff-feed/src/assignment-candidates.ts:108-120
The assignment endpoint accepts source_types = all or a set of appointment, walk-in, and event. workers/staff-feed/src/routes/assignment.ts:349-355; workers/staff-feed/src/routes/assignment.ts:460-465
The assignment rules support fifo, round_robin, performance_weighted, value_optimized, and balanced. workers/staff-feed/src/routes/assignment.ts:8-20; workers/reporting/src/db/schema.sql:43-53
The two-sided value optimizer ranks staff and customers by score. workers/staff-feed/src/routes/assignment.ts:106-150
FIFO assignment preserves queue/order position. workers/staff-feed/src/routes/assignment.ts:152-183
Round-robin assignment uses assignment history. workers/staff-feed/src/routes/assignment.ts:185-223; workers/staff-feed/src/routes/assignment.ts:650-663
Performance-weighted assignment ranks staff by score. workers/staff-feed/src/routes/assignment.ts:225-260
Balanced assignment blends FIFO position and score. workers/staff-feed/src/routes/assignment.ts:262-308
Staff performance scores include conversion rate, rating, completion rate, speed efficiency, revenue per session, and composite score. workers/reporting/src/db/schema.sql:17-28; workers/staff-feed/src/routes/assignment.ts:22-33
Customer value scores include lifetime value, visit frequency, recency, tier, tenure, and composite score. workers/reporting/src/db/schema.sql:30-41; workers/staff-feed/src/routes/assignment.ts:35-46
Auto-assignment loads candidate sessions from all selected source types. workers/staff-feed/src/routes/assignment.ts:491-499
Auto-assignment excludes staff on break, offline, or in meeting. workers/staff-feed/src/routes/assignment.ts:504-515
Auto-assignment loads blocking sessions from service_sessions, regardless of source type. workers/staff-feed/src/routes/assignment.ts:516-525
Auto-assignment groups blocking sessions by staff. workers/staff-feed/src/routes/assignment.ts:527-532
Auto-assignment enforces service-staff eligibility. workers/staff-feed/src/routes/assignment.ts:534-553; workers/staff-feed/src/routes/assignment.ts:592-620
Auto-assignment creates allowed-staff sets by checking cross-source occupancy overlap. workers/staff-feed/src/routes/assignment.ts:582-620
Auto-assignment rejects the request if no staff is available for any candidate. workers/staff-feed/src/routes/assignment.ts:636-641
Auto-assignment persists matches by updating service_sessions to assigned. workers/staff-feed/src/routes/assignment.ts:682-697
Auto-assignment syncs walk-in matches to queue entries. workers/staff-feed/src/routes/assignment.ts:705-714
Auto-assignment syncs event matches to event staffing. workers/staff-feed/src/routes/assignment.ts:716-724
Auto-assignment syncs appointment matches to bookings. workers/staff-feed/src/routes/assignment.ts:726-735
Auto-assignment writes assignment history with strategy and scores. workers/staff-feed/src/routes/assignment.ts:738-751
The assignable-staff endpoint computes available staff for one session using the same occupancy windows. workers/staff-feed/src/routes/assignment.ts:773-805
Manual reassignment validates the target staff against the same availability function. workers/staff-feed/src/routes/assignment.ts:831-860
Manual reassignment updates service_sessions, then source-specific records. workers/staff-feed/src/routes/assignment.ts:862-902
Overrun handling is represented by actual service timestamps and unified busy checks. workers/staff-feed/src/db/schema.sql:15-18; workers/staff-feed/src/routes/actions.ts:90-177
A staff member cannot start a second service while a being_served session exists. workers/staff-feed/src/routes/actions.ts:113-123
Assignment excludes staff whose existing session window overlaps the candidate window. workers/staff-feed/src/routes/assignment.ts:420-451
Reporting flags overbooking when peak concurrent session count exceeds one. workers/reporting/src/routes/reports.ts:986-1004
This is one reassignment and overrun vocabulary for all three operational sources. workers/staff-feed/src/routes/assignment.ts:349-355; workers/staff-feed/src/routes/assignment.ts:516-620; workers/staff-feed/src/routes/assignment.ts:705-735
10. The Staff Timeline
The staff-feed worker exposes the unified timeline. workers/staff-feed/src/routes/feed.ts:21-123
The feed endpoint is keyed by staff id and date. workers/staff-feed/src/routes/feed.ts:21-27
The feed query reads sessions assigned to the staff member or not yet assigned. workers/staff-feed/src/routes/feed.ts:29-37
The feed query includes scheduled sessions, checked-in sessions, and currently-served sessions. workers/staff-feed/src/routes/feed.ts:29-37
The feed query orders active work before future work and terminal work. workers/staff-feed/src/routes/feed.ts:38-50
The endpoint separates the currently served session from the remaining feed. workers/staff-feed/src/routes/feed.ts:55-63
The endpoint reads staff status from the same ops DB. workers/staff-feed/src/routes/feed.ts:65-69
The endpoint builds a schedule from session rows. workers/staff-feed/src/routes/feed.ts:71-87
The schedule includes assigned or being-served walk-ins as timeline blocks. workers/staff-feed/src/routes/feed.ts:71-87
The schedule maps source types to block types. workers/staff-feed/src/routes/feed.ts:15-19; workers/staff-feed/src/routes/feed.ts:102-112
The schedule block start prefers scheduled time, then start time, then service start, then check-in, then creation. workers/staff-feed/src/routes/feed.ts:89-96
The schedule block end prefers end time, then finish time, then estimated duration. workers/staff-feed/src/routes/feed.ts:97-100
The schedule block title uses customer and service name. workers/staff-feed/src/routes/feed.ts:102-108
The response returns currently_serving, feed, schedule, and staff_status. workers/staff-feed/src/routes/feed.ts:115-123
Voyage Bank's design names UTO-backed staff timelines as a first-viewport proof point. ../voyage-bank/docs/architecture/voyage-bank-design.md:7-13
Voyage Bank's design states that service_sessions remains the canonical occupancy table. ../voyage-bank/docs/architecture/voyage-bank-design.md:325-332
Voyage Bank's design states that appointments, walk-ins, and events write into the same occupancy table. ../voyage-bank/docs/architecture/voyage-bank-design.md:325-332
Voyage Bank's design states that branch dashboards, staff timelines, assignment logic, and routing consume that occupancy table. ../voyage-bank/docs/architecture/voyage-bank-design.md:325-332
Voyage Bank's staff app uses the feed schedule to render the day timeline. ../voyage-bank/apps/staff-pages/src/pages/Today.tsx:133-173; ../voyage-bank/apps/staff-pages/src/pages/Today.tsx:307-309
Voyage Bank's timeline component distinguishes event blocks from other blocks. ../voyage-bank/apps/staff-pages/src/components/DayTimeline.tsx:72-72
Voyage Bank's schedule card has filters for all, appointment, event, and queue. ../voyage-bank/apps/staff-pages/src/components/ScheduleCard.tsx:7-18; ../voyage-bank/apps/staff-pages/src/components/ScheduleCard.tsx:212-244
The staff timeline is not a UI join across three product feeds. workers/staff-feed/src/routes/feed.ts:29-123
The staff timeline is a projection of session occupancy. workers/staff-feed/src/db/schema.sql:1-69; workers/staff-feed/src/routes/feed.ts:71-113
11. Reporting And Analytics
The baseline reporting schema includes staff performance scores. workers/reporting/src/db/schema.sql:17-28
The baseline reporting schema includes customer value scores. workers/reporting/src/db/schema.sql:30-41
The baseline reporting schema includes assignment rules. workers/reporting/src/db/schema.sql:43-53
The baseline reporting schema includes assignment history keyed to session id. workers/reporting/src/db/schema.sql:55-69
The reporting unified-session helper pulls appointments from bookings, walk-ins from queue entries, and event sessions from service_sessions. workers/reporting/src/routes/reports.ts:240-260; workers/reporting/src/routes/reports.ts:271-327
The unified-session response exposes total session count and counts by source. workers/reporting/src/routes/reports.ts:325-338
Utilization reporting includes booked appointments. workers/reporting/src/routes/reports.ts:632-643
Utilization reporting includes walk-in sessions from service_sessions. workers/reporting/src/routes/reports.ts:635-658
Deeper staff reporting tracks per-staff by_source counts for appointment, walk-in, and event. workers/reporting/src/routes/reports.ts:836-855
Appointment metrics add appointment count, minutes, and occupancy intervals. workers/reporting/src/routes/reports.ts:862-886
Walk-in metrics add walk-in count, minutes, and occupancy intervals. workers/reporting/src/routes/reports.ts:888-920
Event metrics add event count, minutes, and occupancy intervals. workers/reporting/src/routes/reports.ts:922-950
Staff utilization is computed as served minutes over available minutes. workers/reporting/src/routes/reports.ts:972-984
Staff overbooking is computed from peak concurrent occupancy intervals. workers/reporting/src/routes/reports.ts:986-1004
The activity monitor reads recent activity from service_sessions. workers/reporting/src/routes/activity-monitor.ts:193-208
The activity monitor aggregates branch sessions using service-session-derived counts. workers/reporting/src/routes/activity-monitor.ts:247-295
The activity monitor emits recent session activity from the unified session rows. workers/reporting/src/routes/activity-monitor.ts:297-310
Customer analytics uses fact_customer_conversion for one customer conversion population. workers/reporting/src/routes/customer-analytics.ts:60-120
Voyage Bank's reporting schema declares rollups driven by service_sessions.updated_at. ../voyage-bank/workers/reporting/src/db/meridian-reporting-schema.sql:183-221
Voyage Bank's branch-day rollup sources bookings, queue entries, event registrations, service sessions, and orders. ../voyage-bank/workers/reporting/src/db/meridian-reporting-schema.sql:183-191
Voyage Bank's branch-hour rollup sources service sessions and queue entries. ../voyage-bank/workers/reporting/src/db/meridian-reporting-schema.sql:193-201
Voyage Bank's staff-day rollup sources service sessions, staff assignments, and customer feedback. ../voyage-bank/workers/reporting/src/db/meridian-reporting-schema.sql:203-211
Voyage Bank's service-day rollup sources service sessions, orders, and booking cancellations. ../voyage-bank/workers/reporting/src/db/meridian-reporting-schema.sql:213-221
Voyage Bank's branch-day summary view joins queue and service-session rollups. ../voyage-bank/workers/reporting/src/db/meridian-reporting-schema.sql:370-400
The reporting direction is therefore one session fact spine with source-specific enrichments. workers/reporting/src/routes/reports.ts:836-950; ../voyage-bank/workers/reporting/src/db/meridian-reporting-schema.sql:183-221
12. Why This Is The Linchpin Differentiator
The unification changes the operator's primitive from "booking/event/queue" to "occupied staff time." workers/staff-feed/src/db/schema.sql:1-69; workers/staff-feed/src/routes/feed.ts:71-123
It removes a reconciliation job from daily branch operations. workers/staff-feed/src/routes/feed.ts:29-123
It makes one staff timeline possible without product-specific timeline joins. workers/staff-feed/src/routes/feed.ts:89-123
It makes one assignment engine possible across scheduled and immediate work. workers/staff-feed/src/routes/assignment.ts:349-355; workers/staff-feed/src/routes/assignment.ts:491-499
It makes one occupancy exclusion algorithm possible across appointments, events, and walk-ins. workers/staff-feed/src/routes/assignment.ts:516-620
It makes one reassignment command vocabulary possible across all three source types. workers/staff-feed/src/routes/assignment.ts:808-913
It makes one actual-service lifecycle possible across all three source types. workers/staff-feed/src/engine/state-machine.ts:20-35; workers/staff-feed/src/routes/actions.ts:90-238
It makes one audit log possible for session transitions. workers/staff-feed/src/db/schema.sql:103-123; workers/staff-feed/src/engine/transition.ts:219-259
It makes one reporting spine possible for staff utilization. workers/reporting/src/routes/reports.ts:836-950
It makes overbooking detection source-agnostic. workers/reporting/src/routes/reports.ts:986-1004
It makes staff/customer scoring useful beyond queues. workers/staff-feed/src/routes/assignment.ts:555-577; workers/staff-feed/src/routes/assignment.ts:622-631
It makes event attendance operationally visible to staff, not just to event reports. workers/events/src/session-sync.ts:77-191; workers/staff-feed/src/routes/feed.ts:71-113
It makes walk-ins calendar-addressable through session sync payloads. workers/queue/src/session-calendar-sync.ts:4-26; workers/queue/src/session-calendar-sync.ts:28-90
It makes appointments runtime-addressable through being_served, finished_at, and staff status. workers/staff-feed/src/routes/actions.ts:90-238
It lets source systems keep their real differences while the branch floor uses one operational truth. workers/booking/src/db/schema.sql:22-59; workers/events/src/db/schema.sql:1-58; workers/queue/src/db/schema.sql:1-35; workers/staff-feed/src/db/schema.sql:1-69
The differentiator is not that Voyage can book appointments. workers/booking/src/routes/checkout.ts:326-432
The differentiator is not that Voyage can run queues. workers/queue/src/routes/entries.ts:802-956
The differentiator is not that Voyage can register events. workers/events/src/registration-core.ts:176-345
The differentiator is that all three become one branch-time occupancy graph. workers/staff-feed/src/routes/feed.ts:71-123; workers/staff-feed/src/routes/assignment.ts:516-620; workers/reporting/src/routes/reports.ts:836-950
13. What We Did Not Collapse
Voyage does not collapse appointment checkout into generic sessions. workers/booking/src/db/schema.sql:1-59; workers/booking/src/routes/checkout.ts:326-432
Appointments still need holds. workers/booking/src/db/schema.sql:1-20; workers/booking/src/routes/holds.ts:44-126
Appointments still need booking references and check-in codes. workers/booking/src/db/schema.sql:22-59
Appointments still need booking questions and attendees. workers/booking/src/db/schema.sql:96-137; workers/booking/src/routes/checkout.ts:370-395
Voyage does not collapse event capacity into generic sessions. workers/events/src/db/schema.sql:1-24; workers/events/src/event-runtime.ts:173-270
Events still need ticket types. workers/events/src/db/schema.sql:25-35
Events still need registration-level status and attendance status. workers/events/src/db/schema.sql:36-58
Events still need waitlist capacity and promotion rules. workers/events/src/event-runtime.ts:227-270; workers/events/src/event-runtime.ts:297-399
Events still need per-registration session sync because one event can have many registrants. workers/events/src/session-sync.ts:77-191
Voyage does not collapse queues into generic sessions. workers/queue/src/db/schema.sql:1-35
Queues still need queue definitions and queue policies. workers/queue/src/db/schema.sql:1-11; workers/queue/src/queue-policy.ts:104-244
Queues still need ticket numbers and positions. workers/queue/src/db/schema.sql:13-35; workers/queue/src/routes/entries.ts:878-945
Queues still need public board and position endpoints. workers/queue/src/routes/entries.ts:958-1065
Voyage does not collapse payments into sessions. workers/booking/src/db/schema.sql:216-240; workers/queue/src/routes/entries.ts:501-565; workers/events/src/registration-core.ts:273-322
Voyage does not collapse notification preferences into sessions. workers/booking/src/routes/checkout.ts:525-578; workers/staff-feed/src/engine/effects/send-notification.ts:163-180
Voyage does not collapse calendar provider details into sessions. workers/booking/src/session-calendar-sync.ts:33-126; workers/events/src/session-calendar-sync.ts:28-101; workers/queue/src/session-calendar-sync.ts:28-90
Voyage does not collapse service eligibility into sessions. workers/staff-feed/src/routes/assignment.ts:406-418; workers/staff-feed/src/routes/assignment.ts:534-553
Voyage does not collapse staff break/offline status into sessions. workers/staff-feed/src/db/schema.sql:71-89; workers/queue/src/routes/staff.ts:168-268
The merger is scoped to operational occupancy and lifecycle. workers/staff-feed/src/db/schema.sql:1-123; workers/staff-feed/src/engine/state-machine.ts:1-54
Domain-specific records remain where they carry real domain semantics. workers/booking/src/db/schema.sql:1-240; workers/events/src/db/schema.sql:1-147; workers/queue/src/db/schema.sql:1-49
This anti-hype boundary matters because the model is powerful precisely where the concepts are the same: staff time, customer arrival, service start, service finish, assignment, and reporting. workers/staff-feed/src/db/schema.sql:13-20; workers/staff-feed/src/routes/actions.ts:41-370; workers/reporting/src/routes/reports.ts:836-950
14. Implementation Notes By Source Type
14.1 Appointment Source Contract
Source table: bookings. workers/booking/src/db/schema.sql:22-59
Session source type: appointment. workers/booking/src/routes/checkout.ts:403-410
Session source id: booking id. workers/booking/src/routes/checkout.ts:412-431
Planned start: hold slot start. workers/booking/src/routes/checkout.ts:423-425
Planned end: hold slot end. workers/booking/src/routes/checkout.ts:423-425
Duration: calculated from hold start/end. workers/booking/src/routes/checkout.ts:326-331
Staff: copied from hold. workers/booking/src/routes/checkout.ts:349-350; workers/booking/src/routes/checkout.ts:413-416
Customer: copied from checkout customer. workers/booking/src/routes/checkout.ts:340-342; workers/booking/src/routes/checkout.ts:416-418
Status: copied from booking status at checkout. workers/booking/src/routes/checkout.ts:351-357; workers/booking/src/routes/checkout.ts:426-431
Check-in sync: booking and session both move to checked in. workers/booking/src/routes/check-in.ts:150-235
Serving sync: session start updates booking to being_served. workers/staff-feed/src/routes/actions.ts:138-143
Completion sync: session finish updates booking to completed. workers/staff-feed/src/routes/actions.ts:214-219
Effect sync: transition effect can update checked-in, being-served, completed, cancelled, and no-show. workers/staff-feed/src/engine/effects/update-source-record.ts:27-48
14.2 Walk-In Source Contract
Source table: queue_entries. workers/queue/src/db/schema.sql:13-35
Session source type: walkin. workers/queue/src/routes/entries.ts:930-931
Session source id: queue entry id. workers/queue/src/routes/entries.ts:930-932
Arrival timestamp: queue join time and session checked-in time. workers/queue/src/routes/entries.ts:896-945
Queue token: queue ticket number and session token number. workers/queue/src/routes/entries.ts:887-945
Queue position: queue entry position and session queue position. workers/queue/src/routes/entries.ts:878-945
Service duration: copied from service config or queue fallback. workers/queue/src/routes/entries.ts:74-96; workers/queue/src/routes/entries.ts:890-945
Assignment sync: queue entry and session update together. workers/queue/src/routes/entries.ts:317-341
Serve-now sync: queue entry and session update to being served together. workers/queue/src/routes/entries.ts:342-370
Completion sync: queue entry and session update to completed together. workers/queue/src/routes/entries.ts:457-499
Return-to-queue sync: queue entry and session both return to waiting state. workers/queue/src/routes/entries.ts:678-748
Effect sync: transition effect can update waiting, being-served, completed, no-show, and cancelled queue states. workers/staff-feed/src/engine/effects/update-source-record.ts:49-70
14.3 Event Source Contract
Source table: event_registrations. workers/events/src/db/schema.sql:36-58
Event table: events. workers/events/src/db/schema.sql:1-24
Session source type: event. workers/events/src/session-sync.ts:128-136
Session source id: registration id. workers/events/src/session-sync.ts:128-136; workers/events/src/session-sync.ts:167-191
Planned start: event start. workers/events/src/session-sync.ts:128-136; workers/events/src/session-sync.ts:179-187
Planned end: event end. workers/events/src/session-sync.ts:128-136; workers/events/src/session-sync.ts:185-187
Duration: event end minus event start. workers/events/src/session-sync.ts:110-113
Staff: resolved from event staffing assignments or event fallback staff. workers/events/src/session-sync.ts:25-39
Status: derived from registration and attendance status. workers/events/src/session-sync.ts:17-23
Capacity: stays event-level and registration-level. workers/events/src/event-runtime.ts:173-270
Waitlist promotion: updates registration and upserts session. workers/events/src/event-runtime.ts:297-399
Effect sync: transition effect can update event assignment and attendance state. workers/staff-feed/src/engine/effects/update-source-record.ts:71-86
15. State Vocabulary
pending is a pre-confirmed session state. workers/staff-feed/src/engine/state-machine.ts:1-21
confirmed can move to scheduled, checked in, cancelled, rescheduled, or no-show. workers/staff-feed/src/engine/state-machine.ts:20-23
scheduled can move to checked in, cancelled, rescheduled, or no-show. workers/staff-feed/src/engine/state-machine.ts:22-23
checked_in can move to waiting, waiting in queue, assigned, being served, cancelled, or no-show. workers/staff-feed/src/engine/state-machine.ts:24
waiting can move to assigned, being served, cancelled, no-show, or transferred. workers/staff-feed/src/engine/state-machine.ts:25
waiting_in_queue can move to assigned, being served, cancelled, no-show, or transferred. workers/staff-feed/src/engine/state-machine.ts:26
assigned can move to being served, waiting, waiting in queue, cancelled, no-show, or transferred. workers/staff-feed/src/engine/state-machine.ts:27
being_served can move to completed, cancelled, transferred, or waiting in queue. workers/staff-feed/src/engine/state-machine.ts:28
waitlisted can move to confirmed or cancelled. workers/staff-feed/src/engine/state-machine.ts:29
rescheduled can move to confirmed, scheduled, or cancelled. workers/staff-feed/src/engine/state-machine.ts:30
transferred can move to waiting, waiting in queue, assigned, or being served. workers/staff-feed/src/engine/state-machine.ts:31
completed, no_show, and cancelled are terminal. workers/staff-feed/src/engine/state-machine.ts:32-35
The state machine validates both status names and transitions. workers/staff-feed/src/engine/state-machine.ts:37-54
The transition route exposes the state machine as an API. workers/staff-feed/src/routes/transition.ts:14-62
The transition route exposes per-session audit logs. workers/staff-feed/src/routes/transition.ts:64-84
The transition route exposes company-scoped audit search by session, from status, and to status. workers/staff-feed/src/routes/transition.ts:86-126
This lifecycle is broader than queue-only states. workers/queue/src/state-machine.ts:3-20; workers/staff-feed/src/engine/state-machine.ts:1-54
This lifecycle is broader than booking-only states. packages/booking-state/src/index.ts:6-19; workers/staff-feed/src/engine/state-machine.ts:1-54
16. Calendar Sync
Appointment session calendar payloads use session id, company id, staff id, source type, source id, status, customer, service, location, start/end, timezone, and buffers. workers/booking/src/session-calendar-sync.ts:1-23; workers/booking/src/session-calendar-sync.ts:128-176
Appointment calendar sync only proceeds when a staff id exists and an active calendar connection exists. workers/booking/src/session-calendar-sync.ts:33-56; workers/booking/src/session-calendar-sync.ts:102-126
Appointment calendar sync posts to Exchange and Google/internal sync endpoints. workers/booking/src/session-calendar-sync.ts:58-99
Event session calendar payloads use the same payload shape. workers/events/src/session-calendar-sync.ts:4-26; workers/events/src/session-calendar-sync.ts:52-69
Event session calendar sync posts to Exchange and Google/internal sync endpoints. workers/events/src/session-calendar-sync.ts:71-97
Walk-in session calendar payloads use the same payload shape. workers/queue/src/session-calendar-sync.ts:4-26; workers/queue/src/session-calendar-sync.ts:41-58
Walk-in session calendar sync posts to Exchange and Google/internal sync endpoints. workers/queue/src/session-calendar-sync.ts:60-86
Calendar sync is therefore source-aware but session-shaped. workers/booking/src/session-calendar-sync.ts:159-176; workers/events/src/session-calendar-sync.ts:52-69; workers/queue/src/session-calendar-sync.ts:41-58
17. Read Path Contracts
The primary staff read model starts from service_sessions. workers/staff-feed/src/routes/feed.ts:29-67
The feed endpoint reads current sessions by tenant, branch, status, and optional staff filters. workers/staff-feed/src/routes/feed.ts:29-67
The feed endpoint treats waiting, checked_in, and in_progress as current operational work. workers/staff-feed/src/routes/feed.ts:29-67; workers/staff-feed/src/engine/state-machine.ts:1-12
The feed endpoint treats scheduled rows as future work. workers/staff-feed/src/routes/feed.ts:69-93; workers/staff-feed/src/engine/state-machine.ts:1-12
The feed endpoint uses start_time ordering for schedule presentation. workers/staff-feed/src/routes/feed.ts:69-93
The feed endpoint returns both feed and schedule arrays from the same session table. workers/staff-feed/src/routes/feed.ts:95-123
The feed response type names those arrays as session arrays. workers/staff-feed/src/types.ts:117-122
The feed response includes staff status beside the session arrays. workers/staff-feed/src/types.ts:117-122; workers/staff-feed/src/db/schema.sql:71-89
The staff status table stores the current session id directly. workers/staff-feed/src/db/schema.sql:71-89
The staff status table stores availability and last activity timestamps separately from source records. workers/staff-feed/src/db/schema.sql:71-89
The staff status table is therefore a projection of session execution state, not a booking table. workers/staff-feed/src/db/schema.sql:71-89; workers/staff-feed/src/engine/effects/update-staff-status.ts:3-54
The staff status effect sets staff to busy when a session enters in_progress. workers/staff-feed/src/engine/effects/update-staff-status.ts:16-33
The staff status effect clears the current session when a session finishes, is marked no-show, or is cancelled. workers/staff-feed/src/engine/effects/update-staff-status.ts:35-54
The assignment candidate reader selects from service_sessions, not from three source queues. workers/staff-feed/src/assignment-candidates.ts:38-123
The assignment candidate reader groups appointment, walk-in, and event rows through source_type. workers/staff-feed/src/assignment-candidates.ts:38-123; workers/staff-feed/src/types.ts:38-53
The assignment candidate reader uses session status to find work needing attention. workers/staff-feed/src/assignment-candidates.ts:38-123; workers/staff-feed/src/engine/state-machine.ts:1-12
The assignment candidate reader keeps source metadata available without letting source tables drive the operational list. workers/staff-feed/src/assignment-candidates.ts:38-123
The assignment route loads a session before computing staff candidates. workers/staff-feed/src/routes/assignment.ts:349-451
The assignment route uses the same session branch, tenant, service, and timing fields for staff matching. workers/staff-feed/src/routes/assignment.ts:363-451
The assignment route excludes staff with overlapping active sessions. workers/staff-feed/src/routes/assignment.ts:363-451
The assignment route treats overlap as session overlap, not as booking-only overlap. workers/staff-feed/src/routes/assignment.ts:363-451; workers/staff-feed/src/db/schema.sql:1-69
The assignment route computes available candidates from assignment strategies and occupancy checks. workers/staff-feed/src/routes/assignment.ts:349-770
The manual reassignment route updates session ownership through the session row. workers/staff-feed/src/routes/assignment.ts:808-913
The manual reassignment route records reassignment in the session audit trail. workers/staff-feed/src/routes/assignment.ts:808-913; workers/staff-feed/src/db/schema.sql:103-123
The action routes call session transitions rather than updating source status in isolation. workers/staff-feed/src/routes/actions.ts:90-238; workers/staff-feed/src/engine/transition.ts:74-271
The action routes expose start, finish, no-show, and reassignment operations as session actions. workers/staff-feed/src/routes/actions.ts:90-238; workers/staff-feed/src/routes/actions.ts:300-370
The transition engine reloads the session row before applying lifecycle changes. workers/staff-feed/src/engine/transition.ts:74-133
The transition engine validates the transition against the shared state machine. workers/staff-feed/src/engine/transition.ts:1-72; workers/staff-feed/src/engine/state-machine.ts:14-54
The transition engine updates timestamps according to the target status. workers/staff-feed/src/engine/transition.ts:134-196
The transition engine uses optimistic version checks on the session row. workers/staff-feed/src/engine/transition.ts:197-221; workers/staff-feed/src/db/schema.sql:55-56
The transition engine runs effects after the session update. workers/staff-feed/src/engine/transition.ts:223-257
The transition engine writes an audit row for each accepted transition. workers/staff-feed/src/engine/transition.ts:259-271; workers/staff-feed/src/db/schema.sql:103-123
The source update effect maps session state back to bookings. workers/staff-feed/src/engine/effects/update-source-record.ts:27-45
The source update effect maps session state back to queue entries. workers/staff-feed/src/engine/effects/update-source-record.ts:47-66
The source update effect maps session state back to event registrations. workers/staff-feed/src/engine/effects/update-source-record.ts:68-86
The source update effect proves the model is not a one-way ETL copy. workers/staff-feed/src/engine/effects/update-source-record.ts:27-86; workers/staff-feed/src/engine/transition.ts:223-257
The reporting worker reads sessions as the shared operational fact. workers/reporting/src/db/schema.sql:17-69; workers/reporting/src/routes/reports.ts:836-1004
The reporting schema mirrors the session source type and lifecycle timestamps. workers/reporting/src/db/schema.sql:17-69
The reporting schema stores started_at, completed_at, and no_show_at in the same table. workers/reporting/src/db/schema.sql:17-69
The utilization report groups by source_type. workers/reporting/src/routes/reports.ts:836-1004
The utilization report detects overlapping sessions from one fact table. workers/reporting/src/routes/reports.ts:836-1004
The activity monitor reads recent operational activity from service sessions. workers/reporting/src/routes/activity-monitor.ts:193-310
The customer analytics route reads customer session history from service sessions. workers/reporting/src/routes/customer-analytics.ts:60-120
The branch summary view in the tenant UI consumes session rollups, not separate queue and appointment views. ../voyage-bank/docs/architecture/voyage-bank-design.md:370-400
The tenant reporting design keys refreshes off service_sessions.updated_at. ../voyage-bank/docs/architecture/voyage-bank-design.md:183-221
The tenant design names service_sessions as the canonical occupancy table. ../voyage-bank/docs/architecture/voyage-bank-design.md:325-332
The tenant design says appointments, walk-ins, and events write into that table. ../voyage-bank/docs/architecture/voyage-bank-design.md:325-332
The tenant design says dashboards, timelines, assignment, and routing consume that table. ../voyage-bank/docs/architecture/voyage-bank-design.md:325-332
The UTO spec frames the same read contract as one single timeline. docs/architecture/unified-time-occupancy-spec.md:31-40
The UTO spec ties the single timeline to calendars, utilization, assignment, and reporting. docs/architecture/unified-time-occupancy-spec.md:31-40
The practical result is one read model for "what is occupying staff time." workers/staff-feed/src/routes/feed.ts:29-123; workers/reporting/src/routes/reports.ts:836-1004
18. Write Path Contracts
Appointment checkout creates the source booking first. workers/booking/src/routes/checkout.ts:326-399
Appointment checkout then creates the session row for the booking. workers/booking/src/routes/checkout.ts:400-432
Appointment checkout sets the session source_type to appointment. workers/booking/src/routes/checkout.ts:400-432
Appointment checkout sets the session source_id to the booking id. workers/booking/src/routes/checkout.ts:400-432; workers/booking/src/db/schema.sql:242-300
Appointment checkout copies branch, service, staff, customer, start, end, and status into the session row. workers/booking/src/routes/checkout.ts:400-432; workers/booking/src/db/schema.sql:242-300
Appointment checkout preserves booking-specific fields on the booking row. workers/booking/src/db/schema.sql:22-59; workers/booking/src/routes/checkout.ts:326-399
Appointment checkout therefore has two records with different responsibilities. workers/booking/src/routes/checkout.ts:326-432; ../voyage-bank/docs/architecture/unified-session-architecture.md:5-20
Appointment holds remain hold records, not sessions. workers/booking/src/routes/holds.ts:44-126; workers/booking/src/db/schema.sql:1-20
Appointment holds affect availability before a confirmed session exists. workers/booking/src/routes/holds.ts:44-126; workers/availability/src/services/slot-finder.ts:430-565
Appointment check-in updates an existing session when one already exists. workers/booking/src/routes/check-in.ts:192-235
Appointment check-in creates a missing session when the booking lacks one. workers/booking/src/routes/check-in.ts:192-235
Appointment check-in maps the booking into checked_in session state. workers/booking/src/routes/check-in.ts:192-235; workers/staff-feed/src/engine/state-machine.ts:1-12
Appointment check-in keeps the source booking status aligned. workers/booking/src/routes/check-in.ts:85-191; workers/staff-feed/src/engine/effects/update-source-record.ts:27-45
Walk-in queue join creates the source queue entry first. workers/queue/src/routes/entries.ts:802-913
Walk-in queue join then creates the session row. workers/queue/src/routes/entries.ts:914-945
Walk-in queue join sets the session source_type to walkin. workers/queue/src/routes/entries.ts:914-945
Walk-in queue join sets the session source_id to the queue entry id. workers/queue/src/routes/entries.ts:914-945; workers/queue/src/db/schema.sql:103-141
Walk-in queue join starts from queue-specific customer and reason fields. workers/queue/src/routes/entries.ts:802-913; workers/queue/src/db/schema.sql:1-35
Walk-in queue join translates queue-specific fields into session occupancy fields. workers/queue/src/routes/entries.ts:914-945; workers/queue/src/db/schema.sql:103-141
Walk-in queue join gives immediate work the same operational table as future appointments. workers/queue/src/routes/entries.ts:914-945; workers/booking/src/routes/checkout.ts:400-432
Walk-in "serve now" updates the queue entry and the session. workers/queue/src/routes/entries.ts:317-370
Walk-in completion updates the queue entry and the session. workers/queue/src/routes/entries.ts:457-499
Walk-in return-to-queue updates the queue entry lifecycle and session state. workers/queue/src/routes/entries.ts:678-748
Walk-in leave removes the active queue obligation through queue and session updates. workers/queue/src/routes/entries.ts:751-799
Queue staff endpoints read and update queue-serving state in terms compatible with sessions. workers/queue/src/routes/staff.ts:94-166; workers/queue/src/routes/staff.ts:168-268
Event registration creates the source registration through event-specific capacity checks. workers/events/src/registration-core.ts:94-244
Event registration computes order and payment information outside the session row. workers/events/src/registration-core.ts:245-345
Event registration then syncs a session for operational occupancy. workers/events/src/registration-core.ts:245-345; workers/events/src/session-sync.ts:77-191
Event session sync sets source_type to event. workers/events/src/session-sync.ts:77-191
Event session sync uses the registration id as source_id. workers/events/src/session-sync.ts:77-191; workers/events/src/db/schema.sql:148-216
Event session sync is explicitly idempotent. workers/events/src/session-sync.ts:77-191
Event session sync checks for an existing session before insertion. workers/events/src/session-sync.ts:77-127
Event session sync updates existing session rows when registration data changes. workers/events/src/session-sync.ts:128-191
Event session sync uses a uniqueness constraint for event registration sessions. workers/events/src/db/schema.sql:212-216
Event capacity remains event-specific. workers/events/src/event-runtime.ts:173-270
Event runtime computes capacity before a registration becomes operational occupancy. workers/events/src/event-runtime.ts:173-270; workers/events/src/registration-core.ts:94-244
Event runtime stores capacity and waitlist semantics outside service_sessions. workers/events/src/db/schema.sql:1-58; workers/events/src/event-runtime.ts:173-270
Event runtime can still expose active sessions as sessions. workers/events/src/event-runtime.ts:297-399
The write contract is therefore "source first, session projection second." ../voyage-bank/docs/architecture/unified-session-architecture.md:5-20; workers/booking/src/routes/checkout.ts:326-432
The source-first pattern preserves domain details. workers/booking/src/db/schema.sql:22-59; workers/events/src/db/schema.sql:1-58; workers/queue/src/db/schema.sql:1-35
The session-projection pattern gives operations one table to act on. workers/staff-feed/src/db/schema.sql:1-69; workers/staff-feed/src/routes/feed.ts:21-123
The booking worker owns booking-specific creation. workers/booking/src/routes/checkout.ts:326-432; ../voyage-bank/docs/architecture/unified-session-architecture.md:43-51
The queue worker owns queue-specific creation. workers/queue/src/routes/entries.ts:802-956; ../voyage-bank/docs/architecture/unified-session-architecture.md:43-51
The events worker owns event-specific creation. workers/events/src/registration-core.ts:94-345; ../voyage-bank/docs/architecture/unified-session-architecture.md:43-51
The staff-feed worker owns cross-source operational execution. workers/staff-feed/src/engine/transition.ts:74-271; ../voyage-bank/docs/architecture/unified-session-architecture.md:43-51
19. Field Semantics
id is the session identity used by staff feed and transitions. workers/staff-feed/src/db/schema.sql:2-3; workers/staff-feed/src/types.ts:44-75
tenant_id scopes sessions to the tenant boundary. workers/staff-feed/src/db/schema.sql:4-5; workers/staff-feed/src/routes/feed.ts:29-67
branch_id scopes sessions to the branch timeline. workers/staff-feed/src/db/schema.sql:6-7; workers/staff-feed/src/routes/feed.ts:29-93
source_type is the discriminator for appointment, walk-in, and event origin. workers/staff-feed/src/db/schema.sql:9-10; workers/staff-feed/src/types.ts:38
source_id points back to the source record. workers/staff-feed/src/db/schema.sql:11-12; workers/staff-feed/src/types.ts:44-75
source_id points to bookings.id for appointment sessions. workers/booking/src/routes/checkout.ts:400-432; workers/booking/src/db/schema.sql:22-59
source_id points to queue_entries.id for walk-in sessions. workers/queue/src/routes/entries.ts:914-945; workers/queue/src/db/schema.sql:1-35
source_id points to event_registrations.id for event sessions. workers/events/src/session-sync.ts:77-191; workers/events/src/db/schema.sql:148-216
customer_id is nullable because queue and event flows can carry different customer certainty. workers/staff-feed/src/db/schema.sql:14-15; workers/queue/src/db/schema.sql:1-35; workers/events/src/db/schema.sql:148-216
customer_name gives staff timeline presentation a direct display value. workers/staff-feed/src/db/schema.sql:16-17; workers/staff-feed/src/types.ts:44-75
customer_email gives notification and staff contexts a direct contact field. workers/staff-feed/src/db/schema.sql:18-19; workers/staff-feed/src/types.ts:44-75
customer_phone gives walk-in and appointment contexts a direct contact field. workers/staff-feed/src/db/schema.sql:20-21; workers/staff-feed/src/types.ts:44-75
service_id is nullable because not every session origin requires the same service catalog path. workers/staff-feed/src/db/schema.sql:23-24; workers/events/src/db/schema.sql:1-58
service_name preserves the operational label shown in timelines. workers/staff-feed/src/db/schema.sql:25-26; workers/staff-feed/src/types.ts:44-75
staff_id stores the assigned staff member for the session. workers/staff-feed/src/db/schema.sql:28-29; workers/staff-feed/src/routes/assignment.ts:808-913
staff_name stores the assigned staff display label. workers/staff-feed/src/db/schema.sql:30-31; workers/staff-feed/src/types.ts:44-75
resource_id stores resource occupancy when a resource is involved. workers/staff-feed/src/db/schema.sql:33-34; workers/availability/src/services/slot-finder.ts:430-565
resource_name stores the resource display label. workers/staff-feed/src/db/schema.sql:35-36; workers/staff-feed/src/types.ts:44-75
start_time is the planned or effective start boundary used by feed and reporting. workers/staff-feed/src/db/schema.sql:38-39; workers/staff-feed/src/routes/feed.ts:69-93
end_time is the planned or effective end boundary used for occupancy. workers/staff-feed/src/db/schema.sql:40-41; workers/staff-feed/src/routes/assignment.ts:363-451
estimated_duration_minutes carries expected effort for queue and assignment flows. workers/staff-feed/src/db/schema.sql:42-43; workers/queue/src/routes/entries.ts:914-945
actual_duration_minutes carries measured operational duration. workers/staff-feed/src/db/schema.sql:44-45; workers/reporting/src/db/schema.sql:17-69
status is the shared lifecycle status. workers/staff-feed/src/db/schema.sql:47-48; workers/staff-feed/src/engine/state-machine.ts:1-12
priority gives operations a cross-source ordering input. workers/staff-feed/src/db/schema.sql:49-50; workers/staff-feed/src/types.ts:44-75
notes gives staff a session-level operational note. workers/staff-feed/src/db/schema.sql:51-52; workers/staff-feed/src/types.ts:44-75
metadata holds source-specific operational detail without exploding the session schema. workers/staff-feed/src/db/schema.sql:53-54; workers/staff-feed/src/types.ts:44-75
version supports optimistic concurrency in lifecycle transitions. workers/staff-feed/src/db/schema.sql:55-56; workers/staff-feed/src/engine/transition.ts:197-221
created_at and updated_at support read refresh and reporting recency. workers/staff-feed/src/db/schema.sql:58-61; ../voyage-bank/docs/architecture/voyage-bank-design.md:183-221
checked_in_at is shared across appointment and walk-in operational state. workers/staff-feed/src/db/schema.sql:62-63; workers/booking/src/routes/check-in.ts:192-235
started_at is shared across all source types once staff begins service. workers/staff-feed/src/db/schema.sql:64-65; workers/staff-feed/src/engine/transition.ts:134-196
completed_at is shared across all source types once service is complete. workers/staff-feed/src/db/schema.sql:66-67; workers/staff-feed/src/engine/transition.ts:134-196
no_show_at is shared across all source types where no-show is a valid operational outcome. workers/staff-feed/src/db/schema.sql:68-69; workers/staff-feed/src/engine/state-machine.ts:14-54
The idx_sessions_branch_status index supports branch status views. workers/staff-feed/src/db/schema.sql:91-94; workers/staff-feed/src/routes/feed.ts:29-67
The idx_sessions_staff_time index supports staff timeline lookups. workers/staff-feed/src/db/schema.sql:91-94; workers/staff-feed/src/routes/feed.ts:69-93
The idx_sessions_source index supports source-to-session lookup. workers/staff-feed/src/db/schema.sql:91-94; workers/staff-feed/src/engine/effects/update-source-record.ts:27-86
The idx_sessions_customer index supports customer history lookups. workers/staff-feed/src/db/schema.sql:91-94; workers/reporting/src/routes/customer-analytics.ts:60-120
The reporting schema carries the same source discriminator. workers/reporting/src/db/schema.sql:17-69
The booking schema carries a worker-local copy of session shape. workers/booking/src/db/schema.sql:242-300
The queue schema carries a worker-local copy of session shape. workers/queue/src/db/schema.sql:103-141
The events schema carries a worker-local copy of session shape. workers/events/src/db/schema.sql:148-216
The replicated schema shape reflects Cloudflare worker boundaries. ../voyage-bank/docs/architecture/unified-session-architecture.md:43-51; workers/staff-feed/src/db/schema.sql:1-69
The replicated schema shape does not change the logical model. ../voyage-bank/docs/architecture/unified-session-architecture.md:5-20; workers/staff-feed/src/db/schema.sql:1-69
20. Scheduling And Occupancy Mechanics
The schedule engine defines TIME_UNIT_MINUTES as five minutes. packages/schedule-engine/src/constants.ts:1-31
The schedule engine defines SLOTS_PER_DAY from the five-minute quantum. packages/schedule-engine/src/constants.ts:1-31
The five-minute quantum yields 288 units in a day. packages/schedule-engine/src/constants.ts:1-31
The bitset type represents availability at that fixed quantum. packages/schedule-engine/src/bitset.ts:1-168
The bitset implementation sets and clears unit ranges. packages/schedule-engine/src/bitset.ts:1-168
The bitset implementation supports intersection across constraints. packages/schedule-engine/src/bitset.ts:1-168
The bitset implementation supports conversion between time ranges and occupied units. packages/schedule-engine/src/bitset.ts:1-168
The buffer-time helper expands busy ranges by before and after buffers. packages/schedule-engine/src/buffer-time.ts:9-40
The availability worker imports schedule-engine primitives rather than reimplementing unit math. workers/availability/src/services/slot-finder.ts:1-6
The slot finder defines result shapes for slot search. workers/availability/src/services/slot-finder.ts:39-52
The slot finder loads schedules before generating candidates. workers/availability/src/services/slot-finder.ts:59-178
The slot finder loads existing bookings as busy time. workers/availability/src/services/slot-finder.ts:215-233
The slot finder loads holds as busy time. workers/availability/src/services/slot-finder.ts:235-267
The slot finder loads branch, staff, and resource schedules as availability constraints. workers/availability/src/services/slot-finder.ts:269-360
The slot finder applies schedule exceptions and closures to the grid. workers/availability/src/services/slot-finder.ts:362-415
The slot finder combines schedules, bookings, holds, buffers, and lead time into candidate slots. workers/availability/src/services/slot-finder.ts:430-565
The slot finder enforces minimum lead time when building candidates. workers/availability/src/services/slot-finder.ts:430-565
The slot finder emits ranked candidate slots after constraint application. workers/availability/src/services/slot-finder.ts:568-600
The availability worker's job is pre-session capacity discovery. workers/availability/src/services/slot-finder.ts:430-565; workers/booking/src/routes/checkout.ts:400-432
The session model's job is post-selection occupancy execution. workers/staff-feed/src/db/schema.sql:1-69; workers/staff-feed/src/engine/transition.ts:74-271
Appointment booking consumes slot-finder output and then creates occupancy. workers/availability/src/services/slot-finder.ts:568-600; workers/booking/src/routes/checkout.ts:326-432
Walk-in entry bypasses future slot selection but still creates occupancy. workers/queue/src/routes/entries.ts:802-956
Event registration uses capacity checks before creating occupancy. workers/events/src/event-runtime.ts:173-270; workers/events/src/session-sync.ts:77-191
The assignment route checks occupancy at the session layer after creation. workers/staff-feed/src/routes/assignment.ts:363-451
The assignment route therefore handles appointment, walk-in, and event conflicts using one occupied-session query. workers/staff-feed/src/routes/assignment.ts:363-451; workers/staff-feed/src/db/schema.sql:1-69
The scheduling engine remains a reusable availability primitive. packages/schedule-engine/src/constants.ts:1-31; packages/schedule-engine/src/bitset.ts:1-168
The service session remains the operational occupancy primitive. workers/staff-feed/src/db/schema.sql:1-69; workers/staff-feed/src/types.ts:44-75
The distinction prevents availability search from becoming a lifecycle system. workers/availability/src/services/slot-finder.ts:430-565; workers/staff-feed/src/engine/state-machine.ts:1-54
The distinction prevents lifecycle execution from re-solving availability search. workers/staff-feed/src/engine/transition.ts:74-271; workers/availability/src/services/slot-finder.ts:430-565
JRNI also used five-minute increments for slots. ../bookingbug/app/models/slot.rb:98-109
JRNI did not use that increment as part of one event, queue, and appointment session model. ../bookingbug/app/models/slot.rb:44-109; ../bookingbug/app/models/event.rb:3-19; ../bookingbug/app/models/queuing/queuer.rb:1-20
Voyage's differentiator is therefore not merely five-minute scheduling. packages/schedule-engine/src/constants.ts:1-31; workers/staff-feed/src/db/schema.sql:1-69
Voyage's differentiator is the pairing of that grid with a unified operational session record. packages/schedule-engine/src/constants.ts:1-31; workers/staff-feed/src/db/schema.sql:1-69; workers/staff-feed/src/engine/state-machine.ts:1-54
21. JRNI Contrast In Concrete Terms
JRNI's Slot model contains booking-oriented timing, status, resource, and attendee concepts. ../bookingbug/app/models/slot.rb:5-109
JRNI's Event model contains event-oriented grouping and recurrence concepts. ../bookingbug/app/models/event.rb:3-113
JRNI's Queuing::Queuer model contains queue-oriented waiting and serving concepts. ../bookingbug/app/models/queuing/queuer.rb:1-20; ../bookingbug/app/models/queuing/queuer.rb:189-224
JRNI's Space model contains broad booking object status and metadata concepts. ../bookingbug/app/models/space.rb:5-47; ../bookingbug/app/models/space.rb:2563-2659
JRNI's Person model computes serving state from queue relationships. ../bookingbug/app/models/person.rb:736-750
JRNI's Person model computes booked-slot conflicts from slot relationships. ../bookingbug/app/models/person.rb:791-839
JRNI's appointment conflict service scans overlapping slots. ../bookingbug/lib/services/validation/booking_conflicts.rb:81-133
JRNI's queue serving runtime updates queue attendance directly. ../bookingbug/app/models/queuing/queuer.rb:189-224
JRNI's queue lifecycle has return and completion paths outside the appointment slot conflict service. ../bookingbug/app/models/queuing/queuer.rb:273-314; ../bookingbug/lib/services/validation/booking_conflicts.rb:81-133
JRNI's reporting templates separate booking, queue, and event exports. ../bookingbug/lib/tasks/report_templates.rake:1-70
JRNI's queue analytics payload computes queue-specific wait and service metrics. ../bookingbug/lib/search/payload_builder/queuer.rb:20-48; ../bookingbug/lib/search/payload_builder/queuer.rb:84-133
JRNI's event reporting template uses event-ticket vocabulary. ../bookingbug/lib/tasks/report_templates.rake:61-70
JRNI's booking reporting template uses booking and multi-status vocabulary. ../bookingbug/lib/tasks/report_templates.rake:1-23
JRNI's queue reporting template uses queue wait and service vocabulary. ../bookingbug/lib/tasks/report_templates.rake:37-58
JRNI's internal overlap analysis describes overlap handling as real but distributed. docs/analysis/jrni-overlap-handling.md:7-12
JRNI's internal overlap analysis identifies booking overlap as slot-centric. docs/analysis/jrni-overlap-handling.md:25-65
JRNI's internal overlap analysis identifies queue overlap as queue-centric. docs/analysis/jrni-overlap-handling.md:66-108
The legacy contrast is not "JRNI cannot schedule." ../bookingbug/lib/scheduler/bookable.rb:37-46; ../bookingbug/lib/scheduler/slots.rb:145-176
The legacy contrast is "JRNI schedules through separate operational nouns." ../bookingbug/app/models/slot.rb:5-38; ../bookingbug/app/models/event.rb:3-19; ../bookingbug/app/models/queuing/queuer.rb:1-20
Voyage's appointment source still has appointment nouns. workers/booking/src/db/schema.sql:22-59
Voyage's event source still has event nouns. workers/events/src/db/schema.sql:1-58
Voyage's queue source still has queue nouns. workers/queue/src/db/schema.sql:1-35
Voyage's operational layer replaces separate operational nouns with one session noun. workers/staff-feed/src/db/schema.sql:1-69; workers/staff-feed/src/types.ts:44-75
That replacement is visible in staff feed reads. workers/staff-feed/src/routes/feed.ts:29-123
That replacement is visible in assignment reads. workers/staff-feed/src/routes/assignment.ts:349-770
That replacement is visible in lifecycle writes. workers/staff-feed/src/engine/transition.ts:74-271
That replacement is visible in reporting reads. workers/reporting/src/routes/reports.ts:836-1004
That replacement is visible in tenant design language. ../voyage-bank/docs/architecture/voyage-bank-design.md:325-332
The old model asks integrators to reconcile slot, event, and queue facts. ../bookingbug/lib/tasks/report_templates.rake:1-70; ../bookingbug/app/models/person.rb:736-839
The new model records the reconciliation at write time. workers/booking/src/routes/checkout.ts:400-432; workers/queue/src/routes/entries.ts:914-945; workers/events/src/session-sync.ts:77-191
The old model lets a staff timeline become an aggregation project. ../bookingbug/app/models/person.rb:736-839; ../bookingbug/lib/tasks/report_templates.rake:1-70
The new model lets a staff timeline become a session query. workers/staff-feed/src/routes/feed.ts:29-123
The old model lets utilization become a report-merging project. ../bookingbug/lib/tasks/report_templates.rake:1-70
The new model lets utilization become a grouped session aggregation. workers/reporting/src/routes/reports.ts:836-1004
The old model lets assignment become source-specific work routing. ../bookingbug/app/models/person.rb:736-839; ../bookingbug/app/models/queuing/queuer.rb:189-314
The new model lets assignment become source-aware session routing. workers/staff-feed/src/routes/assignment.ts:349-770
22. Operational Invariants
Every operational session has one source type. workers/staff-feed/src/db/schema.sql:9-10; workers/staff-feed/src/types.ts:38
Every operational session has one source id. workers/staff-feed/src/db/schema.sql:11-12; workers/staff-feed/src/types.ts:44-75
Every operational session belongs to one tenant. workers/staff-feed/src/db/schema.sql:4-5; workers/staff-feed/src/routes/feed.ts:29-67
Every operational session belongs to one branch. workers/staff-feed/src/db/schema.sql:6-7; workers/staff-feed/src/routes/feed.ts:29-93
Every operational session has one lifecycle status. workers/staff-feed/src/db/schema.sql:47-48; workers/staff-feed/src/engine/state-machine.ts:1-12
Every lifecycle transition is checked against the shared transition map. workers/staff-feed/src/engine/transition.ts:1-72; workers/staff-feed/src/engine/state-machine.ts:14-54
Every accepted lifecycle transition updates the session row. workers/staff-feed/src/engine/transition.ts:134-221
Every accepted lifecycle transition can run source and staff status effects. workers/staff-feed/src/engine/transition.ts:223-257
Every accepted lifecycle transition can be audited. workers/staff-feed/src/engine/transition.ts:259-271; workers/staff-feed/src/db/schema.sql:103-123
Source tables remain authoritative for source-only facts. workers/booking/src/db/schema.sql:22-59; workers/events/src/db/schema.sql:1-58; workers/queue/src/db/schema.sql:1-35
The session table remains authoritative for operational occupancy facts. workers/staff-feed/src/db/schema.sql:1-69; workers/staff-feed/src/routes/feed.ts:29-123
Appointment payment, order, and checkout details stay outside the session table. workers/booking/src/db/schema.sql:22-59; workers/booking/src/routes/checkout.ts:326-399
Event price, ticket, and capacity details stay outside the session table. workers/events/src/db/schema.sql:1-58; workers/events/src/registration-core.ts:94-345
Queue waitlist and party details stay outside the session table where they are queue-specific. workers/queue/src/db/schema.sql:1-35; workers/queue/src/routes/entries.ts:802-913
Staff timeline presentation starts from the session table. workers/staff-feed/src/routes/feed.ts:29-123
Staff assignment starts from the session table. workers/staff-feed/src/routes/assignment.ts:349-770
Calendar sync starts from session-shaped payloads. workers/booking/src/session-calendar-sync.ts:1-23; workers/events/src/session-calendar-sync.ts:4-22; workers/queue/src/session-calendar-sync.ts:4-26
Reporting starts from the session fact table. workers/reporting/src/db/schema.sql:17-69; workers/reporting/src/routes/reports.ts:836-1004
Availability search starts from schedules, bookings, holds, and constraints. workers/availability/src/services/slot-finder.ts:430-565
Availability search is not the source of truth for active service state. workers/availability/src/services/slot-finder.ts:430-565; workers/staff-feed/src/engine/state-machine.ts:1-54
Active service state is not the source of truth for future search math. workers/staff-feed/src/engine/state-machine.ts:1-54; workers/availability/src/services/slot-finder.ts:430-565
The same staff member can appear in future slots, active queue work, and event assignments through one session vocabulary. workers/staff-feed/src/db/schema.sql:1-69; workers/staff-feed/src/routes/feed.ts:29-123
The same branch can show future appointments, current walk-ins, and event attendance through one timeline query. workers/staff-feed/src/routes/feed.ts:29-123
The same utilization report can compare appointment, walk-in, and event load through source_type. workers/reporting/src/routes/reports.ts:836-1004
The same reassignment route can handle appointment, walk-in, and event sessions because assignment targets the session row. workers/staff-feed/src/routes/assignment.ts:808-913
The same no-show transition can be represented without source-specific lifecycle code in the caller. workers/staff-feed/src/routes/actions.ts:90-238; workers/staff-feed/src/engine/state-machine.ts:14-54
The same completion transition can be represented without source-specific lifecycle code in the caller. workers/staff-feed/src/routes/actions.ts:90-238; workers/staff-feed/src/engine/transition.ts:134-196
The same in-progress transition can drive staff busy state. workers/staff-feed/src/engine/effects/update-staff-status.ts:16-33
The same terminal transitions can drive staff availability. workers/staff-feed/src/engine/effects/update-staff-status.ts:35-54
The invariant is not that all source flows are identical. workers/booking/src/db/schema.sql:22-59; workers/events/src/db/schema.sql:1-58; workers/queue/src/db/schema.sql:1-35
The invariant is that all source flows become one operational session when they occupy staff time. workers/booking/src/routes/checkout.ts:400-432; workers/queue/src/routes/entries.ts:914-945; workers/events/src/session-sync.ts:77-191
23. Failure Modes Removed
The unified model removes the need for a staff timeline to union appointments, events, and queue entries at presentation time. workers/staff-feed/src/routes/feed.ts:29-123; ../bookingbug/lib/tasks/report_templates.rake:1-70
The unified model removes the need for assignment to ask three different source systems for active work. workers/staff-feed/src/routes/assignment.ts:349-770; ../bookingbug/app/models/person.rb:736-839
The unified model removes the need for reporting to infer source type from unrelated tables. workers/reporting/src/db/schema.sql:17-69; workers/reporting/src/routes/reports.ts:836-1004
The unified model removes the need for staff status to be derived from queue attendance alone. workers/staff-feed/src/engine/effects/update-staff-status.ts:3-54; ../bookingbug/app/models/queuing/queuer.rb:189-224
The unified model removes the need for booking status and queue status to be interpreted as unrelated operational states. workers/staff-feed/src/engine/state-machine.ts:1-54; ../bookingbug/app/models/slot.rb:44-73; ../bookingbug/app/models/queuing/queuer.rb:189-224
The unified model removes the need for separate staff busy checks for queued and booked work. workers/staff-feed/src/routes/assignment.ts:363-451; ../bookingbug/app/models/person.rb:736-839
The unified model removes the need for separate appointment and queue operational audit concepts. workers/staff-feed/src/db/schema.sql:103-123; workers/staff-feed/src/engine/transition.ts:259-271
The unified model removes the need for a dashboard to decide whether a row is "work" based on source-specific status names. workers/staff-feed/src/types.ts:38-75; workers/staff-feed/src/routes/feed.ts:29-123
The unified model removes the need for event attendance to be operationally invisible until event-specific reporting runs. workers/events/src/session-sync.ts:77-191; workers/reporting/src/routes/reports.ts:836-1004
The unified model removes the need for queue joins to sit outside occupancy accounting. workers/queue/src/routes/entries.ts:914-945; workers/reporting/src/routes/reports.ts:836-1004
The unified model removes the need for appointment check-ins to be reconciled separately from walk-in starts. workers/booking/src/routes/check-in.ts:192-235; workers/queue/src/routes/entries.ts:317-370; workers/staff-feed/src/engine/state-machine.ts:1-54
The unified model removes the need for completion semantics to be rewritten per source in staff tools. workers/staff-feed/src/routes/actions.ts:90-238; workers/staff-feed/src/engine/transition.ts:134-196
The unified model removes the need for no-show semantics to be hidden in appointment-only code. workers/staff-feed/src/engine/state-machine.ts:14-54; workers/staff-feed/src/routes/actions.ts:90-238
The unified model removes the need for overrun detection to be booking-only. workers/reporting/src/routes/reports.ts:836-1004; workers/staff-feed/src/routes/assignment.ts:363-451
The unified model removes the need for utilization to be computed from incompatible duration fields. workers/reporting/src/db/schema.sql:17-69; workers/staff-feed/src/db/schema.sql:38-69
The unified model removes the need for "current staff work" to mean "current queue serving" only. workers/staff-feed/src/routes/feed.ts:29-123; ../bookingbug/app/models/person.rb:736-750
The unified model removes the need for "future staff work" to mean "booked slots" only. workers/staff-feed/src/routes/feed.ts:69-93; ../bookingbug/app/models/person.rb:791-839
The unified model removes the need for "event staff work" to be interpreted through event helper methods. workers/events/src/session-sync.ts:77-191; ../bookingbug/app/models/event.rb:174-189
The unified model removes the need for a source-specific calendar payload shape for every operational record. workers/booking/src/session-calendar-sync.ts:1-23; workers/events/src/session-calendar-sync.ts:4-22; workers/queue/src/session-calendar-sync.ts:4-26
The unified model removes the need for manual reassignment to branch into appointment, queue, and event implementations. workers/staff-feed/src/routes/assignment.ts:808-913; workers/staff-feed/src/db/schema.sql:1-69
The unified model removes the need for transition validation to be copied into each source worker. workers/staff-feed/src/engine/transition.ts:1-72; workers/staff-feed/src/engine/state-machine.ts:14-54
The unified model removes the need for staff availability to ignore already-started non-appointment work. workers/staff-feed/src/routes/assignment.ts:363-451; workers/queue/src/routes/entries.ts:317-370
The unified model removes the need for walk-ins to become second-class work in branch reporting. workers/queue/src/routes/entries.ts:914-945; workers/reporting/src/routes/reports.ts:836-1004
The unified model removes the need for event registrants to become second-class work in branch reporting. workers/events/src/session-sync.ts:77-191; workers/reporting/src/routes/reports.ts:836-1004
The unified model removes the need for appointment customers to be the only customers visible in customer session history. workers/reporting/src/routes/customer-analytics.ts:60-120; workers/staff-feed/src/db/schema.sql:14-21
The unified model removes the need for source workers to own staff timeline presentation. workers/staff-feed/src/routes/feed.ts:29-123; ../voyage-bank/docs/architecture/unified-session-architecture.md:43-51
The unified model removes the need for reporting to know whether a session began as checkout, queue join, or event registration before counting operational load. workers/reporting/src/routes/reports.ts:836-1004; workers/staff-feed/src/db/schema.sql:9-12
The unified model removes the need for the tenant dashboard to display queue, booking, and event widgets as unrelated operational surfaces. ../voyage-bank/docs/architecture/voyage-bank-design.md:325-332; workers/staff-feed/src/routes/feed.ts:29-123
The unified model removes the need for source-specific status translation in every consumer. workers/staff-feed/src/types.ts:44-75; workers/staff-feed/src/engine/effects/update-source-record.ts:27-86
The unified model removes the need for write-time source differences to leak into read-time operations. workers/booking/src/routes/checkout.ts:326-432; workers/queue/src/routes/entries.ts:802-956; workers/events/src/session-sync.ts:77-191; workers/staff-feed/src/routes/feed.ts:29-123
The unified model removes the need for branch-level capacity views to ignore already-confirmed event work. workers/events/src/session-sync.ts:77-191; workers/reporting/src/routes/reports.ts:836-1004
The unified model removes the need for real-time activity monitoring to poll three lifecycle tables. workers/reporting/src/routes/activity-monitor.ts:193-310; workers/staff-feed/src/db/schema.sql:1-69
The unified model removes the need for a separate source-specific "current work" API per interaction type. workers/staff-feed/src/routes/feed.ts:21-123; ../voyage-bank/docs/architecture/unified-session-architecture.md:43-51
The unified model removes the need for integrations to treat events as a reporting-only artifact. workers/events/src/session-sync.ts:77-191; workers/staff-feed/src/routes/feed.ts:29-123
The unified model removes the need for integrations to treat queue entries as a separate real-time object class. workers/queue/src/routes/entries.ts:914-945; workers/staff-feed/src/routes/feed.ts:29-123
The unified model removes the need for integrations to treat appointments as the only schedulable object class. workers/booking/src/routes/checkout.ts:400-432; workers/staff-feed/src/routes/feed.ts:69-93
The unified model removes the need for staff tools to equate "scheduled" with "appointment." workers/staff-feed/src/engine/state-machine.ts:1-12; workers/events/src/session-sync.ts:77-191
The unified model removes the need for staff tools to equate "waiting" with "queue entry only." workers/staff-feed/src/engine/state-machine.ts:1-12; workers/queue/src/routes/entries.ts:914-945
The unified model removes the need for staff tools to equate "in progress" with a queue-serving record only. workers/staff-feed/src/engine/state-machine.ts:1-12; workers/staff-feed/src/engine/effects/update-staff-status.ts:16-33
The unified model removes the need for downstream users to understand three histories before understanding one customer interaction. workers/reporting/src/routes/customer-analytics.ts:60-120; workers/staff-feed/src/db/schema.sql:14-21
The unified model removes the need for session duration semantics to be re-derived from source-specific timestamp pairs. workers/staff-feed/src/db/schema.sql:38-69; workers/reporting/src/db/schema.sql:17-69
The unified model removes the need for a reporting consumer to infer actual duration from queue-specific payloads. workers/reporting/src/db/schema.sql:17-69; ../bookingbug/lib/search/payload_builder/queuer.rb:84-133
The unified model removes the need for a reporting consumer to infer attendance from event-specific payloads. workers/events/src/session-sync.ts:77-191; workers/reporting/src/db/schema.sql:17-69
The unified model removes the need for a staff consumer to infer appointment attendance from booking-specific fields. workers/booking/src/routes/check-in.ts:192-235; workers/staff-feed/src/routes/feed.ts:29-123
The unified model removes the need for assignment strategy code to be duplicated by source. workers/staff-feed/src/routes/assignment.ts:349-770; workers/staff-feed/src/assignment-candidates.ts:38-123
The unified model removes the need for a source-specific overbooking dashboard per interaction type. workers/reporting/src/routes/reports.ts:836-1004; workers/staff-feed/src/db/schema.sql:9-12
The unified model removes the need for source-specific "what is next" widgets per staff member. workers/staff-feed/src/routes/feed.ts:69-123; workers/staff-feed/src/db/schema.sql:28-41
The unified model removes the need for source-specific "what is now" widgets per staff member. workers/staff-feed/src/routes/feed.ts:29-67; workers/staff-feed/src/db/schema.sql:28-48
The unified model removes the need for a separate branch queue dashboard to understand active branch load. workers/staff-feed/src/routes/feed.ts:29-123; workers/reporting/src/routes/activity-monitor.ts:193-310
The unified model removes the need for an event-only attendance dashboard to understand active branch load. workers/events/src/session-sync.ts:77-191; workers/reporting/src/routes/activity-monitor.ts:193-310
The unified model removes the need for an appointment-only diary to understand active branch load. workers/booking/src/routes/checkout.ts:400-432; workers/staff-feed/src/routes/feed.ts:29-123
The unified model removes the need for event registration updates to bypass staff operations. workers/events/src/session-sync.ts:128-191; workers/staff-feed/src/routes/feed.ts:29-123
The unified model removes the need for appointment check-in recovery to be manual when a session projection is missing. workers/booking/src/routes/check-in.ts:192-235
The unified model removes the need for event registration session recovery to be manual when the sync path finds an existing session. workers/events/src/session-sync.ts:77-191
The unified model removes the need for session transitions to be unaudited source writes. workers/staff-feed/src/engine/transition.ts:259-271; workers/staff-feed/src/db/schema.sql:103-123
The unified model removes the need for staff busy state to depend on source-specific completion code. workers/staff-feed/src/engine/effects/update-staff-status.ts:35-54; workers/staff-feed/src/engine/state-machine.ts:1-54
The unified model removes the need for a branch manager to learn different lifecycle vocabularies for booked, queued, and event work. workers/staff-feed/src/engine/state-machine.ts:1-54; ../voyage-bank/docs/architecture/voyage-bank-design.md:325-332
The unified model removes the need for a platform architect to explain three operational tables before explaining capacity. workers/staff-feed/src/db/schema.sql:1-69; packages/schedule-engine/src/constants.ts:1-31; workers/availability/src/services/slot-finder.ts:430-565
24. Code Pointer Summary
| Area | Pointer | Why It Matters |
|---|---|---|
| Canonical session schema | workers/staff-feed/src/db/schema.sql:1-69 |
Defines service_sessions and indexes. |
| Staff status schema | workers/staff-feed/src/db/schema.sql:71-89 |
Points staff at current session. |
| Session audit schema | workers/staff-feed/src/db/schema.sql:103-123 |
Records transition audit trail. |
| Session TypeScript type | workers/staff-feed/src/types.ts:44-75 |
Defines operational session shape. |
| Shared state machine | workers/staff-feed/src/engine/state-machine.ts:1-54 |
Defines shared lifecycle. |
| Transition engine | workers/staff-feed/src/engine/transition.ts:74-271 |
Executes transitions, effects, and audit. |
| Source sync effect | workers/staff-feed/src/engine/effects/update-source-record.ts:27-86 |
Pushes session state back to bookings, queue entries, and event registrations. |
| Staff status effect | workers/staff-feed/src/engine/effects/update-staff-status.ts:3-54 |
Updates busy/available state from sessions. |
| Staff timeline | workers/staff-feed/src/routes/feed.ts:21-123 |
Projects sessions into current work, feed, and schedule. |
| Assignment candidates | workers/staff-feed/src/assignment-candidates.ts:38-123 |
Selects unassigned sessions across all sources. |
| Assignment engine | workers/staff-feed/src/routes/assignment.ts:349-770 |
Assigns appointment, walk-in, and event sessions with one strategy layer. |
| Assignable staff | workers/staff-feed/src/routes/assignment.ts:363-451 |
Computes available staff using cross-source occupancy. |
| Appointment session creation | workers/booking/src/routes/checkout.ts:400-432 |
Creates session from booking checkout. |
| Appointment check-in session sync | workers/booking/src/routes/check-in.ts:192-235 |
Updates or creates session on check-in. |
| Walk-in session creation | workers/queue/src/routes/entries.ts:914-945 |
Creates session from queue join. |
| Walk-in runtime sync | workers/queue/src/routes/entries.ts:317-370 |
Keeps queue assignment/serving aligned with sessions. |
| Event session upsert | workers/events/src/session-sync.ts:77-191 |
Creates or updates session per event registration. |
| Event capacity | workers/events/src/event-runtime.ts:173-270 |
Keeps event-specific capacity outside the session row. |
| Schedule constants | packages/schedule-engine/src/constants.ts:1-31 |
Defines 5-minute quantum and availability-affecting statuses. |
| Slot finder | workers/availability/src/services/slot-finder.ts:430-565 |
Builds availability from schedules, overrides, bookings, holds, buffers, and lead time. |
| Reporting utilization | workers/reporting/src/routes/reports.ts:836-1004 |
Aggregates by source and detects overbooking. |
| JRNI slot model | ../bookingbug/app/models/slot.rb:44-109 |
Shows legacy slot status and 5-minute increment. |
| JRNI queue model | ../bookingbug/app/models/queuing/queuer.rb:189-314 |
Shows queue-specific serving lifecycle. |
| JRNI split reporting | ../bookingbug/lib/tasks/report_templates.rake:1-70 |
Shows separate booking, queue, and event reports. |
25. Commit Pins
Voyage repo HEAD: 14f3b190db8817399dcd30e1dc4e1ae7674bbf8a
Voyage Bank repo HEAD: ef4d7d4f9a66a05d68c265debc681d506a0606c6