fix(ci): Harbor HTTP registry + Telegram secrets

CD 修復:
- 修復 buildx HTTP vs HTTPS 問題 (insecure registry 設定)
- 移除 UAT 環境 (違反 Memory 鐵律)
- 新增 Production 部署 Telegram 通知
- 修復 deploy-prod.yml 硬編碼 Token (改用 secrets)

docs:
- 新增 guidelines/ 結構化指引目錄
- ARCHITECTURE.md, FRONTEND.md, OPERATIONS.md

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
OG T
2026-03-23 23:40:40 +08:00
parent 00d94ca71c
commit 8542632cff
5 changed files with 498 additions and 11 deletions

View File

@@ -0,0 +1,137 @@
# AWOOOI 架構指引
> 架構相關的核心原則與規範
## 快速索引
| 主題 | 核心原則 | 詳細章節 |
|------|---------|---------|
| OpenClaw | 產品核心,只能增強不能移除 | [→ OpenClaw](#openclaw-核心架構) |
| 模組化 | Interface → Memory → Brain → Skill | [→ leWOOOgo](#lewooogo-模組化) |
| API 整合 | Props Mapping 五步驟檢查 | [→ API](#api-整合) |
| 防禦性 | 先質疑後實作 | [→ 防禦性工程](#防禦性工程) |
---
## OpenClaw 核心架構
**Memory 來源:** `feedback_architecture_openclaw_core.md`
### 原則
```
✅ OpenClaw 是 AWOOOI 產品核心
✅ 只能增強,不能移除
✅ 決策鏈必須可視化 (ThinkingTerminal)
✅ 雙軌決策: LLM + Expert System Fallback
```
### 決策流程
```
Signal → IncidentEngine → DecisionManager → Telegram/UI
LLM 提案 + Expert System 備援
```
### 命名規範
- ✅ 正確: OpenClaw, openclaw
- ❌ 禁止: ClawBot, clawbot (舊稱)
---
## leWOOOgo 模組化
**Memory 來源:** `feedback_modular_architecture.md`, `feedback_modular_core_spirit.md`
### 四層架構
```
┌─────────────────────────────────────────┐
│ Skill Layer (技能層) │
│ - 特定領域知識 │
│ - 可組合、可替換 │
├─────────────────────────────────────────┤
│ Brain Layer (決策層) │
│ - LLM + Expert System │
│ - 決策邏輯 │
├─────────────────────────────────────────┤
│ Memory Layer (記憶層) │
│ - Working: Redis (短期) │
│ - Episodic: PostgreSQL (長期) │
├─────────────────────────────────────────┤
│ Interface Layer (介面層) │
│ - Telegram Gateway │
│ - REST API │
└─────────────────────────────────────────┘
```
### 核心精神
1. **Interface 先行** - 先定義清晰的介面契約
2. **Memory 分離** - Working Memory ≠ Episodic Memory
3. **Brain 獨立** - 決策邏輯不綁定特定 LLM
4. **Skill 可組合** - 技能可插拔、可替換
---
## API 整合
**Memory 來源:** `feedback_api_response_verification.md`
### Props Mapping 五步驟檢查
新增 API 欄位時,必須確認完整鏈路:
```
1. API Response 有該欄位 ✓
2. Mapper 函數有轉換該欄位 ✓ ← 最常遺漏!
3. TypeScript 型別有定義該欄位 ✓
4. 組件 Props 有接收該欄位 ✓
5. 組件有使用該欄位 ✓
```
### 快速診斷
```bash
# 確認 API 有回傳
curl -s API_URL | jq '.[0].decision'
# 確認 Mapper 有轉換
grep -n "decision" apps/web/src/app/*/page.tsx
```
### 2026-03-23 教訓
Y/n 按鈕灰色無法點擊,因為 `mapToDualState()` 遺漏傳遞 `decision` 欄位。
---
## 防禦性工程
**Memory 來源:** `feedback_defensive_engineering.md`
### 原則
```
1. 先質疑,後實作
2. 看到可疑代碼,先問為什麼存在
3. 不確定的變更,先問統帥
4. 任何刪除操作,三思後行
```
### 常見陷阱
- 「這段代碼看起來沒用」→ 先 grep 確認沒人用
- 「這個 TODO 很久了」→ 先確認是否已完成
- 「這個邏輯很奇怪」→ 可能是特殊 case 處理
---
## 相關 ADR
- [ADR-003: leWOOOgo 模組架構](adr/ADR-003-lewooogo-module-architecture.md)
- [ADR-006: AI Fallback 策略](adr/ADR-006-ai-fallback-strategy.md)
- [ADR-008: Python 模組化](adr/ADR-008-python-modular-packages.md)
- [ADR-009: OpenClaw Agent Teams](adr/ADR-009-openclaw-agent-teams.md)

159
docs/guidelines/FRONTEND.md Normal file
View File

@@ -0,0 +1,159 @@
# AWOOOI 前端指引
> 前端開發的核心原則與規範
## 快速索引
| 主題 | 核心原則 | 詳細章節 |
|------|---------|---------|
| i18n | 100% next-intl零硬編碼 | [→ i18n](#i18n-雙語) |
| 視覺 | Nothing.tech 風格 | [→ 視覺規範](#視覺規範) |
| 狀態 | Zustand (禁止 Redux) | [→ 狀態管理](#狀態管理) |
| 數據 | 真實 API禁止假數據 | [→ 數據規範](#數據規範) |
---
## i18n 雙語
**Memory 來源:** `feedback_i18n_zero_hardcode.md`, `feedback_naming_i18n.md`
### 鐵律
```tsx
// ❌ 禁止 - 任何硬編碼文字
<button>Submit</button>
<span>Loading...</span>
<p>System Status</p>
// ✅ 正確 - 100% next-intl
<button>{t('common.submit')}</button>
<span>{t('common.loading')}</span>
<p>{t('dashboard.systemStatus')}</p>
```
### 支援語言
- `zh-TW` - 繁體中文 (預設)
- `en` - English
### 翻譯檔位置
```
apps/web/src/messages/
├── zh-TW.json
└── en.json
```
### 新增翻譯流程
1.`zh-TW.json` 新增 key
2.`en.json` 新增對應翻譯
3. 在組件使用 `t('your.key')`
---
## 視覺規範
**Memory 來源:** `feedback_naming_i18n.md`
### Nothing.tech 風格
```
- 白玻璃毛玻璃效果 (awoooi-glass)
- 點陣紋理背景
- DataPincer 數據鉗容器
- 黑白紅極簡配色
```
### 顏色系統
```css
/* 主色 */
--nothing-black: #000000
--nothing-white: #ffffff
--claw-red: #ff0000
/* 狀態色 */
--status-healthy: #00ff00
--status-warning: #ffaa00
--status-critical: #ff0000
```
### 組件規範
```tsx
// DataPincerPanel - 標準容器
<DataPincerPanel title={t('dashboard.title')} status="healthy">
{children}
</DataPincerPanel>
// DataPincerCard - 卡片容器
<DataPincerCard>
{content}
</DataPincerCard>
```
---
## 狀態管理
**Memory 來源:** ADR-004
### 鐵律
```tsx
// ❌ 禁止 - Redux
import { useSelector } from 'react-redux'
// ✅ 正確 - Zustand
import { useStore } from '@/stores/xxx.store'
```
### Store 結構
```
apps/web/src/stores/
├── agent.store.ts - Agent 狀態
├── incident.store.ts - Incident 狀態
└── ui.store.ts - UI 狀態
```
---
## 數據規範
**Memory 來源:** `feedback_no_fake_data.md`
### 鐵律
```tsx
// ❌ 禁止 - 假數據
const data = DEMO_DATA
const mockMetrics = generateMockData()
// ✅ 正確 - 真實 API
const { data } = useRealAPI()
const { metrics } = useGlobalPulseMetrics()
```
### 2026-03-23 教訓
`GlobalPulseChartDemo` 使用假數據,導致用戶無法看到真實系統狀態。已修正為 `GlobalPulseChart` 連接真實 API。
### Loading/Error 處理
```tsx
const { data, isLoading, error } = useAPI()
if (isLoading) return <Spinner />
if (error) return <ErrorState message={error} />
return <RealData data={data} />
```
---
## 相關 ADR
- [ADR-002: Nothing.tech 設計系統](adr/ADR-002-nothing-tech-design-system.md)
- [ADR-004: 狀態管理 (Zustand)](adr/ADR-004-state-management.md)
- [UX-001: Incident Card Fatigue](design/UX-001-incident-card-fatigue.md)

View File

@@ -0,0 +1,165 @@
# AWOOOI 維運指引
> 維運、部署、CI/CD 的核心原則與規範
## 快速索引
| 主題 | 核心原則 | 詳細章節 |
|------|---------|---------|
| Telegram | 絕對禁止 logOut | [→ Telegram](#telegram-整合) |
| 部署 | Dev + Prod (禁止 UAT) | [→ 部署拓撲](#部署拓撲) |
| CI/CD | self-hosted runner | [→ CI/CD](#cicd) |
| 構建 | Git Clone Only | [→ 構建流程](#構建流程) |
---
## Telegram 整合
**Memory 來源:** `feedback_telegram_token_disaster.md`, `feedback_openclaw_security.md`
### 2026-03-23 災難事件
```python
# ❌ 禁止 - 會導致 Token 永久失效!
await bot.log_out()
# ✅ 正確流程
1. 先停止舊 Bot Long Polling
2. 確認舊 Bot 完全停止
3. 再啟動新 Bot
```
### Long Polling 規則
```
一個 Bot Token 只能有一個 Long Polling 實例!
✅ OpenClaw (192.168.0.188) - 唯一 Polling 實例
❌ AWOOOI API - 只發送,不接收
```
### 心跳監控
```python
# 防止 Telegram 靜默盲點
heartbeat_interval = 30 minutes
silence_threshold = 2 hours
# 超過 2 小時沒訊息 → 主動告警
```
### 安全規則
```
✅ Webhook Secret 驗證
✅ Chat ID 白名單
✅ Rate Limiting
❌ 禁止在 Telegram 傳送敏感資訊 (密碼、Token)
```
---
## 部署拓撲
**Memory 來源:** `feedback_deployment_topology.md`, `feedback_no_uat_environment.md`
### 環境
```
✅ Dev - 開發環境 (localhost)
✅ Prod - 生產環境 (K3s)
❌ UAT - 禁止 (資源浪費)
```
### 五主機架構
| Host | IP | 角色 | 服務 |
|------|-----|------|------|
| wooo-nas | 192.168.0.100 | NAS + 監控 | Grafana, ClickHouse |
| wooo-k3s | 192.168.0.101 | K3s Master | API 調度 |
| awoooi-110 | 192.168.0.110 | K3s Worker | GitHub Runner |
| openclaw-188 | 192.168.0.188 | AI 服務 | OpenClaw, Ollama |
| wooo-router | 192.168.0.1 | 路由 | DDNS, 防火牆 |
### Port 分配
```
:3000 - Next.js (Web)
:8000 - FastAPI (API)
:8088 - OpenClaw Legacy
:11434 - Ollama
:8123 - ClickHouse
:3001 - Grafana
:4317 - OTEL gRPC
```
---
## CI/CD
**Memory 來源:** `feedback_github_billing.md`
### 鐵律
```yaml
# ❌ 禁止 - 帳單額度限制
runs-on: ubuntu-latest
# ✅ 正確 - self-hosted runner
runs-on: self-hosted
```
### Self-Hosted Runner
```
位置: 192.168.0.110 (awoooi-110)
名稱: awoooi-110
狀態: 需確認是否在線
```
### 自動檢查
Pre-commit 腳本自動檢查:
```bash
# .claude/hooks/pre-commit-check.sh
grep -r "runs-on: ubuntu-latest" .github/workflows/
```
---
## 構建流程
**Memory 來源:** `feedback_build_from_git_only.md`
### 鐵律
```bash
# ❌ 禁止 - 直接在伺服器編輯
vim /path/to/file.py
nano /path/to/config.yaml
# ✅ 正確 - 只從 Git 部署
git clone → build → deploy
```
### 部署流程
```
1. 本地開發 → 2. git push → 3. CI/CD 構建 → 4. K3s 部署
```
### Docker 構建
```yaml
# Next.js 必須 build-time 注入環境變數
ARG NEXT_PUBLIC_API_URL
ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
```
---
## 相關 ADR
- [ADR-005: BFF 架構](adr/ADR-005-bff-architecture.md)
- [ADR-010: Secrets 管理](adr/ADR-010-secrets-management.md)
- [ADR-011: NetworkPolicy 治理](adr/ADR-011-networkpolicy-governance.md)