合并finance和marking-v3

Q ef2e0667e9 chore: 初始化统一 Go 后端(模块化单体骨架 + 9 包参考样例) há 4 dias atrás
cmd ef2e0667e9 chore: 初始化统一 Go 后端(模块化单体骨架 + 9 包参考样例) há 4 dias atrás
config ef2e0667e9 chore: 初始化统一 Go 后端(模块化单体骨架 + 9 包参考样例) há 4 dias atrás
internal ef2e0667e9 chore: 初始化统一 Go 后端(模块化单体骨架 + 9 包参考样例) há 4 dias atrás
.gitignore ef2e0667e9 chore: 初始化统一 Go 后端(模块化单体骨架 + 9 包参考样例) há 4 dias atrás
EXAMPLES.md ef2e0667e9 chore: 初始化统一 Go 后端(模块化单体骨架 + 9 包参考样例) há 4 dias atrás
README.md ef2e0667e9 chore: 初始化统一 Go 后端(模块化单体骨架 + 9 包参考样例) há 4 dias atrás
go.mod ef2e0667e9 chore: 初始化统一 Go 后端(模块化单体骨架 + 9 包参考样例) há 4 dias atrás
go.sum ef2e0667e9 chore: 初始化统一 Go 后端(模块化单体骨架 + 9 包参考样例) há 4 dias atrás

README.md

统一 Go 后端(模块化单体)

两个 PHP 后端(教务 ysw-finance + 教学 yuansiweimarking_v2)收敛为一个 Go 后端,模块化单体、单二进制(ADR-011)。本文档描述工程结构与域分包约定;架构决策见 ../unified/00-planning/用户系统合并规划.md。

定位

单一 Go 服务承载全部业务域:身份/SSO、多租户组织、教务域、教学域、AI 编排、异步任务。对外经 nginx 统一入口(TLS + HTTP/2 终结,ADR-010)暴露;数据库为 PolarDB MySQL 单 schema(ADR-008)。

技术栈(与规划对齐)

关注点 选型 依据
语言 Go 1.27(go.mod 最低版本锁定;2026-11-05 由 1.23 升级,依赖零变化全绿实证) 统一后端重写
Web 框架 Fiber ADR-009(用户拍板)
ORM / 数据访问 GORM + Repository(强制作用域注入) ADR-006/007(多租户 institution/campus 过滤,应用层强制)
数据库 PolarDB MySQL 单 schema ADR-008(源库在阿里云,DTS 迁移)
身份 / SSO OIDC(RS256),identity 模块 = Provider + client 一体 ADR-004 / ADR-011
角色 7 类:超管/教务/财务/老师/学生/家长/市场 三项拍板(市场扩入第 7 角色)
异步任务 统一 DB 任务表 + Go 工作池 替代两套旧队列
配置 / 日志 viper + zap
外部入口 nginx 统一七层入口(proxy_buffering off 支持 SSE) ADR-010
对象存储 阿里云 OSS 文件资产迁移
AI 能力 消费 Python FastAPI Agent(契约 OpenAPI 化) 跨系统综合分析

目录结构约定

backend/
├── README.md            ← 本文件
├── EXAMPLES.md          ← 可编译样例索引 + GoDoc 注释标准(铁律 11 的落地模板)
├── go.mod               ← Go 模块(go 1.27;依赖版本锁定,见"构建与校验")
├── cmd/api/             # 单二进制入口:装配 Fiber app + 各域模块 + 任务工作池(规划待建)
├── config/              # viper 配置:环境、多租户、DB/Redis/OSS、SSO 签发/验签(config.{env}.json 模板)
└── internal/
    ├── identity/        # 身份与 SSO(已有样例:id 生成 ULID / credential argon2 惰性升级 / token RS256 签发验签吊销)
    ├── org/             # 多租户组织:Institution / Campus / Membership / Role(7) / GuardianLink(规划待建)
    ├── academic/        # 教务域:排班 / 费用 / 打卡 / 充值(SP 重写) / 报课 / 同步(规划待建)
    ├── teaching/        # 教学域:备课 / 练习分析 / 题库 / 组卷 / 科目分表 / 共享标志(规划待建)
    ├── ai/              # AI 能力编排:作为 OpenAPI 消费方调用 Python Agent(规划待建)
    ├── task/            # 统一 DB 任务表 + 工作池(已有样例:t_task 状态机/乐观锁认领/指数退避)
    └── infra/           # 横切(已有样例:response 统一信封 / errors 三层错误 / scope 多租户作用域 / validator 入参校验 / config 12-factor 配置)

