Files
hive-manage-v3/docs/superpowers/plans/2026-07-22-hive-manage-v3-p0.md

35 KiB
Raw Permalink Blame History

Hive Manage v3 — P0 核心闭环实施计划

对于 agentic workers: 使用 superpowers:executing-plans 或直接逐 task 执行。所有代码由 Claude Code CLI (--output-format stream-json --include-partial-messages --verbose) 编写,工头负责 QC。Steps 使用 checkbox (- [ ]) 语法追踪进度。

目标: 从零构建蜂群运维中台 v3 的 P0 核心闭环——7 个模块覆盖 58 个 Hermes Agent Profile 的批量管控、健康监控、密钥管理、Kanban 任务追踪、Cron 定时任务管理、事件档案、用户鉴权。

架构: FastAPI async 后端 + React 19 TypeScript 前端,PostgreSQL 持久层,Hermes CLI 作为蜂群数据源(低侵入只读),JWT 鉴权,CSS 变量双模(暗/浅)。

技术栈: Python 3.12, FastAPI, SQLAlchemy 2.0 (async), PostgreSQL, Alembic, Pydantic v2, React 19, TypeScript 5, Tailwind CSS 3, Vite 5, Lucide Icons, JWT (python-jose), bcrypt, pytest, Vitest.

全局约束

  • 不复用 v1 任何代码,全部从零重写
  • 所有 API 路径前缀 /api/v1/
  • 所有 API 请求/响应用 Pydantic 模型校验
  • 四态覆盖:Loading (Skeleton) / Empty (引导文案) / Error (重试按钮) / Normal
  • 暗色模式为默认主题,跟随系统并可手动切换(localStorage hive-theme)
  • 移动端响应式:768px 断点,按钮触控 ≥ 44×44px
  • 鉴权:所有 /api/v1/ 除 /api/v1/auth/* 外需 JWT Bearer Token
  • 审计:所有写操作(POST/PUT/PATCH/DELETE)自动记录到 audit_logs 表
  • Hermes CLI 调用只读,不修改蜂巢核心代码
  • 密钥值始终脱敏显示(前 3 + 后 4 字符)+ 不写入审计日志原文
  • 模型退役 warning 可忽略(底层走 DeepSeek v4 Pro 映射)
  • Nginx 反代:/api/ → FastAPI:8000,其余 → Vite dist

目录结构

/home/enzo/projects/hive-manage-v3/
├── backend/
│   ├── app/
│   │   ├── main.py                 # FastAPI 应用工厂 + 中间件注册
│   │   ├── config.py               # Settings (pydantic-settings),读 .env
│   │   ├── database.py             # async engine + session + Base
│   │   ├── models/
│   │   │   ├── __init__.py
│   │   │   ├── user.py             # User ORM
│   │   │   └── audit.py            # AuditLog ORM
│   │   ├── schemas/
│   │   │   ├── __init__.py
│   │   │   ├── auth.py             # Login/Register/Token 请求响应
│   │   │   ├── user.py             # User CRUD
│   │   │   ├── gateway.py          # Gateway 状态/事件
│   │   │   ├── health.py           # 健康分
│   │   │   ├── cron.py             # Cron Job
│   │   │   ├── kanban.py           # Kanban 任务
│   │   │   ├── keys.py             # 密钥
│   │   │   ├── dashboard.py        # Dashboard 聚合
│   │   │   ├── event.py            # 事件档案
│   │   │   └── audit.py            # 审计日志
│   │   ├── api/
│   │   │   ├── __init__.py
│   │   │   ├── auth.py             # /api/v1/auth/*
│   │   │   ├── users.py            # /api/v1/users/*
│   │   │   ├── gateway.py          # /api/v1/gateway/*
│   │   │   ├── health.py           # /api/v1/health/*
│   │   │   ├── cron.py             # /api/v1/cron/*
│   │   │   ├── kanban.py           # /api/v1/kanban/*
│   │   │   ├── keys.py             # /api/v1/keys/*
│   │   │   ├── dashboard.py        # /api/v1/dashboard/*
│   │   │   ├── events.py           # /api/v1/events/*
│   │   │   └── audit.py            # /api/v1/audit/*
│   │   ├── services/
│   │   │   ├── __init__.py
│   │   │   ├── hermes_cli.py       # hermes gateway/cron/kanban CLI 封装
│   │   │   ├── health_scorer.py    # 健康分计算引擎
│   │   │   ├── key_manager.py      # .env 读写 + 脱敏
│   │   │   └── event_crawler.py    # hm.zhiweidata.ai/events 爬取
│   │   └── middleware/
│   │       ├── __init__.py
│   │       ├── auth.py             # JWT 鉴权依赖
│   │       └── audit.py            # 审计日志中间件
│   ├── alembic/
│   │   ├── env.py
│   │   └── versions/
│   ├── tests/
│   │   ├── conftest.py             # async test fixtures
│   │   ├── test_auth.py
│   │   ├── test_gateway.py
│   │   ├── test_health.py
│   │   ├── test_cron.py
│   │   ├── test_kanban.py
│   │   ├── test_keys.py
│   │   ├── test_dashboard.py
│   │   └── test_events.py
│   ├── requirements.txt
│   ├── .env.example
│   └── pyproject.toml
├── frontend/
│   ├── src/
│   │   ├── main.tsx                # React 入口
│   │   ├── App.tsx                 # 路由 + 布局
│   │   ├── types/
│   │   │   └── index.ts            # 全局 TS 类型
│   │   ├── styles/
│   │   │   └── tokens.css          # CSS 变量 (暗/浅双模)
│   │   ├── components/
│   │   │   ├── ui/
│   │   │   │   ├── Button.tsx
│   │   │   │   ├── Card.tsx
│   │   │   │   ├── Table.tsx
│   │   │   │   ├── Badge.tsx
│   │   │   │   ├── Modal.tsx
│   │   │   │   ├── Drawer.tsx
│   │   │   │   ├── Toast.tsx
│   │   │   │   ├── Skeleton.tsx
│   │   │   │   ├── Toggle.tsx
│   │   │   │   ├── Timeline.tsx
│   │   │   │   └── SearchBox.tsx
│   │   │   └── layout/
│   │   │       ├── Sidebar.tsx
│   │   │       ├── Header.tsx
│   │   │       ├── MobileNav.tsx
│   │   │       ├── TabBar.tsx
│   │   │       └── AppLayout.tsx
│   │   ├── pages/
│   │   │   ├── LoginPage.tsx
│   │   │   ├── DashboardPage.tsx
│   │   │   ├── GatewayPage.tsx
│   │   │   ├── HealthPage.tsx
│   │   │   ├── CronPage.tsx
│   │   │   ├── KanbanPage.tsx
│   │   │   ├── KeysPage.tsx
│   │   │   ├── EventArchivePage.tsx
│   │   │   ├── UserManagementPage.tsx
│   │   │   └── AuditLogPage.tsx
│   │   ├── hooks/
│   │   │   ├── usePolling.ts
│   │   │   ├── useAuth.ts
│   │   │   └── useTheme.ts
│   │   └── api/
│   │       ├── client.ts           # axios 实例 + JWT 拦截器
│   │       ├── auth.ts
│   │       ├── gateway.ts
│   │       ├── health.ts
│   │       ├── cron.ts
│   │       ├── kanban.ts
│   │       ├── keys.ts
│   │       ├── dashboard.ts
│   │       ├── events.ts
│   │       ├── users.ts
│   │       └── audit.ts
│   ├── index.html
│   ├── package.json
│   ├── tsconfig.json
│   ├── vite.config.ts
│   ├── tailwind.config.ts
│   └── postcss.config.js
├── deploy/
│   └── nginx-hive-manage-v3.conf
├── docs/
│   └── superpowers/
│       └── plans/
├── .gitignore
└── README.md

Phase 0:基础设施

所有后续 Phase 的前置依赖。无业务逻辑,纯骨架。

Task 0.1:项目目录 + 基础文件

文件:

  • Create: .gitignore, README.md, backend/.env.example, backend/pyproject.toml

  • Step 1: 创建 .gitignore

__pycache__/
*.pyc
.env
node_modules/
dist/
.pytest_cache/
*.egg-info/
venv/
.DS_Store
  • Step 2: 创建 README.md
# Hive Manage v3

蜂群运维中台 — 58 个 Hermes Agent Profile 的批量管控面板。

## 技术栈

- 后端: FastAPI + SQLAlchemy async + PostgreSQL
- 前端: React 19 + TypeScript + Tailwind CSS + Vite

## 快速开始

见 deploy/ 目录下的部署文档。
  • Step 3: 创建 backend/pyproject.toml
[project]
name = "hive-manage-v3"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
    "fastapi[standard]>=0.115",
    "sqlalchemy[asyncio]>=2.0",
    "asyncpg>=0.30",
    "alembic>=1.14",
    "pydantic>=2.10",
    "pydantic-settings>=2.7",
    "python-jose[cryptography]>=3.3",
    "passlib[bcrypt]>=1.7",
    "httpx>=0.28",
    "uvicorn[standard]>=0.34",
]
[project.optional-dependencies]
dev = [
    "pytest>=8.3",
    "pytest-asyncio>=0.25",
    "httpx>=0.28",
]
  • Step 4: 创建 backend/.env.example
DATABASE_URL=postgresql+asyncpg://hive_admin:changeme@localhost:5432/hive_manage_v3
JWT_SECRET=change-me-to-random-string
JWT_ALGORITHM=HS256
JWT_EXPIRE_MINUTES=1440
HERMES_CLI_PATH=/home/enzo/.local/bin/hermes
HERMES_PROFILES_ROOT=/home/enzo/.hermes/profiles
ADMIN_EMAIL=admin@zhiwei.local
ADMIN_PASSWORD=admin123
  • Step 5: 提交
git add -A && git commit -m "chore: project scaffold with .gitignore, README, pyproject.toml"

Task 0.2:Git 初始化 + Gitea 建库 + Mirror

此 Task 委托 ops-engineer(工蜂)执行。以下为指令规格,由 ops 自行完成。

要求:

  • 在 /home/enzo/projects/hive-manage-v3/ 执行 git init
  • 在主 Gitea (192.168.50.97:3002, 用户 enzo) 创建仓库 hive-manage-v3
  • 设置 remote origin 指向主 Gitea
  • 首次 commit + push
  • 备份 Gitea (192.168.50.92:3030) 的 mirror 由现有 cron 自动发现(每小时),无需手动操作
  • 验证:git remote -v 指向正确地址,Gitea Web UI 可见仓库

ops 执行命令参考:

cd /home/enzo/projects/hive-manage-v3
git init
git remote add origin http://enzo:zhiwei2026!@192.168.50.97:3002/enzo/hive-manage-v3.git
git add -A && git commit -m "chore: initial commit"
git push -u origin main

Task 0.3:FastAPI 骨架

文件:

  • Create: backend/app/__init__.py

  • Create: backend/app/main.py

  • Create: backend/app/config.py

  • Create: backend/app/database.py

  • Step 1: 创建 config.py

"""应用配置 — 从环境变量 / .env 读取。"""
from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    database_url: str = "postgresql+asyncpg://hive_admin:changeme@localhost:5432/hive_manage_v3"
    jwt_secret: str = "change-me"
    jwt_algorithm: str = "HS256"
    jwt_expire_minutes: int = 1440
    hermes_cli_path: str = "/home/enzo/.local/bin/hermes"
    hermes_profiles_root: str = "/home/enzo/.hermes/profiles"
    admin_email: str = "admin@zhiwei.local"
    admin_password: str = "admin123"

    model_config = {"env_file": ".env"}

settings = Settings()
  • Step 2: 创建 database.py
"""异步 SQLAlchemy 引擎 + session 工厂。"""
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession
from sqlalchemy.orm import DeclarativeBase

from app.config import settings

engine = create_async_engine(settings.database_url, echo=False)
async_session = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)


class Base(DeclarativeBase):
    pass


async def get_db() -> AsyncSession:
    async with async_session() as session:
        yield session
  • Step 3: 创建 main.py
"""FastAPI 应用入口。"""
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

from app.database import engine, Base


@asynccontextmanager
async def lifespan(app: FastAPI):
    # 启动时创建表(开发阶段;生产用 Alembic)
    async with engine.begin() as conn:
        await conn.run_sync(Base.metadata.create_all)
    yield
    await engine.dispose()


app = FastAPI(
    title="Hive Manage v3",
    version="0.1.0",
    lifespan=lifespan,
)

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


@app.get("/api/v1/health")
async def health_check():
    return {"status": "ok"}
  • Step 4: 提交
git add backend/app/ && git commit -m "feat: FastAPI skeleton with config, database, health endpoint"

Task 0.4:Alembic 初始化 + User 基础 Schema

文件:

  • Create: backend/alembic/ (通过 alembic init)

  • Modify: backend/alembic/env.py

  • Create: backend/app/models/__init__.py

  • Create: backend/app/models/user.py

  • Step 1: 初始化 Alembic + 创建 User 模型

cd backend && alembic init alembic
  • Step 2: 配置 alembic/env.py

将 target_metadata 指向 Base.metadata,配置异步引擎。关键改动:

from app.database import Base, engine
from app.models import *  # noqa: F401,F403 — 确保所有模型被导入

target_metadata = Base.metadata

def run_migrations_offline():
    ...
    context.configure(url=settings.database_url, target_metadata=target_metadata)

def do_run_migrations(connection):
    context.configure(connection=connection, target_metadata=target_metadata)

async def run_async_migrations():
    async with engine.begin() as conn:
        await conn.run_sync(do_run_migrations)

def run_migrations_online():
    import asyncio
    asyncio.run(run_async_migrations())
  • Step 3: 创建 User 模型 backend/app/models/user.py
"""用户 ORM 模型。"""
import uuid
from datetime import datetime
from sqlalchemy import String, Boolean, DateTime, Enum as SAEnum
from sqlalchemy.orm import Mapped, mapped_column
import enum

from app.database import Base


class UserRole(str, enum.Enum):
    OWNER = "owner"
    OPERATOR = "operator"
    VIEWER = "viewer"


class User(Base):
    __tablename__ = "users"

    id: Mapped[str] = mapped_column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    username: Mapped[str] = mapped_column(String(50), unique=True, nullable=False, index=True)
    email: Mapped[str] = mapped_column(String(255), unique=True, nullable=False)
    hashed_password: Mapped[str] = mapped_column(String(255), nullable=False)
    role: Mapped[UserRole] = mapped_column(SAEnum(UserRole), default=UserRole.VIEWER, nullable=False)
    is_active: Mapped[bool] = mapped_column(Boolean, default=True)
    is_approved: Mapped[bool] = mapped_column(Boolean, default=False)
    login_attempts: Mapped[int] = mapped_column(default=0)
    locked_until: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
    updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
  • Step 4: 生成初始迁移
cd backend && alembic revision --autogenerate -m "create users table"
alembic upgrade head
  • Step 5: 创建 backend/app/models/audit.py
"""审计日志 ORM 模型。"""
import uuid
from datetime import datetime
from sqlalchemy import String, DateTime, Text
from sqlalchemy.orm import Mapped, mapped_column

from app.database import Base


class AuditLog(Base):
    __tablename__ = "audit_logs"

    id: Mapped[str] = mapped_column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    user_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True)
    username: Mapped[str] = mapped_column(String(50), nullable=False)
    action: Mapped[str] = mapped_column(String(100), nullable=False, index=True)
    target: Mapped[str] = mapped_column(String(255), nullable=False)
    detail: Mapped[str | None] = mapped_column(Text, nullable=True)
    ip_address: Mapped[str | None] = mapped_column(String(45), nullable=True)
    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
  • Step 6: 生成 AuditLog 迁移并提交
cd backend && alembic revision --autogenerate -m "create audit_logs table"
alembic upgrade head
git add backend/alembic/ backend/app/models/ && git commit -m "feat: Alembic setup, User and AuditLog models"

Task 0.5:前端 Vite + React + Tailwind 脚手架

文件:

  • Create: frontend/package.json, frontend/tsconfig.json, frontend/vite.config.ts, frontend/tailwind.config.ts, frontend/postcss.config.js, frontend/index.html, frontend/src/main.tsx, frontend/src/App.tsx

  • Step 1: 创建 package.json

{
  "name": "hive-manage-v3-frontend",
  "private": true,
  "version": "0.1.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "react": "^19.0",
    "react-dom": "^19.0",
    "react-router-dom": "^7.0",
    "axios": "^1.7",
    "lucide-react": "^0.460"
  },
  "devDependencies": {
    "@types/react": "^19.0",
    "@types/react-dom": "^19.0",
    "@vitejs/plugin-react": "^4.3",
    "autoprefixer": "^10.4",
    "postcss": "^8.4",
    "tailwindcss": "^3.4",
    "typescript": "^5.6",
    "vite": "^6.0"
  }
}
  • Step 2: 创建 vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
  server: {
    port: 5173,
    proxy: {
      '/api': 'http://127.0.0.1:8000',
    },
  },
})
  • Step 3: 创建 tailwind.config.ts
import type { Config } from 'tailwindcss'

export default {
  content: ['./index.html', './src/**/*.{ts,tsx}'],
  darkMode: 'class',
  theme: {
    extend: {
      colors: {
        honey: { DEFAULT: '#f0b90b', dim: '#b8970e' },
      },
    },
  },
  plugins: [],
} satisfies Config
  • Step 4: 创建 index.html + main.tsx + App.tsx(最小骨架)
