关于 time-slot-generator
用于根据排期策略生成可预订时段的 TypeScript 技能,面向需要将时段逻辑接入自身服务的团队。它侧重确定性时段 ID、时区处理,以及列表与预订共用的可用性检查。
主要功能
- 01按规则生成时段
- 02确定性时段 ID
- 03时区与夏令时处理
- 04结合预订和占用块计算可用性
- 05预订时重新检查容量
适用场景
- 01生成周期或单次可预订时段
- 02展示按容量调整的可用情况
- 03避免并发超额预订
- 04修复时段逻辑中的时区错误
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ timerise-ai/ time-slot-generator --skill time-slot-generator安装后在 Claude Code 中输入/time-slot-generator确认已加载。
包含的文件
除 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.md详细介绍
时段生成器
时段不会被存储。系统会存储策略,每次读取时根据策略重新生成时段;预订则通过确定性 ID 再次找到对应时段。本技能中的一切都由此而来:生成器是策略、当前时间和视口的纯函数,其输出不受视口、服务端时区或一年中的日期影响,因此,访客按下“预订”时,屏幕上显示过的时段仍然存在。
适用场景
- 根据规则生成可预订时段:“周一至周五 09:00 至 17:00,每 30 分钟一个时段”“每月第一个和最后一个周五 18:00 至 20:00”“全天,仅限周末”“某个周六 10:00 至 14:00”。
- 显示可用情况:每个时段的容量减去预订、不可用时段、主持人的其他日程、共享房间或设备,以及非工作时间。
- 按 ID 预订时段,并在容量重新检查后确保并发请求仍能正确处理。
- 修复存在时区问题的时段代码,或迁移一次性将墙上时钟时间按 UTC 存储的实现。
不适用场景
- 预订页面或自助服务终端流程:
booking-kiosk,它使用本技能生成的时段。 - 按主持人提供、可同步日历并发送电子邮件的公开排期链接:
calendar-scheduling-links。 - 日历重复规则(RRULE、iCalendar、Google 或 Outlook 事件系列):使用
rrule或服务提供方的 API。策略描述的是可预订容量,而不是事件。 - 付款、定金、发票:
bookable-events、invoicing。
架构
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
引擎(lib/slots/)是纯 TypeScript,不导入 Next.js。只有路由文件会接触框架,而只有 SlotStore 会接触数据库。
适配契约
adaptation.md 包含完整契约、重命名表、工作顺序和不可妥协的要求。
| 接口 | 本技能提供 | 宿主提供 |
|---|---|---|
| 领域术语 | Service、Strategy、Booking、Host、Location、Resource、BusyBlock、project | 自己的名称 |
| 租户与身份验证 | 从已存储的服务中读取 projectId;一个标记的守卫插槽 | 写入前的守卫 |
| 数据访问 | 基于 Firestore 和 Supabase 的 SlotStore | 自己的项目和架构 |
| 路由 | 基于 Supabase 的列表和预订路由处理程序 | 自己的 URL 方案 |
| 时段 ID | 使用 node:crypto 的 md5 | Edge 运行时中的纯 md5 |
| 文本与 UI | 仅错误代码,不包含页面 | 自己的 i18n 和时段选择器 |
关键事实
- 以 UTC 存储时间瞬间,以墙上时钟时间编写,并固定时区。
start.time: "09:00"表示策略timeZone中的 09:00,该时区在创建时固定,因此之后更改项目时区不会移动已有时段。 - 按本地日历日期迭代,绝不使用
+24h。 DST 日期可能有 23 或 25 个小时,而在春季向前调整时钟的前一晚,从 23:30 加上 24 小时会落到两天后的本地日期。 - 先按时间顺序生成,再提前停止。 生成器会在遇到第一个超出截止时间的时段时停止,因此若按星期几生成候选时段,周视图会在显示完第一个工作日后就结束。
- 限制数量从策略开始处计算,绝不从视口开始处计算。 否则,“前 10 个时段”会取决于客户端请求的是哪一周,而在一个视图中可见的时段可能无法预订。
- 服务端时区无关紧要。
new Date('2026-03-29T09:00')会按进程时区解析,而对偏移后的 Date 调用getUTCDay()只有在 UTC 进程中才会得到正确结果,因此引擎使用 Intl 辅助函数。 - 每次预订只生成一次,然后查找。 每请求一个时段就重新生成,会让工作量乘以预订中的时段数量。
- 写入时生成结果可能已经过时。 两位访客可能都看到最后一个名额,因此必须在预订事务中重新计算剩余名额。
硬性规则
- 绝不更改时段 ID 的输入。
md5("<utcStartISO>;<duration>;<strategyId>")是每个客户端和每个预订持有的标识;输入一旦不同,就会导致它们全部失去关联。 - 绝不根据结束时间早于开始时间推断“跨夜”。 时间范围反转更常见的原因是输入错误,而非夜班,因此跨夜时段必须设置
overnight: true。 - 绝不在没有上限的情况下生成时段。
maxHorizonDays和maxSlots会限制每个策略;否则,没有结束时间的策略会一直生成到 2038 年。 - 绝不只在列表中筛选可用性。 列表和预订流程读取同一张
buildAvailability映射,因此不能让某个 ID 预订列表中隐藏的时段。 - 绝不将主机对该服务的预订计作主机的忙碌时间。 预订已作为
BOOKING扣减席位;再将其视为阻塞项,会隐藏仍有空位的时段。
快速开始
- 阅读主机实现,并填写接缝契约和重命名表:adaptation.md。
- 复制类型定义和验证逻辑:strategy-model.md。
- 复制时间辅助函数、时长和规范化器:timezones.md。
- 复制时段标识和生成器:generators.md。
- 复制可用性逻辑和服务入口:availability.md。
- 复制测试套件,将其接入四个
TZ值下的npm test,并运行测试: testing.md。 - 选择一个后端:supabase-backend.md 或 firestore-backend.md。
- 通过路由处理程序提供服务:nextjs-routes.md。
- 正在重建现有引擎?provenance.md 中有记录台账和修复顺序,testing.md 中有差异检查。
交接时,请提供需要应用的架构或索引、两个环境变量,以及主机守卫逻辑应放置的位置。
参考目录
| 场景 | 触发关键词 | 参考文档 |
|---|---|---|
| 接缝、重命名、工作顺序 | adapt、host、rename、tenant、auth guard、non-negotiables | adaptation.md |
| 策略结构、字段、验证 | RANGE、PERIODICITY、ONCE、DAY_RANGE、tendency、timeOffset、slotsLimit、overnight、strategy-bounds-invalid | strategy-model.md |
| 时区和 DST | IANA、wall clock、UTC、DST gap、overlap、fromZonedTime、offset、storageVersion、legacy | timezones.md |
| 生成时段 | generateSlots、horizon、maxSlots、truncated、slot ID、md5、chronological、viewport | generators.md |
| 当前仍有哪些空闲时段 | availability、seats、BOOKING、BLOCK、working hours、resource、capacity、overbooking、prepareBookingSlots | availability.md |
| Supabase 和 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 |
| 路由处理程序 | app/api/slots、app/api/bookings、route.ts、Node.js runtime、409、SUPABASE_SERVICE_ROLE_KEY | nextjs-routes.md |
| 验证正确性 | node:test、vitest、npm test、TZ=、DST regression、Lord Howe、Auckland、differential check | testing.md |
| 采用这种构建方式的原因 | provenance、audit、kept deliberately、fix order | provenance.md |
本项目属于 Timerise Skills 索引,其中列出了相关技能。
评论
支持 Markdown