Add Zod validation layer and AI blog generation
Introduce a schema-first validation layer and an AI blog generation feature, plus one-command Cloudflare provisioning. - src/schemas/ holds Zod input schemas for post, content, case, settings, AI, and keywords; parseForm() in src/lib/form.ts validates FormData and returns per-field errors. - Migrate all admin POST handlers to parseForm, showing field-level errors and only redirecting once validation passes. - Add blog_keywords table and posts.focus_keyword (migration 0002); uniqueSlug() centralised in src/data/content.ts. - Add src/lib/ai.ts (OpenAI-compatible chat completions + optional Tavily research) and /admin/ai for AI settings, keyword queue, and draft generation. - Add scripts/setup.mjs (npm run setup) to provision D1/KV, set secrets, and optionally migrate, seed, and deploy. - Document AI secrets, Workers Builds deploy flow, and new schemas across README and AGENTS docs.
This commit is contained in:
@@ -9,14 +9,18 @@ Astro 7 + React 19 + Chakra UI v3,部署在 Cloudflare Workers(單一 Worker
|
||||
- `npm run preview` / `npm run deploy` — build 後用 wrangler dev / deploy
|
||||
- DB(本機用 `:local`,雲端省略):`npm run db:generate` → `db:migrate:local` / `db:migrate` → `db:seed:local` / `db:seed`
|
||||
- `npm run types` — 重新產生 `worker-configuration.d.ts`;`npm run secret` — 設定 `ADMIN_PASSWORD`
|
||||
- `npm run setup` — 一鍵 Cloudflare provision(建 D1 / KV、寫 `wrangler.jsonc`、設 secret、可選套 migration + seed)
|
||||
- 沒有 test / lint / typecheck script(未安裝 @astrojs/check)。`npm run build` 是唯一可跑的驗證。
|
||||
|
||||
## 關鍵慣例與陷阱
|
||||
|
||||
- **SSR 頁面必須自己聲明**:`astro.config.mjs` 是 `output: "static"`,所有要讀 D1 的動態頁面都靠檔案內 `export const prerender = false`(首頁、blog、admin、sitemap/robots)。新增需要 request-time 資料的頁面時一定要加。
|
||||
- **SSR 頁面必須自己聲明**:`astro.config.mjs` 是 `output: "static"`,所有要讀 D1 的動態頁面都靠檔案內 `export const prerender = false`(首頁、blog、admin、sitemap.xml)。新增需要 request-time 資料的頁面時一定要加。
|
||||
- **環境變數只用 `getEnv()`**(`src/lib/env.ts`,底層 `cloudflare:workers` 的 `env`)。Astro v6 起已移除 `Astro.locals.runtime.env`。`getEnv()` 只能在 `prerender = false` 的頁面/endpoint 用。
|
||||
- **資料層**:`getDb(getEnv().DB)` → Drizzle;查詢集中在 `src/data/content.ts`,schema 在 `src/db/schema.ts`。改 schema 後跑 `npm run db:generate` 產生 migration。
|
||||
- **Seed 與 migration 是分開的**(README 講法有誤):`db:migrate:local` 只套 migrations,`migrations/seed.sql` 要用 `db:seed:local` 另外執行;seed 可重複跑。
|
||||
- **Seed 與 migration 是分開的**:`db:migrate:local` / `db:migrate` 只套 migrations,`migrations/seed.sql` 要用 `db:seed:local` / `db:seed` 另外執行;seed 可重複跑。
|
||||
- **表單驗證集中在 `src/schemas/`**(Zod)+ `src/lib/form.ts` 的 `parseForm(form, schema)`:admin 頁面唔好再手寫逐欄驗證。實體輸入型別用 `z.infer` 由 schemas 匯出。
|
||||
- **AI Blog**:`src/lib/ai.ts`(OpenAI 相容 chat completions + Tavily)+ `/admin/ai`;同步生成、一律存草稿並標記關鍵字 `generated`。需要 secrets `AI_API_KEY`(必需)/`TAVILY_API_KEY`(可選);未設時回明確錯誤,唔會 throw。
|
||||
- **部署用 Cloudflare Workers Builds**(Git push 自動):build `npm run build`、deploy `npx wrangler deploy`。**Migration 唔會喺 CI 執行**,改 schema 要手動 `npm run db:migrate`(雲端)。
|
||||
- **`wrangler.jsonc` 有佔位 id**:`database_id` / KV `id` 要先用 `db:create` / `kv:create` 產生再貼上,未貼前無法部署。
|
||||
- **上線前要改 `astro.config.mjs` 的 `site`**:sitemap / canonical / OG 全部靠它(現為 `https://example.com`)。
|
||||
- **後台認證**:`src/middleware.ts` 保護所有 `/admin`,用 HMAC-signed cookie(`src/lib/auth.ts`);未設 `ADMIN_PASSWORD`(本機在 `.dev.vars`,已 gitignore)會回 503。
|
||||
@@ -110,12 +114,12 @@ When the user requests a durable behavior change, record it here or in the relev
|
||||
|
||||
| Path | Scope |
|
||||
|---|---|
|
||||
| `src/AGENTS.md` | 原始碼全層:架構、跨層慣例;擁有 `theme/`、`layouts/`、`config.ts`、`middleware.ts`、`env.d.ts`,以及 `pages/` 路由與 `/admin` 後台合約 |
|
||||
| `src/AGENTS.md` | 原始碼全層:架構、跨層慣例;擁有 `theme/`、`layouts/`、`schemas/`、`config.ts`、`middleware.ts`、`env.d.ts`,以及 `pages/` 路由與 `/admin` 後台合約 |
|
||||
| `src/components/site/AGENTS.md` | 前台 React island 與 Chakra UI 元件 |
|
||||
| `src/data/AGENTS.md` | D1 讀取查詢層與後台設定欄位定義 |
|
||||
| `src/db/AGENTS.md` | Drizzle schema(migration 的唯一來源) |
|
||||
| `src/lib/AGENTS.md` | auth / env / db / markdown 基礎工具 |
|
||||
| `src/lib/AGENTS.md` | auth / env / db / form / ai / markdown 基礎工具 |
|
||||
| `migrations/AGENTS.md` | D1 migration 與 seed SQL |
|
||||
| `docs/AGENTS.md` | 設計規格與實作計劃(`superpowers/` 為設計權威) |
|
||||
|
||||
Project-level files with no child doc are owned by this root: `astro.config.mjs`、`wrangler.jsonc`、`drizzle.config.ts`、`tsconfig.json`、`package.json`、`README.md`、`.dev.vars.example`。
|
||||
Project-level files with no child doc are owned by this root: `astro.config.mjs`、`wrangler.jsonc`、`drizzle.config.ts`、`tsconfig.json`、`package.json`、`README.md`、`.dev.vars.example`、`scripts/`。
|
||||
|
||||
Reference in New Issue
Block a user