<!DOCTYPE html>
<html lang="zh-CN">
  <head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Hive Manage v3</title></head>
  <body><div id="root"></div><script type="module" src="/src/main.tsx"></script></body>
</html>
// main.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './styles/tokens.css'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode><App /></React.StrictMode>
)
// App.tsx
export default function App() {
  return <div className="min-h-screen bg-[var(--bg-root)] text-[var(--text)]">Hive Manage v3</div>
}
  • Step 5: 安装依赖 + 验证
cd frontend && npm install && npm run dev
# 访问 http://localhost:5173 应显示 "Hive Manage v3"
  • Step 6: 提交
git add frontend/ && git commit -m "feat: Vite + React 19 + Tailwind + TypeScript scaffold"

Task 0.6:CSS 变量双模体系

文件:

  • Create: frontend/src/styles/tokens.css

根据 UI 设计规范 §2.1 精确实现:

/* ===== 暗色模式(默认) ===== */
:root {
  --bg-root: #0f1117; --bg-nav: #161822; --bg-card: #1a1d2e;
  --bg-hover: #1e2134; --bg-elevated: #222639;
  --border: #2a2d3e; --border-light: rgba(42,45,62,.5);
  --honey: #f0b90b; --honey-dim: #b8970e; --honey-glow: rgba(240,185,11,.12);
  --green: #00c853; --red: #ff3d3d; --yellow: #ffab00;
  --blue: #448aff; --orange: #ff6d00;
  --text: #e0e0e0; --text-dim: #8b8d9a; --text-muted: #5a5d6a;
  --bg-success: #0d2818; --bg-error: #2d0f0f; --bg-warn: #2d2000; --bg-info: #0d1b2d;
  --radius: 8px; --radius-sm: 4px; --radius-lg: 12px; --radius-full: 9999px;
  --shadow: 0 2px 8px rgba(0,0,0,.35); --shadow-lg: 0 12px 32px rgba(0,0,0,.55);
  --shadow-modal: 0 24px 64px rgba(0,0,0,.65);
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-mono: "SF Mono", "Fira Code", Consolas, monospace;
  --header-h: 48px; --sidebar-w: 220px;
}

