# 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/`(Zod `z.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`。 - **後台總覽聚合**:`getDashboardData(db)` 回 `DashboardData`(`posts`/`cases`/`content`/`keywords` 各狀態計數+`recentPosts` 最新 5 篇+`postsWithoutCover`),供 `/admin` dashboard 用;只讀 DB,AI secrets 由頁面層 `getEnv()` 提供。 - **關鍵字佇列**:`getKeywords(db)` 回全部 `blog_keywords`(按 `createdAt`、`id` 排序),供 `/admin/ai` 用。 - **Slug 去重**:`uniqueSlug(db, base, selfId?)` 撞 slug 就加 `-2`、`-3`…;`selfId` 用喺更新自己時排除自己。admin 文章同 AI 生成都用。 - **`Db` 型別**:`DrizzleD1Database`。 - **連結 helper**:`whatsappHref` / `telHref` / `mailHref` / `digits` / `formatDate`;電話/WhatsApp 一律經呢啲 helper,唔好散寫。 - **設定欄位**:`settings-fields.ts` 的 `SETTINGS_GROUPS` 係 `/admin/settings` 表單的唯一來源;新增一個 setting key 之後,要同步加落 `scripts/seed.sql`。追蹤分析欄位(`ga4_measurement_id` / `meta_pixel_id`,空字串=關閉)由 `Base.astro` 消費,見父層 `src/AGENTS.md` 的 Analytics & consent。 - **圖片欄位**:`FieldType` 有 `"image"`;`hero_image` / `og_image` 用呢個型別,`/admin/settings` 會 render `ImageField`(可上傳去 R2)。 - 顯示用文案繁體中文。 ## Work Guidance - 新增可管理欄位:改 `settings-fields.ts` → 加 seed default → 喺前端消費(多數喺 `components/site/*`)。 ## Verification - `npm run build`。 - `npm run db:seed:local` 後 `/admin` 同前台睇得到種子資料。 ## Child DOX Index 無。