generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) wiki_page: Project-Profile wiki_url: https://git.ilapage.cn/OPC/chorus/wiki/Project-Profile.- wiki_revision: 91a2bfa4adde11504ce9cb51a45f02abadab23cd synchronized_at: 2026-08-22T03:42:33Z # 项目档案 本页记录不经常变化、所有维护者都需要知道的信息。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` 按用户已接受的风险决策明文保存在 `provider_credentials.api_key`;列表和普通详情只返回是否已配置,只有受 JWT/Casbin 保护的单 Provider 凭据接口可显式回显,且响应设置 `Cache-Control: no-store` 与 `Pragma: no-cache`。 - 会话签名/加密密钥仍由受保护配置提供;生产 Cookie 必须启用 `Secure`、`HttpOnly` 和合适的 `SameSite`。Provider 明文密钥不得进入代码、日志、审计、错误、工单、Wiki、原型或截图。 - 生成物默认落受保护的本地目录,不能直接把真实路径暴露为公开静态 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 额度或发布生产。 ## Provider 凭据风险决策与 #24 已交付实现(2026-08-22) 用户已在 #30 明确接受 Provider API Key 明文落库及单条主动查看的风险。#24 已交付实现移除了运行时 `CHORUS_MASTER_KEY` 依赖,迁移 000005 在存在旧加密凭据时停止,禁止猜测或丢弃;列表和普通详情不返回完整密钥,单条读取禁止缓存。管理端使用固定 go-admin/go-admin-ui 基线,Casbin 显式读取迁移管理的 `sys_casbin_rule` 并关闭 adapter AutoMigrate。该实现已通过 MySQL 8、Go、前端构建和真实账号密码/API 联调,并于 2026-08-22 通过用户验收。