/* ===== 浅色模式 ===== */
[data-theme="light"] {
  --bg-root: #f5f6fa; --bg-nav: #ffffff; --bg-card: #ffffff;
  --bg-hover: #edf0f5; --bg-elevated: #ffffff;
  --border: #e2e5ee; --border-light: rgba(0,0,0,.06);
  --honey: #e5a800; --honey-dim: #c48f00; --honey-glow: rgba(229,168,0,.08);
  --green: #008c3a; --red: #d32f2f; --yellow: #e65100;
  --blue: #1565c0; --orange: #d84315;
  --text: #1a1d2e; --text-dim: #555a6e; --text-muted: #8b8f9e;
  --bg-success: #e8f5e9; --bg-error: #fdecea; --bg-warn: #fff3e0; --bg-info: #e3f2fd;
  --shadow: 0 1px 4px rgba(0,0,0,.08); --shadow-lg: 0 8px 24px rgba(0,0,0,.10);
  --shadow-modal: 0 16px 48px rgba(0,0,0,.14);
}

/* ===== 全局基础 ===== */
* { box-sizing: border-box; }
body {
  margin: 0; font-family: var(--font); font-size: 13px;
  background: var(--bg-root); color: var(--text);
}
/* 主题切换过渡 */
* { transition: background-color .15s, border-color .15s, color .15s; }
  • Step: 提交
