本文件是模块级指令,聚焦
apps/server/的职责边界、关键文件路由和开发约束。 全局规则(DB 操作、数据访问、ORM 模型、开发流程)见根AGENTS.md和.claude/rules/。
装配层 + 产品级服务:main.cc/bootstrap/ 是纯装配(读配置、注入依赖、启动服务器,不含业务逻辑);openplatform/、organization/ 是产品级服务(跨模块业务,v1.4.0 起写实存在)。
职责边界:
- ✅ Bootstrap 模块(
src/bootstrap/):装配 Domain 服务、注册 Controller、设置 CORS/安全头/异常处理 - ✅ Schema 迁移(
src/SchemaManager.*、migrations/*.sql):数据库 schema 版本管理 - ✅ 配置管理(
config/*.json):JSON 基线 + 环境变量覆盖 - ✅ OpenAPI 文档(
openapi.yaml、docs/api/openapi.json):API 规范 - ✅ 种子数据(
seed/*.sql):开发/测试环境初始数据 - ✅ 产品级服务(
src/organization/:多租户组织管理;src/openplatform/:开放平台自助应用) - ❌ 禁止 Domain 逻辑(业务规则在
libs/oauth2、libs/identity) - ❌ 装配层(
main.cc/bootstrap/)禁止直接 DB 访问 ⚠️ 产品级服务(openplatform/、organization/、bootstrap/AdminBootstrapper)直接构造drogon::orm::Mapper是登记例外(#222,v1.4.0 M0 写实):存量查询允许保留,但 只降不升——tools/arch-guard的 R4 对apps/server/src的 Mapper 构造点数设 冻结基线(当前 57),新增属主/成员类读取优先走libs/storage-postgres的ClientOwnersRepository等共享仓储
| 排名 | 文件 | 职责 | 开发约束 |
|---|---|---|---|
| 1 | openapi.yaml |
OpenAPI 3.0 规范(所有端点定义) | 与 Controller 的 initApiDocs() 保持同步;新增端点必须同时更新此文件 |
| 2 | config/config.bench.json |
性能测试配置(高并发、连接池调优) | 仅用于 bench preset;生产配置在 config.prod.json |
| 3 | config/config.prod.json |
生产配置(启用 Hodor 限流、HTTPS、严格 CORS) | 必须启用所有安全特性;敏感配置通过环境变量覆盖(FULLA_DB_*、FULLA_REDIS_*) |
| 4 | config/config.json |
开发基线配置(所有环境的公共部分) | 修改需同步到 config.dev.json、config.ci.json、config.prod.json |
| 5 | CMakeLists.txt |
构建配置(可执行目标、链接依赖) | 新增 bootstrap 模块需更新 target_sources;链接 fulla::drogon(传递依赖所有 libs) |
纯装配:main() 按顺序调用 bootstrap 模块,不包含业务逻辑。
启动流程:
- 加载配置(
ConfigManager::load()+ 验证) - 注册 Controller(
bootstrap::registerAllControllers()) - 设置跨切面(CORS、安全头、异常处理)
- 注册启动回调(
registerBeginningAdvice):- 验证 ErrorCatalog 不变式
- 验证 ResourceScopeRegistry 一致性
- 注入 Plugin 指针到 Controller/Filter
- 构造 Identity 服务(
AuthService、SessionManager) - 配置 Hodor 限流拒绝响应
- 初始化 OpenAPI 文档(显式调用每个 Controller 的
initApiDocs()) - 构建 ResourceScopeRegistry(从 EndpointInfo 集合)
- 设置数据库迁移(
bootstrap::setupMigrations()) - 启动服务器(
drogon::app().run())
特殊模式:--migrate-only 参数仅运行迁移后退出(Helm pre-install/pre-upgrade hook 使用)。
registerAllControllers():注册所有AutoCreation=false的 Controller- 必须在
drogon::app().run()之前调用
setupCors():从配置读取 CORS 策略(允许的 origin、method、header)- 生产环境限制具体域名;开发环境允许
*
setupSecurityHeaders():添加安全响应头(X-Content-Type-Options、X-Frame-Options、Strict-Transport-Security)- 生产环境启用 HSTS;开发环境禁用
setupExceptionHandler():全局异常捕获,转换为标准 Error Envelope- 未捕获异常 → HTTP 500 +
INTERNAL_ERROR错误码
setupMigrations():检查并运行migrations/*.sql(按版本号排序)runMigrateOnly():仅运行迁移后退出(--migrate-only模式)- 迁移状态记录在
schema_migrations表
wireControllerPluginDependencies():注入OAuth2Plugin指针到 Controller/FilterwireIdentityServices():构造fulla::identity::AuthService和SessionManager,注入到SessionController
setupOpenApi():配置 Swagger UI 路由(/docs/api→static/swagger-ui/)
SchemaManager:执行 SQL 迁移脚本,记录迁移状态- 迁移文件命名:
Vxxx__description.sql(xxx为三位数版本号) - 迁移必须幂等(使用
IF NOT EXISTS、ON CONFLICT DO NOTHING)
OrganizationController:多租户组织管理 API(CRUD、成员管理)OrganizationService:组织业务逻辑(直接 Mapper 登记例外之一,见上文职责边界)- 注意:与
src/openplatform/同为产品级服务目录(跨模块产品级功能)
ApplicationController+ApplicationService:开放平台自助应用注册/管理 (v1.4.0);属主/成员读取走ClientOwnersRepository(#222),其余 Mapper 为登记例外存量
config.json:开发基线(所有环境的公共部分)config.dev.json:本地开发(覆盖config.json的数据库、Redis 连接)config.ci.json:CI 环境(内存存储、禁用持久化)config.bench.json:性能测试(高并发、连接池调优)config.prod.json:生产环境(启用所有安全特性)
- 所有配置项可通过环境变量覆盖:
FULLA_<SECTION>_<KEY>(如FULLA_DB_HOST、FULLA_REDIS_PORT) - 由
ConfigManager在加载时处理
app.log:日志配置(级别、路径)db_clients:Postgres 连接池(host、port、dbname、user、password、pool_size)redis_clients:Redis 连接池(host、port、password)listeners:HTTP/HTTPS 监听地址plugins:Drogon 插件配置(Hodor 限流、SecureSSLRedirector)cors:CORS 策略(allowed_origins、allowed_methods、allowed_headers)
- 按版本号顺序执行(
V001→V026) - 每个迁移文件包含
BEGIN;...COMMIT;事务 - 关键迁移:
V001:基础 schema(schema_migrations表)V002:OAuth2 核心表(clients、tokens、codes、consents)V004:用户表V005:RBAC(roles、permissions、user_roles)V011:MFA 支持V018:WebAuthnV024:用户软删除V025:审计日志分区
dev_admin_user.sql:开发环境管理员用户dev_admin_console_client.sql:管理控制台 OAuth2 客户端dev_backend_client.sql:后端服务 OAuth2 客户端dev_portal_client.sql:门户前端 OAuth2 客户端bench_users.sql:性能测试用户数据
openapi.yaml:源文件(YAML 格式,人工维护)docs/api/openapi.json:生成的 JSON 格式(构建时从 YAML 转换)- 与 Controller 的
initApiDocs()保持同步
login.csp:用户登录页面(CSP 模板)
src/main.cc和src/bootstrap/仅做装配,不包含业务逻辑。- 业务逻辑必须在
libs/oauth2、libs/identity、libs/common的 Domain 层实现。 src/organization/是唯一例外(跨模块产品级功能)。
- 所有
AutoCreation=false的 Controller 必须在bootstrap::registerAllControllers()中注册。 - 每个 Controller 的
initApiDocs()必须在main.cc中显式调用(避免循环依赖)。
- 修改
config.json必须同步到config.dev.json、config.ci.json、config.prod.json。 - 敏感配置(密码、密钥)通过环境变量覆盖,禁止硬编码在配置文件中。
- 生产配置必须启用所有安全特性(Hodor 限流、HTTPS、严格 CORS、HSTS)。
- 新增迁移文件命名:
Vxxx__description.sql(xxx为当前最大版本号 +1) - 迁移必须幂等(使用
IF NOT EXISTS、ON CONFLICT DO NOTHING) - 迁移文件包含
BEGIN;...COMMIT;事务 - 修改已有迁移文件禁止(会破坏已部署环境的迁移状态)
- ✅
apps/server→libs/drogon(传递依赖所有 libs) - ✅
apps/server→libs/common、libs/oauth2、libs/identity(直接引用 Domain 类型) - ❌
libs/*→apps/server(libs 禁止依赖 apps)
main.cc 的启动顺序严格固定:
- 加载配置
- 注册 Controller
- 设置跨切面(CORS、安全头、异常处理)
- 注册
registerBeginningAdvice回调(按注册顺序执行) - 初始化 OpenAPI 文档
- 构建 ResourceScopeRegistry
- 设置数据库迁移
- 启动服务器
禁止调整顺序(会导致依赖未初始化的组件被访问)。
apps/server无独立单元测试(逻辑在 libs 中测试)。- 集成测试在
tests/integration/,使用真实 Postgres 实例(Docker Compose)。 - E2E 测试在
tests/e2e-backend/,验证完整 OAuth2 流程。
- 构建:
./manage.sh build(Linux/macOS)或./manage.ps1 build(Windows) - 运行:
./manage.sh run(启动开发服务器) - 测试:
./manage.sh test(运行所有测试) - 迁移:
./manage.sh migrate(手动运行迁移)
- 根
AGENTS.md:全局规则索引 .claude/rules/db-operations.md:DB 操作规则(async callback + Mapper + Criteria).claude/rules/data-access.md:存储层触发器.claude/rules/orm-models.md:ORM 模型禁止手改.claude/rules/dev-workflow.md:构建/测试命令(./manage.sh、./manage.ps1)