cal.diy 仓库关键文件位置速查:一份 Agent 与开发者通用的代码库导航指南
本指南基于 cal.diy(自托管的开源日程调度与预订基础设施)仓库内 agents/rules 中的参考规则文件 reference-file-locations.md 展开,系统梳理该大型 monorepo 中 UI 组件、数据库、API、业务特性、国际化与 App Store 等核心代码的落位,并给出仓库统一的文件命名约定。读完本文,你将掌握在 cal.diy 代码库中快速定位"一个页面组件、一张数据表、一条 tRPC 路由、一个 API v2 控制器或一种业务类型"的可靠方法,也能理解这套速查文档在 Agent 协作流程中的角色与维护方式。
一、这份速查文档是什么:属于 Agent 规则体系的"参考型条目"
在 cal.diy 仓库的 agents/rules 目录下,存放着一整套面向 AI Agent 与开发者的协作规则(rule),每条规则都带 YAML front matter 元信息。本文所依据的 reference-file-locations.md 是其中的参考型(Reference)规则,其元信息如下:
---
title: Key File Locations
impact: LOW
impactDescription: Quick reference for finding important files
tags: reference, navigation, file-locations
---
从规则体系的编排文件 _sections.md 可以看出,整套规则按 section 分组、以不同 impact 级别区分重要性:
| Section | 前缀 | Impact | 说明 |
|---|---|---|---|
| Architecture | architecture | CRITICAL | 垂直切片架构与领域驱动设计 |
| Code Quality | quality | CRITICAL | 代码质量与 PR 评审、测试规范 |
| Data Layer | data | HIGH | Repository 模式、DTO 与隔离 |
| API Design | api | HIGH | 控制器模式与 API 稳定性 |
| Performance | performance | HIGH | 复杂度与规模化性能 |
| Testing | testing | MEDIUM-HIGH | 覆盖率与测试策略 |
| Design Patterns | patterns | MEDIUM | 工厂、依赖注入等模式 |
| Team Culture | culture | MEDIUM | 工程文化与协作 |
| CI/CD | ci | HIGH | CI、类型检查与 git 流程 |
| Reference | reference | LOW | 信息速查:文件位置与本地开发 |
reference-file-locations 属于 impact 为 LOW 的 Reference 分组,定位是"给 Agent 导航的速查表",解决的核心问题是:大型 monorepo 中"去找某个东西在哪"的检索成本。它通过一组稳定的锚点路径,让 Agent 在接手任务时不必全文搜索即可直达关键文件。这也是它适合与 ci-type-check-first.md、data-repository-pattern.md 等其他规则配合使用的原因——先定位文件,再套用对应的架构与质量规范。
二、UI 组件层:视图文件与共享 UI 模式
文档给出的 UI 层定位锚点全部落在 apps/web/modules/ 下的 views 目录中,这是该仓库 apps/web(Next.js 前端应用)"按模块组织视图"的体现:
- 事件类型(Event types)页面:
apps/web/modules/event-types/views/event-types-listing-view.tsx - 预订(Bookings)页面:
apps/web/modules/bookings/views/bookings-view.tsx
这两条路径对应真实文件(分别位于 event-types-listing-view.tsx 与 bookings-view.tsx),是 Web 端两大核心后台视图的入口。文档同时给出了一条 UI 一致性约束:
共享 UI 模式(tabs、搜索框、筛选按钮)应在各视图间保持一致的排列(alignment)。
这条约束意味着:当你要在事件类型页或预订页中改动或新增共享 UI 元素时,应参照 apps/web/modules/ 下其他视图的既有写法,保持视觉与代码层面的统一,而不是各自为政。
三、数据库层:Schema 与迁移目录
数据模型与迁移是改动任何数据字段时的必经之地,文档给出两个锚点:
- Schema 定义:
packages/prisma/schema.prisma - 迁移目录:
packages/prisma/migrations/
cal.diy 使用 Prisma 作为 ORM,核心数据模型全部集中在 schema.prisma 中。仓库中 packages/prisma/migrations/ 下积累了数百个 .sql 迁移文件(当前仓库含 596 个 SQL 文件),配合 data-prisma-migrations.md 与 data-prisma-feature-flags.md 规则使用。值得注意的实践是:当需要修改数据库结构时,改 schema 与新增迁移是配套动作,且应根据项目约定评估是否需要对历史迁移做兼容处理,可参考 data-prefer-select-over-include.md、data-repository-pattern.md 中关于查询与仓储的约束,避免在业务代码里裸写复杂查询。
四、API 层:tRPC 路由、API v2 控制器与 OpenAPI 规范
cal.diy 同时维护两套 API 面,文档分别给出定位方式:
- tRPC routers:
packages/trpc/server/routers/ - API v2 controllers:
apps/api/v2/src/modules/*/controllers/*.controller.ts - OpenAPI 规范:
docs/api-reference/v2/openapi.json(自动生成,禁止手动编辑)
4.1 tRPC 服务端路由
服务端 tRPC 路由统一收口在 packages/trpc/server/routers/ 下,从目录结构看分为 viewer/、loggedInViewer/、publicViewer/、features/ 等几个主要入口(聚合根为 _app.ts),分别面向已登录用户、团队/组织成员与公开访问场景。这与 architecture-page-level-auth.md 讨论的按访问场景做鉴权隔离的思路一致——路由分组本身就是一种权限边界。
4.2 API v2 控制器(NestJS)
API v2 是一个 NestJS 应用(apps/api/v2),控制器遵循 modules/<模块>/controllers/*.controller.ts 的布局。从源码结构看,apps/api/v2/src/modules/ 下按业务域划分模块,每个模块内含 controller 及配套文件。例如实际文件可对应 event-types、webhooks、stripe、timezones、conferencing、cal-unified-calendars 等模块的控制器。文档对该层还有一条独立规则约束——api-thin-controllers.md 要求控制器保持"薄",HTTP 相关职责与业务逻辑分离,因此在阅读这些控制器时,你通常会看到它们把业务逻辑委托给 service/repository 层,这与 api-no-breaking-changes.md 强调的 API 稳定性要求相呼应。
4.3 OpenAPI 规范为自动生成物
docs/api-reference/v2/openapi.json 是 v2 API 的 OpenAPI 描述文件。文档特别标注它 auto-generated(自动生成),不要手动编辑——任何 API 变更都应改源头(DTO/控制器/装饰器),再重新生成规范,避免手改导致的文档与实现漂移。
五、Features 业务特性:需要重点维护的"高价值锚点"
packages/features/ 是业务特性(feature)的家,文档明确给出的关键位置包括:
- 工作流常量:
packages/features/ee/workflows/lib/constants.ts - Round-robin / 主持人优先级排序:
packages/features/bookings/lib/getLuckyUser.ts - 日历缓存:
packages/features/calendar-cache-sql - DataTable 指南:
packages/features/data-table/GUIDE.md
需要特别提醒:这类速查路径会随仓库持续重构而漂移,使用时务必以当前工作区实际文件为准。例如在本文所检查的这个仓库快照中,日历缓存的实际实现位于 packages/features/calendar-subscription/lib/cache/(含 CalendarCacheEventRepository.ts、CalendarCacheEventService.ts、CalendarCacheWrapper.ts 及其测试),而 getLuckyUser.ts 与 GUIDE.md 则可直接命中。这正说明:速查文档的价值在于给出检索起点与命名语义,而真正动手前应结合目录列表快速复核(例如可先执行 find packages/features -maxdepth 3 -type d | head 或直接在 IDE 中按文档路径跳转)。
Round-robin 的 getLuckyUser 是日程分配公平性逻辑的核心,配合 performance-scheduling-complexity.md 与 patterns-dependency-injection.md 阅读,可以理解"幸运用户"挑选算法为何需要被隔离在 lib 层便于单测。DataTable 模块则配有独立指南 GUIDE.md,说明该特性复杂度较高、值得单独文档化。
六、国际化与 App Store
6.1 翻译文件
- 英文本地化:
packages/i18n/locales/en/common.json
i18n 包位于 packages/i18n/,locales/ 下存放各语言目录(含 en),common.json 是英文翻译的基准文件。当新增文案时,通常先改英文 common.json,再通过 i18n 流程同步到其他语言;仓库根部的 i18n-unused.config.js 与 i18n.lock 则服务于翻译 key 的校验与一致性管理。
6.2 App Store(应用商店目录)
- 生成文件:
packages/app-store/*.generated.ts - CLI 工具:
packages/app-store-cli/
App Store 是 cal.diy 的第三方应用生态目录(packages/app-store/),其注册表采用生成式工作流:所有以 .generated.ts 结尾的文件(如 apps.metadata.generated.ts、apps.schemas.generated.ts、apps.keys-schemas.generated.ts、apps.server.generated.ts、apps.browser.generated.tsx、bookerApps.metadata.generated.ts 等)均由脚本依据各应用目录下的元数据与 schema 自动生成,不应手改。新增一个应用或调整应用元数据时,正确入口是 packages/app-store-cli/(内含 cli.tsx、core.ts、validateCreateAppFlags.ts 及测试等),由 CLI 校验并生成注册表文件。这与 patterns-app-store.md 中关于 App Store 插件的约定是配套的。
七、文件命名约定:让"猜路径"变成"推路径"
这是该速查文档的收尾部分,也是最具实操价值的规则之一:统一的命名约定让 Agent 无需打开目录即可推断出目标文件的准确名称。整理如下:
| 文件类别 | 命名模式 | 示例 |
|---|---|---|
| Repository 文件 | PascalCase + Repository 后缀 |
PrismaBookingRepository.ts |
| Service 文件 | PascalCase + Service 后缀 |
MembershipService.ts |
| 组件 | PascalCase | BookingForm.tsx |
| 工具函数 | kebab-case | date-utils.ts |
| 类型定义 | PascalCase + .types.ts 后缀 |
Booking.types.ts |
| 测试文件 | 源文件名 + .test.ts / .spec.ts |
getLuckyUser.test.ts 之类 |
对照仓库实际可以验证这套约定是"活"的:
- 仓储类命名:参考 data-repository-methods.md 相关规范,Prisma 仓储在 repo 中多以
PrismaXxxRepository.ts形式出现。 - 特性代码中的 lib 层与测试同目录共生,例如
packages/features/bookings/lib/getLuckyUser.ts的测试以.test.ts命名并置于其旁,符合"测试与源文件同名加后缀"的约定。 - 工具函数走 kebab-case,比如
packages/lib/slugify.ts、packages/lib/random.ts、packages/lib/rateLimit.ts、packages/lib/notEmpty.ts等遍布全仓库,一眼可辨。
实战提示:当你需要"新增一个针对某个类型的校验工具"时,按约定它应叫
xxx-validator.ts(kebab-case 放 lib)而非Validator.tsx;当你封装数据访问时,应叫XxxRepository.ts并放在仓储层而非控制器里。命名即导航。
八、如何让速查路径保持可用:给维护者与使用者的建议
从本文对若干路径的现场核对可以看出(例如 calendar-cache-sql 在当前快照已迁移到 calendar-subscription/lib/cache/),任何 monorepo 速查文档都存在"随重构过期"的风险。结合本仓库规则体系,可给出三条可落地的实践:
- 把文档当索引而非真相源:
reference-file-locations.md的作用是缩小搜索范围、提供命名语义,最终以list/跳转命中的实际文件为准;若发现锚点失效,优先通过目录遍历(或 IDE 的"在路径中搜索")找到迁移后的新位置。 - 把命名约定当作第一推理手段:即使速查条目过期,只要记住"Repository/Service 用 PascalCase + 后缀、组件 PascalCase、工具 kebab-case、类型
.types.ts"这套约定,就能大概率反推出目标文件名。 - 修改新代码时主动对齐约定:新增组件、仓储、服务、工具或类型时遵循同一命名与目录规则,既方便人类阅读,也让依赖文件名推断的 Agent 工具链(含本规则所在 agents/ 目录中的其他规则)持续有效;生成类文件(App Store
.generated.ts、openapi.json)则始终交给对应 CLI 或构建步骤产出。
综上,这份 impact 为 LOW 的参考规则,实际是把整个 cal.diy monorepo 的"藏宝图"浓缩成了一页纸:UI 去 apps/web/modules/*/views,数据去 packages/prisma,tRPC 去 packages/trpc/server/routers,v2 控制器去 apps/api/v2/src/modules/*/controllers,特性去 packages/features,翻译去 packages/i18n/locales/en,应用生态去 packages/app-store 与 app-store-cli——配合一套自洽的命名约定,任何人或 Agent 都能在分钟级内找到并理解目标代码的上下文。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python08
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00