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:
@@ -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 不同列的組件。
|
||||
|
||||
一般功能需求不應修改這裡的檔案。
|
||||
|
||||
@@ -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` 命名。
|
||||
|
||||
@@ -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
@@ -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 失敗等。
|
||||
|
||||
@@ -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。
|
||||
|
||||
@@ -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
@@ -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。
|
||||
|
||||
Reference in New Issue
Block a user