Update DOX docs for R2 image upload
This commit is contained in:
@@ -23,6 +23,7 @@ Astro 7 + React 19 + Chakra UI v3,部署在 Cloudflare Workers(單一 Worker
|
||||
- **AI Blog**:`src/lib/ai.ts`(OpenAI 相容 chat completions + Tavily)+ `/admin/ai`;**預設供應商 DeepSeek 官方(`https://api.deepseek.com`、`deepseek-flash`)**,提示詞通用唔綁行業(角色/公司資料由後台 `ai_context_prompt`/`ai_business_context` 提供)。同步生成、一律存草稿並標記關鍵字 `generated`。需要 secrets `AI_API_KEY`(必需)/`TAVILY_API_KEY`(可選);未設時回明確錯誤,唔會 throw。已部署 DB 轉供應商要喺 `/admin/ai` 改,唔好重跑 `db:seed`(會覆蓋後台設定)。
|
||||
- **部署用 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` 產生再貼上,未貼前無法部署。R2 bucket 唔使貼 id,用 `r2:create`(或 `npm run setup`)建立即可,binding 係 `MEDIA`。
|
||||
- **圖片上傳**:圖片存 Cloudflare R2(binding `MEDIA`、bucket `yingfung-solar-media`),由同一個 Worker 的 `/media/*` 出圖;上傳經 `/admin/upload`,client 端先縮圖轉 WebP。本機靠 `platformProxy` 模擬 R2,雲端要先 `npm run r2:create`。圖片欄位仍可貼 URL;換圖/刪除時 `lib/media.ts` 會清舊 R2 檔。
|
||||
- **上線前要改 `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。
|
||||
- **Chakra v3 + Emotion**:前台 React 元件要用 `Provider` / `SiteChrome`(內含 `<ChakraProvider value={system}>`),theme 在 `src/theme/system.ts`。Astro 以 `client:load` 掛 island。
|
||||
@@ -115,11 +116,11 @@ When the user requests a durable behavior change, record it here or in the relev
|
||||
|
||||
| Path | Scope |
|
||||
|---|---|
|
||||
| `src/AGENTS.md` | 原始碼全層:架構、跨層慣例;擁有 `theme/`、`layouts/`、`schemas/`、`config.ts`、`middleware.ts`、`env.d.ts`,以及 `pages/` 路由與 `/admin` 後台合約 |
|
||||
| `src/AGENTS.md` | 原始碼全層:架構、跨層慣例;擁有 `theme/`、`layouts/`、`schemas/`、`config.ts`、`middleware.ts`、`env.d.ts`、`components/admin/`,以及 `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 / form / ai / markdown 基礎工具 |
|
||||
| `src/lib/AGENTS.md` | auth / env / db / form / media / ai / markdown 基礎工具 |
|
||||
| `migrations/AGENTS.md` | D1 migration 與 seed SQL |
|
||||
| `docs/AGENTS.md` | 設計規格與實作計劃(`superpowers/` 為設計權威) |
|
||||
|
||||
|
||||
+5
-3
@@ -15,6 +15,7 @@
|
||||
- `env.d.ts` — `App.Locals.isAdmin` 型別宣告。
|
||||
- `schemas/` — Zod 驗證層:admin 表單輸入(post / content / case / settings / ai / keyword)同 AI 輸出格式;配合 `lib/form.ts` 的 `parseForm` 同 `lib/ai.ts` 的生成流程使用(`lib/` 細節由 `lib/AGENTS.md` 擁有)。
|
||||
- `pages/` — 路由層同 `/admin` 後台(詳見下面 Routes & SSR / Admin,因 Astro 限制冇獨立 child doc)。
|
||||
- `components/admin/ImageField.astro` — 後台圖片欄位(URL text input + 揀檔上傳/預覽);client 端縮圖同 fetch `/admin/upload` 嘅 script 喺 `layouts/AdminLayout.astro`。
|
||||
|
||||
## Local Contracts
|
||||
|
||||
@@ -32,7 +33,8 @@
|
||||
- **環境變數**:只用 `getEnv()`,且只可喺 `prerender = false` 的頁面/endpoint 用。
|
||||
- **前台動態頁**:讀 D1 → 傳 props 畀單一 React island(`client:load`),並設邊緣快取 `Cache-Control: public, s-maxage=60, stale-while-revalidate=300`。
|
||||
- **404**:`blog/[slug].astro` 找唔到文章 → 設 `Astro.response.status = 404` 並 render noindex 頁。
|
||||
- **Endpoint**:用 `APIRoute`;`sitemap.xml.ts` 由 D1 讀已發布文章並設 `s-maxage=3600`;`media/[...key].ts` 由 R2 讀圖並回 `public, max-age=31536000, immutable`(+ ETag / 304)。
|
||||
- **Endpoint**:用 `APIRoute`;`sitemap.xml.ts` 由 D1 讀已發布文章並設 `s-maxage=3600`。
|
||||
- **圖片 endpoints**:`/admin/upload`(POST,受 middleware 保護,寫入 R2 `MEDIA`);`/media/[...key]`(GET,公開讀 R2 出圖,設 `Cache-Control: public, max-age=31536000, immutable` 同 ETag/304)。
|
||||
- **AI 生成(同步)**:`/admin/ai` 的生成喺 admin POST 內同步 `await` 完成先 redirect。如日後要改做背景處理,可用 `Astro.locals.cfContext`(Cloudflare `ExecutionContext`)嘅 `waitUntil`,唔使改現有流程。
|
||||
- **SEO**:用 `Base.astro`;canonical / OG / sitemap 全部靠 `astro.config.mjs` 的 `site`(現為佔位 `https://example.com`,上線前要改)。
|
||||
|
||||
@@ -48,7 +50,7 @@
|
||||
- **網站設定**:`settings.astro` 用 `data/settings-fields.ts` 的 `SETTINGS_GROUPS` / `ALL_SETTING_KEYS` 產生表單,逐 key upsert。
|
||||
- **文章**:`index.astro` 列表、`post/[id].astro` 新增/編輯(`id === "new"` 為新增);slug 自動 `slugify` 並用 `uniqueSlug` 去重。
|
||||
- **AI 生成**:`ai.astro`(`/admin/ai`)管 AI 設定 + 關鍵字佇列,同步呼叫 `generateBlogPost`;成功會 redirect 去新草稿 `/admin/post/<id>`。生成按鈕用 inline `onsubmit` 顯示「生成中…」。
|
||||
- **圖片**:一律以 URL 字串處理。上傳經 `admin/upload.ts`(`POST`,`scope ∈ settings | cases | posts`,JPG/PNG/WebP/GIF、上限 8MB,存 R2 `MEDIA`,回 `{ ok, url }`);對外由公開 `media/[...key].ts` 服務。
|
||||
- **圖片**:圖片欄位(settings 的 `hero_image` / `og_image`、`cases.imageUrl`、`posts.coverImage`)用 `components/admin/ImageField.astro`,可揀檔即時上傳去 R2(binding `MEDIA`),亦可貼 URL;client 端縮到最大寬 1600px 並轉 WebP 先上傳。上傳 endpoint `/admin/upload`(受 middleware 保護,`scope ∈ settings | cases | posts`、JPG/PNG/WebP/GIF、上限 8MB),出圖 endpoint `/media/[...key]`(公開、`immutable` cache)。換圖/刪除時由 `lib/media.ts` 的 `deleteMedia` 清舊 R2 檔。
|
||||
- 前台可見性靠 `status`(`published` / `draft`);列表頁顯示全部,前台只顯示 published。
|
||||
|
||||
## Work Guidance
|
||||
@@ -70,4 +72,4 @@
|
||||
| `components/site/AGENTS.md` | 前台 React island 與 Chakra UI 元件 |
|
||||
| `data/AGENTS.md` | D1 讀取查詢層與後台設定欄位定義 |
|
||||
| `db/AGENTS.md` | Drizzle schema(migration 的唯一來源) |
|
||||
| `lib/AGENTS.md` | auth / env / db / form / ai / markdown 基礎工具 |
|
||||
| `lib/AGENTS.md` | auth / env / db / form / media / ai / markdown 基礎工具 |
|
||||
|
||||
@@ -19,6 +19,7 @@ D1 讀取查詢層(`content.ts`)同後台網站設定欄位定義(`setting
|
||||
- **`Db` 型別**:`DrizzleD1Database<typeof schema>`。
|
||||
- **連結 helper**:`whatsappHref` / `telHref` / `mailHref` / `digits` / `formatDate`;電話/WhatsApp 一律經呢啲 helper,唔好散寫。
|
||||
- **設定欄位**:`settings-fields.ts` 的 `SETTINGS_GROUPS` 係 `/admin/settings` 表單的唯一來源;新增一個 setting key 之後,要同步加落 `migrations/seed.sql`。
|
||||
- **圖片欄位**:`FieldType` 有 `"image"`;`hero_image` / `og_image` 用呢個型別,`/admin/settings` 會 render `ImageField`(可上傳去 R2)。
|
||||
- 顯示用文案繁體中文。
|
||||
|
||||
## Work Guidance
|
||||
|
||||
Reference in New Issue
Block a user