mcpField
T
time-slot-generator

time-slot-generator

github.com/timerise-aiDevelopment016 installsUpdated 3d ago
Repository

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

  1. 01Rule-based slot generation
  2. 02Deterministic slot IDs
  3. 03Time-zone and DST handling
  4. 04Availability from bookings and blocks
  5. 05Capacity rechecks during booking

Use cases

  1. 01Build recurring or one-off bookable times
  2. 02Display capacity-adjusted availability
  3. 03Prevent concurrent overbooking
  4. 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-generator

After installing, type/time-slot-generatorin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

CHANGELOG.md
.gitattributes
CLAUDE.md
LICENSE
README.md
.github/workflows/
agent-eval.yml
evals/
prompts.md
references/
firestore-backend.md
adaptation.md
availability.md
generators.md
provenance.md
timezones.md
nextjs-routes.md
strategy-model.md
testing.md
supabase-backend.md

Details

From the project README

Time-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): rrule or 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.

SeamThe skill shipsThe host supplies
Domain wordsService, Strategy, Booking, Host, Location, Resource, BusyBlock, projectIts names
Tenant and authprojectId read from the stored service; a marked guard slotIts guard before writes
Data accessSlotStore on Firestore and on SupabaseIts project and schema
RoutesListing and booking route handlers on SupabaseIts URL scheme
Slot IDsmd5 via node:cryptoA pure md5 on the Edge runtime
Strings and UIError codes only, no screensIts i18n and its slot picker

Critical facts

  1. Store instants in UTC, author in wall clock, pin the zone. start.time: "09:00" means 09:00 in the strategy's timeZone, fixed at create time, so a later change to the project's zone does not move existing slots.
  2. 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.
  3. 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.
  4. 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.
  5. The server's time zone does not matter. new Date('2026-03-29T09:00') is parsed in the process zone and getUTCDay() on a shifted Date is right only in a UTC process, so the engine uses the Intl helpers.
  6. One generation per booking, then lookups. Regenerating per requested slot multiplies the work by the number of slots in the booking.
  7. 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

  1. 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.
  2. 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.
  3. Never generate without a horizon. maxHorizonDays and maxSlots cap every strategy, since one with no end would otherwise generate until 2038.
  4. 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.
  5. 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

  1. Read the host and fill the seam contract and the rename table: adaptation.md.
  2. Copy the types and validation: strategy-model.md.
  3. Copy the time helpers, durations and the normalizer: timezones.md.
  4. Copy slot identity and the generators: generators.md.
  5. Copy availability and the service entry point: availability.md.
  6. Copy the suite, wire it to npm test under four TZ values and run it: testing.md.
  7. Pick a backend: supabase-backend.md or firestore-backend.md.
  8. Serve it from route handlers: nextjs-routes.md.
  9. 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

ScenarioTrigger keywordsReference
Seams, renaming, order of workadapt, host, rename, tenant, auth guard, non-negotiablesadaptation.md
Strategy shape, fields, validationRANGE, PERIODICITY, ONCE, DAY_RANGE, tendency, timeOffset, slotsLimit, overnight, strategy-bounds-invalidstrategy-model.md
Time zones and DSTIANA, wall clock, UTC, DST gap, overlap, fromZonedTime, offset, storageVersion, legacytimezones.md
Producing slotsgenerateSlots, horizon, maxSlots, truncated, slot ID, md5, chronological, viewportgenerators.md
What is still freeavailability, seats, BOOKING, BLOCK, working hours, resource, capacity, overbooking, prepareBookingSlotsavailability.md
Supabase and Postgrestimestamptz, jsonb, RLS, with check, gin index, book_slots, advisory locksupabase-backend.md
Firestorefirebase-admin, Timestamp, composite index, array-contains-any, onSnapshot, runTransactionfirestore-backend.md
Route handlersapp/api/slots, app/api/bookings, route.ts, Node.js runtime, 409, SUPABASE_SERVICE_ROLE_KEYnextjs-routes.md
Proving itnode:test, vitest, npm test, TZ=, DST regression, Lord Howe, Auckland, differential checktesting.md
Why it is built this wayprovenance, audit, kept deliberately, fix orderprovenance.md

Part of the Timerise Skills index, which lists the sibling skills.

Comments

Markdown supported