# 运维管理平台模块化开发规范 依据: - [液态玻璃后台 UI 设计规范](./liquid-glass-admin-ui-guideline.md) - [运维管理平台第一版开发内容](./v1-development-scope.md) 目标:建立一套可长期维护的开发规范,让第一版能快速落地,同时避免后续接入真实 Kubernetes、日志、监控、数据库资源、审批流时推倒重来。 ## 1. 技术方向 第一版默认按前后端分离设计,前端先使用 Mock 数据完成完整业务闭环,后端接口后续按相同契约接入。 推荐前端技术栈: | 类型 | 推荐 | | --- | --- | | 语言 | TypeScript | | UI 框架 | React | | 构建工具 | Vite | | 路由 | React Router | | 服务端状态 | TanStack Query | | 客户端状态 | Zustand 或 React Context | | 表单 | React Hook Form | | 校验 | Zod | | Mock | MSW | | 单元测试 | Vitest | | 组件测试 | Testing Library | | E2E | Playwright | | 样式 | CSS Variables + CSS Modules | | 图标 | lucide-react | | 图表 | Recharts 或 ECharts | 技术选择原则: - 服务端数据用 Query 管理,不放进全局 Store。 - 项目、环境、集群这类 UI 上下文可以放全局 Store。 - UI Token 必须通过 CSS 变量统一管理。 - Mock 层必须和真实 API 共用类型定义。 - 业务模块优先纵向切分,不按文件类型横向堆叠。 ## 2. 模块化架构 推荐使用“业务垂直切片 + 分层依赖”的结构。 目录结构: ```text src/ app/ App.tsx router.tsx providers/ QueryProvider.tsx AppStateProvider.tsx styles/ tokens.css glass.css layout.css components.css pages/ overview/ services/ service-detail/ releases/ resources/ logs-events/ audit/ widgets/ app-shell/ top-context-bar/ service-table/ release-drawer/ restart-dialog/ metric-dashboard/ event-timeline/ features/ switch-project-context/ filter-services/ release-service/ restart-service/ search-logs/ filter-audits/ entities/ project/ cluster/ service/ release/ resource/ event/ audit/ user/ shared/ api/ config/ constants/ lib/ types/ ui/ hooks/ mocks/ assets/ ``` 分层职责: | 层级 | 职责 | 示例 | | --- | --- | --- | | `app` | 应用启动、路由、全局 Provider、全局样式 | `router.tsx`、`QueryProvider` | | `pages` | 页面编排,只组合 widgets/features/entities | `OverviewPage` | | `widgets` | 页面级业务区块,可包含多个 feature | `ServiceTable`、`ReleaseDrawer` | | `features` | 用户可执行的业务动作 | 发布服务、重启服务、筛选服务 | | `entities` | 业务实体模型、实体 API、实体展示组件 | `service`、`release` | | `shared` | 无业务含义的通用能力 | Button、Table、fetcher、formatDate | 依赖方向: ```text app -> pages -> widgets -> features -> entities -> shared ``` 规则: - 下层不能 import 上层。 - `shared` 不能 import 任何业务模块。 - `entities` 之间尽量不直接互相 import,跨实体组合放在 `features` 或 `widgets`。 - 页面不能直接写复杂业务逻辑,页面只做布局和组合。 - 同一业务动作只允许有一个入口模块,例如发布服务统一放在 `features/release-service`。 ## 3. 模块目录规范 每个业务模块使用相同结构,便于查找。 ```text features/release-service/ api/ createRelease.ts model/ schema.ts types.ts useReleaseService.ts ui/ ReleaseForm.tsx ReleaseSteps.tsx lib/ buildReleasePayload.ts index.ts ``` `index.ts` 只导出模块的公开 API。 允许导出: - 页面或组件需要使用的 UI。 - Hook。 - 类型。 - 纯工具函数。 禁止导出: - 内部私有组件。 - 临时常量。 - Mock 实现细节。 - 只为绕过依赖规则而暴露的对象。 ## 4. 命名规范 文件命名: | 类型 | 规范 | 示例 | | --- | --- | --- | | React 组件 | PascalCase | `ServiceTable.tsx` | | Hook | camelCase,以 `use` 开头 | `useServicesQuery.ts` | | 工具函数 | camelCase | `formatDuration.ts` | | 类型文件 | `types.ts` | `entities/service/model/types.ts` | | Schema | `schema.ts` | `release/model/schema.ts` | | 常量 | `constants.ts` | `shared/constants/status.ts` | | 样式模块 | 同组件名 | `ServiceTable.module.css` | | 测试 | 同文件名 + `.test` | `formatDuration.test.ts` | 类型命名: - 业务实体:`Service`、`ReleaseRecord`、`DataResource`。 - API 请求:`CreateReleaseRequest`。 - API 响应:`ServiceListResponse`。 - 表单值:`ReleaseFormValues`。 - 组件 Props:`ServiceTableProps`。 状态枚举: - TypeScript 使用字符串联合类型优先。 - 后端返回值必须稳定,不使用中文作为状态码。 示例: ```ts export type ServiceStatus = "healthy" | "warning" | "critical" | "unknown" | "running"; ``` ## 5. TypeScript 规范 必须开启: ```json { "compilerOptions": { "strict": true, "noUncheckedIndexedAccess": true, "exactOptionalPropertyTypes": true } } ``` 规则: - 禁止使用 `any`,确实无法确定时使用 `unknown` 并收窄。 - API 返回值必须有类型。 - 表单提交值必须有 Zod Schema 校验。 - 组件 Props 必须显式定义。 - 复杂类型放在 `model/types.ts`。 - 跨模块共享类型只能从模块 `index.ts` 导入。 - 不在组件里直接拼接后端数据结构,使用 mapper 转成前端 ViewModel。 推荐: ```ts type ServiceTableRow = { id: string; name: string; status: ServiceStatus; version: string; instanceText: string; cpuUsage: number; memoryUsage: number; owner: string; }; ``` ## 6. API 层规范 统一入口: ```text shared/api/ httpClient.ts queryKeys.ts errors.ts ``` 实体 API: ```text entities/service/api/ getServices.ts getServiceDetail.ts getServiceInstances.ts getServiceMetrics.ts ``` 规则: - 所有请求必须经过 `shared/api/httpClient.ts`。 - API 函数只负责请求和数据转换,不处理 UI Toast。 - 请求参数统一使用对象,不使用多个位置参数。 - 列表接口必须支持 `projectId`、`environment`、`clusterId`。 - 写操作必须返回可用于刷新缓存的业务 ID。 - API 错误统一转成标准错误对象。 标准错误: ```ts type ApiError = { code: string; message: string; requestId?: string; details?: unknown; }; ``` Query Key 规范: ```ts export const queryKeys = { services: (params: ServiceListParams) => ["services", params] as const, serviceDetail: (id: string) => ["service", id] as const, releases: (params: ReleaseListParams) => ["releases", params] as const, }; ``` ## 7. 状态管理规范 状态分三类: | 类型 | 管理方式 | 示例 | | --- | --- | --- | | 服务端状态 | TanStack Query | 服务列表、发布记录、数据资源 | | 全局 UI 上下文 | Zustand / Context | 项目、环境、集群、当前用户 | | 局部 UI 状态 | React `useState` | 抽屉开关、当前 Tab、表单中间态 | 全局 Store 只放: - 当前项目。 - 当前环境。 - 当前集群。 - 当前用户和角色。 - 全局布局状态。 禁止放入全局 Store: - 服务列表。 - 发布记录。 - 日志列表。 - 监控图表数据。 - 临时表单值。 原因:这些数据属于服务端状态,应该由 Query 缓存、刷新和失效控制。 ## 8. UI 组件规范 组件分三类: | 类型 | 目录 | 说明 | | --- | --- | --- | | 通用 UI | `shared/ui` | Button、Table、Badge、Drawer | | 实体组件 | `entities/*/ui` | ServiceStatusBadge、ResourceTypeIcon | | 业务组件 | `features` / `widgets` | ReleaseDrawer、ServiceTable | 通用 UI 规则: - 不包含业务字段。 - 不直接请求接口。 - 不读取全局业务 Store。 - 通过 Props 接收数据。 - 支持 `className`。 - 支持键盘焦点。 - 支持 disabled、loading、error 状态。 业务组件规则: - 可以组合实体组件和通用 UI。 - 可以调用 feature 内 Hook。 - 不直接写全局样式。 - 危险操作必须显式传入 `environment`。 组件文件结构: ```text Button/ Button.tsx Button.module.css Button.test.tsx index.ts ``` ## 9. 样式规范 样式分层: ```text app/styles/ tokens.css glass.css layout.css components.css ``` 规则: - 颜色、圆角、阴影、字号、间距必须使用 Token。 - 组件局部样式使用 CSS Modules。 - 禁止在业务组件里硬编码主色和状态色。 - 禁止使用行内样式写核心布局。 - 不使用负字距。 - 不使用大面积单色主题覆盖液态玻璃风格。 - 图表颜色从 Token 或统一常量中读取。 CSS 命名: ```css .root {} .header {} .body {} .footer {} .title {} .meta {} .actions {} .isActive {} .isDisabled {} ``` 玻璃样式统一使用类: - `.glass-surface` - `.glass-surface-strong` - `.glass-subtle` 不要在每个组件里重复实现玻璃效果。 ## 10. 页面开发规范 页面只做三件事: - 读取路由参数。 - 组合 widgets/features。 - 控制页面级布局。 页面不做: - 直接调用底层 HTTP。 - 写复杂数据转换。 - 处理发布和重启流程细节。 - 写超过 80 行的业务逻辑。 页面示例: ```tsx export function ServicesPage() { return ( ); } ``` ## 11. 业务模块规范 ### 11.1 服务模块 目录: ```text entities/service/ api/ model/ ui/ lib/ index.ts ``` 职责: - 服务类型定义。 - 服务列表接口。 - 服务详情接口。 - 服务状态展示。 - 服务数据格式化。 不负责: - 发布服务。 - 重启服务。 - 服务筛选表单。 ### 11.2 发布模块 目录: ```text features/release-service/ api/ model/ ui/ lib/ index.ts ``` 职责: - 版本选择。 - 发布策略选择。 - 预检查展示。 - 发布提交。 - 发布状态反馈。 规则: - `prod` 必须要求二次确认。 - 发布完成后必须刷新服务详情和发布记录。 - 发布成功或失败都必须生成事件和审计记录。 ### 11.3 重启模块 职责: - 单实例重启。 - 全部实例重启。 - 滚动重启和立即重启。 - 影响范围展示。 规则: - `prod` 默认滚动重启。 - 立即重启必须二次确认。 - 操作完成后必须生成事件和审计记录。 ### 11.4 数据资源模块 职责: - 展示 MySQL、MongoDB、Redis、Kafka 状态。 - 展示容量、连接数、备份、关联服务。 - 展示异常事件。 规则: - 第一版不开放查询入口。 - 第一版不开放恢复入口。 - 生产环境不显示任何直接执行数据库命令的能力。 ## 12. 表单规范 所有表单必须: - 使用 Schema 校验。 - 提交前做客户端校验。 - 提交中禁用提交按钮。 - 提交失败展示错误原因。 - 危险操作展示影响范围。 发布表单必须校验: - 目标版本不能为空。 - 发布策略不能为空。 - `prod` 环境必须勾选确认。 重启表单必须校验: - 重启范围不能为空。 - 立即重启必须二次确认。 - 单实例重启必须有实例 ID。 ## 13. 权限规范 前端权限用于控制体验,后端权限用于保证安全。第一版即使没有真实后端,也要按这个结构设计。 权限点: ```ts type Permission = | "service:read" | "service:release" | "service:restart" | "release:read" | "resource:read" | "logs:read" | "audit:read"; ``` 规则: - 权限不足的危险操作显示禁用态,不直接隐藏。 - 禁用态必须说明原因。 - 生产环境操作必须额外判断角色和确认状态。 - 审计页面只对有 `audit:read` 权限的角色开放。 ## 14. Mock 规范 Mock 使用 MSW 或等价方案。 目录: ```text shared/mocks/ browser.ts handlers.ts data/ projects.ts services.ts releases.ts resources.ts events.ts audits.ts ``` 规则: - Mock 数据结构必须复用实体类型。 - Mock 行为要模拟真实写操作。 - 发布成功后更新服务版本。 - 重启成功后新增事件和审计。 - 支持模拟失败场景。 - 支持模拟空状态。 必须覆盖: - Healthy、Warning、Critical 服务。 - 发布成功、失败、执行中。 - MySQL、MongoDB、Redis、Kafka 多种状态。 - `prod` 环境二次确认。 - 权限不足禁用操作。 ## 15. 错误处理规范 错误分三层: | 层级 | 处理 | | --- | --- | | API 层 | 转换为 `ApiError` | | 业务层 | 判断是否可重试、是否需要刷新 | | UI 层 | 展示错误状态、Toast、下一步操作 | 页面错误态必须提供: - 错误原因。 - 重试按钮。 - 可选的查看事件入口。 写操作失败必须提供: - 失败原因。 - requestId,如果有。 - 是否可以重试。 - 是否需要查看事件。 禁止: - 只显示“操作失败”。 - 把原始异常对象直接渲染到页面。 - 静默吞掉接口错误。 ## 16. 日志和审计规范 前端事件日志用于排查,审计记录用于追责。 发布、重启、回滚必须产生审计记录。 审计记录字段: - 操作时间。 - 操作人。 - 角色。 - 操作对象。 - 操作类型。 - 环境。 - 集群。 - 执行结果。 - 关联记录 ID。 生产环境操作必须有明显标识。 ## 17. 测试规范 测试分层: | 类型 | 工具 | 覆盖内容 | | --- | --- | --- | | 单元测试 | Vitest | 工具函数、mapper、权限判断、表单校验 | | 组件测试 | Testing Library | Button、Table、Badge、ReleaseDrawer | | 集成测试 | Testing Library + MSW | 发布流程、重启流程、筛选流程 | | E2E | Playwright | 核心用户路径 | 必须测试: - 服务状态 Badge 文案和颜色类。 - 服务搜索和筛选。 - `prod` 发布确认。 - 发布成功后版本更新。 - 发布失败后错误反馈。 - 重启成功后事件和审计新增。 - 权限不足时按钮禁用。 - Secret 不显示明文。 E2E 核心路径: 1. 进入总览页。 2. 切换到 `prod`。 3. 打开 `user-service` 详情。 4. 打开发版抽屉。 5. 选择目标版本。 6. 勾选生产确认。 7. 执行发布。 8. 验证发布记录和审计记录。 ## 18. 代码质量规范 必须配置: - ESLint。 - Prettier。 - TypeScript strict。 - lint-staged。 - 单元测试命令。 - 构建命令。 建议脚本: ```json { "scripts": { "dev": "vite", "build": "tsc -b && vite build", "preview": "vite preview", "lint": "eslint .", "format": "prettier --write .", "test": "vitest run", "test:watch": "vitest", "e2e": "playwright test", "check": "npm run lint && npm run test && npm run build" } } ``` 提交前最低要求: - TypeScript 无错误。 - ESLint 无错误。 - 单元测试通过。 - 构建通过。 涉及 UI 的改动还要: - 浏览器预览。 - 检查桌面宽度 1280px。 - 检查表格文字不重叠。 - 检查抽屉内容可滚动。 - 检查 `prod` 危险操作二次确认。 ## 19. Git 和提交规范 分支命名: ```text feature/overview-page feature/release-drawer fix/prod-release-confirm chore/setup-eslint ``` 提交信息: ```text feat: add service release drawer fix: require confirmation before prod restart chore: setup testing pipeline docs: add modular development guideline ``` 提交类型: | 类型 | 含义 | | --- | --- | | `feat` | 新功能 | | `fix` | 修复 | | `docs` | 文档 | | `style` | 格式和样式调整 | | `refactor` | 重构 | | `test` | 测试 | | `chore` | 工程配置 | 规则: - 一个提交只做一类事情。 - 不把大范围格式化混进功能提交。 - 不提交本地环境文件。 - 不提交密钥、Token、数据库连接串。 ## 20. 环境变量规范 命名: ```text VITE_API_BASE_URL= VITE_ENABLE_MOCK= VITE_APP_ENV= ``` 规则: - 前端环境变量必须以 `VITE_` 开头。 - `.env.example` 必须维护。 - `.env.local` 不提交。 - 不在前端存储真实密钥。 - 生产环境配置由部署平台注入。 ## 21. 性能规范 第一版性能目标: - 首屏可交互时间控制在合理范围。 - 表格 100 条数据内交互不卡顿。 - 路由页面按需加载。 - 图表组件按页面懒加载。 - 日志列表避免一次渲染过多行。 规则: - 路由级代码分割。 - 大图表库懒加载。 - 表格筛选优先使用 memoized selector。 - 不在 render 中做重型计算。 - 日志列表超过 500 行时考虑虚拟列表。 ## 22. 安全规范 第一版必须遵守: - 不展示 Secret 明文。 - 不在 localStorage 存储敏感 Token。 - 所有危险操作必须检查权限。 - 所有生产环境操作必须二次确认。 - 后端接入后必须校验权限,不能只依赖前端。 - 日志内容渲染要避免 XSS。 - 用户输入不能直接拼接到 URL path,必须 encode。 数据库资源限制: - 第一版不做 SQL 查询。 - 第一版不做 Mongo 查询。 - 第一版不做备份恢复。 - 生产环境不显示直接执行命令入口。 ## 23. 可访问性规范 最低要求: - 所有按钮可键盘访问。 - 抽屉和弹窗可按 Esc 关闭。 - 菜单可键盘导航。 - 状态 Badge 必须有文字。 - 表单错误信息和字段绑定。 - 点击目标不小于 32px x 32px。 - 颜色不能作为唯一状态表达。 ## 24. 开发顺序 推荐顺序: 1. 初始化项目和质量工具。 2. 建立 Token、玻璃样式、App Shell。 3. 建立 Mock 数据和 API 适配层。 4. 开发通用 UI 组件。 5. 开发实体模块:service、release、resource、event、audit。 6. 开发首页和微服务列表。 7. 开发服务详情页。 8. 开发发布抽屉和重启流程。 9. 开发发布记录、数据资源、日志事件、审计页。 10. 补齐测试、空状态、错误状态。 11. 浏览器视觉验收。 12. 构建验收。 ## 25. Definition of Done 一个功能完成必须满足: - 代码按模块边界放置。 - 类型完整,无 `any`。 - 样式使用全局 Token。 - Loading、Empty、Error 状态完整。 - 权限不足有禁用态和原因。 - `prod` 危险操作有二次确认。 - 写操作成功和失败都有反馈。 - 相关事件和审计记录更新。 - 单元测试或集成测试覆盖关键逻辑。 - `lint`、`test`、`build` 通过。 - 浏览器中验证 UI 不重叠、不溢出、抽屉可滚动。 ## 26. 禁止项 - 禁止页面直接调用 `fetch`。 - 禁止在页面里堆业务逻辑。 - 禁止业务模块跨层反向依赖。 - 禁止在组件里硬编码设计 Token。 - 禁止把服务端状态放进全局 Store。 - 禁止生产环境危险操作绕过确认。 - 禁止展示 Secret 明文。 - 禁止生产数据库直接查询入口。 - 禁止只做成功态,不做失败态和空状态。 - 禁止没有审计记录的发布、重启、回滚。 ## 27. 第一版推荐任务拆分 ### 基础工程 - 初始化 Vite + React + TypeScript。 - 配置 ESLint、Prettier、Vitest。 - 配置路由和 Query Provider。 - 建立 `src` 分层目录。 - 建立全局样式 Token。 ### UI 基础 - Button。 - IconButton。 - StatusBadge。 - GlassSurface。 - Table。 - Select。 - Tabs。 - Drawer。 - Dialog。 - Toast。 - EmptyState。 ### 业务闭环 - Mock 数据。 - 总览页。 - 微服务页。 - 服务详情页。 - 发布抽屉。 - 重启确认。 - 发布记录页。 - 数据资源页。 - 日志与事件页。 - 权限与审计页。 ### 验收 - 单元测试。 - 发布流程集成测试。 - 重启流程集成测试。 - Playwright 核心路径。 - 构建验证。 - 视觉检查。