样例即规范:internal/infra/*、internal/identity/{id,credential,token}、internal/task 为可编译参考样例 (go build ./... + go vet ./... 全绿,基于真实依赖版本),每个结构体/函数/方法均带 GoDoc 中文注释(功能说明+典型样例、入参逐项、出参逐项+异常场景)。新增业务域代码须对齐此注释标准(铁律 11)。 样例索引与注释模板见 EXAMPLES.md。

分包铁律

  1. 域间不直接互调内部实现,跨域走 internal/ 内定义的接口(接口在 org/identity 侧,消费方在业务域)。
  2. 所有数据访问必须经 Repository 层,作用域(institution_id / campus_id)由中间件从 token 解析后强制注入,禁止绕过。
  3. infra 不依赖任何业务域;业务域可依赖 infra、org、identity,但 org/identity 不得反向依赖业务域。
  4. SP 行为(充值/审批/同步)在 academic 域内用 Go 事务重写,旧存储过程仅留档对照,不迁移(见统一规划风险登记册)。
  5. 硬编码身份/魔法值(如 user->id==393、teacherId=354)一律进配置或权限判断,阶段 0 硬编码 ID 清单为消灭目标。
  6. 统一响应契约:HTTP 恒 200,真实状态码在 body R.code(成功 code=200,{code,data,message} 信封);e2e 断言 body code 而非 HTTP status(源自教务 Go 重构在产验证,ADR 见统一规划)。
  7. 入参校验惯例:validateReq(c, req) bool——校验失败内部已写 400 并返 false,调用方 if !validateReq { return nil }(用 err!=nil 判会误判通过继续落库)。
  8. 路由注册顺序纪律:Fiber 字面路径先于 /:id(如 /courses/list-detail 先于 /courses/:id);同 method+path 不重复注册(先注册优先);新增端点全局 grep 同路径。
  9. GORM 纪律:IS_NULLABLE=YES 列一律 *string/*int(写边界 nil→""/0 归一);聚合/别名/无下划线列显式 gorm:"column:xxx";链式调用勿就地改接收者(三查各自 Model());事务内全部用 tx;service 返回 sentinel 错误(非 gorm.ErrRecordNotFound),handler 用 errors.Is。
  10. e2e id 段独立:TestMain 建库建 SP→跑→DROP;多 e2e 共用库时用独立业务键/独立 id 段/独占时间窗/专属 token(避开教务已占 97090/97481/98141)。
  11. 注释标准(GoDoc 三段式):每个导出的结构体/函数/方法/常量/错误必须带 GoDoc 中文注释,含①功能说明(用途+核心逻辑,导出项附"典型使用样例")②入参说明(逐项:名称、类型、含义、约束)③出参说明(逐项:名称、类型、含义;异常场景单列)。代码即文档——注释与实现必须一致,改实现同步改注释;索引与模板见 EXAMPLES.md。

构建与校验

# go.mod `go 1.27`(语言级别 + 最低工具链),本机 go 1.27.x 直接构建。
# 未写 toolchain 指令:旧机器(GOTOOLCHAIN=auto)会自动从 goproxy.cn 拉取 go1.27 工具链,
# 有网即可,离线/内网隔离环境需预装 1.27 或设 GOPROXY 可达。
go build ./...    # 0 错误
go vet   ./...    # 0 告警(1.27 起 go vet/go test 默认含 stdversion 检查:只用 ≤ go.mod 版本的标准库符号,天然满足)

依赖版本锁定(go.mod,升 go 1.27 后版本不变,已实测无意外升级): fiber/v2 v2.52.16 / gorm v1.31.2 / validator/v10 v10.27.0 / golang-jwt/jwt/v5 v5.3.1 / oklog/ulid v1.3.1 / x/crypto v0.33.0。

工具链沿革:初版锁 go 1.23 + validator v10.27.0(go 1.20 要求),防 tidy 把工具链抬到 1.26; 2026-11-05 工具链升级为 go 1.27(泛型方法/encoding-json-v2/小对象分配提速 ~30%/goroutine 泄漏检测 GA), 依赖保持原锁定版本,go build+go vet 全绿实证兼容。

与文档目录的关系

  • 本目录只放代码与工程配置;任何架构决策、数据模型、迁移/割接方案放 ../unified/;单项目事实画像放 ../academic/、../teaching/。
  • 代码内注释如需引用决策,用相对路径指向 ../unified/00-planning/用户系统合并规划.md,不在代码注释里复述结论。