# AGENTS.md — MengStack 软盟开发框架 AI 规范 > 本文件是 AI 助手参与 MengStack 开发的最高约束。违反即返工。 ## 技术栈(锁定,10 年不换) | 层 | 选型 | |---|---| | 语言 | Go 1.23+ | | Web | Gin | | ORM | GORM v2 | | 数据库 | PostgreSQL 16 | | 缓存/会话 | Redis 7 | | 依赖注入 | Uber fx | | 配置 | Viper(YAML + 环境变量) | | 日志 | Zap(结构化 JSON) | | 认证 | JWT + bcrypt(cost≥12) | | 迁移 | golang-migrate | | API 文档 | Swag 注解 | | 容器 | Docker + Docker Compose | ## 目录结构(三层隔离) ``` mengstack-api/ ├── cmd/ # 入口:server, migrate ├── internal/ │ ├── kernel/ # L0 内核(开源,零业务语义) │ │ ├── cache/ # 缓存接口 │ │ ├── errors/ # 统一错误码 │ │ ├── eventbus/ # 事件总线 │ │ ├── i18n/ # 国际化 │ │ ├── jobs/ # 定时任务 │ │ ├── model/ # 基础模型(BaseEntity) │ │ ├── plugin/ # 插件接口 + 注册中心 │ │ ├── response/ # 统一响应 │ │ ├── storage/ # 存储抽象 │ │ ├── tenant/ # 多租户(Resolver/Scope/Context) │ │ ├── testutil/ # 测试工具 │ │ └── websocket/ # WebSocket Hub │ ├── modules/ # 业务模块(4 层分层) │ │ ├── auth/ # 认证 │ │ ├── rbac/ # 权限 │ │ ├── org/ # 组织 │ │ ├── audit/ # 审计 │ │ ├── settings/ # 配置 │ │ ├── notification/ # 通知 │ │ └── example/ # 示例插件 │ ├── app/ # 应用层(启动/中间件/生命周期) │ ├── config/ # 配置加载 │ └── logger/ # 日志初始化 ├── migrations/ # 核心数据库迁移 ├── pkg/query/ # 公共查询工具 ├── configs/ # 配置文件(yaml) └── tests/ # 集成测试 + 基准测试 ``` ## 四层分层(每个业务模块必须遵循) ``` domain/ → 实体 + 领域接口。禁止 import gorm/http/redis application/ → Service 编排。不直接操作数据库 infrastructure/ → Repo 实现(GORM/Redis)。不含业务逻辑 interfaces/ → Handler + Routes。参数校验,调 Service ``` ## 十条铁律(违反即返工) 1. **内核零业务语义** — kernel/ 不得出现 article/order/goods 等词 2. **依赖只向内** — domain 层零外部依赖,禁止 import gorm/http/redis 3. **跨模块走接口** — 只调对方 Service 接口,禁止 import 对方 Repo 4. **依赖方向单向** — modules → app → kernel,禁止反向 5. **tenantID 显式传递** — 作为方法参数逐层传递,禁止 context 隐式透传 6. **统一响应格式** — `{code, message, data, trace_id}`,5xx 只返"内部错误" 7. **迁移脚本** — 所有表结构变更走 golang-migrate,禁止 AutoMigrate 8. **参数化查询** — 禁止 SELECT *、禁止字符串拼接 SQL 9. **SEO 服务端直出** — 需搜索引擎收录的页面禁止客户端 JS 注入 10. **品牌统一** — 英文 MengStack,中文 软盟开发框架 ## 多租户规则 - 所有业务表必须含 `tenant_id` 字段 - 查询必须带租户条件(使用 `tenant.Scope(tenantID)` GORM scope) - Redis Key 格式:`{tenantID}:{module}:{key}` - 文件存储路径:`{tenantID}/{YYYY/MM/DD}/{random}{ext}` - 单租户模式:Resolver 返回固定 defaultID,系统照常运行 ## 公共字段规范 所有业务实体继承 `model.BaseEntity`: ```go ID string // UUID CreatedAt time.Time UpdatedAt time.Time DeletedAt gorm.DeletedAt // 软删除 TenantID string // 租户标识 ``` ## 错误处理三层转换 ``` infrastructure → sql.ErrNoRows 翻译为 errors.ErrNotFound application → fmt.Errorf("...: %w", err) 保留错误链 interfaces → 映射 HTTP 状态码 + 业务错误码,原文只进日志 ``` ## 禁止清单 - 禁止内核 import 任何 modules/ 代码 - 禁止明文存储密码(bcrypt cost≥12) - 禁止 context 隐式传递 tenantID - 禁止生产环境 AutoMigrate - 禁止 SELECT * 或字符串拼接 SQL - 禁止硬编码密钥/配置(一律环境变量) - 禁止日志打印密码/token/密钥 - 禁止浮点存储金额(用最小单位整数) - 禁止非 UTC 时间存储 ## 插件开发规范 新业务模块作为插件开发,遵循: 1. 在 `internal/modules//` 下创建 4 层目录 2. 实现 `plugin.Plugin` 接口(Metadata/FxOption/SetupRoutes/Init/MigrationsFS) 3. 数据库迁移放在插件自己的 migrations FS 中 4. 在 `app.go` 注册插件模块 5. 插件代码不得 import kernel 以外的内部模块 ## 构建与测试 ```bash GOPROXY=https://goproxy.cn,direct go build ./... # 编译 go test ./... # 测试 go vet ./... # 静态检查 ``` ## 文档索引 | 文档 | 位置 | |------|------| | 项目说明书 v1.5 | mengstack-docs/ | | 开发标准 v2.5 | mengstack-docs/ | | API 文档(Swagger) | /swagger/index.html | | 官网 | VitePress 站点 | | 开发者文档 | VitePress 文档站 |