实施计划 / Implementation Plan
项目: 个人博客 v4 — Next.js + OpenNext on Cloudflare Workers 架构来源:
blog_v_4_nextjs_open_next_cloudflare_workers.md日期: 2026-03-26Project: Personal Blog v4 — Next.js + OpenNext on Cloudflare Workers Architecture source:
blog_v_4_nextjs_open_next_cloudflare_workers.mdDate: 2026-03-26
总览 / Overview
整个项目分为 11 个阶段,按依赖顺序排列。每个阶段完成后,项目应处于可部署的状态。阶段之间的并行机会在各阶段的「依赖」字段中标注。
The project is divided into 11 phases in dependency order. After each phase the project should be in a deployable state. Parallelism opportunities are noted in each phase's "Dependencies" field.
Phase 0 ──► Phase 1 ──► Phase 2 ──► Phase 3
│ │
├──► Phase 4 ◄──���────┘
│
├──► Phase 8 (search)
└──► Phase 9 (AI tooling)
Phase 2 ──► Phase 5 ──► Phase 6
Phase 2 ──► Phase 7 (analytics)
Phase 0 ──► Phase 10 (deploy, start early)
Phase 10 ──► Phase 11 (observability)
Phase 0 — 脚手架与配置基线 / Scaffolding & Config Baseline
目标 / Goal
建立可编译、可本地运行、可部署到 Cloudflare Workers 的最小项目骨架。这一阶段的产出是所有后续工作的先决条件。
Establish the smallest project skeleton that compiles, runs locally, and can be deployed to Cloudflare Workers. All subsequent phases depend on this phase.
交付物 / Deliverables
| 文件 / File | 说明 / Notes |
|---|---|
package.json |
固定依赖版本;脚本包含 dev, build, cf:build, cf:preview, cf:deploy, lint:content, ai:check |
tsconfig.json |
strict: true;路径别名 @/* 指向项目根目录 |
next.config.ts |
启用 App Router;配置 Cloudflare 兼容的 image loader;不使用 standalone 输出 |
open-next.config.ts |
使用 defineCloudflareConfig();暂不接入缓存后端 |
wrangler.jsonc |
声明 Worker 名称、compatibility_date、nodejs_compat flag;开发与生产环境分离 |
.gitignore |
排除 .open-next/, reports/, content/.generated/, .wrangler/, .env*.local |
.env.example |
列出所有必要的环境变量占位符 |
eslint.config.js + .prettierrc |
代码风格统一 |
关键依赖包 / Key Dependencies
{
"next": "^15",
"@opennextjs/cloudflare": "latest",
"wrangler": "^3",
"typescript": "^5",
"tailwindcss": "^4",
"zod": "^3",
"gray-matter": "^4",
"remark": "^15",
"remark-gfm": "^4",
"rehype-slug": "^6",
"rehype-autolink-headings": "^7",
"rehype-pretty-code": "^0",
"shiki": "^1",
"next-mdx-remote": "^5",
"heti": "^0",
"fuse.js": "^7",
"@anthropic-ai/sdk": "^0",
"@next/third-parties": "latest",
"isomorphic-dompurify": "^2",
"husky": "^9",
"lint-staged": "^15"
}验收标准 / Acceptance Criteria
-
npm run dev启动本地 Next.js dev server,无报错 / starts without errors -
npx opennextjs-cloudflare build产出.open-next/目录 / produces.open-next/ -
npx opennextjs-cloudflare preview本地 Worker 预览可访问 / local Worker preview accessible - TypeScript 编译零错误(
tsc --noEmit)/ zero TS errors - ESLint 零错误 / zero ESLint errors
Phase 1 — 内容层与数据模型 / Content Layer & Data Model
目标 / Goal
建立从 Git 仓库读取内容的完整数据管道。所有页面的数据来源都依赖这一层,必须在页面开发之前完成。
Build the complete data pipeline that reads content from the Git repository. All page data flows through this layer — it must be complete before page development.
交付物 / Deliverables
类型定义 / Type definitions
lib/content/types.ts # Post, Page, Taxonomy, GeneratedMeta 接口
内容加载器 / Content loaders
lib/content/posts.ts # getAllPosts(), getPostBySlug(), getPostsByTag(), getPostsByCategory()
lib/content/pages.ts # getPageBySlug()
lib/content/taxonomy.ts # getAllTags(), getAllCategories(), getTagCounts()
lib/content/index-builder.ts # 构建搜索索引用的轻量数据快照
Markdown/MDX 处理管道 / Processing pipeline
lib/content/processor.ts # remark + rehype 管道;代码高亮(shiki);GFM;slug 锚点
lib/content/frontmatter.ts # Zod schema 校验 frontmatter;明确报告缺失字段
首图提取 / First-image extraction
lib/content/cover-resolver.ts # cover > 正文第一张图 > 站点默认;构建期执行,结果持久化
Frontmatter Schema(Zod)
// lib/content/frontmatter.ts
const PostSchema = z.object({
title: z.string(),
description: z.string(),
date: z.coerce.date(),
updated: z.coerce.date().optional(),
tags: z.array(z.string()).default([]),
category: z.string().optional(),
draft: z.boolean().default(false),
featured: z.boolean().default(false),
author: z.string().optional(),
canonical: z.string().optional(),
summary: z.string().optional(),
seoTitle: z.string().optional(),
seoDescription: z.string().optional(),
cover: z.string().optional(),
coverAlt: z.string().optional(),
thumbnail: z.string().optional(),
thumbnailAlt: z.string().optional(),
imageCredit: z.string().optional(),
ogImage: z.string().optional(),
});示例内容 / Sample content
content/posts/hello-world.mdx # 包含各种排版元素的示例文章
content/pages/about.mdx
content/taxonomy/tags.json # 标签描述(可选)
验收标准 / Acceptance Criteria
-
getAllPosts()返回正确排序(日期降序)的文章列表,draft: true的文章在非开发环境中被过滤 -
getPostBySlug()返回含html字段(已处理的 HTML)和完整 frontmatter 的 Post 对象 - frontmatter schema 验证失败时,构建报错并指出具体文件和缺失字段
-
cover-resolver.ts能正确按优先级解析封面图,并在content/.generated/中写入 JSON 旁路文件
Phase 2 — 应用骨架与核心页面 / Application Shell & Core Pages
目标 / Goal
实现所有博客路由,完成静态生成配置。这一阶段结束时,站点应可完整浏览(无样式也可接受),并能成功部署到 Cloudflare Workers。
Implement all blog routes and configure static generation. By the end of this phase the site should be fully navigable (unstyled is acceptable) and deployable to Cloudflare Workers.
依赖 / Dependencies
Phase 0, Phase 1
交付物 / Deliverables
根布局 / Root layout
app/layout.tsx # html lang="zh-CN";字体加载;基础 meta
app/globals.css # CSS reset;设计变量(颜色、间距、字体)
路由页面 / Route pages
app/(site)/page.tsx # 首页:精选文章 + 最近文章
app/(site)/posts/page.tsx # 文章列表(分页)
app/(site)/posts/[slug]/page.tsx # 文章详情;generateStaticParams + generateMetadata
app/(site)/tags/[tag]/page.tsx # 标签页
app/(site)/categories/[category]/page.tsx # 分类页
app/(site)/archives/page.tsx # 按年月归档
app/(site)/about/page.tsx
app/(site)/projects/page.tsx
app/api/health/route.ts # 动态路由:健康检查
基础设施页面 / Infrastructure
app/sitemap.ts # 动态 sitemap
app/robots.ts
app/rss.xml/route.ts # Content-Type: application/xml
app/not-found.tsx
app/error.tsx # 'use client' error boundary
app/loading.tsx # Suspense fallback
关键实现约束 / Key Implementation Constraints
- 每个内容路由必须导出
generateStaticParams,确保完全静态生成 - 每个内容路由必须导出
generateMetadata(SEO 基础在此阶段即接入) - Server Components 优先;
'use client'仅用于error.tsx等必须的场景 dangerouslySetInnerHTML仅用于构建期生成的可信 HTML;如接入外部内容源,必须通过isomorphic-dompurify净化
验收标准 / Acceptance Criteria
-
npm run build零错误,所有内容路由呈现为静态输出 -
npx opennextjs-cloudflare preview下所有页面可访问 -
/api/health返回 200 JSON -
/rss.xml返回合法 XML,Content-Type 正确 -
/sitemap.xml包含所有已发布文章的 URL
Phase 3 — SEO 系统 / SEO System
目标 / Goal
为所有页面生成完整的、确定性的 SEO 元数据。元数据必须在构建期解析,不依赖运行时生成。
Generate complete, deterministic SEO metadata for all pages. Metadata must be resolved at build time, not at request time.
依赖 / Dependencies
Phase 1, Phase 2
交付物 / Deliverables
lib/seo/metadata.ts # buildPostMetadata(), buildPageMetadata(), buildSiteMetadata()
lib/seo/structured-data.ts # JSON-LD: BlogPosting, BreadcrumbList, WebSite
lib/seo/og.ts # Open Graph 标签生成
lib/seo/constants.ts # 站点名、默认 OG 图、baseURL 等常量
元数据层级 / Metadata cascade
- 显式
seoTitle/seoDescriptionfrontmatter 字段(最高优先级) - 文章
title/description - 站点默认值
结构化数据范围 / Structured data scope
- 文章详情页:
Article+BreadcrumbList - 首页:
WebSite+SearchAction(预留) - 所有页面:
Organization/Person(作者信息)
验收标准 / Acceptance Criteria
- 每篇文章页面包含完整的
<title>、<meta name="description">、OG 标签和<link rel="canonical"> - 每篇文章页面包含合法的
BlogPostingJSON-LD,可通过 Google Rich Results Test - 草稿文章的页面携带
noindex指令 - Sitemap 的
lastmod字段来自 frontmatterupdated字段
Phase 4 — 图片分发系统 / Image Delivery System
目标 / Goal
建立基于预定义变体的图片分发系统。应用层只消费固定变体,不暴露任意变换��数。
Establish a predefined-variant image delivery system. The application layer consumes fixed variants only — no arbitrary transformation parameters are exposed.
依赖 / Dependencies
Phase 1(封面解析逻辑复用 cover-resolver)
交付物 / Deliverables
lib/cloudflare/images.ts # getImageUrl(src, variant), VARIANT_CATALOG 常量
lib/cloudflare/loader.ts # Next.js 自定义 image loader,指向 Cloudflare 变体
components/ui/ArticleImage.tsx # 封�� next/image,自动选择变体
components/ui/CoverImage.tsx # 封面图组件,含 alt 文本和加载策略
变体目��� / Variant catalog
| Variant | 用途 / Use | 宽高比 / Aspect |
|---|---|---|
thumb-sm |
紧凑列表卡片 / compact list cards | 16:9 |
thumb-md |
首页精选 / homepage featured | 16:9 |
cover-md |
文章头图(标准)/ article hero standard | 2:1 |
cover-lg |
文章头图(高清)/ article hero hi-DPI | 2:1 |
og-cover |
社交分享 / social sharing | 1200×630 |
next.config.ts 补充 / next.config.ts addition
images: {
loader: 'custom',
loaderFile: './lib/cloudflare/loader.ts',
// 或使用 remotePatterns 指向 Cloudflare Images 域名
}验收标准 / Acceptance Criteria
- 文章列表页使用
thumb-md变体,文章详情页使用cover-md/cover-lg,社交元数据使用og-cover - 原始源图 URL 不出现在任何公开渲染的 HTML 中
-
cover-resolver.ts的三级回退(显式 cover > 正文首图 > 站点默认)通过单元测试验证
Phase 5 — UI 组件库 / UI Component Library
目标 / Goal
实现博客所需的全部 UI 组件。组件保持小而单一职责,服务端组件优先。
Implement all UI components required by the blog. Components are small, single-responsibility, and server-component-first.
依赖 / Dependencies
Phase 2(路由结构已确定), Phase 4(图片组件)
交付物 / Deliverables
文章相关 / Article
components/article/ArticleCard.tsx # 列表卡片:标题、摘要、封面、标签、日期
components/article/ArticleHeader.tsx # 文章头部:标题、作者、日期、分类
components/article/ArticleContent.tsx # 正文容器(含排版类名挂载点)
components/article/ArticleToc.tsx # 目录(client,ScrollSpy)
components/article/RelatedPosts.tsx # 相关文章推荐
components/article/CopyCodeButton.tsx # 代码块复制按钮('use client')
导航与布局 / Navigation & layout
components/layout/Header.tsx # 顶部导航:logo、菜单、暗色模式切换
components/layout/Footer.tsx
components/layout/Pagination.tsx
分类与标签 / Taxonomy
components/taxonomy/TagList.tsx # 标签云 / 标签列表
components/taxonomy/CategoryBadge.tsx
通用 / Common
components/ui/ThemeToggle.tsx # 暗色模式切换('use client')
components/ui/SearchTrigger.tsx # 打开搜索的触发按钮('use client')
验收标准 / Acceptance Criteria
- 所有内容类组件为 Server Components(无
'use client') -
CopyCodeButton、ThemeToggle、ArticleToc正确标记为'use client'且不影响 SSR 输出 - 列表页面在无封面图时优雅降级(显示站点默认图)
- 移动端响应式布局验收通过(375px、768px、1280px 三个断点)
Phase 6 — 中文排版系统 / Chinese Typography System
目标 / Goal
为文章阅读页接入 Heti 风格排版增强。增强必须局限于文章容器,不影响导航、代码块、��格等区域。支持 feature flag 快速回退。
Apply Heti-style typography enhancement to article reading pages. Enhancement must be scoped to the article container and must not affect navigation, code blocks, or tables. Support a feature flag for fast rollback.
依赖 / Dependencies
Phase 5(ArticleContent.tsx)
交付物 / Deliverables
lib/typography/heti-client.ts # initHetiForArticle();幂等;feature flag 控制
lib/typography/excluded-selectors.ts # 排除选择器常量列表
lib/typography/policy.ts # 导出排版规范常量供 lint 和 AI 提示词复用
components/article/ArticleTypography.tsx # 'use client';useEffect 挂载;返回 null
styles/heti-overrides.css # 作用域限定在 [data-article-content].heti
config/typography/chinese-typography.md # 排版规范文件(硬规则 / 软规则 / 排除区域)
Feature flag
NEXT_PUBLIC_ENABLE_HETI=true三层边界 / Three-layer boundary
lib/typography/policy.ts— 什么是规范(供 lint 和 AI 引用)ArticleTypography.tsx— 客户端初始化入口styles/heti-overrides.css— 纯视觉覆盖,作用域锁定
验收标准 / Acceptance Criteria
-
NEXT_PUBLIC_ENABLE_HETI=false时文章页样式无变化,无 JS 报错 - 代码块、表格、行内代码的字间距和字符语义不受 Heti autoSpacing 影响
- 暗色模式下文章正文对比度 ≥ 4.5:1(WCAG AA)
- 移动端(375px)段落行距、标点节奏视觉验收通过
Phase 7 — 分析系统 / Analytics System
目标 / Goal
接入 Umami(内容分析)和 Google Analytics 4(获取与转化分析)。两套系统的事件归属通过中央注册表管理,analytics 故障不影响页面渲染。
Integrate Umami (content analytics) and GA4 (acquisition and conversion analytics). Event ownership for both systems is managed through a central registry. Analytics failures must not affect page rendering.
依赖 / Dependencies
Phase 2(根布局已存在)
交付物 / Deliverables
lib/analytics/event-registry.ts # 事件名、目标系统、category、描述
lib/analytics/providers.ts # hasUmami(), hasGA4()(具体函数签名,非 Function 类型)
lib/analytics/track.ts # trackEvent();从注册表分发;fail-open;开发环境 warn
lib/analytics/route-change-debug.ts # useRouteChangeDebug();wrapped in <Suspense>
Environment variables
NEXT_PUBLIC_UMAMI_SCRIPT_URL=
NEXT_PUBLIC_UMAMI_WEBSITE_ID=
NEXT_PUBLIC_GA_ID=
NEXT_PUBLIC_ENABLE_UMAMI=true
NEXT_PUBLIC_ENABLE_GA=true
NEXT_PUBLIC_ENABLE_HETI=true # (从 Phase 6 延续)事件归属 / Event ownership
| Event | Target |
|---|---|
toc_click, copy_code, open_search, click_cover, read_related_post, scroll_depth |
umami |
outbound_link |
both |
subscribe, generate_lead, download_file, sign_up |
ga4 |
验收标准 / Acceptance Criteria
- Umami 和 GA4 各自可通过 feature flag 独立禁用,禁用时无 JS 报错
-
trackEvent('copy_code')在 Umami 不可用时静默降级,不抛出异常 - SPA 路由切换在两个系统中均正确触发 pageview(本地和 preview 环境实测验证)
- 两套系统不会同时初始化两次(无重复 pageview)
Phase 8 — 搜索功能 / Search
目标 / Goal
实现构建期生成搜索索引、前端按需加载的静态搜索方案。不引入独立搜索后端。
Implement static search: build-time index generation, on-demand client-side loading. No dedicated search backend.
依赖 / Dependencies
Phase 1(内容加载器), Phase 5(SearchTrigger.tsx)
交付物 / Deliverables
scripts/content/build-search-index.ts # 生成 public/search-index.json
lib/search/types.ts # SearchDocument, SearchResult 接口
lib/search/client.ts # 加载索引 + Fuse.js 搜索;单例模式;懒加载
components/search/SearchModal.tsx # 搜索弹窗('use client');Cmd+K 快捷键
components/search/SearchResults.tsx # 结果列表
搜索索引字段 / Index fields
interface SearchDocument {
slug: string;
title: string;
description: string;
tags: string[];
category?: string;
date: string;
summary?: string;
}构建集成 / Build integration
在 package.json 的 build 脚本中,next build 之前先运行 build-search-index:
"build": "tsx scripts/content/build-search-index.ts && next build"验收标准 / Acceptance Criteria
-
public/search-index.json在每次构建时自动更新 - 搜索���窗仅在用户触发后加载索引(初始页面加载不请求
search-index.json) - 搜索结果在输入 300ms 后响应(防抖)
- Cmd+K / Ctrl+K 触发搜索;Esc 关闭
Phase 9 — AI 编辑工具链 / AI Editorial Tooling
目标 / Goal
实现在本地和 CI 中运行的 AI 辅助内容审查工具。所有工具以 TypeScript CLI 形式存在,输出 JSON + Markdown 报告,支持 dry-run,不修改源文件。
Implement AI-assisted content review tools that run locally and in CI. All tools are TypeScript CLIs, output JSON + Markdown reports, support dry-run, and never auto-modify source files.
依赖 / Dependencies
Phase 1(content types), Phase 0(@anthropic-ai/sdk 已安装)
交付物 / Deliverables
共享基础设施 / Shared infrastructure
scripts/ai/shared/types.ts # AIReport, AISuggestion, ExecutionMode 接口
scripts/ai/shared/client.ts # Anthropic 客户端;重试;超时
scripts/ai/shared/schema-validator.ts # Zod 验证模型输出
scripts/ai/shared/file-resolver.ts # 解析 file | glob | changed-files 执行模式
scripts/ai/shared/reporter.ts # 写 JSON 到 reports/ai/;写 Markdown 摘要
四个 CLI 工具 / Four CLI tools
scripts/ai/proofread.ts # 校对:拼写、语法、标点风格
scripts/ai/summarize.ts # 生成/校验 summary 字段建议
scripts/ai/seo-suggest.ts # 生成 seoTitle、seoDescription 建议
scripts/ai/typography-review.ts # 排版审查:段落长度、中英混排、标题层级
提示词模板 / Prompt templates
prompts/proofread.md
prompts/summarize.md
prompts/seo-suggest.md
prompts/typography-review.md
执行模式 / Execution modes
# 单文件
tsx scripts/ai/proofread.ts --file content/posts/my-post.mdx
# Glob 批量
tsx scripts/ai/proofread.ts --glob "content/posts/*.mdx"
# 仅变更文件(CI 用)
tsx scripts/ai/proofread.ts --changed-files验收标准 / Acceptance Criteria
- 每个 CLI 工具在
--dry-run模式下不写入任何文件 - 模型输出未通过 Zod schema 验证时,工具退出码非零并报告原因
-
reports/ai/下生成.json+.md两种格式的报告 - AI 服务不可用时(网络断开),工具退出码非零但不影响站点构建
Phase 10 — 部署流水线 / Deployment Pipeline
目标 / Goal
建立可重复的、fail-fast 的 CI/CD 流水线。部署流程与 AI 内容检查流程分离。
Establish a repeatable, fail-fast CI/CD pipeline. The deployment workflow and AI content check workflow are separate.
依赖 / Dependencies
Phase 0(配置文件), Phase 2(可构建的应用)
交付物 / Deliverables
.github/workflows/deploy.yml
触发条件: push to main
步骤:
1. Checkout
2. Setup Node + cache
3. npm ci
4. 内容 lint(硬性门禁)
5. tsc --noEmit
6. next build
7. opennextjs-cloudflare build
8. opennextjs-cloudflare deploy (使用 CLOUDFLARE_API_TOKEN)
.github/workflows/ai-content-check.yml
触发条件: pull_request(内容文件变更时)
步骤:
1. Checkout
2. Setup Node + cache
3. npm ci
4. tsx scripts/ai/proofread.ts --changed-files
5. tsx scripts/ai/typography-review.ts --changed-files
6. Upload reports/ as artifact
7. (可选) Post PR comment summary
注意: AI 步骤失败时降级为 warning,不阻断 PR
环境变量管理 / Environment variable management
| 变量 / Variable | 存储位置 / Location |
|---|---|
CLOUDFLARE_API_TOKEN |
GitHub Actions Secret |
ANTHROPIC_API_KEY |
GitHub Actions Secret |
NEXT_PUBLIC_* |
GitHub Actions Variable |
| 本地开发 / local dev | .env.local(不提交) |
验收标准 / Acceptance Criteria
-
main分支的 push 触发完整部署,全流程无需人工干预 - 内容 lint 失败时部署不继续
- AI 内容检查报告作为 GitHub Actions artifact 可下载
- 部署成功后
https://<worker>.workers.dev/api/health返回 200
Phase 11 — 可观测与运维 / Observability & Operations
目标 / Goal
建立构建、运行时和部署的可见性基础。运维基线保持轻量但必须显式。
Establish visibility into build, runtime, and deployment states. The operational baseline is lightweight but must be explicit.
依赖 / Dependencies
Phase 10(部署已工作)
交付物 / Deliverables
构建报告 / Build reports
scripts/ci/build-report.ts # 收集页面数量、静态路由列表、构建耗时;写入 reports/build/
运行时监控 / Runtime monitoring
app/api/health/route.ts # 返回 { status, version, timestamp, env }(已在 Phase 2 建立)
告警配置 / Alert configuration(文档化,不代码化)
config/ops/monitoring.md # 告警规则文档:
# - 部署失败 → GitHub Actions notification
# - /api/health 连续失败 → Cloudflare Alert
# - 构建时间超过阈值 → 构建报告 flag
操作手册 / Operations runbook
config/ops/runbook.md # 常见操作:回滚、缓存清理、环境变量更新、bindings 变更
验收标准 / Acceptance Criteria
- 每次部署后
reports/build/下有可读的构建摘要 -
/api/health返回当前部署的版本信息(与package.json版本一致) - 部署失败的 GitHub Actions 通知已配置
-
runbook.md覆盖所有 Phase 10 部署产物的常见操作场景
实施顺序图 / Implementation Sequence
Week 1-2 │ Phase 0: Scaffolding
Week 2-3 │ Phase 1: Content Layer
Week 3-4 │ Phase 2: Core Pages ← 同步: Phase 10 基础部署
Week 4 │ Phase 3: SEO
Week 5 │ Phase 4: Image Delivery ← 同步: Phase 8 Search index
Week 5-6 │ Phase 5: UI Components
Week 6 │ Phase 6: Typography ← 同步: Phase 7 Analytics
Week 7 │ Phase 9: AI Tooling
Week 7-8 │ Phase 10: Full CI/CD ← Phase 11 Observability
全局约束与原则 / Global Constraints
以下约束适用于所有阶段,不重复在各阶段中列出:
These constraints apply to all phases and are not repeated per phase:
- TypeScript strict —
tsconfig.json的strict: true始终开启;禁止使用any和Function类型 - 模块小 — 每个文件单一职责;helper 不超过 150 行
- 无隐藏全局状态 — 禁止 module-level mutable state;Cloudflare bindings 通过
getCloudflareContext()显式传入 - 配置走环境变量 — 所有部署相关、密钥相关的值都通过
process.env注入 - Dry-run 支持 — 所有 AI 脚本和内容修改脚本必须支持
--dry-run选项 - fail-open for enhancements — 排版增强、analytics、搜索功能出错时静默降级,不影响页面渲染
- fail-closed for auth — 私有资源的访问控制出错时拒绝访问(默认安全)
- AI 不在请求路径上 — 任何 AI API 调用只发生在本地 CLI 或 CI 中
完成定义(引自架构文档)/ Definition of Done (from architecture doc)
当开发者能够在 Git 中编写 Markdown 或 MDX 内容,使用 Next.js 静态生成博客页面,通过 OpenNext 将站点部署到 Cloudflare Workers,在本地和 CI 中运行 AI 编辑检查,并同时获得机器可读与人工可读的报告,而且整站在运行时对 AI 服务没有任何依赖时,就可以认为这套架构已经完成落地。
The architecture is considered implemented when a developer can author Markdown or MDX content in Git, statically generate blog pages through Next.js, deploy the site to Cloudflare Workers using OpenNext, run AI editorial checks locally and in CI, review machine-readable and human-readable reports, and operate the site without any runtime dependence on AI services.