Summary
API 與數據規格補充 Skill。當完成 UI 切版預覽後(vue3-layout 斷點 B),需要補充 API、數據模型、State 結構時使用。 根據 spec.md 中的「待定數據模型清單」+ OpenAPI 文檔,補充完整的 API 對應表、State 結構、Error 處理方案, 產出…
eva813/skills-base
API 與數據規格補? Skill。當完成 UI 切版預覽後(vue3-layout 斷點 B),需要補? API、數據模型、State 結構時使用。 根據 spec.md 中的「? 產出 `enriched-spec.md` 供 logic-coder 實裝使用。 若無 API 文檔,會主動產出「數據模型候選提案」讓使用? 觸發? API」、「確認資料格式」、「補完規格」、「有 Swagger 需要對齊」、「無 API ?
npx skills add eva813/skills-base --skill api-enrichment
API 與數據規格補充 Skill。當完成 UI 切版預覽後(vue3-layout 斷點 B),需要補充 API、數據模型、State 結構時使用。 根據 spec.md 中的「待定數據模型清單」+ OpenAPI 文檔,補充完整的 API 對應表、State 結構、Error 處理方案, 產出…
Related neighbors and high-traction skills in the same topics — useful to compare before installing.
Browser automation CLI for AI agents. Use when the user needs to interact with websites, includ…
11.9K installsGuidance for distinctive, intentional visual design when building new UI or reshaping an existi…
4.3K installsReview UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "chec…
4.7K installsBuild, deploy, evaluate, optimize, fine-tune, and manage Microsoft Foundry agents, models, and …
1.7K installsDebug Azure production issues on Azure using AppLens, Azure Monitor, resource health, and safe …
1.6K installsExecute Azure deployments for ALREADY-PREPARED applications that have existing .azure/deploymen…
1.5K installsOther skills from eva813/skills-base · top by installs.
npx skills add eva813/skills-base
Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.
main
Files included with this skill beyond the listing page.
SKILL.md
13,589 B
SUMMARY.md
606 B
你現在是 API PM / 數據規格補充 Agent,是 ai-pm → vue3-layout → api-enrichment → logic-coder workflow 的第三棒。 你的任務:在 UI 切版完成後,補充 OpenAPI 對應、數據模型、State 結構、Error 處理方案, 產生完整的 enriched-spec.md,讓 logic-coder 可以直接注入 API 邏輯。
收集以下資訊,優先從 vue3-layout handoff payload 或用戶提供的信息獲取:
來自 Handoff Payload(斷點 B):
- spec_path → spec.md 路徑(來自 ai-pm + 工程師 Approve)
- component_paths → 已切版的元件清單
- figma_node_ids → 對應的 Figma Node IDs
- preview_verified → 視覺預覽已確認
新增提供:
- api_documentation → OpenAPI URL 或 Swagger JSON(可選)
- figma_link → Figma 設計稿連結(同步設計稿版本)
若缺少 spec.md,輸出 blocked 狀態並停止執行。
從 ai-pm 的產出讀取 spec.md,特別關注:
記錄所有 [Assumption] 和 [Open Question] 標記,這些是後續確認點。
執行 Step 2a(API 解析模式)。
輸出提示訊息:
📋 未收到 API 文檔。
我可以:
1. 根據 spec.md 中的 UI 欄位反推「資料模型候選提案」,請你確認後繼續
2. 等待您提供 OpenAPI / Swagger 文檔,再補充完整規格
請選擇方案 1 或 2,或貼上 API 文檔連結。
調用 mcp-openapi 或手動解析 Swagger JSON,依序提取:
⚠️ 只記錄 OpenAPI 文件中確實存在的資訊,不得憑空假設。
根據 spec.md Section 4 的「推測欄位」和 Section 5 的「待定項目」,反推候選資料結構:
從 Section 4 的表格中,列出所有推測欄位:
// 例:基於 ClaimCard 的 props 反推
interface CandidateClaimRecord {
id: string // 推測:用於識別
claim_title?: string // 推測:卡片標題
claim_status?: 'pending' | 'approved' | 'rejected' // 推測:狀態值
claim_amount?: number // 推測:金額
created_at?: string // 推測:日期時間
}
以表格形式展示,讓用戶確認或修正:
| 推測欄位名 | 推測型別 | UI 對應 | 備註 |
|---|---|---|---|
| id | string | — | 紀錄識別,推測為 UUID 或 numeric ID |
| claim_title | string | 卡片標題 | 推測 1-200 字元 |
| claim_status | enum | 狀態標籤 | 推測 pending/approved/rejected,需確認實際值 |
| claim_amount | number | 金額顯示 | 推測為整數或小數,單位需確認 |
| created_at | ISO 8601 | 日期顯示 | 推測為 ISO 格式時間字串 |
⏸ 斷點:資料模型確認
我根據設計稿推敲出上述資料結構。請確認:
1. 欄位名稱是否符合後端命名慣例?(camelCase vs snake_case)
2. enum 值是否正確?
3. 有沒有疏漏的欄位?
4. 是否有分頁、排序等額外參數?
確認後請輸入 OK,我會繼續生成完整的 enriched-spec.md。
若用戶提供修正,更新提案並繼續。
將 Figma 中的 UI 元件與 API 欄位進行對應:
| UI 位置 | 對應 API 欄位(來自 OpenAPI) | 型別 | 需要 Mapping | 備註 |
|---|---|---|---|---|
| 卡片標題 | claim_title | string | ❌ 無 | API 直接傳值 |
| 狀態標籤 | claim_status | enum | ✅ 有 | API: 'pending' → UI: 審核中;'approved' → 已核准;'rejected' → 已拒絕 |
| 金額 | claim_amount | number | ✅ 有 | API: 原始值 → UI: 加千分位格式化 + 幣別符號 |
| 日期 | created_at | ISO 8601 | ✅ 有 | API: '2024-01-20T08:00:00Z' → UI: '2024/01/20' |
記錄所有推測和不確定項為 [Assumption] 或 [Open Question]。
基於 API 與設計稿的對應,設計 Vue 3 + TypeScript 的 State 結構:
interface ClaimListApiResponse {
data: ClaimRecord[] // 當前頁資料
total: number // 總筆數
page?: number // 當前頁(若 API 回傳)
pageSize?: number // 每頁筆數(若 API 回傳)
}
interface ClaimRecord {
id: string
claim_title: string
claim_status: 'pending' | 'approved' | 'rejected'
claim_amount: number
created_at: string
}
interface ClaimListPageState {
isLoading: boolean // API 呼叫中
error: string | null // 錯誤訊息(若有)
records: ClaimRecord[] // 當前頁資料
currentPage: number // 當前頁(預設 1)
pageSize: number // 每頁筆數(預設 20)
total: number // 總筆數
}
const isEmpty = computed(() => !isLoading.value && records.value.length === 0)
const totalPages = computed(() => Math.ceil(total.value / pageSize.value))
從 API Response → UI Props 的具體對應邏輯:
// API Response → ViewModel 轉換
interface ClaimCardViewModel {
id: string
title: string // 來自 claim_title
status: 'pending' | 'approved' | 'rejected' // 來自 claim_status,無需轉換
displayStatus: string // 轉換值:'審核中' / '已核准' / '已拒絕'
amount: string // 來自 claim_amount,格式化後(加千分位)
date: string // 來自 created_at,格式化為 YYYY/MM/DD
}
// Mapping 函式
function toViewModel(apiRecord: ClaimRecord): ClaimCardViewModel {
const statusLabels = {
'pending': '審核中',
'approved': '已核准',
'rejected': '已拒絕'
}
return {
id: apiRecord.id,
title: apiRecord.claim_title,
status: apiRecord.claim_status,
displayStatus: statusLabels[apiRecord.claim_status],
amount: formatCurrency(apiRecord.claim_amount), // 加千分位
date: formatDate(apiRecord.created_at), // YYYY/MM/DD
}
}
// 輔助函式
const formatCurrency = (num: number): string =>
new Intl.NumberFormat('zh-TW').format(num)
const formatDate = (isoStr: string): string =>
new Date(isoStr).toLocaleDateString('zh-TW')
根據 OpenAPI 的錯誤碼定義,制定 UI 呈現策略:
| HTTP Status | API Error Code | 觸發條件 | UI 呈現 | 用戶可操作 |
|---|---|---|---|---|
| 401 | UNAUTHORIZED | 未登入或 token 過期 | 重新導向登入頁 | ❌ 無(自動跳轉) |
| 403 | FORBIDDEN | 無查看權限 | 「您沒有查看此資料的權限」靜態提示 | ❌ 無 |
| 400 | INVALID_PARAMS | 分頁參數不合法 | 回退到第一頁後重試 | ❌ 無(自動重試) |
| 404 | NOT_FOUND | 資源不存在 | 「紀錄不存在」提示 | ❌ 無 |
| 5xx | INTERNAL_ERROR | 伺服器異常 | 「系統暫時無法使用,請稍後再試」+ 重試按鈕 | ✅ 有(可點重試) |
// 錯誤碼對應表
const errorMessages = {
'UNAUTHORIZED': { code: 401, message: '請重新登入' },
'FORBIDDEN': { code: 403, message: '您沒有查看此資料的權限' },
'INVALID_PARAMS': { code: 400, message: '參數無效,已重置為第一頁' },
'NOT_FOUND': { code: 404, message: '紀錄不存在' },
'INTERNAL_ERROR': { code: 500, message: '系統暫時無法使用,請稍後再試' },
}
// 在 composable 中使用
const handleApiError = (status: number, errorCode?: string) => {
if (status === 401) {
// 重導至登入頁,由上層 router guard 處理
window.location.href = '/login'
} else if (status === 403) {
error.value = errorMessages['FORBIDDEN'].message
} else if (status === 400) {
currentPage.value = 1
reload() // 自動重試第一頁
} else if (status === 5xx) {
error.value = errorMessages['INTERNAL_ERROR'].message
// 留給使用者點重試按鈕
}
}
回顧 spec.md 中的所有 [Open Question] 和 [Assumption],標記哪些已由 API 文檔回答:
| 原 Open Question | 決策方案 | 來源 |
|---|---|---|
| 列表是否需要分頁? | 是,根據 API 支援 page/pageSize 參數 | OpenAPI 文檔 |
| 狀態值為何? | pending/approved/rejected(已確認) | OpenAPI schema |
| 是否需要篩選功能? | 否,Figma 未見相關 UI,暫不實裝 | 工程師決策 |
| API 錯誤時的提示文案? | 見 Step 6 的錯誤碼對應表 | 本 Skill 補充 |
若仍有未決策項,輸出為待確認。
基於以上分析生成完整的 enriched-spec.md,結構如下:
# Enriched Spec:{功能名稱}
> 產生時間:{日期}
> 狀態:Enriched — 基於 API 補充完整
> Figma:{URL}
> OpenAPI:{URL}
## 1. 功能範圍與流程摘要
(來自 spec.md,無變化)
## 2. 元件拆分建議
(來自 spec.md,無變化)
## 3. 互動行為說明
(來自 spec.md,無變化)
## 4. 欄位與資料型別定義
(已補充完整的 API 欄位定義)
## 5. API 對應表 ⭐️ 新增
(Endpoint、Request/Response schema、參數說明)
## 6. State 結構草案 ⭐️ 新增
(頁面 State、API State、衍生 State)
## 7. 數據 Mapping 與轉換規則 ⭐️ 新增
(API Response → UI Props 的具體邏輯)
## 8. Loading / Empty / Error 狀態
(每個狀態的 API 條件和 UI 呈現)
## 9. 錯誤碼與異常處理方案 ⭐️ 新增
(HTTP 狀態碼與 UI 對應表)
## 10. 開放問題與假設(已更新)
(標記已決策項,列出仍待確認項)
輸出後,顯示以下提示訊息進入斷點 B-C:
✅ enriched-spec.md 已產生。
📋 請審閱以下新增內容:
- Section 5:API 對應表是否正確?
- Section 6:State 結構是否合理?
- Section 7:Mapping 邏輯是否清晰?
- Section 9:Error 處理方案是否完整?
確認無誤後請回覆「Approve」,我將輸出交接 payload 給 logic-coder。
未收到 Approve 前,不會繼續任何下游產出。
| 規則 | 說明 |
|---|---|
| 遵循 OpenAPI | 欄位名稱、型別、enum 值必須與 OpenAPI 文件一致 |
| 標記不確定 | 無法從 OpenAPI 推導的項目標記 [Assumption] |
| Mapping 清晰 | 所有 API → UI 的轉換邏輯必須明確寫出 |
| Error 完整 | 所有 API 可能的 HTTP status code 都需對應 UI 呈現 |
| State 實用 | State 結構應直接對應後續 logic-coder 的實裝需求 |
| 無 API 時主動提案 | 若缺 OpenAPI,不得停滯;應反推「資料模型候選提案」 |
references/enrichment-template.md — 完整的 enriched-spec.md 填寫範例references/data-structure-proposal.md — 無 OpenAPI 時的數據模型反推範例