# Time-slot generator (Agent Skill)

> Bookable time slots generated from rules: daily ranges, every first Monday of the month, one-off and whole-day slots, with seats, bookings, blackouts and the host's busy time taken out, safe to book under load.

Page: https://timerise.ai/skills/time-slot-generator

Agent Skill `time-slot-generator`: https://github.com/timerise-ai/time-slot-generator. Category: Scheduling. Runs on Next.js; backend: Firestore or Supabase/Postgres behind a `SlotStore` seam.

Latest release: v0.1.3 (2026-10-16).

Install: npx skills add timerise-ai/time-slot-generator. Timerise builds it on a brief; the price comes from the brief.

Every booking system has a list of times a client can pick. Nobody types those times in one by one: they come from rules such as "every weekday from 9 to 5 in half-hour slots" or "a class on the first Monday of every month", minus whatever is already booked, closed or taken.

The list is the easy part. The hard part is what happens on the Sunday the clocks change, when the server runs in a different time zone from the shop, when a monthly rule meets a week that starts mid-month, or when two clients press "book" on the last seat in the same second. Get one of those wrong and a slot disappears for a day, shows an hour late, or is sold twice.

This skill gives your coding agent the slot engine, written by the engineers who build the one inside a booking platform: rules authored in local time and stored as exact instants, seats, bookings, blackouts, the host's busy time, shared resources and working hours taken out, one availability check for both the list and the booking, and the last seat counted again at the moment it is booked. You own the code, run it on Next.js on Vercel, with Supabase or Firestore, under your own accounts.

Build a strategy-driven time-slot generator with availability in a Next.js App Router app: daily ranges, Nth-weekday-of-month rules, one-off slots and whole-day slots, authored in local wall-clock time and stored as UTC instants, with seats, bookings, blackouts, host busy time, shared resources and working hours subtracted, a listing route and a booking route that re-checks capacity in the write transaction. Use when: (1) an app needs appointment, class, rental or reservation slots generated from rules rather than stored one by one, (2) slot code gives wrong days around DST, wrong weekdays far from UTC, a week view with one day, or times that change with the server's time zone, (3) strategies must be validated, pinned to a zone, or moved off wall-clock-as-UTC storage, (4) two guests can book the last seat at once, (5) the user mentions: time slots, slot generator, availability, booking slots, opening hours, slot strategy, RANGE, PERIODICITY, DAY_RANGE, ONCE, slotInterval, slotDuration, slotsLimit, daysLimit, first Monday of the month, last Friday, overnight slots, lead time, booking window, timeOffset, IANA time zone, DST, fromZonedTime, storageVersion, slot ID, md5, overbooking, capacity check, book_slots, slot-no-longer-available, slot-has-not-enough-capacity. Carries a dependency-free engine on Intl with a 23-test suite run under four process time zones, slot IDs that stay stable for existing bookings, one availability map for listing and booking, and a capacity re-check inside the booking transaction on both backends. Next.js App Router route handlers on the Node.js runtime; Firestore or Supabase/Postgres behind the SlotStore seam. Not a calendar UI, not RRULE or iCalendar recurrence, not payments or booking-flow screens.

This skill was written by the engineer who builds the slot engine of a booking platform, and audited against the earlier implementation of that engine. The templates hold the properties a slot engine has to hold: every weekday of a monthly rule appears in any viewport; local days survive both DST changes; limits count from the strategy, not the requested week; output is the same under any process time zone; nothing the listing hides can be booked by ID; and on ordinary windows the slot IDs are the ones existing bookings already hold. A 23-test suite run under four process time zones states each one, and [`references/provenance.md`](references/provenance.md) has the record.

What it builds:
- Daily ranges
- Nth-weekday-of-month rules
- One-off and whole-day slots authored in local time and stored as UTC
- Seats
- Bookings
- Blackouts
- Host busy time
- Shared resources and working hours subtracted
- One availability map for listing and booking
- Capacity re-checked inside the booking transaction
- Slot IDs that stay stable for existing bookings

When to use:
- Generating bookable slots from rules: "Monday to Friday 09:00 to 17:00 every 30 min", "first and last Friday of each month 18:00 to 20:00", "whole days, weekends only", "this one Saturday 10:00 to 14:00".
- Showing availability: capacity per slot, minus bookings, blackouts, a host's other commitments, shared rooms or equipment, and outside working hours.
- Booking slots by ID with a capacity re-check that holds under concurrent requests.
- Fixing slot code with time-zone bugs, or moving one off wall-clock-as-UTC storage.

When not to use:
- **The booking screens or a kiosk flow**: `booking-kiosk`, which consumes the slots this skill produces.
- **Public scheduling links per host with calendar sync and e-mail**: `calendar-scheduling-links`.
- **Calendar recurrence (RRULE, iCalendar, Google or Outlook event series)**: `rrule` or the provider's API. Strategies describe bookable capacity, not events.
- **Payments, deposits, invoices**: `bookable-events`, `invoicing`.

Non-negotiables:
- Never change the slot ID input. `md5("<utcStartISO>;<duration>;<strategyId>")` is the identity every client and every booking holds; a different input orphans them all. A test pins the format.
- Never infer "overnight" from end before start. A reversed range is far more often a typo than a night shift, so an overnight window needs `overnight: true`. The validation test refuses 17:00 to 09:00 and accepts the explicit overnight window.
- Never generate without a horizon. `maxHorizonDays` and `maxSlots` cap every strategy, since one with no end would otherwise generate until 2038. A test stops a strategy at a 10-day horizon, then at `maxSlots`, and expects `truncated` only in the second case.
- Never filter availability in the listing only. The listing and the booking path read one `buildAvailability` map, so an ID cannot book what the listing hides. Both entry points in `service.ts` call the same `computeAvailability`, and a test resolves booking IDs against that map.
- Never count a host's booking of this service as host busy time. It already subtracts seats as a `BOOKING`; blocking on it as well hides a slot that still has room. Both stores exclude the service from the host query, and `SlotStore.listBusy` states the rule.

Not this:
- Booking screens, a walk-up terminal: `booking-kiosk`
- Public scheduling links per host, calendar sync, e-mail invites: `calendar-scheduling-links`
- Ticketed events on one date, deposits, no-show holds: `bookable-events`
- Invoices for bookings: `invoicing`
- Calendar recurrence (RRULE, iCalendar event series): `rrule` or the calendar provider's API

What to tell your agent:
- Our studio books classes and private sessions from weekly opening hours, like weekdays 9 to 5 every 30 minutes and the first Saturday of each month. Add an API to this Next.js app on Supabase that lists the free times for a service and books one, without overbooking when two people take the last spot.
- Our booking times are an hour off after the clock change, and the week view sometimes only shows Monday. Fix how this app generates its time slots so it is right in every time zone our customers are in.
- Audit our availability code: customers can book times that the calendar does not show, and staff who are busy with another service still appear free.

Agent eval results (newest per agent and prompt):
- Gemini CLI (gemini-3.8-flash) on v0.1.3, 2026-10-16: pass (Supabase)
- Codex CLI (gpt-6.1-sol) on v0.1.3, 2026-10-16: pass (Supabase)
- Claude Code (claude-opus-5-5) on v0.1.3, 2026-10-16: pass (Supabase)

Recent releases:
- v0.1.3 (2026-10-16): From scoring the prompt-1 agent eval runs against 0.1.2. No template changed.
- v0.1.2 (2026-10-16): Fix release, from scoring the dispatched prompt-1 agent eval runs against 0.1.1.
- v0.1.1 (2026-10-16): Security fix release, from scoring the prompt-1 agent eval runs against 0.1.0.
