跳转到主要内容

参与贡献

提交 Issue、开发代码与发起 Pull Request

如果你准备为 ImQi1 CMS 报告问题、提出功能或提交代码,请先阅读本节,并以主仓库最新的 master 分支为准。本文介绍的是 imqi1-cms 的协作流程;部署和使用问题请先查阅 常见问题 及其他相关章节。

先确认范围

创建 Issue 前,请先查阅 项目文档 和主仓库现有的 Issues,确认问题不是已有说明、重复反馈或已经讨论过的方案。通用浏览器和操作系统问题、第三方服务自身的问题、个人站点的部署配置错误,以及面向其他 CMS 的通用需求,不属于本项目 Issue 的范围,请到对应上游反馈。

项目当前只有 master 作为持续开发主线。较早提交与当前行为不一致时,以仓库最新源码为准;如果你准备处理的改动较大或会影响多个模块,请先开 Issue 说明要解决的问题,确认方向后再开始实现。

提交 Issue

反馈 Bug

可复现的问题请使用 Bug 反馈模板。请写清问题描述、逐步复现步骤和预期行为,并填写完整运行环境,包括 Node 或 Bun 版本、部署方式、PostgreSQL 与 Redis 状态、浏览器版本以及访问端是 Web、微信小程序还是支付宝小程序。日志和截图可以帮助定位,但必须先隐藏 token、IP、主机名、用户数据以及其他敏感信息,并说明涉及的功能模块。

提交前请确认问题确实可以复现、已经查过项目文档,并且与本项目源码或官方部署方式有关。无法稳定复现的问题,可以先在 Issue 中说明尝试过的环境和步骤,不要把猜测直接当成结论。

提出功能

新功能或改进请使用 功能建议模板。先描述当前状况和痛点,再说明期望方案;有其他可接受的做法时一并写出,并标注可能影响的端、模块或数据库,以及你认为的优先级。请先确认文档中没有已经支持或规划的方案,也不要把通用建站需求、第三方工具替代请求或个人定制要求直接当成功能建议。

空白 Issue 入口仍然保留,但无法套用模板时,也请按同样的顺序补充背景、范围、复现或验证信息,方便后续讨论。

准备开发环境

主仓库要求 Nodejs ≥ 22、PostgreSQL ≥ 14、Bun ≥ 1.3,包管理器版本以 package.json 锁定的 Bun 版本为准。克隆仓库时同时初始化小程序子模块:

Bashgit clone --recurse-submodules https://github.com/imqi1-github/imqi1-cms.git

已有仓库但 mini/ 为空时,初始化子模块:

Bashgit submodule update --init --recursive

安装主项目依赖:

Bashbun install

生成 Prisma Client:

Bashbun run prisma:generate

需要本地数据库时,使用项目提供的幂等初始化脚本:

Bashbun run db:init

启动开发服务:

Bashbun run dev

.env 中的数据库连接、COS、高德、Redis、小程序签名密钥和部署凭据只填写在本机或部署环境,不要提交到仓库。第一次运行 scripts/ 下的上传、压缩或密码重置工具前,还需要安装该目录的独立依赖:

Bashbun run scripts:install

认领 Issue 与分支

已有 Issue 时,先在 Issue 下留言说明你准备处理的范围,避免多人同时修改同一处。较大改动先经过 Issue 讨论;小范围修复也应在提交信息或 PR 中说明对应背景。

从最新的 master 创建独立分支,不要直接把未完成的改动推到 master。一个分支尽量围绕一个 Issue 或一个清晰的变更目标,发现范围需要扩大时,先回到 Issue 或 PR 中说明原因和影响。

提交信息使用 Conventional Commits,并用中文说明,例如 feat: 增加评论审核筛选、fix: 修复附件删除鉴权、docs: 补充 Docker 部署说明。代码注释保持简短,只写非显而易见的取舍或原因。

遵守硬性约定

接口与后台

公开接口只返回实际需要的字段。Prisma 查询使用 select 白名单,或逐字段构造响应,禁止用 ...row 把整条记录直接返回;内部审核状态、邮箱、IP、User-Agent 和其他非必要字段同样不能泄露。

