Files
tennis-book/AGENTS.md
2026-07-15 18:50:12 +08:00

4.4 KiB
Raw Blame History

Tennis Book 开发约定

产品边界

  • 本项目是桌面端网球场聚合预约工具,不在渲染层直接调用第三方微信小程序接口。
  • 每个球场必须通过独立适配器接入;公共层只定义球场、日期、场地和时段等稳定概念。
  • 不在公共模型中硬塞某个球场的专属字段。专属请求参数、签名、Cookie 和流程状态留在对应适配器内。

目录结构

  • src/main/Electron 主进程、第三方网络请求、凭证和适配器注册。
  • src/main/settings/:按球场保存的本机配置与原子写入逻辑,存储位置使用 Electron userData 目录。
  • src/main/bookings/:待支付锁场订单摘要与恢复逻辑;不得持久化支付签名。
  • src/main/monitors/空场监控任务、10 秒轮询调度、变化去重和系统通知;只允许调用无凭证列表接口。
  • 带报名活动(如双打活动)的时段统一视为已订场地;不得计入可订数量,也不得触发空场监控提醒。
  • 空场监控日期可选;未指定日期的任务持续滚动检查主界面支持的未来 7 天数据,不能在跨日时自动失效。
  • src/main/adapters/<court-id>/:单个球场的接口与预约流程实现。
  • src/preload/:仅暴露经过白名单审核的类型安全 IPC。
  • src/renderer/React UI不可使用 Node.js API不可持有第三方密钥。
  • src/shared/:主进程、预加载和渲染层共享的纯类型与消息契约。
  • docs/:架构决策和球场接入说明。

命名与扩展规则

  • 桌面应用对外名称统一为 Tennis Book;开发模式和打包产物都必须通过 Electron 运行时名称与 productName 保持一致。
  • Electron userData 目录固定使用稳定存储 ID tennis-book,不得从显示名称推导;修改品牌名称不能导致配置、待支付订单或监控任务切换存储目录。
  • 球场 ID 使用稳定的 kebab-case,适配器目录名必须与 ID 一致。
  • IPC channel 使用 domain:action,新增 channel 时必须同时更新共享类型和 preload 白名单。
  • 新球场先实现 CourtAdapter,再注册到适配器注册表;禁止在 React 组件里按球场 ID 写业务分支。
  • 第三方接口字段 userId 在本项目语义中是“场地 ID”固定场地 ID 属于球场适配器私有常量,不得通过 IPC 或配置界面暴露。
  • 场地 ID 只允许在对应适配器请求边界映射到第三方 userId 字段和 STOREID 请求头。
  • 下单、取消等写操作必须由对应球场适配器独立实现;公共层只编排确认、状态和恢复,不拼装球场专属请求。
  • 模拟数据只允许存在于 demo 适配器或明确命名的 fixture 中,接入真实 API 后不得静默回退到模拟成功。

安全规则

  • Electron 必须保持 contextIsolation: truenodeIntegration: falsesandbox: true
  • 第三方令牌、Cookie、签名密钥不得进入渲染进程、日志或版本库。
  • 第三方请求诊断日志只允许在 dev 模式输出;请求头和响应中的访客凭证、支付签名、预支付标识及个人信息必须递归脱敏。
  • PSPLVISITORID 持久化在 Electron 主进程管理的本机配置中;设置弹窗可通过白名单 IPC 读取原值用于回填,但关闭弹窗后必须清除渲染层状态,其他业务接口不得返回原值。
  • 可订列表等只读接口禁止读取或携带 PSPLVISITORID;只有下单、释放等明确需要访客身份的写接口可以从持久化配置加载并注入该请求头。
  • 每球场配置以 courtId 隔离;标识符在共享模型和持久化文件中使用字符串,实际请求前再按接口契约安全转换。
  • 预约人昵称和手机号仅可按产品明确要求存在于当次时段查询的内存结果中;不得写日志、落盘、缓存或用于预约以外的用途。
  • 外部链接只能通过主进程白名单打开;页面不得任意导航或创建窗口。
  • 写操作前必须在主进程重新验证实时可用性和价格UI 必须二次确认。不得用真实接口做自动化下单或取消测试。

完成标准

  • 每次修改至少通过 npm run typechecknpm run buildgit diff --check
  • 影响交互或布局时必须做一次实际渲染检查。
  • 接入真实球场时需要覆盖:正常数据、无可用时段、登录失效、限流、接口格式变化和网络失败。