docs: update LLM guides for models and layout rules

Document new GUIDE.md expectations for src-layer edits and add index
entries for models and shared types. Clarify layout usage, composable
placement, error page conventions, and model/type ownership so future
changes follow the intended layer boundaries.docs: update LLM guides for models and layout rules

Document new GUIDE.md expectations for src-layer edits and add index
entries for models and shared types. Clarify layout usage, composable
placement, error page conventions, and model/type ownership so future
changes follow the intended layer boundaries.
This commit is contained in:
skytek_xinliang
2026-05-19 17:33:53 +08:00
parent ac7e1959cf
commit e90d412956
9 changed files with 98 additions and 5 deletions
+17
View File
@@ -2,6 +2,13 @@
`components/layouts` 是 app shell layout。一般功能需求不應修改這裡。
## 可用 Layout
- **MainLayout**`layout: 'default'`):完整 app shell,包含 drawer、app bar、breadcrumb、favorites、toolbar actions 與主內容 slot。
- **PlainLayout**`layout: 'none'`):極簡空白佈局,只提供 `<v-app>` / `<v-main>` 外殼與一個 slot。登入頁、錯誤頁、維護中頁使用此 layout。
一般功能頁面統一使用 `layout: 'default'`
## MainLayout 責任
- drawer
@@ -20,3 +27,13 @@
- domain-specific 狀態
如果頁面要影響 breadcrumb、favorites、menu 或 toolbar,優先使用 route meta、store 或 `shell/AppShell.vue` 已提供的 props/events。
## `main-layout/` 子目錄
`src/components/layouts/main-layout/` 收納 MainLayout 拆解出的子組件與共用的型別定義:
- `types.ts``AdminLayoutMenuItem``AdminLayoutBreadcrumbItem``AdminLayoutFeatures` 等型別,供 layout composable 與 shell 使用。
- `DrawerDesktopMenu.vue` / `DrawerMobileMenuPanel.vue` / `DrawerMobileFavoritesPanel.vue`:桌面與行動版 drawer 內容。
- `AppBarTopCol.vue` / `AppBarBreadcrumbCol.vue` / `AppBarFavoritesCol.vue`app bar 不同列的組件。
一般功能需求不應修改這裡的檔案。
+2
View File
@@ -9,6 +9,8 @@
- `layout/`AppShell / layout 狀態與事件協調。
- `maint/`maintenance demo 的表單、CRUD、editable grid 狀態。
頂層也可放通用 composable,例如 `useApiCall.ts`:封裝 loading / data / error / execute 模式、自動 snackbar 錯誤提示與取消請求過濾。適合為單一 API 呼叫提供輕量狀態管理,但不替代 page driver 或 command composable。
## 新增規則
-`useXxx.ts` 命名。
+26
View File
@@ -0,0 +1,26 @@
# Models Guide
`models` 放 domain model 與 page model 型別定義。model 只定義形狀(interface/type),不含業務邏輯、API 呼叫或 UI 狀態。
## 種類
- **Domain Model**:特定領域的資料型別,例如 `StudentRecord`。檔名用 domain 命名(`student.ts`),型別使用 domain 前綴。
- **Page Model**`page.ts` 定義頁面驅動資料的 union type,供 page driver 組裝後傳給 page component。例如 `BasePageModel``MaintenancePageModel`
## 規則
- 用 interface 或 type,不加 class。
- domain model 應與 service response / store state 共用型別來源。
- page model 僅定義畫面需要的欄位,不鏡像整個 service response。
- 不 import component、view、store、composable。
- 型別 export 時明確命名,避免與其他層混淆。
## Page Model 慣例
`src/models/page.ts` 定義基礎型別與 union
- `BasePageModel`:所有頁面共用欄位(`title``loading``error`)。
- 各頁面的 specific model 擴展 `BasePageModel`(例如 `MaintenancePageModel``type``records`)。
- `PageModel` union 供 page component props 型別使用。
新增頁面類型時,先擴充 `PageModel` union 再新增對應的 page driver。
+26 -3
View File
@@ -23,9 +23,32 @@ meta: { layout: 'default' }
meta: { layout: 'none' }
```
## Auth Meta
| Meta | 效果 |
|------|------|
| `requiresAuth: true` | 未登入時導向 login,附 `redirect` query |
| `guestOnly: true` | 已登入時導向 home(含 `VITE_SKIP_LOGIN` 啟用時) |
| `roles: string[]` | RBAC,缺任一角色時導向 `/403` |
以上 meta 只在 `registerGuards` 中消費,不要在 component 裡重複檢查。
## 錯誤頁路由慣例
錯誤頁(403/500/503/network/maintenance/not-found)統一使用:
```ts
meta: { title: 'Forbidden', layout: 'none' }
```
- `layout: 'none'` 使頁面不被 `MainLayout` 包住,自己獨立渲染。
- catch-all `/:pathMatch(.*)*` 放在路由陣列最後。
- 錯誤頁 view 通常使用 `ErrorShell.vue` 共用組件,只傳入 props,不用重複寫佈局。
## Guards
- 登入需求使用既有 `requiresAuth` meta。
- 訪客專用頁使用既有 `guestOnly` meta。
- guard 流程放在 `guards.ts`,不要散落在 view/component。
- catch-all route 保持在最後
- `beforeEach`:登入檢查、RBAC、`VITE_SKIP_LOGIN` 跳過
- `beforeResolve`:輕量前置工作(例如進度條)。
- `afterEach`document title、追蹤。
- `onError`chunk load 失敗等。
+8
View File
@@ -17,6 +17,14 @@ component/view -> store/composable -> service module -> httpClient -> hooks
- request option 可接收 `signal`
- 錯誤正規化交給既有 error/http hooks 流程。
## 錯誤處理體系
- `error.ts`:定義 `ApiRequestError`(正規化後的錯誤類別)、`CanceledRequestError`(取消請求)、`normalizeError()`(將 ky HTTPError / TimeoutError / DOMException 統一轉為 `ApiRequestError`)。
- `http-error.ts`ky `beforeError` hook,將 response body 的錯誤訊息注入 error 物件。
- `http-toast.ts`:全域 HTTP error toast,依 status code 顯示對應 snackbar。
service module 不需要自行 catch 並處理錯誤,交由 interceptors/hooks 與上層 composable(如 `useApiCall`)處理。
## ky 注意事項
- 本專案使用 ky,不使用 axios。
+10
View File
@@ -0,0 +1,10 @@
# Types Guide
`types` 放跨模組共用的 TypeScript 型別定義,例如 API 回應格式(`ApiError`)、認證相關型別(`User``LoginPayload``CaptchaResponse`)。
## 規則
- 只放純型別(interface / type),不放邏輯、class、常數或 runtime code。
- 型別應小而聚焦,避免一個大雜燴檔。
-`models/` 的區別:`types/` 偏向 API 協定層(request/response、錯誤格式),`models/` 偏向領域實體與 page model。
- 不 import component、view、store、composable。
+1 -1
View File
@@ -29,4 +29,4 @@ const page = useReportsPage()
## 子目錄
- `views/maint` 是 maintenance demo route entry。詳見 `src/views/maint/GUIDE.md`
- `views/errors` 是錯誤頁入口,通常使用 `meta.layout = 'none'`
- `views/errors` 是錯誤頁入口,通常使用 `meta.layout = 'none'`每個錯誤頁(`Forbidden.vue``ServerError.vue``NotFound.vue` 等)只傳入 props 給共用的 `ErrorShell.vue`,不再各自重複佈局邏輯。`ErrorShell.vue` 提供標題、圖示、顏色、描述、後端訊息、操作按鈕(返回上頁 / 回首頁 / 前往登入)等 slots。