git add frontend/src/styles/tokens.css && git commit -m "feat: CSS variable dual-theme system (dark default + light)"

Task 0.7:共享 UI 组件库

文件: 全部在 frontend/src/components/ui/ 下创建。

每个组件遵循 UI 设计规范 §4 规格。以下列出关键组件及核心实现要点,完整代码由 Claude Code 根据原型 HTML 和设计规范实现。

组件 文件 规范参考 关键要点
Button Button.tsx §4.4 4 变体 (primary/danger/outline/ghost) + 2 尺寸 + loading/disabled 态
Card Card.tsx §4.1 header(label+action) + value(彩色) + change(↑↓)
Table Table.tsx §4.3 sticky 表头 + hover 高亮 + row-danger 样式 + 移动端卡片化
Badge Badge.tsx §4.5 6 变体 (success/danger/warning/info/honey/outline) + 胶囊形
Modal Modal.tsx §4.8 居中弹窗 + 遮罩 + Esc 关闭 + 确认短语输入
Drawer Drawer.tsx §4.9 右侧滑入 480px + 遮罩 + Esc 关闭
Toast Toast.tsx §4.10 4 类型 (success/error/warn/info) + 顶部居中 + 自动消失
Skeleton Skeleton.tsx §4.14 shimmer 动画 + 形状匹配 (card/table/text)
Toggle Toggle.tsx §4.7 44×24px + 滑块动画 + 标签
Timeline Timeline.tsx §4.13 横向时间线 + 点 hover tooltip
SearchBox SearchBox.tsx §4.11 输入框 + 下拉面板 + 分组结果 + debounce 300ms

