AWS Builder 工作坊

與 Kiro 一起開發:重建 CME Direct 風格的量化損益排行榜 UI

工作坊系列

量化損益排行榜排名截圖 1
量化損益排行榜排名截圖 2

摘要: 本獨立工作坊旨在教導專業開發人員使用 Kiro,將上傳的 CME Direct 風格量化排行榜重建為 React 與 TypeScript 應用程式。開發人員將學習規格驅動的 UI 拆解、深色模式設計權標 (Design Tokens)、回應式網格轉換、無障礙搜尋與排序控制項、可重複使用的市場卡片、排行榜資料列、可展開的分析面板,以及用於維持 UI 一致性、文件化和產品級學習成果回歸測試的 Kiro Hooks。

工作坊目的

這個 2 小時的工作坊專注於示範專案的前端系統設計。開發人員將把單一檔案的 HTML/CSS/JavaScript 實作轉換為具可維護性的 React + TypeScript 應用程式,同時保留交易工作空間的使用者體驗:頂部欄、主視覺區 (Hero)、狀態統計、市場圖卡、控制項、排行榜資料列、可展開的分析面板、SVG 圖表容器、頁尾免責聲明、回應式版面配置以及即時時鐘行為。

學習目標不只是「複製 UI」,而是教導開發人員如何使用 Kiro 規格驅動開發 (Spec-driven development)、指引檔案 (Steering files) 和 Hooks,將密集的原型轉化為產品級的元件邊界。

示範範圍地圖

本工作坊涵蓋上傳的 HTML 示範專案中以下部分:

  • 頁面外殼: .page.terminal、深色網格背景、放射狀亮點背景。
  • 固定頂部欄: CME 標誌、產品名稱、工作流程副標題、即時綠色狀態點、HKT 時鐘。
  • 主視覺區 (Hero): Institutional Trading Challenge、中文標題、副標題、工作流程標籤、創辦人想法卡片。
  • 摘要統計數據: 參與者 (Participants)、最佳夏普值 (Best Sharpe)、平均勝率 (Avg Win Rate)、最佳 NAV (Best NAV)、工作空間 RFQ 開啟 (Workspace RFQ ON)。
  • 市場數據條: ES、CL、GC、BTC 卡片,帶有「BID STACK (買盤堆疊)」和「OFFER HIT (賣盤遭擊)」標籤。
  • 控制項: 搜尋方塊以及用於 NAV、DAILY、SR、PF、WR、MAX DD 的排序按鈕。
  • 排行榜網格: 排名、姓名、策略、NAV、每日報酬、走勢圖 (Sparkline)、SR、PF、WR、Max DD、分析。
  • 可展開的詳細資訊面板容器配置。
  • 支援桌上型電腦、平板電腦和行動裝置的回應式斷點。
  • 頁尾免責聲明與行動呼籲 (CTA)。

目標開發人員

  • 構建金融儀表板的前端開發人員。
  • 將原型 HTML 現代化為類型化應用程式的全端開發人員。
  • 學習 Kiro 如何協助處理規格、指引、Hooks 和重構的 UI 工程師。
  • 需要在提高可維護性的同時,保留金融 UI 業務含義的開發人員。

兩小時議程

時間 模組 開發人員產出
0:00-0:10 檢查示範專案並建立專案 UI 資產清單與 React scaffolding
0:10-0:25 Kiro 指引 (Steering) 產品、設計系統、無障礙、金融 UI 規則
0:25-0:40 Kiro 規格 (Spec) 需求、元件樹、回應式策略
0:40-1:05 版面配置外殼 深色終端機框架、頂部欄、主視覺區、統計數據
1:05-1:25 市場 + 控制項 市場卡片、搜尋、排序按鈕組
1:25-1:45 排行榜資料列 類型化資料列、回應式標籤、進度條
1:45-1:55 可展開面板預留位置 分析插槽與頁尾免責聲明
1:55-2:00 Kiro 審查 UI 一致性待辦清單

架構

React application
├─ src/app/App.tsx
├─ src/styles/tokens.css
├─ src/styles/layout.css
├─ src/data/demoBoard.ts
├─ src/components/TopBar.tsx
├─ src/components/HeroPanel.tsx
├─ src/components/StatsStrip.tsx
├─ src/components/MarketStrip.tsx
├─ src/components/LeaderboardControls.tsx
├─ src/components/LeaderboardTable.tsx
├─ src/components/TraderRow.tsx
├─ src/components/AnalysisPanelShell.tsx
└─ src/components/FooterDisclaimer.tsx

Kiro workspace
├─ .kiro/steering/product.md
├─ .kiro/steering/ui-design-system.md
├─ .kiro/steering/accessibility.md
└─ .kiro/specs/leaderboard-ui/
   ├─ requirements.md
   ├─ design.md
   └─ tasks.md

