Recurrence¶
The core stores concrete, dated slots. Recurrence - repeating availability
("every Tuesday 10:00-11:00") - is an optional layer that materializes
those concrete slots. It will ship separately, as yoyaku_recur, and this page
is the design it will be built to; nothing of it exists yet.
Why materialize rather than store a rule¶
Bookings attach to concrete slots, and the BookingManager is oblivious to a
slot's origin. So recurrence adds cleanly: what it needs on the slot is one
nullable string naming the rule a slot came from, and a submodule adds a base
field of its own without the engine knowing.
flowchart LR
RULE[RecurrenceRule<br/>yoyaku_recur] -->|generator + cron| GEN[Materialize slots]
GEN --> S1[Slot 2026-07-07]
GEN --> S2[Slot 2026-07-14]
GEN --> S3[Slot 2026-07-21]
S1 --> C1[tariffs + bookings]
S2 --> C2[tariffs + bookings]
Note[slot names its rule] -.-> S1
Bonus of materializing versus storing a pure RRULE:
- Per-occurrence overrides are trivial - skip a date or bump one day's capacity by editing that single slot.
- Open-ended recurrence is handled by a rolling-horizon cron that keeps a window of future slots materialized (the Smart Date Recur approach). The engine only ever sees concrete slots.
What yoyaku_recur will add¶
- A
RecurrenceRuleentity (RRULE + a default tariff template + horizon). - A generator service + cron that creates/updates slots and stamps each one with the id of the rule it came from.
- A policy for already-booked generated slots when a rule changes - the one decision recurrence defers, and it lives entirely in the submodule.
Nothing is reserved for it
The engine stores nothing on a slot on this layer's behalf. A field that only the generator writes and only the generator reads belongs to the generator, and the submodule adds it when it is built.