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.
Bulk data enrichment. Adds web-sourced fields (CEO names, funding, contact info) to lists of co…
12K installsMatch external CSV/JSONL records to CRM contacts (by email) or companies (by domain) and write …
1.3K installsRun pathway and gene-set enrichment analysis on gene lists or ranked gene data, then interpret …
15 installsEnrich a list of email addresses to find the person behind each one (email to person profile). …
6 installsGene-set enrichment analysis — GO (Biological Process, Molecular Function, Cellular Component),…
370 installsWhen the user wants to build or improve a sales bot's ability to pull in firmographic or contac…
321 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 時的數據模型反推範例