测试要求: 每个组件提供基础渲染测试(Vitest + React Testing Library),验证所有变体和状态。

  • Step: 逐个组件实现(Claude Code 编写 + 工头 QC)
git add frontend/src/components/ui/ && git commit -m "feat: shared UI component library (11 components)"

Task 0.8:布局组件

文件: frontend/src/components/layout/

组件 文件 规范参考 关键要点
Sidebar Sidebar.tsx §3.5 220px 固定 + 5 Section + NavItem active/hover + Badge
Header Header.tsx §3.4 48px + 面包屑 + 搜索框 + 主题切换 + 更新指示
MobileNav MobileNav.tsx §3.2 汉堡菜单 → 左侧抽屉 280px + 遮罩
TabBar TabBar.tsx §3.6 底部固定 56px + 4 核心入口 (总览/Gateway/Kanban/Cron)
AppLayout AppLayout.tsx §3.1 CSS Grid: Sidebar + Header + Main,响应式 768px 断点切换移动布局
  • Step 1: 实现 AppLayout.tsx(核心布局)
// 桌面: CSS Grid (sidebar 220px + header 48px + main)
// 平板 (768-1279px): sidebar 180px
// 移动 (<768px): Header + TabBar + 汉堡抽屉
// 使用 CSS 媒体查询 + data-viewport 属性切换
  • Step 2: 实现路由占位