/api/admin/* 的 POST、PUT、PATCH、DELETE 写接口必须同时完成 getUser 登录检查和 validateCsrfToken 校验。POST、PUT、PATCH 从 body 读取 csrfToken,DELETE 从 x-csrf-token 请求头读取;Referer 检查不能代替这两条检查。新增或修改后台破坏性操作时,统一使用 useConfirm() 和全局 ConfirmDialog,不使用原生 confirm() 或 alert()。

服务端捕获异常时,不能把所有错误都改成 500。带有 statusCode 的业务错误要原样抛出,Prisma 的 P2025 要返回 404,输入校验失败仍需让调用方收到 400。

数据库与类型

不要运行 prisma migrate dev 或 prisma migrate reset。本项目的数据库历史与本地迁移目录并不作为同步依据,schema 变更使用 prisma db execute 或 scripts/ 中可重复执行的幂等脚本,操作前确认真实数据库结构;数据库名使用 imqi1-cms。

前端 API 类型放在 app/types/apis,服务端 API 类型放在 server/types/apis,不要在 .ts 或 .vue 文件中重复内联公共 interface 或 type。API 响应类型优先使用 Nuxt 的 InternalApi,请求参数在 handler 附近用 zod 做局部校验。

配置与安全

Redis、高德、COS、小程序和登录相关密钥只能通过环境变量或构建期配置注入,不能写死在源码、前端 bundle 或日志中。sessionId、authCode、两步验证 challenge、信任设备密钥等令牌必须使用 crypto.randomBytes,不能用 Math.random() 和时间戳拼接。来自 cookie、query 或 body 的值在拼接文件路径前必须净化;远程资源请求要经过项目的 SSRF 防护;媒体直链统一使用 HTTPS。

涉及 Nuxt 双 bundle、Admin CSRF、鉴权回跳、Tiptap、AMap、Redis、小程序或其他已知高风险模块时,修改前先查主仓库 .claude/memory/ 中对应的记忆条目。完整的安全不变式、已知局限和威胁范围见主仓库 SECURITY.md。

本地校验

每次代码改动完成后,都在主仓库根目录立即运行三项校验,也可以用一条 bun run check 依次执行。不要把它们拖到提交前才运行:

Bashbunx eslint .
Bashbunx nuxi typecheck
Bashbun run tailwindcss:lint

如果改动了 mini/,还要运行 bun run mini:lint 和 bun run mini:type-check。如果改动了 API 或数据库,除了静态检查,还要用 curl 或浏览器实际请求对应接口;如果改动了界面,提交 PR 时准备前后对比或行为变化说明。

发起 Pull Request

完成自测后,从分支向 master 发起 Pull Request,并填写主仓库的 Pull Request 模板。PR 描述先说明做了什么、解决了什么问题,再记录自测命令和实际结果;涉及 API 或数据库时补充接口实测,涉及 UI 时附截图或可观察的行为变化。

模板中的敏感约定需要逐项确认:公开接口是否使用字段白名单,Admin 写接口是否有 CSRF,数据库 schema 是否通过安全方式修改,类型是否放在独立目录。关联已有 Issue 时,在 PR 描述中写 Fixes #123 或其他准确的关联语句,让合并后能自动更新 Issue 状态。

PR 应保持范围清晰,不要顺手混入无关格式化或未讨论的重构。收到 review 意见后,在 PR 中说明修改结果和仍待确认的取舍;维护者完成检查后再合并。版本号、tag、Release 以及双仓库同步由维护者处理,贡献者不需要自行发布版本。

安全问题与协作行为

疑似安全漏洞绝不能发到公开 Issue 或 PR。请优先使用 GitHub 仓库的 Security → Report a vulnerability,或按照 SECURITY.md 提供的备用方式私下联系,并附上脱敏的复现步骤、影响范围和修复建议。

讨论集中在代码和方案上,有分歧时给出依据并说明取舍,不进行人身攻击、骚扰、歧视或隐私披露;具体行为边界见主仓库的 CODE_OF_CONDUCT.md。违反公开接口白名单、Admin CSRF、数据库安全变更、密钥不入库和令牌强随机等硬性约定的 PR,会在修正前停止评审。