- 与用户沟通、代码注释、文档、日志和面向用户的界面文案,尽量使用中文。
- 技术专有名词、代码标识符、第三方库名称和命令可保留英文,以保证准确性与可检索性。
- 供
irm ... | iex直接执行的 PowerShell 安装脚本必须保存为 UTF-8 无 BOM;BOM 会被管道执行当作脚本首字符,导致CmdletBinding解析失败。Windows 安装脚本的 CPU 架构检测应优先使用PROCESSOR_ARCHITEW6432、PROCESSOR_ARCHITECTURE等环境变量,不能依赖旧版 .NET 中可能为空的RuntimeInformation.OSArchitecture。当前目录名已是certd-client时默认安装目录必须使用当前目录,不能重复追加。AtomGit 附件地址应从最新 Release API 的browser_download_url获取,不能套用 GitLab 风格的 permalink;候选下载源即使返回 HTTP 200 也必须先校验 ZIP 或tar.gz内容,校验失败应记录原因并自动尝试下一源。对此保留自动化检查。
- 新功能、缺陷修复和重构遵循测试驱动开发:先编写或更新测试,再运行测试确认 RED,最后实现最小改动并确认 GREEN。
- 测试应覆盖正常路径、边界条件和明确的错误处理;优先为扫描、数据库和交互状态等核心逻辑添加自动化测试。
- 交付前至少执行相关测试;对 Go 代码默认执行
go test ./...和go vet ./...,无法执行时应说明原因。
- 开始工作前阅读
readme.md,将其描述的 Certd 客户端目标作为设计和实现的边界。 - 当前重点是本机应用与站点扫描、证书部署支持、终端 UI 和 CLI;实现应兼容本地服务器及常见面板环境,避免偏离这些目标的无关改造。
- 应用类型的发现和站点解析必须通过已注册的
app_provider实现;新增应用类型时提供对应 Provider,而不是在 TUI 主流程中增加类型分支。 - Provider 自行维护其应用特征识别和配置解析;可复用的目录遍历、进度统计放在
internal/app_provider,不创建独立的internal/scanner层。 - Provider 的类型专属行为应定义为具体 Provider 结构体的方法;包级仅保留构造函数等不依赖实例的入口。
- Linux/Windows 目录扫描遇到权限不足或枚举后已消失的瞬时目录(例如
/proc/<pid>)时应跳过该目录并记录可读的提示,不应因单个受限目录中断整个扫描;根目录本身不可读时仍应返回明确错误。 - 应用发现遍历必须跳过
docker/overlay2及其子目录,避免将容器文件系统层误识别为宿主机应用安装目录。 - IIS Provider 不递归扫描用户输入目录;通过执行
appcmd list site确认 IIS 安装,并以inetsrv为应用根目录,站点配置从config/applicationHost.config解析。 - IIS 证书部署不写入 PEM 文件路径;应将 Certd 返回的 PFX 通过 PowerShell 导入
LocalMachine\My证书存储,FriendlyName 使用主域名和证书到期时间,再用WebAdministration按 IIS 站点名称更新全部 HTTPS 绑定,并验证全部绑定使用的新证书有效期。 - Windows 上的 Apache Provider 应先按可执行文件路径定位对应服务;找到服务时使用
net stop <服务名>、net start <服务名>重启,兼容宝塔注册的apache服务;未找到服务时才使用带-f配置文件路径的httpd -k graceful重载。Windows 命令输出按 GBK 解码后再写入日志和错误信息。 - Nginx Provider 解析配置中相对证书路径和执行重载时必须使用同一有效 prefix:优先读取运行中同一
nginx.exe命令行的绝对-p,无法读取或未设置时使用登记的应用根目录;重载须将进程工作目录设为该 prefix,并传入-p <prefix>与相对 prefix 的-c <nginx.conf>,不能依赖客户端当前工作目录。 - Nginx 站点扫描必须从主
nginx.conf递归解析include指令,支持通配符和绝对路径,以覆盖面板位于应用根目录之外的虚拟主机目录;已包含的配置文件按规范路径去重后再解析。 - 证书同步由已注册 Provider 的部署能力执行,TUI 不按应用类型分支写入证书文件;非 HTTPS 站点不参与同步。Certd 返回申请中或暂未返回证书时应重试,只有 Certd 证书有效期晚于本地证书才部署。证书部署成功后,Nginx、Apache 和 IIS Provider 必须分别执行配置重载、服务重启或绑定刷新使证书生效;需要重启才能生效的 Provider 应在部署后重启并验证证书,验证失败计入同步异常。同步失败需汇总原因并调用 Certd 默认通知渠道,标题使用
【Certd Client】 证书同步失败【数量:N】(本机名称)格式;未填写本机名称时使用主机名和 IPv4。 - 证书请求阶段最多同时处理 3 个站点;并发仅限 Certd 证书获取和申请轮询,证书写入、状态更新、应用重启及部署后验证必须保持串行,避免 Provider 和数据库状态竞争。
- 同步中的请求、等待、重试、失败和完成日志必须包含应用类型、站点 ID 与域名,确保并行处理时能定位当前站点。
- 证书同步编排统一放在
internal/syncservice,供 TUI、CLI 和定时任务调用;TUI 仅负责读取界面设置、转发进度和展示结果。一个应用的多个站点完成证书文件写入后最多重启一次;重启失败须将本批已写入站点全部标记失败,单个站点写入失败不得阻断同一应用其余站点的部署和重启。 - CLI 的
sync与start每一轮必须先执行已登记应用的站点扫描,再执行证书同步;定时任务使用start --cron的五段 Cron 表达式,启动成功后立即执行一轮,并在每轮结束后打印下次执行时间;未指定时后续按进程启动的小时和分钟每天运行一次。定时任务与 TUI/CLI 共用同一编排服务,不在入口重复实现业务流程。同步任务必须接受context.Context,TUI 按Esc取消时停止后续请求、部署、重启和失败通知;定时任务响应Ctrl+C与SIGTERM。 - CLI 批处理任务的阶段切换必须输出清晰的分隔标题(例如站点扫描、证书同步),每轮结束必须输出成功、跳过、失败数量的执行总结;失败明细继续逐行保留,便于脚本日志排查。
- CLI 批处理模式的启动、进度、总结、错误和下次执行时间必须同时写入标准输出与
./logs/日志文件,不能只写文件导致交互终端无反馈。 - Certd 请求失败的执行日志必须包含接口返回的具体
message,不能只显示“请求失败”等泛化文本;申请中等待日志同样应保留具体原因。 - 请求 Certd 证书接口时必须发送
autoApply: true和autoApplyTemplateId: 0,使用 Certd 默认申请模板。 - Certd 开放接口错误码:
20000ApiToken 错误、20001ApiToken 签名错误、20002ApiToken 时间戳错误、20003不支持的签名类型、20010请求参数错误、20011证书不存在、20012证书还未生成、20013证书正在申请中、20014域名校验方式未配置、20015流水线执行异常、20021用户邮箱未配置。只有连续返回20013时使用后台长轮询,不得立即报同步失败,轮询间隔为 10 秒;轮询过程中一旦返回其他错误,必须立即失败,不得继续长轮询。最长等待时长由 Certd 接口设置中的分钟数决定,默认 10 分钟。首次或后续发生的其他接口错误最多重试 3 次,重试间隔不得少于 6 秒。 - 客户端版本统一由
internal/version.Version管理,必须符合 Node.js SemVer;发布标签使用vX.Y.Z,版本号按 Conventional Commits 自动递增,破坏性变更为 major、feat为 minor、fix与perf为 patch;未出现上述类型时默认升 patch。CHANGELOG 仅记录feat、fix、perf类型的提交(包含 scope 与!标记)。scripts/release.ps1必须在修改版本、提交、打标签和推送之前执行本地go test ./...与go vet ./...,任一失败即取消发布;首次发布尚无v*标签时,CHANGELOG 必须包含完整 Git 历史,后续发布仅记录上一版本标签后的提交。发布脚本生成或改写文本文件时必须使用 UTF-8 无 BOM,保证中文 changelog 在跨平台工具中可读;读取 Git 中文历史须显式按 UTF-8 解码,并将标准输出与标准错误分开处理。 - GitHub 发布流程需先完成跨平台构建并创建 GitHub Release;Release 正文必须提取
CHANGELOG.md中当前版本段的提交条目,不能使用 GitHub 自动生成的 Full Changelog。GitHub push 通过atomgit.com同步代码,GitHub Release 发布成功后通过https://api.atomgit.com/api/v5创建同版本 Release;创建请求必须显式传入 AtomGit 支持的release_status: "latest"(预发布使用pre),不能使用published或依赖服务端默认状态。附件先调用releases/{tag}/upload_url获取签名地址,再按返回的请求头使用PUT上传。所有 AtomGit 令牌只能通过 GitHub Secret 传入,禁止写入仓库。 - 所有 GitHub Actions 工作流必须提供
workflow_dispatch,以支持从 GitHub 页面手动触发;手动发布或同步 Release 时应提供可选或必填的版本标签输入,避免误用当前分支名。 - GitHub 到 AtomGit 的代码同步必须先将 GitHub 分支 fetch 到
refs/remotes/origin/*,再显式映射推送至 AtomGit 分支,不能 fetch 到可能已检出的本地分支;AtomGit 作为镜像时可强制更新其分支和标签。 - 平台专用实现的测试必须仅在对应平台执行;发布工作流的测试矩阵至少覆盖 Linux 与 Windows,避免 Linux CI 漏测 Windows 专用行为。
- 当前应用尚未发布,数据库结构变更不需要维护向下兼容逻辑。
- 所有数据库表和后续字段、索引变更统一通过 GORM
AutoMigrate自动同步,不手写迁移脚本。 - 修改 GORM 模型时必须考虑已有数据执行
AutoMigrate的行为;新增字段优先设置安全的default值,或不要设置not null,避免 SQLite 因历史记录无法填充而启动失败。 - 客户端的可扩展设置统一保存到
settings表:以key区分设置类型,setting使用longtext保存 JSON;不为单个设置类型创建专用配置表。 - 每个数据模型使用独立 Repository;跨模型的原子操作由所属业务仓库协调事务,不将站点或设置 CRUD 堆叠到应用仓库中。
- 站点模型使用
AppId、Https字段,对应数据库小写列app_id、https;不要使用全大写缩写字段名。 - 每次应用扫描前检查已登记根目录;丢失目录标记为禁用,禁用应用不参与站点扫描,重新发现同路径时恢复启用。
- Windows 平台比较应用根目录时必须忽略路径大小写,等价路径应更新已有应用,不能重复插入。
- 删除已登记应用时,必须在同一数据库事务中删除其全部站点记录,避免留下孤立的
app_site数据。 - 站点支持单独启用或禁用;禁用站点不参与证书同步,也不计入应用的站点、HTTPS 站点及同步状态统计;后续扫描发现同一站点时应保留其状态。
- 站点同步写入前必须按
primary_domain + config_path + app_id去重;同一身份的重复结果优先保留 HTTPS 和证书路径信息。Windows 比较config_path时忽略大小写。
- Windows 平台启动客户端时应检测管理员权限;未提升时通过 UAC 重新启动当前可执行文件,非 Windows 平台不进行提权。
- 顶部菜单使用直角边框;左右键和上下键均可选择菜单,当前菜单项下方必须显示中文帮助说明。
- 顶部菜单的“定时同步”按 Enter 后必须退出 TUI 并复用 CLI
start模式,以默认每日 Cron 立即执行一轮后继续定时运行。 - 耗时的扫描和 I/O 操作必须在后台执行,不能阻塞终端界面的键盘响应和重绘。
- 长时间扫描开始时立即记录日志;执行超过 10 秒后,每 10 秒输出一次进度,至少包含已处理数量和当前待处理数量。
- 站点扫描完成提示必须汇总发现总数、保留的禁用站点数、启用的 HTTPS 站点数和新增站点数;存在错误时同时显示失败数。禁用站点不计入 HTTPS 与同步统计。
- 执行日志需要有独立边框、每条记录的本地时间,并支持
PageUp/PageDown分页浏览。 - 日志中的换行与超长文本必须按日志内容区可用宽度折行,折行后的实际高度须参与布局计算,不能越过边框或触发终端滚屏。
- TUI 任一渲染行都应保留终端最后一列,避免 Windows 终端在满宽输出时自动换行,造成增量重绘错位或残留内容。
- 证书同步的进度日志、失败汇总和通知内容必须包含应用类型、站点 ID 与站点域名,方便定位具体部署目标。
- 整个 TUI 输出必须适配当前终端高度;空间不足时优先压缩日志可见行并截断数据列表,不能因终端滚屏让旧内容混入菜单或其他区域。
- 已登记应用以表格展示,包含清晰表头、应用 ID、应用类型、安装目录和站点数量;不展示添加时间作为常规列表列。站点管理列表同样显示站点 ID。
- 表格中的安装目录和配置文件路径列必须随可用终端宽度扩展,并仅在空间不足时截断;省略号的预留宽度必须与实际显示字符一致。
- 应用列表的站点数、HTTPS 站点数、已同步和异常列必须使用固定列宽,表头与数据行使用同一组宽度。
- 应用和站点表格的表头与数据行之间必须显示横向分隔线,且分隔线宽度与表格内容区一致。
- 通过键盘触发的管理操作必须在对应视图中有可见提示,不能依赖用户猜测快捷键。
- 站点管理列表必须显示站点启用状态,并支持用键盘切换状态。
- 每次任务收尾时,回顾用户提出的要求,识别其中可跨任务复用、稳定且不与既有规范冲突的约束。
- 将这些共性要求精炼后更新本文件;一次性的任务细节、临时偏好和未经确认的推断不写入长期规范。
- 更新后检查规则是否清晰、可执行且没有重复或互相矛盾的表述。