// App.tsx 中使用 react-router-dom
// / → Dashboard
// /login → LoginPage
// /gateway → GatewayPage
// ...
// 未登录重定向 /login,已登录根据 JWT 存在与否判断
  • Step 3: 提交
git add frontend/src/components/layout/ frontend/src/App.tsx && git commit -m "feat: layout components (Sidebar, Header, MobileNav, TabBar, AppLayout)"

Phase 1:用户中心 + 鉴权(P0-6)

Task 1.1:JWT 鉴权服务 + 中间件

文件:

  • Create: backend/app/services/auth_service.py

  • Create: backend/app/middleware/auth.py

  • Create: backend/app/schemas/auth.py

  • Step 1: 创建 auth schema

# backend/app/schemas/auth.py
from pydantic import BaseModel, EmailStr

class LoginRequest(BaseModel):
    username: str
    password: str

class RegisterRequest(BaseModel):
    username: str
    email: EmailStr
    password: str

class TokenResponse(BaseModel):
    access_token: str
    token_type: str = "bearer"
    expires_in: int
    user: "UserResponse"  # 引用 user schema

class ChangePasswordRequest(BaseModel):
    old_password: str
    new_password: str
  • Step 2: 创建 auth_service.py

核心功能:

  • hash_password(password: str) -> str — bcrypt

  • verify_password(plain: str, hashed: str) -> bool

  • create_access_token(user_id: str, role: str) -> str — JWT 编码

  • decode_access_token(token: str) -> dict — JWT 解码 + 过期检查

  • get_current_user(token: str, db: AsyncSession) -> User — FastAPI Depends

  • Step 3: 创建 auth 中间件

# backend/app/middleware/auth.py
from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from sqlalchemy.ext.asyncio import AsyncSession
from app.database import get_db
from app.services.auth_service import decode_access_token, get_user_by_id

security = HTTPBearer()

async def require_auth(
    credentials: HTTPAuthorizationCredentials = Depends(security),
    db: AsyncSession = Depends(get_db),
):
    """解析 JWT → 查询 User → 返回 User ORM 对象。失败抛 401。"""
    payload = decode_access_token(credentials.credentials)
    user = await get_user_by_id(db, payload["sub"])
    if not user or not user.is_active:
        raise HTTPException(status_code=401, detail="Invalid or inactive user")
    return user

def require_role(*roles: str):
    """角色守卫工厂。用法: Depends(require_role("owner", "operator"))"""
    async def role_check(user = Depends(require_auth)):
        if user.role.value not in roles:
            raise HTTPException(status_code=403, detail="Insufficient permissions")
        return user
    return role_check
  • Step 4: 编写测试
# backend/tests/test_auth.py
# 测试用例:
# - 注册成功 → 201
# - 重复注册 → 409
# - 登录成功 → 200 + JWT
# - 错误密码 → 401
# - 登录锁定(5 次失败) → 423
# - Token 过期 → 401
# - 无 Token 访问受保护路由 → 401
# - Viewer 角色访问写操作 → 403
  • Step 5: 提交
git add backend/app/services/auth_service.py backend/app/middleware/ backend/app/schemas/auth.py backend/tests/test_auth.py && git commit -m "feat: JWT auth service, middleware, and role guards"

Task 1.2:Auth API 路由