此 UI 中使用的金融與交易工作空間術語

術語 示範定義 如何影響交易決策
P&L 損益 (Profit and Loss);顯示為每日百分比變動和累積排行榜報酬。 幫助交易員在當前市場背景下識別某個策略是在賺錢還是賠錢。
NAV 淨資產價值 (Net Asset Value);示範中每個策略起點約為 100,並顯示百分比收益,例如 +18.4%。 用於對累積績效進行排名,但必須結合回撤和風險品質進行評估。
Futures 期貨;由 ES、CL、GC 等標籤引用的標準化交易所交易衍生商品。 交易員使用期貨來表達總體觀點並對沖風險敞口。
Options 選擇權;具有非線性報酬的衍生商品;在頂部副標題中顯示為工作流程內容。 選擇權引入了 Greeks (避險參數)、凸性 (Convexity) 和波動度決策。
Blocks 大宗交易;顯示為工作流程內容。 與流動性和市場衝擊決策相關。
RFQ 報價請求 (Request for Quote);顯示為工作流程標籤和 RFQ ON 工作空間狀態。 表示報價驅動的執行工作流程,其中流動性和定價品質至關重要。
BID STACK 買盤堆疊;用於向上/正向市場狀態的市場字卡標籤。 在示範顯示中暗示買方深度或上漲壓力。
OFFER HIT 賣盤遭擊;用於向下/負向市場狀態的市場字卡標籤。 暗示賣壓或要價被執行。
SR 夏普值 (Sharpe Ratio);風險調整後的品質評分。 有助於比較具有不同波動度的策略。
PF 獲利因子 (Profit Factor);總獲利除以總虧損。 有助於識別贏家的獲利是否能有效覆蓋輸家的虧損。
WR 勝率 (Win Rate);正報酬週期的百分比。 對於一致性很有用,但必須與報酬大小進行比較。
Max DD 最大回撤 (Maximum Drawdown);從波峰到波谷的最大跌幅。 風險限制和資本配置的核心防禦性指標。

步驟 1 — 建立 React 應用程式腳手架

npm create vite@latest kiro-cme-quant-board -- --template react-ts
cd kiro-cme-quant-board
npm install
npm install -D vitest @testing-library/react @testing-library/jest-dom
mkdir -p .kiro/steering .kiro/specs/leaderboard-ui src/components src/data src/styles

業務邏輯: 原始示範專案是一個單一的 HTML 檔案。這對於快速建立原型很有用,但專業開發人員需要可分離的元件,以便交易看板在演進時不會帶來高回歸風險。

程式碼邏輯: Vite 提供了一個快速的 TypeScript React 基準。資料夾結構分離了應用程式組合、元件算繪、示範資料和 CSS 設計權標。

預期結果: npm run dev 啟動一個空的 React 應用程式,Kiro 可以對其進行檢查和修改。

系統設計原理解析:

  1. 選擇本地 React 應用程式是因為工作坊只有 2 小時,必須專注於提取 UI 架構,而非雲端部署。開發人員稍後仍可將靜態構建部署到 Amazon S3 和 CloudFront。
  2. 專案從一開始就分離了 datacomponentsstyles。這可以防止 Kiro 生成一個將交易資料、算繪邏輯和設計權標混在一起的巨大元件。
  3. 測試依賴項在開始時就已安裝,因為網路無障礙和算繪測試應該是遷移的一部分,而不是在 UI 完成後才補上。

步驟 2 — 新增 Kiro 指引檔案 (Steering Files)

建立 .kiro/steering/product.md

# 產品概述

建立一個受 CME Direct 啟發的量化損益排行榜,用於開發人員教育。
UI 僅顯示示範交易分析,不得作為投資建議。
保留原始概念:期貨、選擇權、大宗交易、RFQ、即時 NAV、損益分析、市場字卡、可排序排行榜和可展開分析。

建立 .kiro/steering/ui-design-system.md

# UI 設計系統

使用帶有青色、綠色、紅色、黃色、柔和藍灰色和等寬指標文字的深色終端機風格。
使用 CSS 變數作為設計權標。
保持視覺層級:頂部欄 -> 主視覺區 -> 統計數據 -> 市場數據條 -> 控制項 -> 看板 -> 頁尾。
使用等同於桌上型電腦、平板電腦和手機的回應式斷點。

建立 .kiro/steering/accessibility.md

# 無障礙規則

所有搜尋輸入都需要標籤。
排序按鈕需要具備可存取名稱和作用中狀態。
分析按鈕必須使用 aria-expanded 顯示展開/折疊狀態。
不要僅依賴顏色來表示正/負值;保留加號/減號符號。

