Files
chorus/docs/00-project-profile.md
T

170 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- gitea-wiki-mirror:start -->
generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件)
wiki_page: Project-Profile
wiki_url: https://git.ilapage.cn/OPC/chorus/wiki/Project-Profile.-
wiki_revision: 811dfc91e824a8ce509fe042455a66c6c1a4f433
synchronized_at: 2026-08-21T15:02:06Z
<!-- gitea-wiki-mirror:end -->
# 项目档案
本页记录不经常变化、所有维护者都需要知道的信息。Wiki 初始化完成后,Wiki 的 `Project-Profile` 是事实来源,本文件是只读镜像。
## 文档状态
线上 Gitea Wiki 已于 2026-08-20 初始化,15 个核心页面均已创建并回读确认。本页事实来源是 Wiki 的 `Project-Profile`,仓库中的 `docs/00-project-profile.md` 是只读镜像。长期文档的修改顺序固定为:修改 Wiki → 读取确认 → 导出 `docs/` → 校验差异 → 提交镜像。不要直接编辑带 `generated: true` 头的本地文件。
## 基本信息
| 项目 | 内容 |
|---|---|
| 项目名称 | chorus |
| 一句话目标 | 提供独立于 cmhub 的 Go 生图生文服务:用户提交提示词与原图得到新图或文本,运营在管理端配置上游并查看记录 |
| 主要使用者 | 终端用户(Web 端生成)、运营与管理员(管理端)、Claude/Codex Agent、接手简单维护的初级程序员 |
| Gitea 地址 | https://git.ilapage.cn |
| 仓库 | `OPC/chorus` |
| 默认分支 | `main` |
| 主要维护者 | `ila` |
| 需求来源 | Obsidian 笔记《cmgen · 从 cmhub 抽取生图生文服务 — 需求与 Go 技术方案》(2026-08-20);项目代号由 `cmgen` 改为 `chorus` |
| 文档适用范围 | 默认分支当前版本 |
## DevHarness 来源与基线
| 项目 | 内容 |
|---|---|
| DevHarness 来源仓库 | `https://git.ilapage.cn/OPC/dev_harness` |
| 当前基线提交 | `3696663781c569c57f47bb26e3b5b6369180fdaa` |
| 最后接入或升级日期 | 2026-08-20 |
| 项目适配说明 | 完整保留 Harness 规则、工单模板、Wiki 镜像与结构检查工具;`docs/00`、`02`–`06`、`09` 和 `docs/README.md` 改写为 chorus 内容,`docs/01`、`07`、`08`、`delivery/`、`templates/` 沿用上游文本 |
## 子项目与交付单元
| 子项目 / 交付单元 | 职责 | 技术栈与版本 | 构建与测试 | 发布方式 | 共享边界 |
|---|---|---|---|---|---|
| `internal/core` 核心域库 | 领域模型、provider 协议抽象、生成编排、队列状态、加密接口 | Go 1.26.5、GORM、标准库 | `go test ./internal/core/...` | 不单独发布 | **不得 import Gin、go-admin、gobreaker 或 imaging** |
| `internal/platform` 基础设施适配 | 出站 HTTP/SSRF、熔断、图片处理、存储等接口实现 | 标准库、sony/gobreaker、disintegration/imaging | `go test ./internal/platform/...` | 随服务二进制发布 | 通过接口注入 core,不反向污染领域层 |
| `portal` 用户端二进制 | 会话、页面/HTMX 片段、JSON API,MVP 阶段内嵌 worker | Gin、html/template、HTMX、Alpine、Tailwind | `pnpm --dir portal/web build`、`go test ./portal/...`、浏览器 E2E | 单二进制 | 依赖 core 与 platform;提交链路不得调用上游 |
| `admin` 管理端后端 | Provider、模型、Prompt、路由池、生成记录与终端用户只读查询 | 固定提交的 go-admin(Gin、GORM、Casbin、JWT) | `go -C admin test ./...` | 独立二进制 | 嵌套 Go module;依赖 core;不得复制生成逻辑或读写点数 |
| `admin-ui` 管理端前端 | go-admin-ui CRUD 与少量定制页 | Vue 3.5.41、Element Plus 2.14.4、Vue CLI 5.0.9 | `pnpm install --frozen-lockfile`、`pnpm build:prod` | 静态产物 | 代码生成器只在隔离开发环境使用 |
| `migrations` 数据库迁移 | 业务表、`sys_*` 基线和菜单/API 配置的全部生产演进 | golang-migrate SQL | up/down 隔离库验证 | 随版本发布 | **生产数据库结构的唯一事实来源** |
管理员 `sys_user` 与终端用户 `users` 分表。MVP-0 只要求 core、platform、portal 和必要迁移可运行;admin/admin-ui 在 MVP-1 接入,但生产所需 `sys_*` 初始结构和配置仍必须先转成版本化 SQL。任何构建、CI 或部署都不得依赖 `D:\github\goadmin` 的绝对路径。
#23 已把固定 `go-admin` 的所需后端源导入 `admin/` 这个嵌套 Go module,并把内部 import 改为仓库模块路径。运行入口是 `admin/cmd/server.go`;生产仅保留 `chorus-admin server --config <受保护配置>`,不导入原项目的 `cmd/migrate`、代码生成、Swagger、WebSocket 或静态文件路由。该入口只连接已经迁移的数据库,不执行 AutoMigrate、迁移或 seed。
## 技术栈与运行环境
### 固定来源基线
| 项目 | 本地审查来源 | 固定提交 | 关键约束 |
|---|---|---|---|
| go-admin | `D:\github\goadmin\go-admin` | `f06540883b41d03782bb6b2c4150f298f328c6b6` | `go.mod` 要求 Go 1.26.5 |
| go-admin-ui | `D:\github\goadmin\go-admin-ui` | `67d393d713877572fab0b897296a4c1d525fc81d` | Vue 3.5.41、Element Plus 2.14.4、Vue CLI 5.0.9、Node >=22、`packageManager=pnpm@9.15.1` |
| go-admin-doc | `D:\github\goadmin\go-admin-doc` | `424855aacf6905f3fde860c3331385cb25529a0d` | 只作固定版本说明参考 |
这些路径用于审查和导入来源,不是运行依赖。首次接入必须把需要的脚手架/前端代码纳入 chorus 仓库或把 Go 依赖锁定到可复现版本,并在实现工单记录来源提交、导入范围和本地修改。
### 运行栈
| 部分 | 技术 | 说明 |
|---|---|---|
| Go | 1.26.5 | 以固定 go-admin 的 `go.mod` 为最低统一版本,不再使用原文档的 Go 1.22+ |
| HTTP | Gin | portal 与 admin 共用生态,但 core 不依赖 Gin |
| ORM 与迁移 | GORM + golang-migrate | GORM 负责运行期持久化;生产禁止 AutoMigrate |
| 数据库 | MySQL 8.0+;当前开发验收为 8.4.8 | 单库;队列依赖 `SELECT … FOR UPDATE SKIP LOCKED` |
| 队列 | MySQL 租约 | 不引入 Redis/MQ;租约 token + CAS 防止陈旧 worker 提交 |
| 管理端 | 固定 go-admin + go-admin-ui | schema-first 生成 CRUD;生产关闭 dev-tools |
| 用户端会话 | alexedwards/scs | Cookie 会话,不复用管理员 JWT |
| 平台适配 | gobreaker、imaging | 只能位于 `internal/platform` |
| 限流 | ulule/limiter | MVP-2 用户维度令牌桶 |
| 上游调用 | `net/http` 适配器 | 支持多图、`extra_body`、URL/Base64 差异,并实施 SSRF 钩子 |
| 用户端 UI | html/template + HTMX 2.x + Alpine 3.x + Tailwind 4.x | portal 运行时不需要 Node;重建 portal/web 与 admin-ui 静态资源需要 Node/pnpm |
| 开发环境 | Windows + PowerShell + Git;本机隔离 MySQL 8 | Harness 使用 Python 3 标准库;Chorus 专用实例使用回环地址和独立端口/数据目录 |
### 已验证的 MVP-0 本机基线(2026-08-20)
- Go 使用官方 Windows amd64 压缩包固定为 1.26.5;SHA-256 为 `97e6b2a833b6d89f9ff17d25419ac0a7e3b482a044e9ab18cdef834bd834fd38`。便携工具目录加入当前开发 Shell 的 `PATH`,不替换机器已有 Go。
- `golang-migrate` 固定为 v4.19.1;Windows amd64 发布资产 SHA-256 为 `d2537dfd991787c1e458965c4f49098c5a72f943bfc9d975c573a9c245f7ba2e`。
- 开发数据库复用本机 MySQL 8.4.8 二进制,但使用 Chorus 专用数据目录、`127.0.0.1:3308` 和独立账号/库;现有 `3307` 实例和 MySQL 5.7 服务均不修改。
- 本机凭据由仓库外、仅当前账号可读的 PowerShell 环境文件注入;Wiki、工单、Git 和日志只记录变量名,不记录密码或完整 DSN。
- 已验证实例停止/重启、最小权限连接以及 `SELECT ... FOR UPDATE SKIP LOCKED`。这只证明开发环境可用,不代表生产部署已经验证。
### AutoMigrate 与代码生成结论
- go-admin 固定提交的 `cmd/migrate` 和模板中确有 AutoMigrate;它适合帮助理解脚手架初始化结构,但不是可审查、可回退的生产迁移。
- 如确需研究该初始化结果,只能由人工在**隔离、可丢弃、无生产数据**的开发数据库中单独运行,并把得到的结构差异整理为 `migrations/*.up.sql` 与 `*.down.sql`。
- go-admin-ui 的生成器先从数据库导入已有表到 `sys_tables/sys_columns`,再生成 Go/Vue 文件;因此标准流程是先执行版本化 SQL,再导入和生成。
- 生成器的“生成迁移脚本”主要写菜单、权限与 API 配置的 Go 迁移代码,并不是业务表 DDL,也没有本项目要求的可逆性和幂等证据;这些配置必须人工转换为可逆 SQL。
- dev-tools 路由包含写文件和写菜单的能力,固定提交中只有 JWT 保护且被 Casbin 排除,生产构建不得注册、代理或暴露这些路由。
## 阅读入口
- 新人入口:[Home](Home)。
- 产品需求与 MVP 分期:[产品需求总览](Product-Requirements-Overview.-)。
- 代码入口:[架构与代码地图](Architecture-and-Code-Map.-)。
- 业务边界:[业务规则与术语](Business-Rules-and-Glossary.-)。
- 运行验证:[本地开发与验证](Local-Development-and-Verification.-)。
- 简单维护:[常见修改指南](Common-Changes.-)。
- 错误定位:[故障排查](Troubleshooting)。
## 常用命令
所有命令默认从仓库根目录执行。Windows 本地开发优先使用 #14 提供的受管启动脚本;脚本只封装已有构建与运行入口,不执行迁移、AutoMigrate 或 seed。
| 用途 | 命令 | 预期结果 |
|---|---|---|
| 查看工作区 | `git status --short --branch` | 显示分支且没有无关修改 |
| 检查文档结构 | `python dev_scripts/harness.py check --strict` | 输出“DevHarness 检查通过” |
| 运行 Harness 测试 | `python -m unittest discover -s tests -v` | 所有测试通过 |
| 检查核心 Wiki 镜像 | `python dev_scripts/harness.py sync --check` | Wiki 初始化后输出核心镜像一致 |
| 编译 | `go build ./...` | 无错误 |
| 单元测试 | `go test ./...` | 全部通过 |
| 静态检查 | `go vet ./...` | 无输出 |
| 管理端编译与测试 | `go -C admin build .`、`go -C admin test ./...` | 独立 admin module 无错误 |
| 数据库迁移 | `migrate -path migrations -database "$CHORUS_MIGRATE_URL" up` | 迁移版本前进且无错误 |
| 幂等种子 | `go run ./cmd/chorus-seed` | 只输出完成状态,不输出凭据 |
| 启动用户端 | `scripts\chorus-dev.bat start` | 后台启动并检查 `/login`,不执行迁移或 seed |
| 查看本地进程 | `scripts\chorus-dev.bat status` | 显示受管 portal 和 mock 的状态、PID 与日志位置 |
| 停止本地进程 | `scripts\chorus-dev.bat stop` | 只停止脚本记录且路径匹配的进程 |
## 目录边界
| 目录 | 职责 | 不应放入 |
|---|---|---|
| `internal/core/` | 领域模型、协议接口、编排与状态规则 | Gin、go-admin、gobreaker、imaging、HTTP handler |
| `internal/platform/` | HTTP/SSRF、熔断、图片、存储等适配器 | 页面、管理端 CRUD、业务状态机复制 |
| `portal/` | 用户端 Gin、模板、静态资源、worker 组装 | 直接实现 provider 选路和上游协议 |
| `admin/` | go-admin 后端及 `app/chorus/` | 绕过 core 的生成实现、生产代码生成路由 |
| `admin-ui/` | 固定 go-admin-ui 导入代码与定制页 | 运行时依赖 `D:\github\goadmin` |
| `migrations/` | 全部生产表结构与配置种子 SQL | 测试数据、AutoMigrate、不可逆一次性修数 |
| `docs/` | 核心长期文档的 Wiki 只读镜像 | 人工直接维护的最终事实 |
| `docs/task/` | 人工按需导出的任务归档快照 | 讨论过程和默认自动导出 |
| `prototypes/` | 按工单/版本保存 HTML 审核快照 | 凭据、个人信息、生产数据 |
| `scripts/` | Chorus 本地开发与运行辅助脚本 | DevHarness 工具、凭据和生产数据 |
| `dev_scripts/` | DevHarness 工具 | 产品业务脚本 |
| `tests/` | Harness 测试;Go 测试与代码同目录 | 生产数据 |
## 环境、配置与凭据
- 核心 Wiki 同步配置是 `wiki-docs.json`;Gitea 地址可用 `GITEA_URL` 覆盖。
- Gitea PAT 仅从进程环境、MCP 安全配置或本机未跟踪的环境文件加载,不写入仓库、工单或 Wiki。
- 数据库连接串由 `CHORUS_DSN` 提供。
- Provider `api_key` 使用 AES-GCM 加密落库;`api_key_enc` 采用带 `version`、非敏感 `key_id`、nonce 和 ciphertext 的版本化信封,主密钥从环境/密钥管理系统取得且不入库。轮换按“新 key_id 写入、后台重加密、验证后退役旧密钥”执行,不原地猜测密钥版本。
- 会话签名/加密密钥与 Provider 主密钥分离,生产 Cookie 必须启用 `Secure`、`HttpOnly` 和合适的 `SameSite`。
- 生成物默认落受保护的本地目录,不能直接把真实路径暴露为公开静态 URL;访问先校验用户归属。storage 从第一天是接口,预留 S3/OSS。
- 测试只用构造数据与 mock 上游;真实连通性检查必须是管理员明确触发的单次低成本动作,并有审计和冷却。
- 上传数量、单文件/总大小、允许 MIME、像素上限、上游超时、租约时长、保留期和限流阈值均为配置。未确认生产值前保持部署门禁,不由 Agent 臆造。
## 项目专用验收要求
- 长期核心文档必须先更新 Wiki,再导出本地镜像;Wiki 初始化未完成前,文档修改直接在 `docs/` 进行并在工单说明。
- `python dev_scripts/harness.py check --strict` 必须通过。
- MVP-0 落地后:`go build ./...`、`go vet ./...`、`go test ./...` 必须通过。
- 涉及 `retryable` 判定、SSRF 校验、密钥加解密和迁移的修改必须有针对性单元测试。
- 未执行或无法覆盖的验证必须记录到工单。
## MVP-0 完成状态(2026-08-21)
- #5~#12 和 #14 已由用户验收;#13 集成验收执行中发现 #10 的内嵌 worker 未接入 `portal/main.go`,已用缺陷 #15 恢复既有确认行为。
- 当前候选版本已在本机 MySQL 8.4.8 隔离库完成空库 `up/down/up`、重复种子、Go build/vet/race、真实 portal 进程认领、Playwright 四视口和终态验证。
- 用户于 2026-08-21 明确确认 #4 验收通过;MVP-0 的全部单元任务、独立集成验收和父工单均已完成并归档。Epic #3 保持开启,后续 MVP 必须另行确认。
- 验证只使用构造用户、构造图片、mock 上游与测试 fixture;没有连接生产/共享库、调用真实 Provider 额度或发布生产。