文件:

  • Create: backend/app/api/auth.py

  • Step 1: 实现路由

# backend/app/api/auth.py
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from app.database import get_db
from app.schemas.auth import LoginRequest, RegisterRequest, TokenResponse
from app.services.auth_service import *
from app.models.user import User, UserRole

router = APIRouter(prefix="/api/v1/auth", tags=["auth"])

@router.post("/register", status_code=201)
async def register(body: RegisterRequest, db: AsyncSession = Depends(get_db)):
    """新用户注册。默认 Viewer 角色 + 待审批。首个用户自动设为 Owner + 已审批。"""
    ...

@router.post("/login", response_model=TokenResponse)
async def login(body: LoginRequest, db: AsyncSession = Depends(get_db)):
    """用户名 + 密码登录。失败 5 次锁定 15 分钟。成功返回 JWT。"""
    ...

@router.post("/refresh")
async def refresh_token(user = Depends(require_auth)):
    """刷新 Token(重置过期时间)。"""
    ...

@router.post("/change-password")
async def change_password(body: ChangePasswordRequest, user = Depends(require_auth), db = Depends(get_db)):
    """修改当前用户密码。"""
    ...
  • Step 2: 在 main.py 注册路由
from app.api import auth
app.include_router(auth.router)
  • Step 3: 编写集成测试并提交

Task 1.3:用户管理 API

文件:

  • Create: backend/app/api/users.py
  • Create: backend/app/schemas/user.py

路由:GET /api/v1/users(列表) / GET /api/v1/users/{id}(详情) / PATCH /api/v1/users/{id}(改角色) / POST /api/v1/users/{id}/approve(审批) / DELETE /api/v1/users/{id}(停用)。

  • Step 1: 实现 + 测试 + 提交

Task 1.4:审计日志中间件 + API

文件:

  • Modify: backend/app/middleware/audit.py(自动记录写操作)
  • Create: backend/app/api/audit.py

核心逻辑:中间件监听所有 POST/PUT/PATCH/DELETE 请求,提取 user_id、action、target、ip_address,写入 audit_logs。审计日志不可删除(API 只提供 GET 查询)。

  • Step: 实现 + 测试 + 提交

Task 1.5-1.9:前端鉴权页面

文件:

  • frontend/src/pages/LoginPage.tsx

  • frontend/src/pages/UserManagementPage.tsx

  • frontend/src/pages/AuditLogPage.tsx

  • frontend/src/hooks/useAuth.ts

  • frontend/src/api/auth.ts, users.ts, audit.ts

  • frontend/src/api/client.ts(axios 实例 + JWT 拦截器 + 401 自动跳转登录)

  • Step: 逐页面实现(Claude Code 编写 + 工头 QC)

git add frontend/src/pages/LoginPage.tsx frontend/src/pages/UserManagementPage.tsx frontend/src/pages/AuditLogPage.tsx frontend/src/hooks/useAuth.ts frontend/src/api/ && git commit -m "feat: login, user management, audit log pages with JWT auth flow"

Phase 2-8:业务模块

每个模块遵循相同模式:Hermes CLI 封装服务 → Pydantic Schema → API 路由 → 前端页面。以下为模块规格摘要,完整实现由 Claude Code 按此模式执行。

通用实现模式(以 Gateway 为例)

1. backend/app/services/hermes_cli.py   — 添加 gateway_status(), gateway_start(), gateway_stop()
2. backend/app/schemas/gateway.py       — GatewayStatus, GatewayEvent, ToggleRequest
3. backend/app/api/gateway.py           — router + require_auth + 角色守卫
4. backend/tests/test_gateway.py        — pytest + httpx AsyncClient
5. frontend/src/api/gateway.ts          — axios 调用封装
6. frontend/src/pages/GatewayPage.tsx   — 完整页面(四态 + 轮询 + 操作)

Phase 2:Dashboard 增强(P0-3)

Task 后端 API 前端页面 估时
2.1 GET /api/v1/dashboard/summary — 在线/离线/任务/Cron 计数 DashboardPage 统计卡片 2h
2.2 GET /api/v1/dashboard/health-distribution — A/B/C/D 四级计数 健康分布柱状图 1.5h
2.3 GET /api/v1/dashboard/gateway-trend — 24h 异常事件按小时 Gateway 异常趋势折线图 1.5h
2.4 GET /api/v1/dashboard/kanban-summary — 活跃看板概览 Kanban 概览卡片 1h
2.5 GET /api/v1/dashboard/cron-recent — 最近 Cron 执行 Cron 最近执行卡片 1h
2.6 GET /api/v1/search?q= — 全局搜索 SearchBox 组件集成 1.5h