給 Kiro 的提示詞範例

閱讀指引檔案並建立一個規格,將單一檔案的 CME Direct 風格量化看板轉換為 React 元件。保留版面配置區塊、深色設計權標、回應式行為、排序/搜尋控制項、分析展開、市場卡片和頁尾免責聲明。生成需求、元件設計和實作任務。

業務邏輯: 指引檔案告訴 Kiro 哪些原型細節是強制性的:工作流程標籤、統計數據、搜尋、排序和免責聲明。這可以防止 AI 簡化掉領域含義。

程式碼邏輯: 指引檔案是 Kiro 應用於未來程式碼生成中的 Markdown 指令。設計系統檔案直接影響生成的 CSS 和元件邊界。

預期結果: Kiro 產生一個組件化的計劃,而不是將示範專案重寫為另一個大檔案。

系統設計原理解析:

  1. 產品指引和設計指引是分離的,因為產品需求描述的是必須保留什麼,而設計系統指引描述的是它應該長什麼樣子以及如何運作。
  2. 網路無障礙被視為一等公民的指引檔案,因為金融儀表板通常是鍵盤驅動的,交易員需要在壓力下快速消費資料。
  3. 指引檔案刻意包含了原始的區塊層級結構,以便 Kiro 可以將每個原型區塊對應到元件中,避免意外遺失功能。

步驟 3 — 擷取 UI 的示範資料

建立 src/data/demoBoard.ts

export type TraderRow = {
    name: string;
    strategy: string;
    navPct: number;
    dailyPct: number;
    sharpe: number;
    profitFactor: number;
    winRatePct: number;
    skew: number;
    maxDrawdownPct: number;
    series: number[];
};

export type MarketTile = {
    symbol: 'ES' | 'CL' | 'GC' | 'BTC';
    move: string;
    state: 'BID STACK' | 'OFFER HIT';
    up: boolean;
    series: number[];
};

export const traders: TraderRow[] = [
    { name: 'Sofia Garcia', strategy: 'Cross-Asset Convex Macro Alpha', navPct: 18.4, dailyPct: 0.42, sharpe: 0.73, profitFactor: 1.8, winRatePct: 58, skew: 0.44, maxDrawdownPct: 18, series: [100,101,100.7,102.2,104,103.2,105.7,106.1,108,109.8,111,112.4,114.9,116.2,118.4] },
    { name: 'Lucia Fernandez', strategy: 'Crypto Momentum Rotation', navPct: 16.9, dailyPct: 0.88, sharpe: 0.91, profitFactor: 1.7, winRatePct: 61, skew: 0.31, maxDrawdownPct: 22, series: [100,102.1,101.5,103.8,102.9,106.4,108.2,107.5,110.8,112.2,111.6,114.1,115.2,116,116.9] },
    { name: 'Carmen Lopez', strategy: 'Crypto Carry & Volatility', navPct: 14.2, dailyPct: -0.31, sharpe: 0.68, profitFactor: 1.6, winRatePct: 56, skew: 0.22, maxDrawdownPct: 25, series: [100,99.4,101.7,103.2,104.8,103.7,106.8,108.9,110.4,109.2,112.6,113.8,115.1,114.8,114.2] },
    { name: 'Elena Martin', strategy: 'Global Macro Trend Rider', navPct: 11.8, dailyPct: 0.17, sharpe: 0.62, profitFactor: 1.5, winRatePct: 54, skew: 0.18, maxDrawdownPct: 17, series: [100,100.8,101.1,102.5,103.2,104,103.8,105.4,106.2,107,108.9,109.3,110.2,111.1,111.8] },
    { name: 'Marta Sanchez', strategy: 'Rates & FX Relative Value', navPct: 9.6, dailyPct: 0.09, sharpe: 0.57, profitFactor: 1.4, winRatePct: 53, skew: 0.09, maxDrawdownPct: 15, series: [100,100.2,99.9,101,101.8,102.5,102.2,103.6,104.1,105.4,106,106.8,108.2,109,109.6] },
    { name: 'Paula Romero', strategy: 'Equity Factor Ensemble', navPct: 7.1, dailyPct: -0.12, sharpe: 0.49, profitFactor: 1.3, winRatePct: 52, skew: -0.04, maxDrawdownPct: 14, series: [100,100.5,101.2,100.8,102.1,102.7,103.4,104.2,103.8,105,105.4,106.2,106.8,107.3,107.1] },
    { name: 'Ana Torres', strategy: 'Commodity Breakout System', navPct: 5.4, dailyPct: 0.28, sharpe: 0.42, profitFactor: 1.2, winRatePct: 51, skew: 0.12, maxDrawdownPct: 19, series: [100,99.1,100.4,101.6,100.8,102.2,101.5,103.4,102.8,104.2,103.8,104.7,105.1,105.2,105.4] },
    { name: 'Laura Navarro', strategy: 'Multi-Asset Mean Reversion', navPct: 3.8, dailyPct: -0.06, sharpe: 0.35, profitFactor: 1.1, winRatePct: 49, skew: -0.11, maxDrawdownPct: 16, series: [100,100.4,99.8,100.9,101.4,100.6,101.8,102.2,101.7,102.8,103.1,102.9,103.6,103.9,103.8] }
];

