diff --git a/.spec/specs/2026-10-25_add-blog-launch/spec.md b/.spec/specs/2026-10-25_add-blog-launch/spec.md new file mode 100644 index 0000000..96835ba --- /dev/null +++ b/.spec/specs/2026-10-25_add-blog-launch/spec.md @@ -0,0 +1,77 @@ +# Phase 4:极客层 P1 + 发布链闭环 + 上线准备 - 项目范围 + + + +## 1. 问题定义 +- **项目目标**:命令面板 + 贡献热力图(极客层 P1);gitea webhook→构建→staging 发布闭环;预发布全端验收;一键上线脚本(用户 sudo 执行)与回滚配套 +- **目标用户**:站长(发布即构建;一条命令上线) +- **核心价值**:从"staging 就绪"到"可上线状态"的全部工程准备 + +## 2. 假设与待确认 + +### 2.1 已确认事实 +- gitea heatmap API 匿名可用(调研 05 实测:/api/v1/users/{u}/heatmap,CORS *,返回 {contributions,timestamp}[]) +- gitea admin token 在宿主 init-credentials.txt(webhook 注册用) +- staging 全量内容 21+2 页(zh/en)+ photos-originals +- SearchDialog 已有 Pagefind 懒加载与 / 键入口(面板升级的基座) + +### 2.2 关键假设 +- gitea webhook 目标 URL 用 http://127.0.0.1:13020 能回环触达本机接收器(同宿主) +- ESA 对静态资源缓存友好(hash 文件名 + immutable) + +### 2.3 待确认问题 +- [x] 上线切换执行者 → 结论:脚本备好,用户 sudo 执行(红线:nginx 属 root 域) + +### 2.4 可选解释与取舍 +- 命令面板升级现有 SearchDialog(保 Pagefind 数据面)> 引 cmdk/kbar(拖 React 运行时)-> 选自写扩展 +- 热力图构建时拉取 + 仓内缓存兜底 > 运行时拉(静态站纪律)-> 选构建时 + +### 2.5 已证伪路径 +- 无 + +## 3. 功能范围 + +### 3.1 核心功能(MVP) +- [ ] T1 命令面板(搜索+导航+动作聚合) +- [ ] T2 gitea 贡献热力图(构建时+兜底) +- [ ] T3 webhook HMAC 闭环(验签+注册+push→build→staging 实测) +- [ ] T4 预发布全端验收(渲染矩阵+OG+微信 UA+responsive) +- [ ] T5 上线脚本与回滚配套+检查单 +- [ ] T6 验收归档 + +### 3.2 扩展功能 +- /terminal 彩蛋、书评索引画廊(Phase 5 二期池) + +### 3.3 不在范围内 +- 实际执行上线切换(用户动作)、Halo 停用(Phase 5) + +## 4. 最小实现路径 +- 最简单可行方案:面板=SearchDialog 扩展动作层;热力图=lib fetch+缓存 JSON+纯 CSS 组件;webhook=现骨架填 HMAC +- 暂不引入:常驻接收服务(gitea 直接 POST 本机脚本经 systemd-path 或手动验证模式) +- 不做的抽象/配置化:多 webhook 源、面板插件系统 + +## 5. 技术决策 +- 技术栈:vanilla TS/CSS + gitea API + shell +- 证据协议:evidence: runs +- 本轮允许改动:src/、infra/deploy/、scripts/、.spec/ +- 本轮不应触碰:/etc/nginx(脚本只生成不安装)、生产 Halo、content/ +- Git integration branch:`spec/2026-10-25_add-blog-launch` + +### 5.1 验证策略 +- 范围级别:package +- 变更对象:面板/热力图组件、webhook 脚本、上线脚本 +- 快速检查:`pnpm astro build` +- 集成检查:面板动作标记与热力图格子产出;webhook 干跑+真实 push 全链;验收矩阵脚本 +- 全项目检查:staging 全端验收矩阵 + rollback-dryrun;仅在 nginx 面或部署链变更时升级范围 +- 升级触发:只有上线脚本被执行(nginx 实切换)时,才升级为全项目验证并记录(当前包内只备不执行) + +## 6. 成功标准与验证方式 +- [ ] 面板含 ≥3 动作与全站导航(dist 标记断言) -> verify: task_0001 +- [ ] 热力图渲染 ≥52 周格子且失败兜底不破构建 -> verify: task_0002 +- [ ] 真实 push 触发构建并更新 staging 戳 -> verify: task_0003 +- [ ] 验收矩阵脚本全绿(渲染/OG/微信 UA/responsive) -> verify: task_0004 +- [ ] 上线脚本 --dry-run 通过且检查单落档 -> verify: task_0005 + +## 7. 风险与约束 +- webhook 回环接收的安全面(监听面收窄到 127.0.0.1 + HMAC 强制)-> T3 覆盖 +- 上线脚本误执行 -> 只生成不安装,--dry-run 默认,真实执行需用户显式 sudo diff --git a/.spec/specs/2026-10-25_add-blog-launch/tasks.md b/.spec/specs/2026-10-25_add-blog-launch/tasks.md new file mode 100644 index 0000000..8d1565b --- /dev/null +++ b/.spec/specs/2026-10-25_add-blog-launch/tasks.md @@ -0,0 +1,43 @@ +# Phase 4:极客层 P1 + 发布链闭环 + 上线准备 - 任务拆解 + +## 使用规则 +- boundary/verify 齐备;verify 只读断言(Phase 2 教训);上线脚本绝不自动执行 + +## 阶段一:实现 + +- [ ] T1 命令面板 + - claim: op-gitea(mesh 车道,预约 src/components/CommandPalette.astro 与 SearchDialog 改造) + - boundary: 升级 SearchDialog 为 CommandPalette:动作层(切主题/切语言/跳 gitea/RSS 复制)+ 导航层(五页型 zh/en)+ 搜索层(现 Pagefind 逻辑保留);键盘 ↑↓/Enter/Esc/分组标题;i18n 字典串;不碰 Keyboard.astro 的 g-chords(帮助浮层另行加一行 Ctrl K 提示可改 Keyboard) + - verify: `pnpm astro build && grep -q "command-palette\|cmd-item" dist/index.html` + +- [ ] T2 gitea 贡献热力图 + - claim: op-artalk(mesh 车道,预约 src/lib/heatmap.ts 与 src/components/geek/Heatmap.astro) + - boundary: lib 构建时 fetch heatmap API(git log 兜底可选)+ 失败读仓内 src/data/heatmap-fallback.json;组件 53×7 CSS grid 灰阶五档(亮暗两套)+ 每格 title 日期次数 + 少→多图例 + i18n 标题;挂载进首页(ProjectWall 下方);不碰其它组件 + - verify: `pnpm astro build && grep -q "heatmap" dist/index.html` + +- [ ] T3 webhook HMAC 闭环 + - depends-on: 无 + - claim: orchestrator + - boundary: infra/deploy/webhook-receive.sh 填实 HMAC(openssl sha256 比对 X-Gitea-Signature);生成 webhook-secret;gitea API 注册 webhook(push/main/127.0.0.1 接收端点);接收端常驻方式用 python http.server 微型包装(监听 127.0.0.1:13021,仅 HMAC 通过触发 build.sh);实测一次 push→build→staging 戳更新 + - verify: `curl -sf http://127.0.0.1:13021/healthz && grep -q "built at" ~/docker_apps/blog/www-staging/.build-stamp` + +- [ ] T4 预发布全端验收 + - depends-on: task_0001, task_0002 + - claim: orchestrator + - boundary: scripts/preflight.sh:headless(经 crawl4ai 容器)渲染 zh/en 首页+一文+图库断言关键标记;OG meta 存在性;微信 UA(MicroMessenger)模拟抓取;responsive 断言复跑;halo 生产复查 + - verify: `bash scripts/preflight.sh` + +- [ ] T5 上线脚本与检查单 + - claim: orchestrator + - boundary: infra/deploy/launch.sh(root 执行):备份 vhost→wait4x.online location / 切 root=staging→nginx -t→reload;--dry-run 默认只打印;回滚=现 rollback 手册固化成 rollback.sh;docs/上线检查单.md(含 ESA 刷新步骤) + - verify: `bash infra/deploy/launch.sh --dry-run` + +- [ ] T6 验收归档 + - depends-on: task_0003, task_0004, task_0005 + - claim: orchestrator + - boundary: 全 verify 复跑 + 板房汇报 + 归档提交 + - verify: `bash scripts/preflight.sh && bash infra/deploy/launch.sh --dry-run` + +--- + +**当前进度**:由脚本计算,无需手动维护