Phase 3:Gateway 健康监控(P0-1)

Task 后端 API 前端页面 估时
3.1 GET /api/v1/gateway/status — 全部 Profile 状态列表 GatewayPage 状态表(10s 轮询) 3h
3.2 GET /api/v1/gateway/events — 24h 异常事件时间线 异常时间线组件 2h
3.3 POST /api/v1/gateway/{profile}/start|stop|restart 启停按钮 + 二次确认弹窗 2.5h
3.4 筛选 + 蜂型分类 前端筛选器(即时生效) 1.5h

Phase 4:Profile 健康分(P0-2)

Task 后端 API 前端页面 估时
4.1 GET /api/v1/health/scores — 排行列表 HealthPage 列表 + 展开详情 3h
4.2 GET /api/v1/health/scores/{profile} — 单 Profile 详情 四维度扣分明细面板 2h
4.3 POST /api/v1/health/compare — 批量对比 批量对比视图 2h
4.4 POST /api/v1/health/calculate — 手动触发计算 凌晨定时 + 手动触发按钮 2h

Phase 5:Cron 管理(P0-4b)

Task 后端 API 前端页面 估时
5.1 GET /api/v1/cron/jobs — 跨 Profile Cron 列表(含系统 Cron) CronPage 列表 + 筛选 3h
5.2 GET /api/v1/cron/jobs/{id}/logs — 最近 8 条日志 日志面板(遮罩 + 居中弹窗) 2h
5.3 POST /api/v1/cron/jobs/{id}/run|pause|resume 操作按钮 + Toast 2h
5.4 失败告警联动 Dashboard Badge + 导航栏红色标记 1.5h

Phase 6:密钥批量管理(P0-5)

Task 后端 API 前端页面 估时
6.1 GET /api/v1/keys — 密钥字段列表 KeysPage 列表 2h
6.2 POST /api/v1/keys/batch-overwrite — 批量覆盖 批量覆盖弹窗(确认短语) 2h
6.3 POST /api/v1/keys/batch-scan — 批量检查 缺失扫描结果 + CSV 导出 1.5h
6.4 GET /api/v1/keys/diff — 差异视图 字段对比表 1.5h

Phase 7:Kanban 增强(P0-4)

Task 后端 API 前端页面 估时
7.1 GET /api/v1/kanban/tasks — 跨 Profile 五列聚合 KanbanPage 五列看板 4h
7.2 GET /api/v1/kanban/tasks/{id} — 任务详情 详情抽屉 2h
7.3 PATCH /api/v1/kanban/tasks/{id}/move — 拖拽移动 拖拽 + 异常标记 3h
7.4 异常检测(阻塞超时/长期无主/失败重试) 卡片标红/警告 2h
7.5 Worker 筛选 + 看板筛选 + 异常筛选 筛选器 2h

Phase 8:事件档案管理(P0-7)

Task 后端 API 前端页面 估时
8.1 GET /api/v1/events — 事件卡片列表(三维筛选) EventArchivePage 卡片网格 2h
8.2 数据爬取 → PG(hm.zhiweidata.ai/events) — 2h
8.3 超期标记 + Toast 详情 超期红色标记 + 点击 Toast 1.5h

Phase 9:集成测试 + 上线

Task 内容 估时
9.1 全量 API 集成测试(httpx + pytest-asyncio) 3h
9.2 前端冒烟测试(Vitest + Testing Library) 2h
9.3 Nginx 部署配置 + 静态文件服务 1h
9.4 部署文档 + API 文档(FastAPI 自动生成) 0.5h

执行说明

  • 所有代码由 Claude Code 编写,命令格式:
cd /home/enzo/projects/hive-manage-v3 && \
ANTHROPIC_API_KEY="sk-4eem6h6DfcPIT7EbY3tLhtd7oepyw9GaqgbSUHmkv3shmNym" \
ANTHROPIC_BASE_URL="http://127.0.0.1:3000" \
ANTHROPIC_MODEL="claude-3-opus-20240229" \
claude --model claude-3-opus-20240229 \
  --dangerously-skip-permissions \
  --output-format stream-json --include-partial-messages --verbose \
  -p "<完整任务描述 + 上下文 + 验收标准>"
  • 每个 Task 完成后:工头审查产出(代码质量 + 测试覆盖 + 是否符合设计规范),通过则提交,不通过则反馈 Claude Code 修改。
  • 提交粒度:一个 Task 一个 commit,commit message 格式 feat: / fix: / test: / chore: + 简短描述。

计划版本: v1.0 · 2026-07-22 · 开发工程