About time-slot-generator
A TypeScript skill for generating bookable time slots from scheduling strategies, intended for teams adapting slot logic to their own services. It emphasizes deterministic slot IDs, time-zone correctness, and shared availability checks for listing and booking.
Key features
- 01Rule-based slot generation
- 02Deterministic slot IDs
- 03Time-zone and DST handling
- 04Availability from bookings and blocks
- 05Capacity rechecks during booking
Use cases
- 01Build recurring or one-off bookable times
- 02Display capacity-adjusted availability
- 03Prevent concurrent overbooking
- 04Fix time-zone errors in slot logic
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ timerise-ai/ time-slot-generator --skill time-slot-generatorAfter installing, type/time-slot-generatorin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
CHANGELOG.md.gitattributesCLAUDE.mdLICENSEREADME.md.github/workflows/agent-eval.ymlevals/prompts.mdreferences/firestore-backend.mdadaptation.mdavailability.mdgenerators.mdprovenance.mdtimezones.mdnextjs-routes.mdstrategy-model.mdtesting.mdsupabase-backend.mdDetails
From the project READMETime-Slot Generator
Slots are never stored. Strategies are stored, slots are regenerated from them on every read, and a booking finds its slot again by a deterministic ID. Everything in this skill follows from that: the generator is a pure function of strategies, now and viewport whose output does not depend on the viewport, the server's time zone or the day of the year, so a slot that was on screen is still there when the guest presses "book".
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):
rruleor the provider's API. Strategies describe bookable capacity, not events. - Payments, deposits, invoices:
bookable-events,invoicing.
Architecture
strategies (DB) --normalizeStrategy--> SlotStrategy[] --generateSlots(now, viewport)--> GeneratedSlot[]
|
bookings, busy blocks, host bookings, resources, working hours --SlotStore--> buildAvailability
|
GET /api/slots listServiceSlots: toSlotOutput (UTC + local offset) <-----------------+
POST /api/bookings prepareBookingSlots(ids): one generation, then lookups <--------------+
|
v
book_slots / assertCapacityInTransaction: seats re-counted in the write
The engine (lib/slots/) is plain TypeScript with no Next.js import. The routes are the only files that
touch the framework, and SlotStore is the only one that touches the database.
Adaptation contract
adaptation.md holds the full contract, the rename table, the order of work and the non-negotiables.
| Seam | The skill ships | The host supplies |
|---|---|---|
| Domain words | Service, Strategy, Booking, Host, Location, Resource, BusyBlock, project | Its names |
| Tenant and auth | projectId read from the stored service; a marked guard slot | Its guard before writes |
| Data access | SlotStore on Firestore and on Supabase | Its project and schema |
| Routes | Listing and booking route handlers on Supabase | Its URL scheme |
| Slot IDs | md5 via node:crypto | A pure md5 on the Edge runtime |
| Strings and UI | Error codes only, no screens | Its i18n and its slot picker |
Critical facts
- Store instants in UTC, author in wall clock, pin the zone.
start.time: "09:00"means 09:00 in the strategy'stimeZone, fixed at create time, so a later change to the project's zone does not move existing slots. - Iterate local calendar dates, never
+24h. A DST day is 23 or 25 hours, and adding 24 hours to 23:30 the evening before a spring-forward day lands two local days later. - Emit chronologically before you stop early. Generators stop at the first slot past a cutoff, so candidates produced weekday by weekday would end a week view after its first weekday.
- Limits count from the strategy start, never from the viewport. Otherwise "the first 10 slots" depends on which week the client asks for, and a slot visible in one view is unbookable.
- The server's time zone does not matter.
new Date('2026-03-29T09:00')is parsed in the process zone andgetUTCDay()on a shifted Date is right only in a UTC process, so the engine uses the Intl helpers. - One generation per booking, then lookups. Regenerating per requested slot multiplies the work by the number of slots in the booking.
- Generation is stale by the time you write. Two guests can both have seen the last seat, so seats are re-counted inside the booking transaction.
Hard rules
- 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. - 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. - Never generate without a horizon.
maxHorizonDaysandmaxSlotscap every strategy, since one with no end would otherwise generate until 2038. - Never filter availability in the listing only. The listing and the booking path read one
buildAvailabilitymap, so an ID cannot book what the listing hides. - 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.
Quick start
- Read the host and fill the seam contract and the rename table: adaptation.md.
- Copy the types and validation: strategy-model.md.
- Copy the time helpers, durations and the normalizer: timezones.md.
- Copy slot identity and the generators: generators.md.
- Copy availability and the service entry point: availability.md.
- Copy the suite, wire it to
npm testunder fourTZvalues and run it: testing.md. - Pick a backend: supabase-backend.md or firestore-backend.md.
- Serve it from route handlers: nextjs-routes.md.
- Rebuilding an existing engine? provenance.md has the ledger and the fix order, and testing.md the differential check.
Hand over with the schema or indexes to apply, the two environment variables, and the place the host's guard goes.
Reference directory
| Scenario | Trigger keywords | Reference |
|---|---|---|
| Seams, renaming, order of work | adapt, host, rename, tenant, auth guard, non-negotiables | adaptation.md |
| Strategy shape, fields, validation | RANGE, PERIODICITY, ONCE, DAY_RANGE, tendency, timeOffset, slotsLimit, overnight, strategy-bounds-invalid | strategy-model.md |
| Time zones and DST | IANA, wall clock, UTC, DST gap, overlap, fromZonedTime, offset, storageVersion, legacy | timezones.md |
| Producing slots | generateSlots, horizon, maxSlots, truncated, slot ID, md5, chronological, viewport | generators.md |
| What is still free | availability, seats, BOOKING, BLOCK, working hours, resource, capacity, overbooking, prepareBookingSlots | availability.md |
| Supabase and Postgres | timestamptz, jsonb, RLS, with check, gin index, book_slots, advisory lock | supabase-backend.md |
| Firestore | firebase-admin, Timestamp, composite index, array-contains-any, onSnapshot, runTransaction | firestore-backend.md |
| Route handlers | app/api/slots, app/api/bookings, route.ts, Node.js runtime, 409, SUPABASE_SERVICE_ROLE_KEY | nextjs-routes.md |
| Proving it | node:test, vitest, npm test, TZ=, DST regression, Lord Howe, Auckland, differential check | testing.md |
| Why it is built this way | provenance, audit, kept deliberately, fix order | provenance.md |
Part of the Timerise Skills index, which lists the sibling skills.