export const markets: MarketTile[] = [
    { symbol: 'ES', move: '+0.38%', state: 'BID STACK', up: true, series: [20,21,20,22,23,23,24,25,24,26] },
    { symbol: 'CL', move: '-0.22%', state: 'OFFER HIT', up: false, series: [30,29,31,28,27,26,25,24,23,22] },
    { symbol: 'GC', move: '+0.62%', state: 'BID STACK', up: true, series: [18,18.5,19,18.7,20,21,20.5,22,23,23.5] },
    { symbol: 'BTC', move: '+2.18%', state: 'BID STACK', up: true, series: [20,22,21,24,26,25,29,28,32,34] }
];

業務邏輯: 這保留了示範專案中所有的參與者和市場字卡資訊,同時為開發人員提供了一個類型化的單一事實來源。

程式碼邏輯: 資料模組對交易員資料列和市場字卡使用 TypeScript 類型。元件匯入類型化陣列,而不是讀取 DOM 或解析嵌入的指令碼資料。

預期結果: UI 可以算繪所有 8 個參與者和 4 個市場,而無需在元件內部硬編碼數值。

系統設計原理解析:

  1. 資料被放置在獨立模組中,因為原始的單一檔案中原型資料和算繪是混在一起的。將其提取出來是邁向具維護性架構的第一步。
  2. 欄位名稱明確了單位:navPctdailyPctwinRatePct 是百分比,而 series 包含索引 NAV 點。這可以防止在格式化時產生混淆。
  3. 市場字卡類型將有效代號限制為四個示範商品,這有助於 Kiro 生成更安全的程式碼並減少元件 Props 中的意外打錯。

步驟 4 — 建立 CSS 設計權標 (Design Tokens)

建立 src/styles/tokens.css

:root {
    --bg: #061018;
    --panel: #081522;
    --panel2: #0c1f31;
    --line: #28465f;
    --soft: rgba(40,70,95,.62);
    --text: #edf6ff;
    --muted: #9fb3c8;
    --cyan: #38bdf8;
    --cyan2: #77c7ff;
    --green: #31c48d;
    --red: #f05252;
    --yellow: #f6c85f;
    --mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
    --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Noto Sans TC", "Noto Sans SC", Arial, sans-serif;
}

body {
    margin: 0;
    min-height: 100vh;
    color: var(--text);
    font-family: var(--sans);
    background:
            linear-gradient(rgba(255,255,255,.025) 1px, transparent 1px),
            linear-gradient(90deg, rgba(255,255,255,.025) 1px, transparent 1px),
            radial-gradient(circle at 10% 0, rgba(56,189,248,.2), transparent 30%),
            radial-gradient(circle at 88% 10%, rgba(49,196,141,.12), transparent 26%),
            var(--bg);
    background-size: 32px 32px, 32px 32px, auto, auto, auto;
}

.metric { font-family: var(--mono); font-variant-numeric: tabular-nums; font-weight: 900; }
.pos { color: var(--green); }
.neg { color: var(--red); }
.cyan { color: var(--cyan2); }

業務邏輯: 設計權標保留了機構交易終端機的外觀,同時使視覺語言可重複使用。

程式碼邏輯: CSS 變數取代了重複的十六進位值。元件可以一致地對金融數字使用 .metric.pos.neg

預期結果: 應用程式符合深色網格、青色/綠色/紅色的交易看板美學。

系統設計原理解析:

  1. 使用 CSS 變數而不是元件局部顏色,以便可以在一個地方進行視覺變更。這對於可能需要品牌或無障礙調整的儀表板非常重要。
  2. 指標文字使用等寬數字 (Tabular Numerals),因為金融數值在資料列更新時應保持視覺對齊。這提高了即時更新下的可讀性。
  3. 正值和負值類別是根據語義命名,而不是顏色名稱。這使得設計更容易適應非紅/綠主題或色盲模式。

步驟 5 — 建立頂部欄與主視覺組件

建立 src/components/TopBar.tsx

import { useEffect, useState } from 'react';

