docs(specs): Sprint 5 四份技術文檔 — Tab 規格/路由對照/元件抽取/API 變更
1. Tab 結構規格書: 每個新頁面的 Tab 配置、區塊佈局、元件複用方式 2. 路由對照表: 26 個舊 URL → 新位置的精確映射 + redirect 實作方式 3. 元件抽取計畫: 17 個頁面抽取為 Panel 元件的步驟和目錄結構 4. API 變更規格: DashboardResponse +3 欄位 + SSE +1 事件 (不新增 API) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
102
docs/superpowers/specs/2026-04-08-sprint5-api-changes.md
Normal file
102
docs/superpowers/specs/2026-04-08-sprint5-api-changes.md
Normal file
@@ -0,0 +1,102 @@
|
||||
# Sprint 5 — API 變更規格
|
||||
|
||||
> 後端 Dashboard API 的擴充欄位定義
|
||||
|
||||
---
|
||||
|
||||
## 現有 API (不動)
|
||||
|
||||
```
|
||||
GET /api/v1/dashboard → DashboardResponse (聚合資料)
|
||||
GET /api/v1/dashboard/stream → SSE (每30秒推送)
|
||||
GET /api/v1/dashboard/hosts → 4主機概覽
|
||||
GET /api/v1/stats/disposition → Sprint 4 處置統計
|
||||
GET /api/v1/approvals/pending → 待核准列表
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 擴充: DashboardResponse 新增欄位
|
||||
|
||||
```python
|
||||
# apps/api/src/api/v1/dashboard.py
|
||||
|
||||
class DashboardResponse(BaseModel):
|
||||
# ─── 現有欄位 (不動) ───
|
||||
timestamp: datetime
|
||||
environment: str
|
||||
mock_mode: bool
|
||||
overall_status: str
|
||||
hosts: list[HostStatusResponse]
|
||||
alerts_count: int
|
||||
pending_approvals: int
|
||||
|
||||
# ─── Sprint 5 新增 ───
|
||||
k8s_pods: list[PodStatusBrief] = []
|
||||
ai_diagnosing: list[str] = [] # OpenClaw 正在分析的服務名稱
|
||||
topology_metadata: TopologyMetadata | None = None
|
||||
|
||||
|
||||
class PodStatusBrief(BaseModel):
|
||||
"""K8s Pod 簡要狀態 (不需要完整 Pod spec)"""
|
||||
name: str # "awoooi-api-7b8f4c-x9k2p"
|
||||
deployment: str # "awoooi-api"
|
||||
namespace: str # "awoooi-prod"
|
||||
status: str # "Running" | "Pending" | "CrashLoopBackOff"
|
||||
restart_count: int = 0
|
||||
ready: bool = True
|
||||
|
||||
|
||||
class TopologyMetadata(BaseModel):
|
||||
"""拓撲圖元資料"""
|
||||
total_entities: int # 67
|
||||
healthy_count: int # 65
|
||||
warning_count: int # 1
|
||||
critical_count: int # 0
|
||||
ai_active: bool # OpenClaw 是否正在分析
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 擴充: SSE 新事件類型
|
||||
|
||||
```python
|
||||
# 現有事件:
|
||||
# - HOST_UPDATE: 每30秒推送主機狀態
|
||||
|
||||
# Sprint 5 新增:
|
||||
# - AI_DIAGNOSING: OpenClaw 開始/結束分析時推送
|
||||
{
|
||||
"type": "AI_DIAGNOSING",
|
||||
"data": {
|
||||
"service_name": "awoooi-worker",
|
||||
"incident_id": "INC-20260407-5E0B84",
|
||||
"action": "start", # "start" | "complete" | "failed"
|
||||
"confidence": 0.91, # 分析完成時
|
||||
"playbook_matched": "restart_worker.yml" # 匹配到的 Playbook
|
||||
},
|
||||
"timestamp": "2026-04-08T10:03:42+08:00"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 資料來源
|
||||
|
||||
| 新欄位 | 來源 | 檔案 |
|
||||
|--------|------|------|
|
||||
| `k8s_pods` | `k3s_monitor_service.py` 已有的 Pod 查詢 | `services/k3s_monitor_service.py` |
|
||||
| `ai_diagnosing` | Redis working memory 中 active incidents | `services/incident_service.py` |
|
||||
| `topology_metadata` | 從 hosts 聚合計算 | `api/v1/dashboard.py` 內計算 |
|
||||
|
||||
---
|
||||
|
||||
## 不需要的新 API
|
||||
|
||||
| 之前提過的 | 是否需要 | 原因 |
|
||||
|-----------|---------|------|
|
||||
| `POST /topology/execute` | ❌ 不需要 | 現有 `/approvals/{id}/sign` 已涵蓋 |
|
||||
| `GET /topology/service/{host}/{name}` | ❌ 不需要 | 現有 `/dashboard` 已有服務資料 |
|
||||
| `GET /topology/events?host={ip}` | ❌ 不需要 | 現有 `/incidents` + SSE 已涵蓋 |
|
||||
|
||||
**結論: 後端只需擴充 DashboardResponse (+3 欄位) + SSE 新事件 (+1 類型),不需要新 API 端點。**
|
||||
@@ -0,0 +1,130 @@
|
||||
# Sprint 5 — 元件抽取計畫
|
||||
|
||||
> 哪些頁面需要抽取為獨立元件,以便在 Tab 容器中複用
|
||||
|
||||
---
|
||||
|
||||
## 抽取原則
|
||||
|
||||
1. **只移動,不修改邏輯** — 確保功能零損失
|
||||
2. **保留原始 page.tsx 做 redirect** — 舊連結不失效
|
||||
3. **元件接收 props 而非自行 fetch** — 父層 (Tab 容器) 負責資料載入
|
||||
4. **i18n 不變** — 繼續使用原有的 `useTranslations()` namespace
|
||||
|
||||
---
|
||||
|
||||
## 抽取清單
|
||||
|
||||
### 高優先 (AI 指令中心需要)
|
||||
|
||||
| # | 原始頁面 | 抽取為 | 放置位置 | 行數 | 用於 |
|
||||
|---|---------|--------|---------|------|------|
|
||||
| 1 | `/alerts/page.tsx` | `AlertsPanel.tsx` | `components/panels/` | 183 | AI 中心 Tab 2 左側 |
|
||||
| 2 | `/reports/page.tsx` | `DispositionPanel.tsx` | `components/panels/` | 317 | AI 中心 Tab 4 |
|
||||
|
||||
### 中優先 (其他整合頁面需要)
|
||||
|
||||
| # | 原始頁面 | 抽取為 | 放置位置 | 行數 | 用於 |
|
||||
|---|---------|--------|---------|------|------|
|
||||
| 3 | `/monitoring/page.tsx` | `MonitoringPanel.tsx` | `components/panels/` | 269 | 可觀測性 Tab 1 |
|
||||
| 4 | `/apm/page.tsx` | `APMPanel.tsx` | `components/panels/` | 128 | 可觀測性 Tab 2 |
|
||||
| 5 | `/errors/page.tsx` | `ErrorsPanel.tsx` | `components/panels/` | 164 | 可觀測性 Tab 3 |
|
||||
| 6 | `/apps/page.tsx` | `AppsPanel.tsx` | `components/panels/` | 103 | 可觀測性 Tab 4 |
|
||||
| 7 | `/services/page.tsx` | `ServicesPanel.tsx` | `components/panels/` | 120 | 可觀測性 Tab 5 |
|
||||
| 8 | `/auto-repair/page.tsx` | `AutoRepairPanel.tsx` | `components/panels/` | 460 | 自動化 Tab 1 |
|
||||
| 9 | `/neural-command/page.tsx` | `NeuralCommandPanel.tsx` | `components/panels/` | 209 | 自動化 Tab 2 |
|
||||
| 10 | `/drift/page.tsx` | `DriftPanel.tsx` | `components/panels/` | 324 | 自動化 Tab 3 |
|
||||
| 11 | `/deployments/page.tsx` | `DeploymentsPanel.tsx` | `components/panels/` | 113 | 營運 Tab 1 |
|
||||
| 12 | `/tickets/page.tsx` | `TicketsPanel.tsx` | `components/panels/` | 120 | 營運 Tab 2 |
|
||||
| 13 | `/cost/page.tsx` | `CostPanel.tsx` | `components/panels/` | 95 | 營運 Tab 3 |
|
||||
| 14 | `/action-logs/page.tsx` | `ActionLogsPanel.tsx` | `components/panels/` | 551 | 營運 Tab 4 |
|
||||
| 15 | `/billing/page.tsx` | `BillingPanel.tsx` | `components/panels/` | 113 | 營運 Tab 5 |
|
||||
| 16 | `/security/page.tsx` | `SecurityPanel.tsx` | `components/panels/` | 137 | 安全合規 Tab 1 |
|
||||
| 17 | `/compliance/page.tsx` | `CompliancePanel.tsx` | `components/panels/` | 124 | 安全合規 Tab 2 |
|
||||
|
||||
---
|
||||
|
||||
## 抽取步驟 (以 AlertsPanel 為例)
|
||||
|
||||
### Step 1: 建立 Panel 元件
|
||||
|
||||
```typescript
|
||||
// apps/web/src/components/panels/AlertsPanel.tsx
|
||||
|
||||
'use client'
|
||||
|
||||
// 從原始 /alerts/page.tsx 移入完整內容
|
||||
// 唯一差異: 移除 AppLayout wrapper (由 Tab 容器提供)
|
||||
|
||||
import { useTranslations } from 'next-intl'
|
||||
// ... 原始 import 保留 ...
|
||||
|
||||
// 移除 export default function AlertsPage({ params })
|
||||
// 改為:
|
||||
export function AlertsPanel() {
|
||||
const t = useTranslations('alerts')
|
||||
|
||||
// ... 原始邏輯完全不動 ...
|
||||
|
||||
return (
|
||||
// 移除 <AppLayout> wrapper
|
||||
// 只保留內部內容
|
||||
<div className="space-y-4">
|
||||
{/* 原始告警列表內容 */}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Step 2: 原始頁面改為 redirect
|
||||
|
||||
```typescript
|
||||
// apps/web/src/app/[locale]/alerts/page.tsx
|
||||
import { redirect } from 'next/navigation'
|
||||
|
||||
export default function AlertsPage() {
|
||||
redirect('/?tab=alerts')
|
||||
}
|
||||
```
|
||||
|
||||
### Step 3: 在 Tab 容器中使用
|
||||
|
||||
```typescript
|
||||
// apps/web/src/app/[locale]/page.tsx (AI 指令中心)
|
||||
import { lazy, Suspense } from 'react'
|
||||
|
||||
const AlertsPanel = lazy(() => import('@/components/panels/AlertsPanel').then(m => ({ default: m.AlertsPanel })))
|
||||
|
||||
// Tab 2 內容:
|
||||
<Suspense fallback={<Skeleton />}>
|
||||
<AlertsPanel />
|
||||
</Suspense>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 新建目錄結構
|
||||
|
||||
```
|
||||
apps/web/src/components/panels/
|
||||
├── index.ts # 匯出所有 Panel
|
||||
├── AlertsPanel.tsx # 從 /alerts 抽取
|
||||
├── DispositionPanel.tsx # 從 /reports 抽取
|
||||
├── MonitoringPanel.tsx # 從 /monitoring 抽取
|
||||
├── APMPanel.tsx # 從 /apm 抽取
|
||||
├── ErrorsPanel.tsx # 從 /errors 抽取
|
||||
├── AppsPanel.tsx # 從 /apps 抽取
|
||||
├── ServicesPanel.tsx # 從 /services 抽取
|
||||
├── AutoRepairPanel.tsx # 從 /auto-repair 抽取
|
||||
├── NeuralCommandPanel.tsx # 從 /neural-command 抽取
|
||||
├── DriftPanel.tsx # 從 /drift 抽取
|
||||
├── DeploymentsPanel.tsx # 從 /deployments 抽取
|
||||
├── TicketsPanel.tsx # 從 /tickets 抽取
|
||||
├── CostPanel.tsx # 從 /cost 抽取
|
||||
├── ActionLogsPanel.tsx # 從 /action-logs 抽取
|
||||
├── BillingPanel.tsx # 從 /billing 抽取
|
||||
├── SecurityPanel.tsx # 從 /security 抽取
|
||||
└── CompliancePanel.tsx # 從 /compliance 抽取
|
||||
```
|
||||
|
||||
**共 17 個 Panel 元件**
|
||||
73
docs/superpowers/specs/2026-04-08-sprint5-route-mapping.md
Normal file
73
docs/superpowers/specs/2026-04-08-sprint5-route-mapping.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# Sprint 5 — 頁面路由對照表
|
||||
|
||||
> 每個舊 URL 的精確去向,確保零連結失效
|
||||
|
||||
---
|
||||
|
||||
## 路由對照表
|
||||
|
||||
| # | 舊路由 | 新位置 | 實作方式 | Tab ID |
|
||||
|---|--------|--------|---------|--------|
|
||||
| 1 | `/` | `/` | **保留** (重構為 4-Tab) | — |
|
||||
| 2 | `/alerts` | `/?tab=alerts` | redirect | `alerts` |
|
||||
| 3 | `/authorizations` | `/?tab=alerts` | redirect | `alerts` |
|
||||
| 4 | `/topology` | `/topology` | **保留** (升級為完整拓撲) | — |
|
||||
| 5 | `/reports` | `/?tab=disposition` | redirect | `disposition` |
|
||||
| 6 | `/monitoring` | `/observability?tab=monitoring` | redirect | `monitoring` |
|
||||
| 7 | `/apm` | `/observability?tab=apm` | redirect | `apm` |
|
||||
| 8 | `/errors` | `/observability?tab=errors` | redirect | `errors` |
|
||||
| 9 | `/apps` | `/observability?tab=apps` | redirect | `apps` |
|
||||
| 10 | `/services` | `/observability?tab=services` | redirect | `services` |
|
||||
| 11 | `/auto-repair` | `/automation?tab=repair` | redirect | `repair` |
|
||||
| 12 | `/neural-command` | `/automation?tab=neural` | redirect | `neural` |
|
||||
| 13 | `/drift` | `/automation?tab=drift` | redirect | `drift` |
|
||||
| 14 | `/deployments` | `/operations?tab=deployments` | redirect | `deployments` |
|
||||
| 15 | `/tickets` | `/operations?tab=tickets` | redirect | `tickets` |
|
||||
| 16 | `/cost` | `/operations?tab=cost` | redirect | `cost` |
|
||||
| 17 | `/action-logs` | `/operations?tab=logs` | redirect | `logs` |
|
||||
| 18 | `/billing` | `/operations?tab=billing` | redirect | `billing` |
|
||||
| 19 | `/security` | `/security-compliance?tab=security` | redirect | `security` |
|
||||
| 20 | `/compliance` | `/security-compliance?tab=compliance` | redirect | `compliance` |
|
||||
| 21 | `/knowledge-base` | `/knowledge` | redirect | — |
|
||||
| 22 | `/terminal` | `/terminal` | **保留** (底部固定項) | — |
|
||||
| 23 | `/settings` | `/settings` | **保留** (加 Tab: users/notifications/help) | — |
|
||||
| 24 | `/users` | `/settings?tab=users` | redirect | `users` |
|
||||
| 25 | `/notifications` | `/settings?tab=notifications` | redirect | `notifications` |
|
||||
| 26 | `/help` | `/settings?tab=help` | redirect | `help` |
|
||||
| 27 | `/demo` | `/demo` | **保留** (環境變數保護) | — |
|
||||
|
||||
## 保留的獨立路由 (不整合)
|
||||
|
||||
| 路由 | 原因 |
|
||||
|------|------|
|
||||
| `/` | 首頁,重構為 4-Tab |
|
||||
| `/topology` | 完整版拓撲圖 (全展開模式) |
|
||||
| `/terminal` | 需要全螢幕,不適合 Tab |
|
||||
| `/settings` | 底部固定項 |
|
||||
| `/demo` | 開發用 |
|
||||
|
||||
## Redirect 實作方式
|
||||
|
||||
```typescript
|
||||
// 方案 A: next.config.js (推薦 — 伺服器端 301)
|
||||
module.exports = {
|
||||
async redirects() {
|
||||
return [
|
||||
{ source: '/alerts', destination: '/?tab=alerts', permanent: false },
|
||||
{ source: '/authorizations', destination: '/?tab=alerts', permanent: false },
|
||||
{ source: '/reports', destination: '/?tab=disposition', permanent: false },
|
||||
{ source: '/monitoring', destination: '/observability?tab=monitoring', permanent: false },
|
||||
// ... 其他 20+ 條
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
// 方案 B: 各頁面內 redirect (fallback)
|
||||
// apps/web/src/app/[locale]/alerts/page.tsx
|
||||
import { redirect } from 'next/navigation'
|
||||
export default function AlertsPage() {
|
||||
redirect('/?tab=alerts')
|
||||
}
|
||||
```
|
||||
|
||||
**建議**: 方案 A (next.config.js) 為主,效能最好。
|
||||
150
docs/superpowers/specs/2026-04-08-sprint5-tab-spec.md
Normal file
150
docs/superpowers/specs/2026-04-08-sprint5-tab-spec.md
Normal file
@@ -0,0 +1,150 @@
|
||||
# Sprint 5 — Tab 結構規格書
|
||||
|
||||
> 每個新頁面的 Tab 配置、來源元件、資料源、互動行為
|
||||
|
||||
---
|
||||
|
||||
## 🏠 AI 指令中心 (`/`)
|
||||
|
||||
| Tab ID | 名稱 | i18n Key | Icon | Badge | 內容來源 |
|
||||
|--------|------|---------|------|-------|---------|
|
||||
| `overview` | 戰情總覽 | `tabs.overview` | LayoutDashboard | — | 現有首頁 + **新拓撲圖** |
|
||||
| `alerts` | 告警 & 授權 | `tabs.alerts` | Bell | `alertsCount` | `/alerts` + `/authorizations` |
|
||||
| `stream` | 活動串流 | `tabs.stream` | Activity | — | SSE + ActionTimeline |
|
||||
| `disposition` | 處置統計 | `tabs.disposition` | BarChart3 | — | `/reports` (Sprint 4) |
|
||||
|
||||
### Tab 1: 戰情總覽 — 區塊配置
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ [MetricsStrip] 7 指標橫排 (現有,不動) │
|
||||
├───────────────────────────┬─────────────────────┤
|
||||
│ │ OpenClaw Panel │
|
||||
│ ServiceTopology │ (現有,不動) │
|
||||
│ (React Flow 收合模式) │ │
|
||||
│ 4 群組 + 依賴邊線 │ Toggle: 拓撲/主機 │
|
||||
│ │ [拓撲圖] [主機網格] │
|
||||
├───────────────────────────┤ │
|
||||
│ IncidentCard Feed │ │
|
||||
│ (現有,不動,最新 3 筆) │ │
|
||||
└───────────────────────────┴─────────────────────┘
|
||||
```
|
||||
|
||||
**元件複用**:
|
||||
- `MetricsStrip`: 現有首頁 L446-525 → 原地保留
|
||||
- `IncidentCard`: 現有 `components/incident/incident-card.tsx` → 原地保留
|
||||
- `OpenClawPanel`: 現有 `components/ai/openclaw-panel.tsx` → 原地保留
|
||||
- `ServiceTopology`: **新建** `components/topology/ServiceTopology.tsx`
|
||||
- `HostGrid`: 現有 `components/infra/host-grid.tsx` → Toggle 切換顯示
|
||||
|
||||
**Toggle 行為**: 「拓撲圖 / 主機網格」切換按鈕
|
||||
- 預設: 拓撲圖
|
||||
- 切換: 隱藏拓撲,顯示現有 HostGrid (4主機卡片)
|
||||
- 記住選擇: localStorage
|
||||
|
||||
### Tab 2: 告警 & 授權 — 區塊配置
|
||||
|
||||
```
|
||||
┌──────────────────────┬──────────────────────────┐
|
||||
│ AlertsPanel │ LiveApprovalPanel │
|
||||
│ (從 /alerts 抽取) │ (現有元件) │
|
||||
│ │ │
|
||||
│ · 嚴重度篩選 │ · 待批准列表 │
|
||||
│ · 告警列表 │ · SSH URI + 風險等級 │
|
||||
│ · 時間排序 │ · 批准/拒絕按鈕 │
|
||||
│ │ · 執行歷史 │
|
||||
└──────────────────────┴──────────────────────────┘
|
||||
```
|
||||
|
||||
**元件複用**:
|
||||
- `AlertsPanel`: 從 `/alerts/page.tsx` (183行) 抽取核心內容
|
||||
- `LiveApprovalPanel`: 現有 `components/approval/live-approval-panel.tsx` (484行)
|
||||
|
||||
### Tab 3: 活動串流 — 區塊配置
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ 篩選: [全部] [告警] [AI] [修復] [心跳] │
|
||||
├─────────────────────────────────────────────────┤
|
||||
│ 18:05 ● 心跳確認 mon/mon1 Ready │
|
||||
│ 18:04 ● OpenClaw 匹配 Playbook (91%) │
|
||||
│ 18:03 ● OpenClaw 啟動 RCA │
|
||||
│ 18:02 ● Prometheus 警報: Worker CPU 89% │
|
||||
│ 17:58 ● 自動修復完成 restart: api (12s) │
|
||||
│ ... │
|
||||
└─────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**資料源**: SSE `/api/v1/dashboard/stream` (現有)
|
||||
**元件複用**: `ActionTimeline` (`components/timeline/action-timeline.tsx`, 245行)
|
||||
|
||||
### Tab 4: 處置統計 — 區塊配置
|
||||
|
||||
直接嵌入 `/reports/page.tsx` 的完整內容:
|
||||
- KPI 3 卡 (處置總數/自動化率/人工介入率)
|
||||
- 四大計數卡 (自動/人工/手動/冷啟動)
|
||||
- 堆疊分佈條
|
||||
- 按異常類型明細表
|
||||
- 事件摘要 + 解決率
|
||||
|
||||
**元件複用**: 從 `/reports/page.tsx` (317行) 抽取為 `DispositionPanel`
|
||||
|
||||
---
|
||||
|
||||
## 📊 可觀測性 (`/observability`)
|
||||
|
||||
| Tab ID | 名稱 | i18n Key | 內容來源 | 行數 |
|
||||
|--------|------|---------|---------|------|
|
||||
| `monitoring` | 服務監控 | `obs.monitoring` | `/monitoring/page.tsx` | 269 |
|
||||
| `apm` | APM | `obs.apm` | `/apm/page.tsx` | 128 |
|
||||
| `errors` | 錯誤追蹤 | `obs.errors` | `/errors/page.tsx` | 164 |
|
||||
| `apps` | 應用 | `obs.apps` | `/apps/page.tsx` | 103 |
|
||||
| `services` | 服務目錄 | `obs.services` | `/services/page.tsx` | 120 |
|
||||
|
||||
---
|
||||
|
||||
## 🔧 自動化 (`/automation`)
|
||||
|
||||
| Tab ID | 名稱 | i18n Key | 內容來源 | 行數 |
|
||||
|--------|------|---------|---------|------|
|
||||
| `repair` | 自動修復 | `auto.repair` | `/auto-repair/page.tsx` | 460 |
|
||||
| `neural` | 神經指揮 | `auto.neural` | `/neural-command/page.tsx` + 4元件 | 1241 |
|
||||
| `drift` | Drift 偵測 | `auto.drift` | `/drift/page.tsx` | 324 |
|
||||
|
||||
---
|
||||
|
||||
## 📦 營運 (`/operations`)
|
||||
|
||||
| Tab ID | 名稱 | i18n Key | 內容來源 | 行數 |
|
||||
|--------|------|---------|---------|------|
|
||||
| `deployments` | 部署管理 | `ops.deployments` | `/deployments/page.tsx` | 113 |
|
||||
| `tickets` | 工單 | `ops.tickets` | `/tickets/page.tsx` | 120 |
|
||||
| `cost` | 成本分析 | `ops.cost` | `/cost/page.tsx` | 95 |
|
||||
| `logs` | 行動日誌 | `ops.logs` | `/action-logs/page.tsx` | 551 |
|
||||
| `billing` | 計費 | `ops.billing` | `/billing/page.tsx` | 113 |
|
||||
|
||||
---
|
||||
|
||||
## 🛡️ 安全合規 (`/security-compliance`)
|
||||
|
||||
| Tab ID | 名稱 | i18n Key | 內容來源 | 行數 |
|
||||
|--------|------|---------|---------|------|
|
||||
| `security` | 安全掃描 | `sec.security` | `/security/page.tsx` | 137 |
|
||||
| `compliance` | 合規報告 | `sec.compliance` | `/compliance/page.tsx` | 124 |
|
||||
|
||||
---
|
||||
|
||||
## 📚 知識 (`/knowledge`)
|
||||
|
||||
單頁,無 Tab。內容 = `/knowledge-base/page.tsx` (532行)
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ 設定 (`/settings`)
|
||||
|
||||
| Tab ID | 名稱 | i18n Key | 內容來源 | 行數 |
|
||||
|--------|------|---------|---------|------|
|
||||
| `general` | 一般設定 | `settings.general` | `/settings/page.tsx` | 245 |
|
||||
| `users` | 用戶管理 | `settings.users` | `/users/page.tsx` | 136 |
|
||||
| `notifications` | 通知 | `settings.notifications` | `/notifications/page.tsx` | 97 |
|
||||
| `help` | 幫助 | `settings.help` | `/help/page.tsx` | 57 |
|
||||
Reference in New Issue
Block a user