feat: scheduling platform — offices, clients, service types, rules engine #1

Merged
ronit merged 9 commits from feat/scheduling-platform into master 2026-03-24 18:10:14 +00:00
Owner

Summary

Replaces the old schedules + blocked_times tables with a unified scheduling platform:

  • Offices — account-scoped locations with timezone, default slot duration, buffer config
  • Clients — account-scoped client records (not office-scoped) with preferences (AI-authored JSONB)
  • Service Types — catalog of services with default durations
  • Provider Services — junction linking providers to service types with optional duration overrides
  • Scheduling Rules — unified rules engine (4 types: weekly_hours, date_override, recurring_exception, holiday_calendar) with priority-aware conflict resolution
  • Availability rewrite — timezone-aware slot generation via chrono-tz, driven by the rules engine
  • Full HTTP CRUD — routes for all entities + cancel/reschedule appointment actions
  • RPC updates — check_availability uses rules, create_appointment accepts client_id/service_type_id, new next_available endpoint
  • NATS events — scheduling_rule and client mutation events
  • Migration — data migration from old schedules/blocked_times to scheduling_rules

Key design decisions

  • Booking is a vertical-agnostic scheduling primitive, not dental-specific
  • AI agents are the primary interface; human UIs are secondary channels
  • Source + compiled pattern: AI-authored data stores both natural language and structured form
  • Client records are account-scoped (can visit multiple offices)

Testing

  • 18 tests passing
  • cargo fmt + clippy clean

🤖 Generated with Claude Code

## Summary Replaces the old `schedules` + `blocked_times` tables with a unified scheduling platform: - **Offices** — account-scoped locations with timezone, default slot duration, buffer config - **Clients** — account-scoped client records (not office-scoped) with preferences (AI-authored JSONB) - **Service Types** — catalog of services with default durations - **Provider Services** — junction linking providers to service types with optional duration overrides - **Scheduling Rules** — unified rules engine (4 types: weekly_hours, date_override, recurring_exception, holiday_calendar) with priority-aware conflict resolution - **Availability rewrite** — timezone-aware slot generation via chrono-tz, driven by the rules engine - **Full HTTP CRUD** — routes for all entities + cancel/reschedule appointment actions - **RPC updates** — check_availability uses rules, create_appointment accepts client_id/service_type_id, new next_available endpoint - **NATS events** — scheduling_rule and client mutation events - **Migration** — data migration from old schedules/blocked_times to scheduling_rules ### Key design decisions - Booking is a vertical-agnostic scheduling primitive, not dental-specific - AI agents are the primary interface; human UIs are secondary channels - Source + compiled pattern: AI-authored data stores both natural language and structured form - Client records are account-scoped (can visit multiple offices) ### Testing - 18 tests passing - cargo fmt + clippy clean 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Pure-function engine that resolves effective working hours for a given
date by evaluating exclusions, date overrides, and weekly hours rules
with office/provider intersection support.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace Schedule-based slot generation with rules engine. The new
generate_available_slots() uses resolve_effective_hours() for timezone-
aware slot generation. Remove generate_raw_slots(), subtract_blocked(),
and local OccupiedSlot struct. Update rpc.rs with placeholder rule
fetching (TODO: wire to DB once db/api.rs is rewritten).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Convert db.rs to db/ module with offices, clients, service_types,
  rules submodules. Remove deprecated Schedule/BlockedTime types.
- Add new error variants: OfficeNotFound, ClientNotFound,
  ServiceTypeNotFound, InvalidRule.
- Add Serialize derive to all DB row types for JSON responses.
- Create AppState and HTTP routes for offices, clients, service_types,
  providers, rules, and appointments (CRUD + pagination).
- Update RPC handlers to use rules-based availability (replace TODO
  placeholders), office defaults, and service type durations.
- Update insert_appointment to accept client_id and service_type_id.
- Add next_available RPC handler (day-by-day search).
- Wire up HTTP routes in main.rs alongside health endpoints.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fix: address code review issues (panic safety, priority semantics, missing endpoints, events)
All checks were successful
pipeline-service No pipeline action (save)
c2b77c8b83
- Replace expect() with Option in WeeklyHoursRule and DateOverrideRule time/date parsing
- Restructure resolve_scope_hours so date overrides take priority over recurring exclusions
- Add resolve_slot_config helper for provider-level slot duration and buffer cascade
- Add GET /v1/clients/:id/appointments endpoint
- Add NATS events for scheduling rule and client create/update/delete
- Fix RLS bypass in get_provider by using begin_account_tx
- Add rule type and compiled_rule shape validation on creation
- Add timezone validation on office create and update

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ronit merged commit 508be5df41 into master 2026-03-24 18:10:14 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
isoastra/booking!1
No description provided.