export function TopBar() {
    const [clock, setClock] = useState('LIVE');
    useEffect(() => {
        const tick = () => setClock(`LIVE ${new Date().toLocaleString('zh-HK', {
            hour12: false, month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit'
        })} HKT`);
        tick();
        const id = window.setInterval(tick, 1000);
        return () => window.clearInterval(id);
    }, []);

    return <header className="topbar">
        <div className="brand"><div className="logo">CME</div><div>
            <div className="brand-main">CME DIRECT STYLE QUANT BOARD</div>
            <div className="brand-sub">FUTURES / OPTIONS / BLOCKS / RFQ / P&amp;L ANALYTICS</div>
        </div></div>
        <div className="status"><span className="dot" />{clock}</div>
    </header>;
}

建立 src/components/HeroPanel.tsx

export function HeroPanel() {
    const chips = ['CME DIRECT MODE', 'FUTURES', 'OPTIONS', 'BLOCKS', 'RFQ', 'LIVE NAV'];
    const quoteChips = ['DEPTH', 'RFQ', 'GREEKS', 'VaR', 'CALMAR'];
    return <section className="hero">
        <div className="hero-grid">
            <div>
                <div className="eyebrow">Institutional Trading Challenge</div>
                <h1>AWS 金融量化怪傑<br /><span>P&amp;L 排行榜</span></h1>
                <p className="subhead">天啊,我們要真的拿一點錢出來做實盤。百家爭鳴,每天公布 NAV。Crypto、宏觀、Cross-Asset、Convex Alpha 同場陪跑,大家互相學習。🍻</p>
                <div className="chips">{chips.map(c => <span key={c} className={c === 'CME DIRECT MODE' ? 'chip hot' : 'chip'}>{c}</span>)}</div>
            </div>
            <aside className="quote">
                <div><div className="quote-label">Founder Idea</div>
                    <p><strong>「聽說 Carmen Lopez, Lucia Fernandez 也在做 Crypto 實盤,</strong>那我就用宏觀策略下場陪跑。每天公布 NAV,大家互相學習。」</p></div>
                <div><div className="chips">{quoteChips.map(c => <span key={c} className="chip hot">{c}</span>)}</div>
                    <div className="quote-foot">WORKSPACE: FUTURES · OPTIONS · BLOCKS · RFQ / DEMO DATA</div></div>
            </aside>
        </div>
    </section>;
}

業務邏輯: 頂部欄和主視覺區在使用者檢查數字之前告訴他們交易工作空間的上下文。文字將看板框架定位為使用示範或內部分析的學習競賽。

程式碼邏輯: TopBar 擁有時鐘狀態和清理機制。HeroPanel 是靜態的,並從陣列中算繪標籤和引言內容。

預期結果: 應用程式頂部在視覺上與原始示範專案相符,包含即時狀態、HKT 時鐘、標題、中文文案、創辦人引言和工作流程標籤。

系統設計原理解析:

  1. 時鐘邏輯被隔離在 TopBar 中,因為它具有計時器副作用。保持副作用局部化使測試和清理更容易。
  2. 即使主視覺內容是靜態的,也將其元件化,因為產品文案通常獨立於交易看板的其餘部分進行更改。
  3. 工作流程標籤是陣列而不是重複的 JSX,以便 Kiro 或開發人員輕鬆新增或重新排序標籤,而無需編輯版面結構。

步驟 6 — 建立統計數據條、市場數據條、控制項與表格

import { markets, traders } from '../data/demoBoard';

export function StatsStrip() {
    const bestSharpe = Math.max(...traders.map(t => t.sharpe));
    const avgWinRate = traders.reduce((s, t) => s + t.winRatePct, 0) / traders.length;
    const bestNav = Math.max(...traders.map(t => t.navPct));
    return <section className="stats">
        <div className="stat"><div className="stat-label">Participants</div><div className="stat-val">{traders.length}</div></div>
        <div className="stat"><div className="stat-label">Best Sharpe</div><div className="stat-val pos">{bestSharpe.toFixed(2)}</div></div>
        <div className="stat"><div className="stat-label">Avg Win Rate</div><div className="stat-val cyan">{avgWinRate.toFixed(1)}%</div></div>
        <div className="stat"><div className="stat-label">Best NAV</div><div className="stat-val pos">+{bestNav.toFixed(1)}%</div></div>
        <div className="stat"><div className="stat-label">Workspace</div><div className="stat-val cyan">RFQ ON</div></div>
    </section>;
}

export function MarketStrip() {
    return <div className="market">{markets.map(m => <div className="mcard" key={m.symbol}>
        <div className="mhead"><span>{m.symbol}</span><span>{m.state}</span></div>
        <div className={m.up ? 'mval pos' : 'mval neg'}>{m.move}</div>
    </div>)}</div>;
}

