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.
1.8 KiB
1.8 KiB
src/data/AGENTS.md
Purpose
D1 讀取查詢層(content.ts)同後台網站設定欄位定義(settings-fields.ts)。
Ownership
- 擁有
src/data/兩個檔案。 - Drizzle schema 本體喺
src/db/schema.ts(見兄弟db/AGENTS.md),呢度只消費其 select 型別;表單同 AI 嘅輸入型別由src/schemas/(Zodz.infer)提供,兩者唔重覆。
Local Contracts
- 查詢集中:所有前台/Blog 的 D1 查詢寫喺
content.ts,唔好散落喺頁面或元件。 - 只回前台可見:
getItems/getCases/getPublishedPosts只回status = "published",並按sortOrder或publishedAt DESC排序;getPostBySlug同時要求 published。 - 首頁聚合:
getHomeData(db)用Promise.all一次過攞 settings + services/features/steps/faqs + cases,形狀係HomeData。 - 關鍵字佇列:
getKeywords(db)回全部blog_keywords(按createdAt、id排序),供/admin/ai用。 - Slug 去重:
uniqueSlug(db, base, selfId?)撞 slug 就加-2、-3…;selfId用喺更新自己時排除自己。admin 文章同 AI 生成都用。 Db型別:DrizzleD1Database<typeof schema>。- 連結 helper:
whatsappHref/telHref/mailHref/digits/formatDate;電話/WhatsApp 一律經呢啲 helper,唔好散寫。 - 設定欄位:
settings-fields.ts的SETTINGS_GROUPS係/admin/settings表單的唯一來源;新增一個 setting key 之後,要同步加落migrations/seed.sql。 - 顯示用文案繁體中文。
Work Guidance
- 新增可管理欄位:改
settings-fields.ts→ 加 seed default → 喺前端消費(多數喺components/site/*)。
Verification
npm run build。npm run db:seed:local後/admin同前台睇得到種子資料。
Child DOX Index
無。