業務邏輯: 摘要統計數據在進入個別資料列之前,提供了快速的交易桌級別概覽。市場字卡顯示了股指、原油、黃金和比特幣代理市場的宏觀背景。

程式碼邏輯: 統計數據衍生自交易員資料,而非硬編碼。市場卡片對應到類型化的市場資料。

預期結果: UI 顯示 8 個參與者、最佳夏普值 0.91、平均勝率 55.8%、最佳 NAV +18.4%、RFQ 開啟,外加四張市場卡片。

系統設計原理解析:

  1. 摘要統計數據是計算出來的,因此如果示範資料列發生更改,它們仍保持正確。這避免了過時的頁首數字。
  2. 市場字卡與排行榜資料列分離,因為它們代表環境上下文,而非參與者績效。
  3. 工作空間狀態在此工作坊中保持為靜態指示器,因為 RFQ 工作流程是一個標籤,而不是真正的交易連線。

步驟 7 — 新增用於 UI 品質的 Kiro Hooks

建立 .kiro/hooks/ui-regression-review.md

# Hook: UI 回歸審查

觸發條件:當 src/components/*.tsx 或 src/styles/*.css 儲存時
執行動作:
要求 Kiro 檢查變更是否保留了:頂部欄、主視覺區、統計數據、市場數據條、搜尋、排序按鈕、排行榜欄位、可展開的分析、回應式標籤、深色權標和免責聲明。

建立 .kiro/hooks/accessibility-review.md

# Hook: 無障礙審查

觸發條件:當 src/components/*.tsx 儲存時
執行動作:
要求 Kiro 審查鍵盤操作、輸入標籤、aria-expanded、作用中排序狀態以及正值/負值的語義。

業務邏輯: UI 回歸 Hooks 有助於保護原型的涵蓋範圍。開發人員在重構過程中不太可能意外刪除某個功能。

程式碼邏輯: Hooks 在檔案儲存事件上執行 Kiro 審查提示詞。它們不取代單元測試,但提供即時的 Agent 輔助審查。

預期結果: 當元件遺失標籤、刪除必要區塊或破壞互動語義時,Kiro 會建議修正方案。

系統設計原理解析:

  1. UI 遷移有許多小細節,因此檔案儲存審查可在上下文仍記憶猶新時捕捉到回歸錯誤。
  2. 網路無障礙審查是分開的,因為視覺上的對等並不保證鍵盤或螢幕閱讀器的品質。
  3. Hooks 是建議性質的,而不是自動重寫程式碼,因為開發人員應該控制金融儀表板行為的變更。

最終實驗挑戰

詢問 Kiro:

將 React UI 與原始的單一檔案示範清單進行比較。產生一個涵蓋版面配置區塊、標籤、市場字卡、控制項、排行榜欄位、回應式能力、即時時鐘、免責聲明和分析面板預留位置的差異清單。然後針對剩餘的差異生成實作任務。

完成檢查清單

  • 所有 8 位交易員和 4 張市場卡片皆已呈現。
  • 固定頂部欄和 HKT 即時時鐘運作正常。
  • 主視覺區、創辦人引言、標籤和頁尾免責聲明皆存在。
  • 統計數據條從資料中計算數值。
  • 搜尋和排序控制項具備網路無障礙功能。
  • 排行榜欄位與示範專案相符。
  • 回應式版面配置涵蓋桌上型電腦/平板電腦/行動裝置。
  • Kiro Hooks 審查 UI 和無障礙功能的變更。

原始示範專案參考

本工作坊基於上傳的 aws_quant_pnl_leaderboard_v3.html 示範專案。該示範專案包含一個 CME Direct 風格的深色工作空間、參與者排行榜、市場卡片、可排序/可搜尋的損益看板、進階分析面板、圖表功能、回應式 CSS、即時 HKT 時鐘以及模擬的定期 NAV 更新。所有資料均視為示範預留位置資料,不構成投資建議。


進階開發人員附加實作實驗 — HTML 圖形分析

這些實驗擴展了 UI 工作坊,對上傳的 HTML 檔案的視覺系統進行更深入的分析。它們專注於深色交易工作空間的圖形構建:分層背景、漸層、終端機框架、顏色語義、回應式組合、視覺層級和 CSS 驅動的能動性 (Affordances)。它們不會重複基礎 React 遷移或分析引擎實驗。

進階圖形分析目標

在本節結束時,進階開發人員將能夠:

  • 將 HTML 檔案的視覺語法逆向工程為可重複使用的設計權標。
  • 解釋網格背景、發光效果、邊框和面板如何營造出 CME Direct 風格的終端機感。
  • 建立一個將 CSS 選取器映射到圖形意圖的視覺資產清單。
  • 驗證桌上型電腦、平板電腦和行動裝置斷點處的回應式圖形行為。
  • 建立 Kiro 審查提示詞,在重構時保持視覺忠實度。

來自 HTML 檔案的圖形資產清單

上傳的 HTML 使用了一個緊湊但豐富的圖形系統:

  • 終端機框架: .terminal 建立了一個帶有邊框、深色半透明背景和大陰影的受限交易工作空間。
  • 分層主體背景: 多個線性漸層建立了一個微妙的網格,而放射狀漸層則建立了青色和綠色的光暈。
  • 固定命令欄: .topbar.logo.status.dot 確立了即時工作空間的能動性。
  • 主視覺區組合: .hero.hero-grid.eyebrowh1.chips.quote 定義了儀表板的品牌故事和工作流程上下文。
  • 指標顏色語言: .pos.neg.cyan.metric 編碼了正值、負值、醒目提示和等寬數字文字。
  • 看板密度: .row.cell.rank.strategy.barwrap.bar 建立了一個密集的金融網格。
  • 回應式轉換:1120px560px 處的媒體查詢將看板從類似表格的網格轉換為行動裝置的資料列卡片。

進階實驗 1 — 建立視覺權標提取報告

目標: 將 HTML 的 CSS 值轉換為記錄完善的設計權標報告,解釋每種顏色、字型、間距、邊框、陰影和背景層。

建立 docs/html-graphic-token-report.md

# HTML 圖形權標報告

## 顏色權標

| 權標 | 數值 | 圖形角色 |
|---|---:|---|
| --bg | #061018 | 工作空間背景 |
| --panel | #081522 | 主要面板表面 |
| --panel2 | #0c1f31 | 突出的控制項表面 |
| --line | #28465f | 網格與邊框系統 |
| --cyan | #38bdf8 | 互動式發光與主要醒目提示 |
| --green | #31c48d | 正值指標狀態 |
| --red | #f05252 | 負值指標狀態 |
| --yellow | #f6c85f | 保留的警告強調色 |

## 字型排版

- `--mono` 用於指標、控制項、狀態和密集的交易標籤。
- `--sans` 用於內文、主視覺文字和策略描述。
- `.metric` 透過 `font-variant-numeric: tabular-nums` 啟用等寬數字掃視。

## 表面語言

- 深色面板使用 `--line` 邊框進行分隔。
- 柔和的內部格線使用 `--soft` 以減少視覺雜訊。
- 青色發光保留給作用中控制項、主視覺區強調和即時工作空間識別。

Kiro 提示詞:

分析上傳的 HTML CSS 並建立一個設計權標報告。解釋每個根變數、主要面板顏色、邊框、陰影、字型家族、指標類別以及正/負狀態的視覺目的。保持報告面向實作,供 React 開發人員參考。

預期結果: 開發人員可以在更改原始圖形系統之前對其進行描述。

進階實驗 2 — 將分層背景重構為元件

目標: 將 HTML 檔案的網格與發光背景隔離到一個具名的 React 外殼類別中,以便對其進行測試和重複使用。

建立 src/components/GraphicWorkspaceShell.tsx

import type { ReactNode } from 'react';

export function GraphicWorkspaceShell({ children }: { children: ReactNode }) {
  return (
    <main className="page graphic-workspace" id="top">
      <section className="terminal graphic-terminal">{children}</section>
    </main>
  );
}

建立 src/styles/graphic-background.css

.graphic-workspace {
  min-height: 100vh;
  background:
    linear-gradient(rgba(255,255,255,.025) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.025) 1px, transparent 1px),
    radial-gradient(circle at 10% 0, rgba(56,189,248,.2), transparent 30%),
    radial-gradient(circle at 88% 10%, rgba(49,196,141,.12), transparent 26%),
    var(--bg);
  background-size: 32px 32px, 32px 32px, auto, auto, auto;
}

.graphic-terminal {
  border: 1px solid #315875;
  background: rgba(4,14,23,.95);
  box-shadow: 0 26px 90px rgba(0,20,36,.72);
}

圖形邏輯: 前兩個漸層建立網格。接下來的兩個放射狀漸層建立了大氣的青色和綠色深度。最後一個顏色層錨定了深色終端機環境。

Kiro 提示詞:

將 HTML 主體背景和終端機框架提取到具名的 React/CSS 外殼類別中。保留確切的漸層順序、background-size 行為、框架邊框、半透明終端機表面和方塊陰影。新增註釋以解釋每個圖層的圖形角色。

預期結果: 背景變成了一個可移植的視覺原語,而不是未記錄的主體樣式。

進階實驗 3 — 建立視覺層級標註覆蓋層

目標: 新增一個僅在開發時顯示的覆蓋層,用於標記視覺區塊:頂部欄、主視覺區、統計數據、市場、控制項、看板、詳細資訊面板和頁尾。

建立 src/dev/VisualHierarchyOverlay.tsx

const zones = [
  ['topbar', '命令 / 即時狀態'],
  ['hero', '敘事識別與工作流程標籤'],
  ['stats', '交易桌級別摘要指標'],
  ['market', '市場內容條'],
  ['controls', '搜尋與排名控制項'],
  ['board', '密集的損益表格'],
  ['footer', '免責聲明與導覽'],
] as const;

export function VisualHierarchyOverlay() {
  return (
    <aside className="visual-audit-panel" aria-label="Visual hierarchy audit panel">
      <h3>圖形層級</h3>
      <ol>
        {zones.map(([selector, role]) => (
          <li key={selector}><code>.{selector}</code> — {role}</li>
        ))}
      </ol>
    </aside>
  );
}

新增開發環境 CSS:

.visual-audit-panel {
  position: fixed;
  right: 12px;
  bottom: 12px;
  z-index: 99;
  width: min(360px, calc(100vw - 24px));
  border: 1px solid var(--line);
  background: rgba(4, 16, 26, .94);
  color: var(--text);
  padding: 12px;
  font-family: var(--mono);
  font-size: 11px;
}

預期結果: 開發人員學會將頁面檢查為圖形區域的層級結構,而不僅僅是元件列表。

進階實驗 4 — 回應式圖形行為稽核

目標: 驗證 HTML 的兩個斷點在看板改變形狀時是否保留了視覺含義。

建立 docs/responsive-graphic-audit.md

# 回應式圖形稽核

## 桌上型電腦檢視

- 看板頁首列可見。
- 十欄網格支援交易員比較。
- 主視覺區使用雙欄組合。
- 市場數據條使用四欄。

## 平板電腦檢視,最大寬度 1120px

- 主視覺區、圖表網格和風險網格折疊為單欄。
- 統計數據變為雙欄。
- 市場卡片變為雙欄。
- 看板頁首隱藏,每列公開行動裝置標籤。

## 手機檢視,最大寬度 560px

- 狀態文字和品牌副標題隱藏以保護空間。
- 統計數據和市場使用單欄卡片。
- 排序按鈕變為雙欄網格。
- 頁尾 CTA 堆疊在免責聲明下方。

Kiro 提示詞:

從上傳的 HTML 建立回應式圖形稽核。對於每個斷點,記錄哪些視覺結構發生了變化、為什麼該變化保護了可讀性,以及回歸測試應該驗證什麼。

預期結果: 回應式設計被視為圖形行為,而不僅僅是 CSS 機制。

進階實驗 5 — HTML 外觀的回歸檢查清單

目標: 建立一個檢查清單,供開發人員在接受 UI 重構之前使用。

建立 docs/html-look-regression-checklist.md

# HTML 外觀回歸檢查清單

## 必須保留

- 帶有青色和綠色光暈層的深色網格主體背景。
- 終端機邊框和深陰影。
- 帶有即時綠色點的固定頂部欄。
- 帶有青色次要線條的高對比主視覺區大標題。
- 具有正常和熱門狀態的工作流程標籤。
- 帶有等寬數字的密集指標排版。
- 帶有加號和綠色的正值。
- 帶有減號和紅色的負值。
- 看板資料列分隔線和柔和的內部儲存格分隔線。
- 頁首列消失時的行動裝置標籤。
- 頁尾免責聲明的可見性。

## 絕不能引入

- 真實的市場數據宣稱。
- 交易建議。
- 沒有文字符號或標籤的純顏色含義。
- 隱藏免責聲明或分析按鈕的斷點行為。

Kiro 提示詞:

將 React UI 與上傳的 HTML 圖形系統進行比較。產生一個涵蓋背景、框架、頂部欄、主視覺區、標籤、統計數據、市場卡片、控制項、看板資料列、回應式標籤、詳細資訊面板和頁尾免責聲明的回歸檢查清單。

進階最終挑戰 — HTML 圖形忠實度審查

詢問 Kiro:

對 React UI 進行針對上傳的 HTML 檔案的圖形忠實度審查。僅專注於視覺系統行為:背景層、終端機框架、顏色語義、字型排版、間距、層級、回應式斷點、密集看板版面、焦點狀態和免責聲明可見性。產生一個按嚴重性排序的差異清單。

進階圖形分析完成檢查清單

  • 設計權標報告解釋了 HTML 視覺系統。
  • 背景和終端機框架已提取到具名、可重複使用的類別中。
  • 視覺層級覆蓋層記錄了頁面的圖形區域。
  • 回應式稽核涵蓋了兩個斷點層級。
  • 回歸檢查清單保護了原始外觀和非諮詢性的頁尾。