# RMDC 项目管理模块详细设计说明书 (DDS) **产品名称**: RMDC 项目管理模块 (rmdc-project-management) **版本**: v5.0 **编制日期**: 2026-01-16 --- ## 1. 概述 ### 1.1 模块定位 `rmdc-project-management` 是 RMDC 系统的核心业务模块,负责维护以 K8s Namespace 为粒度的"项目"全生命周期管理。该模块通过与 `rmdc-work-procedure`(工单模块)深度集成,实现了基于 Git Flow 思想的"草稿-审核-发布"的版本控制流程。 ### 1.2 核心职责 1. **项目全生命周期管理**: 创建、维护(编辑/通过工单)、发布、归档/删除 2. **版本控制**: 记录项目配置的变更历史,支持版本回溯与差异对比(Diff) 3. **细粒度权限控制**: 基于 ACL 的权限控制,精确到用户与项目模块 4. **授权管理**: 管理项目的一级 TOTP 授权信息,与 Watchdog 交互 ### 1.3 版本修订历史 | 版本 | 日期 | 修订内容 | |:---|:---|:---| | v1.0 | 2026-01-06 | 初始版本 | | v2.0 | 2026-01-12 | 增加生命周期状态机设计 | | v3.0 | 2026-01-14 | 完善草稿版本设计、细化权限模型、优化数据库结构 | | v4.0 | 2026-01-15 | 新增项目与工单模块状态同步机制设计(HTTP回调、状态映射表、风险处理) | | v5.0 | 2026-01-16 | 状态同步机制从HTTP回调改为接口注入方式,HTTP回调方案移至备选文档 | --- ## 2. 系统架构 ### 2.1 模块依赖关系 ```mermaid graph TB subgraph 核心层 Core[rmdc-core
API Gateway] end subgraph 业务协作 PM[rmdc-project-management] WP[rmdc-work-procedure
工单流程] UA[rmdc-user-auth
用户认证/权限] Aud[rmdc-audit-log
审计日志] end subgraph 边缘交互 EH[rmdc-exchange-hub
消息网关] WD[rmdc-watchdog] end Core --> PM PM -->|用户鉴权/查询| UA PM -->|项目权限管理| UA PM -->|发起审批/接收回调| WP PM -->|记录操作日志| Aud PM -->|下发授权指令| EH EH <--> WD ``` --- ## 3. 项目生命周期管理 ### 3.1 生命周期状态机 引入明确的生命周期状态机,管理项目从创建到销毁的全过程。 | 状态 | 说明 | 触发动作 | 权限 | |:---|:---|:---|:---| | **INIT** | 项目元数据已创建,等待详细信息录入 | 超级管理员创建项目 | SuperAdmin | | **DRAFTING** | 正在进行初始信息填写(关联填写工单) | 指定填写人保存/编辑 | 填写人/SuperAdmin | | **REVIEWING** | 初始信息或变更信息提交审核 | 提交审核 | SuperAdmin | | **RELEASED** | 审核通过,正常运行中 | 审核通过 | All (View) | | **MODIFYING** | 存在活跃的变更工单(不影响主线运行) | 发起修改工单 | Owner/SuperAdmin | | **ARCHIVED** | 软删除状态,不可见但保留数据 | 删除项目 | SuperAdmin | ### 3.2 状态转换图 ```mermaid stateDiagram-v2 [*] --> INIT: 创建项目 INIT --> DRAFTING: 分配填写人 DRAFTING --> DRAFTING: 保存草稿 DRAFTING --> REVIEWING: 提交审核 REVIEWING --> DRAFTING: 审核打回 REVIEWING --> RELEASED: 审核通过 RELEASED --> MODIFYING: 发起修改工单 RELEASED --> ARCHIVED: 归档删除 MODIFYING --> MODIFYING: 保存草稿 MODIFYING --> REVIEWING: 提交变更审核 MODIFYING --> RELEASED: 撤销变更/审核通过 ARCHIVED --> [*] note right of RELEASED: 项目认证状态=official note right of DRAFTING: 支持多次保存草稿 note right of MODIFYING: 可同时存在多个变更工单 ``` ### 3.3 生命周期与工单状态映射 | 工单事件 | 工单目标状态 | 项目生命周期状态 | 说明 | |:---|:---|:---|:---| | create | created | INIT→DRAFTING | 创建填写工单 | | draft_save | in_progress | DRAFTING/MODIFYING(保持) | 保存草稿 | | complete | pending_review | REVIEWING | 提交审核 | | resubmit | pending_review | REVIEWING | 被打回后重新提交 | | return | returned | DRAFTING | 审核人打回 | | approve | approved→closed | RELEASED | 审核人通过 | ### 3.4 状态同步机制设计 #### 3.4.1 设计原则 项目模块(`rmdc-project-management`)与工单模块(`rmdc-work-procedure`)之间需要双向协作: 1. **项目 → 工单**:项目模块调用工单模块创建/转换工单 2. **工单 → 项目**:工单状态变更后同步更新项目生命周期状态 当前系统采用 **"模块化单体"架构**,所有模块运行在 `rmdc-core` 同一进程中,因此采用 **接口注入(依赖注入)** 方式实现模块间回调,而非 HTTP 回调。 > **备选方案**:如未来需要微服务化部署,可参考 [HTTP回调设计方案](5-rmdc-project-http-callback-design.md) #### 3.4.2 架构设计(接口注入方式) ```mermaid sequenceDiagram participant Frontend as 前端 participant PM as rmdc-project-management participant Core as rmdc-core participant WP as rmdc-work-procedure Note over Core: 启动时注入回调接口 Core->>PM: 注入 WorkflowTransitioner Core->>WP: 注入 ProjectLifecycleUpdater Note over PM,WP: 提交审核流程 Frontend->>PM: POST /api/project/draft/submit PM->>WP: workflowTransitioner.TransitionWorkflow(complete) WP->>WP: 状态机转换 (in_progress → pending_review) WP->>PM: projectLifecycleUpdater.SetLifecycleToReviewing() PM->>PM: 更新 lifecycle_status = REVIEWING WP-->>PM: 返回新状态 PM-->>Frontend: 返回成功响应 ``` #### 3.4.3 接口定义 **项目模块调用工单模块的接口**: ```go // WorkflowTransitioner 工单状态转换接口 // 由 rmdc-core 在初始化时注入,项目模块通过此接口调用工单模块 type WorkflowTransitioner interface { // TransitionWorkflow 触发工单状态转换 // @param workflowID string - 工单ID // @param event string - 事件类型 (complete/submit/resubmit等) // @param operatorID uint64 - 操作人ID // @param operatorName string - 操作人姓名 // @param remark string - 操作备注 // @return newStatus string - 工单新状态 // @return error - 错误 TransitionWorkflow(workflowID, event string, operatorID uint64, operatorName string, remark string) (newStatus string, err error) } ``` **工单模块回调项目模块的接口**: ```go // ProjectLifecycleUpdater 项目生命周期状态更新接口 // 由 rmdc-core 在初始化时注入,工单模块状态变更时调用 type ProjectLifecycleUpdater interface { // UpdateLifecycleStatus 更新项目生命周期状态 UpdateLifecycleStatus(projectID, lifecycleStatus string) error // SetLifecycleToDrafting 设置为填写中状态(工单被打回后) SetLifecycleToDrafting(projectID string) error // SetLifecycleToReviewing 设置为审核中状态(提交审核时) SetLifecycleToReviewing(projectID string) error // SetLifecycleToReleased 设置为已发布状态(审批通过时) SetLifecycleToReleased(projectID string) error // SetLifecycleToModifying 设置为变更中状态(发起修改工单时) SetLifecycleToModifying(projectID string) error } ``` #### 3.4.4 依赖注入流程 在 `rmdc-core/cmd/main.go` 中完成模块间的依赖注入: ```go // 1. 初始化项目和工单服务 projectSvc := projectHandler.RegisterRoutes(r, dbs.Project, authMiddleware) workflowSvc := workflowHandler.RegisterRoutes(r, dbs.Workflow, authMiddleware) // 2. 注入工单→项目的回调(状态同步) projectCallbackSvc := initProjectWorkflowCallbacks(dbs.Project) workflowSvc.SetProjectLifecycleUpdater(projectCallbackSvc) // 3. 注入项目→工单的调用(创建/转换工单) workflowCreator := initProjectWorkflowCreator(workflowSvc) projectSvc.SetWorkflowCreator(workflowCreator) workflowTransitioner := initProjectWorkflowTransitioner(workflowSvc) projectSvc.SetWorkflowTransitioner(workflowTransitioner) ``` #### 3.4.5 接口注入方式的优势 | 特性 | 说明 | |:---|:---| | **简单高效** | 进程内调用,无网络开销 | | **类型安全** | 编译期检查接口实现 | | **事务一致性** | 可在同一数据库事务中执行 | | **无需重试** | 不涉及网络失败,无需复杂的重试机制 | | **开发调试** | 调试更简单,堆栈清晰 | #### 3.4.6 与 HTTP 回调的对比 | 特性 | 接口注入(当前实现) | HTTP 回调 | |:---|:---|:---| | **模块解耦** | ⚠️ 接口级解耦 | ✅ 完全解耦 | | **分布式支持** | ❌ 不支持 | ✅ 支持 | | **性能** | ✅ 进程内调用 | ⚠️ 网络开销 | | **复杂度** | ✅ 简单直接 | ⚠️ 需要重试/幂等处理 | | **适用场景** | 模块化单体架构 | 微服务架构 | > 如果未来系统需要微服务化,可参考 [HTTP回调设计方案](5-rmdc-project-http-callback-design.md) 进行迁移。 ### 3.5 详细状态映射表 根据工单类型和事件,映射到项目生命周期状态: #### 3.5.1 填写工单 (project_detail) | 工单事件 | 工单From状态 | 工单To状态 | 项目生命周期状态 | 说明 | |:---|:---|:---|:---|:---| | `create` | - | `created` | `INIT→DRAFTING` | 创建填写工单,分配填写人 | | `accept` | `assigned` | `in_progress` | `DRAFTING` (保持) | 填写人开始填写 | | `draft_save` | `in_progress` | `in_progress` | `DRAFTING` (保持) | 保存草稿 | | `submit/complete` | `in_progress` | `pending_review` | `REVIEWING` | 提交审核 | | `return` | `pending_review` | `returned` | `DRAFTING` | 审核人打回 | | `resubmit` | `returned` | `pending_review` | `REVIEWING` | 重新提交 | | `approve` | `pending_review` | `approved` | `RELEASED` | 审核通过,项目发布 | | `revoke` | any | `revoked` | `INIT` | 撤销工单,恢复初始状态 | #### 3.5.2 修改工单 (project_modify) | 工单事件 | 工单From状态 | 工单To状态 | 项目生命周期状态 | 说明 | |:---|:---|:---|:---|:---| | `create` | - | `created` | `RELEASED→MODIFYING` | 发起修改工单 | | `accept` | `assigned` | `in_progress` | `MODIFYING` (保持) | 开始修改 | | `draft_save` | `in_progress` | `in_progress` | `MODIFYING` (保持) | 保存草稿 | | `submit/complete` | `in_progress` | `pending_review` | `REVIEWING` | 提交审核 | | `return` | `pending_review` | `returned` | `MODIFYING` | 审核人打回 | | `resubmit` | `returned` | `pending_review` | `REVIEWING` | 重新提交 | | `approve` | `pending_review` | `approved` | `RELEASED` | 审核通过,合并修改 | | `revoke` | any | `revoked` | `RELEASED` | 撤销工单,恢复发布状态 | ### 3.6 回调处理实现 工单模块状态转换后,自动调用已注入的 `ProjectLifecycleUpdater` 接口更新项目状态: ```go // 工单模块 - 状态转换后触发项目状态更新 func (s *WorkflowService) handleProjectLifecycleCallback(workflow *entity.Workflow, event string) { // 从业务载荷中获取项目ID projectID, ok := workflow.BusinessPayload["project_id"].(string) if !ok || projectID == "" { return } // 根据事件类型更新项目生命周期状态 if s.projectLifecycleUpdater != nil { switch event { case entity.EventApprove: s.projectLifecycleUpdater.SetLifecycleToReleased(projectID) case entity.EventReturn: s.projectLifecycleUpdater.SetLifecycleToDrafting(projectID) case entity.EventComplete, entity.EventResubmit: s.projectLifecycleUpdater.SetLifecycleToReviewing(projectID) } } } ``` --- ## 4. 权限控制模型 ### 4.1 设计原则 权限控制分为 **功能权限** (RBAC) 和 **数据权限** (ACL),**数据权限需精确到项目模块级别**。 > **重要决策**:项目权限相关表设计在 `rmdc-user-auth` 模块中,由该模块统一管理所有权限数据。 ### 4.2 功能权限 (RBAC) | 权限代码 | 说明 | 角色 | |:---|:---|:---| | `project:create` | 创建项目 | SuperAdmin | | `project:delete` | 删除/归档项目 | SuperAdmin | | `project:edit` | 直接编辑项目 | SuperAdmin | | `project:edit_workflow` | 通过工单编辑项目 | User (有ACL权限) | | `project:auth_manage` | 一级/二级授权管理 | SuperAdmin | | `project:permission_manage` | 项目权限分配 | SuperAdmin | ### 4.3 数据权限 (ACL) - 模块级别 #### 4.3.1 权限模块定义 | 模块代码 | 模块名称 | 说明 | |:---|:---|:---| | `basic_info` | 基本信息模块 | 项目名称、命名空间、省份城市等 | | `business_info` | 部署业务模块 | 部署人、部署时间、系统版本等 | | `environment_info` | 部署环境模块 | 主机信息、网络环境、域名等 | | `middleware_info` | 部署中间件模块 | MySQL、Redis、EMQX等中间件配置 | | `authorization_info` | 项目授权模块 | TOTP授权信息(仅SuperAdmin) | #### 4.3.2 权限类型 | 权限类型 | 说明 | |:---|:---| | `view` | 查看权限(可查看项目信息,可发起修改工单) | | `export` | 导出权限(可导出项目信息) | > **说明**:编辑权限通过工单系统实现,拥有 `view` 权限的用户可以发起修改工单,由 SuperAdmin 审批后生效。 ### 4.4 权限规则 1. **SuperAdmin**: 拥有所有项目的所有模块的全部权限,可直接修改 2. **Admin**: 可以访问自己被授权的项目模块,可以向普通用户转授权限 3. **Normal User**: 只能访问被授权的项目模块,修改需通过工单 4. **项目填写人**: 自动获得该项目的查看权限 5. **授权模块**: 仅 SuperAdmin 可见 --- ## 5. 版本控制设计 (GIT-like) ### 5.1 设计原则 采用**统一版本表**设计,将正式版本和草稿版本存储在同一张表中,通过 `version_type` 字段区分。 ### 5.2 版本类型 | 版本类型 | 代码 | 说明 | |:---|:---|:---| | 正式版本 | `official` | 审核通过后的正式版本,构成版本历史 | | 填写草稿 | `fill_draft` | 项目创建时填写人的草稿 | | 修改草稿 | `modify_draft` | 发起变更工单时的草稿 | ### 5.3 版本与工单关系 1. **填写草稿**: 与填写工单 1:1 关联 2. **修改草稿**: 与修改工单 1:1 关联 3. **正式版本**: 审核通过后由草稿转化而来 4. **一个项目可以有多个修改草稿**(对应多个修改工单) ### 5.4. 版本快照机制 每次审核通过后,系统自动生成一个**完整快照**存储到 `project_versions` 表中。 #### 5.4.1 快照结构 ```go // VersionSnapshot 版本快照结构 type VersionSnapshot struct { BasicInfo *BasicInfo `json:"basic_info"` DeployBusiness *DeployBusiness `json:"deploy_business"` DeployEnv *DeployEnv `json:"deploy_env"` DeployMiddleware *DeployMiddleware `json:"deploy_middleware"` } ``` #### 5.4.2 快照生成时机 | 场景 | 版本号 | 版本类型 | 说明 | |:---|:---|:---|:---| | 项目首次审批通过 | v1 | official | 项目初始版本 | | 修改工单审批通过 | v(N+1) | official | 增量版本 | | **超管直接修改** | v(N+1) | official | **重要:超管直改也必须生成新版本** | | 用户保存草稿 | 0 | fill_draft/modify_draft | 临时版本,不计入历史 | #### 5.4.3 超级管理员直改与版本一致性 **问题风险**: 如果超级管理员直接修改 `projects` 表数据而不生成版本历史,会导致版本链断裂,后续基于旧版本的工单 Diff 结果将失效或产生误导。 **解决方案**: 超级管理员的 "Direct Edit" 操作必须被视为一次**自动审批通过的事务**: 1. **原子操作**:更新 `projects` 表 + 插入 `project_versions` 表必须在同一数据库事务中完成。 2. **版本归属**:生成的 Version 记录中,`workflow_id` 为空(或特定系统标识),`committer_id` 记录为 SuperAdmin ID,`commit_message` 强制填写或自动生成(如 "SuperAdmin Direct Update")。 3. **结果**:确保 `projects.current_version` 永远指向最新的 `project_versions.version`。 #### 5.4.4 并发修改与冲突检测 (Optimistic Locking) 由于超级管理员可能在其他用户编辑草稿期间直接修改项目,需要引入乐观锁机制处理冲突。 **冲突场景**: 1. 用户 A 基于 v3 版本创建草稿(Draft based on v3)。 2. 超级管理员直接修改项目,版本升级为 v4(Current = v4)。 3. 用户 A 提交草稿审核。 **处理策略**: 1. **提交时校验**:工单提交/审核接口需校验 `draft.base_version == project.current_version`。 2. **冲突提示**:如果版本不一致,后端返回 `409 Conflict` 错误。 3. **前端交互**: * 提示用户:"项目已被修改,当前草稿已过期"。 * 提供 **"Rebase" (变基)** 选项:将当前草稿的修改重新应用到最新的 v4 版本上(即自动合并,若有字段冲突则让用户手动解决)。 * 或者提供 **"Diff Check"**:让用户查看当前草稿与最新 v4 的差异,决定是否覆盖或调整。 --- ### 5.5 版本 Diff 算法 采用 **JSON Diff** 算法,对比两个版本快照的差异。 #### 5.5.1 差异结构 ```go // DiffResult 差异结果 type DiffResult struct { Module string `json:"module"` // 模块名称 FieldDiffs []FieldDiff `json:"field_diffs"` // 字段差异列表 } // FieldDiff 字段差异 type FieldDiff struct { FieldPath string `json:"field_path"` // 字段路径 如 "deploy_business.deployer_name" FieldName string `json:"field_name"` // 字段中文名 OldValue interface{} `json:"old_value"` // 旧值 NewValue interface{} `json:"new_value"` // 新值 ChangeType string `json:"change_type"` // add/modify/delete } ``` #### 5.5.2 Diff 实现 ```go // CompareVersions 比较两个版本的差异 // @param baseVersion 基准版本(通常是较早的版本或 master) // @param targetVersion 目标版本(通常是较新的版本或草稿) // @return []DiffResult 差异结果列表,按模块分组 func (s *VersionService) CompareVersions( ctx context.Context, baseVersion, targetVersion *VersionSnapshot, ) ([]DiffResult, error) { var results []DiffResult // 分模块对比 modules := []struct { Name string Base interface{} Target interface{} }{ {"基本信息", baseVersion.BasicInfo, targetVersion.BasicInfo}, {"部署业务", baseVersion.DeployBusiness, targetVersion.DeployBusiness}, {"部署环境", baseVersion.DeployEnv, targetVersion.DeployEnv}, {"部署中间件", baseVersion.DeployMiddleware, targetVersion.DeployMiddleware}, } for _, m := range modules { diffs := s.diffJSON(m.Base, m.Target) if len(diffs) > 0 { results = append(results, DiffResult{ Module: m.Name, FieldDiffs: diffs, }) } } return results, nil } ``` --- ### 5.6 版本历史查询 #### 5.6.1 版本列表结构 ```go // VersionHistory 版本历史记录 type VersionHistory struct { Version int `json:"version"` // 版本号 VersionType string `json:"version_type"` // 版本类型 CommitMessage string `json:"commit_message"` // 变更说明 CommitterID int64 `json:"committer_id"` // 提交人 ID CommitterName string `json:"committer_name"` // 提交人姓名 WorkflowID string `json:"workflow_id"` // 关联工单 ID CreatedAt time.Time `json:"created_at"` // 创建时间 ChangeSummary string `json:"change_summary"` // 变更摘要(如:修改了 3 个字段) } ``` #### 5.6.2 版本历史 API | 方法 | 路径 | 描述 | |:---|:---|:---| | POST | `/api/project/version/list` | 获取版本历史列表 | | POST | `/api/project/version/detail` | 获取指定版本详情 | | POST | `/api/project/version/diff` | 对比两个版本差异 | | POST | `/api/project/version/diff-with-current` | 对比指定版本与当前版本差异 | --- ### 5.7 前端展示设计 #### 5.7.1 版本历史页面 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 项目版本历史 - [项目名称] │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ●──v3 (当前版本) 2026-01-14 15:30 张三 │ │ │ └─ 变更说明: 更新部署环境信息 │ │ │ └─ 关联工单: #WF-20260114-001 │ │ │ │ │ ●──v2 2026-01-10 10:00 李四 │ │ │ └─ 变更说明: 修改中间件配置 │ │ │ └─ 关联工单: #WF-20260110-002 │ │ │ │ │ ●──v1 (初始版本) 2026-01-05 09:00 王五 │ │ └─ 变更说明: 项目初始填写 │ │ └─ 关联工单: #WF-20260105-001 │ │ │ │ [查看详情] [对比版本] │ └─────────────────────────────────────────────────────────────────┘ ``` #### 5.7.2 Diff 对比页面 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 版本对比: v2 → v3 │ ├─────────────────────────────────────────────────────────────────┤ │ 模块: 部署环境 │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ 字段 │ v2 (旧值) │ v3 (新值) │ │ │ ├───────────────────────────────────────────────────────────┤ │ │ │ 主机台数 │ 3 │ 5 │ │ │ │ 主要公网 IP │ 10.0.0.1 │ 192.168.1.100 │ │ │ │ 域名 URL │ - │ www.example.com [新增] │ │ │ └───────────────────────────────────────────────────────────┘ │ │ │ │ 模块: 部署中间件 │ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ 字段 │ v2 (旧值) │ v3 (新值) │ │ │ ├───────────────────────────────────────────────────────────┤ │ │ │ MySQL.内网端口 │ 3306 │ 3307 │ │ │ └───────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ``` --- ## 6. 数据模型设计 ### 6.1 设计决策 | 决策点 | 决策 | 理由 | |:---|:---|:---| | JSONB vs 分表 | 使用JSONB存储 | 1. 项目信息结构复杂但查询简单 2. 版本快照需完整存储 3. 减少JOIN提升性能 | | 草稿存储位置 | project_versions表 | 统一版本管理,方便Diff比较 | | 权限表位置 | rmdc-user-auth模块 | 统一权限管理,便于跨模块授权 | ### 6.2 ER 图 ```mermaid erDiagram projects ||--o{ project_versions : has projects ||--o{ project_workflows : has projects ||--|| project_auth_configs : has projects { bigint id PK string project_id UK string name string namespace UK string lifecycle_status string certification_status bigint detail_filler_id string detail_filler_name int current_version jsonb basic_info jsonb deploy_business jsonb deploy_env jsonb deploy_middleware datetime created_at datetime updated_at datetime deleted_at } project_versions { bigint id PK string project_id FK int version string version_type bigint user_id string workflow_id jsonb snapshot_data string commit_message bigint committer_id string committer_name datetime created_at datetime updated_at } project_workflows { bigint id PK string project_id FK string workflow_id UK string workflow_type string status datetime created_at } project_auth_configs { bigint id PK string project_id FK string tier_one_secret int time_offset bool totp_enabled string auth_type int auth_days datetime created_at datetime updated_at } ``` **表关系说明**: | 关系 | 说明 | |:---|:---| | `projects` → `project_versions` | 一对多,一个项目有多个版本记录(含草稿) | | `projects` → `project_workflows` | 一对多,一个项目可关联多个工单 | | `projects` → `project_auth_configs` | 一对一,一个项目对应一个授权配置 | **字段说明**: | 表 | 字段 | 说明 | |:---|:---|:---| | projects | lifecycle_status | INIT/DRAFTING/REVIEWING/RELEASED/MODIFYING/ARCHIVED | | projects | certification_status | draft/pending/official | | project_versions | version_type | official/fill_draft/modify_draft | | project_versions | workflow_id | 关联 rmdc-work-procedure 模块的工单 ID | | project_workflows | workflow_type | fill(填写)/modify(修改) | > **注意**:`workflow_id` 字段引用 `rmdc-work-procedure` 模块的 `workflows` 表,属于跨模块关联,不在本模块ER图中展示外部表结构。 ### 6.3 主表 DDL - projects ```go // Project 项目主表 type Project struct { ID int64 `gorm:"primaryKey;autoIncrement" json:"id"` ProjectID string `gorm:"type:varchar(64);uniqueIndex;not null" json:"project_id"` Name string `gorm:"type:varchar(128);not null" json:"name"` Namespace string `gorm:"type:varchar(64);uniqueIndex;not null" json:"namespace"` // 生命周期状态 LifecycleStatus string `gorm:"type:varchar(32);default:'INIT'" json:"lifecycle_status"` // 认证状态 (draft/pending/official) CertificationStatus string `gorm:"type:varchar(32);default:'draft'" json:"certification_status"` // 当前正式版本号 CurrentVersion int `gorm:"default:0" json:"current_version"` // 主版本数据 (使用JSONB存储,便于版本快照) BasicInfo json.RawMessage `gorm:"type:jsonb" json:"basic_info"` DeployBusiness json.RawMessage `gorm:"type:jsonb" json:"deploy_business"` DeployEnv json.RawMessage `gorm:"type:jsonb" json:"deploy_env"` DeployMiddleware json.RawMessage `gorm:"type:jsonb" json:"deploy_middleware"` // 项目填写人 DetailFillerID int64 `json:"detail_filler_id"` DetailFillerName string `gorm:"type:varchar(64)" json:"detail_filler_name"` // 审计字段 CreatedBy int64 `json:"created_by"` CreatedByName string `gorm:"type:varchar(64)" json:"created_by_name"` common.BaseModel } ``` ### 6.4 版本表 DDL - project_versions ```go // ProjectVersion 项目版本表 (含草稿) type ProjectVersion struct { ID int64 `gorm:"primaryKey;autoIncrement" json:"id"` ProjectID string `gorm:"type:varchar(64);index;not null" json:"project_id"` // 版本号 (正式版本递增, 草稿为0) Version int `gorm:"not null;default:0" json:"version"` // 版本类型: official/fill_draft/modify_draft VersionType string `gorm:"type:varchar(32);not null" json:"version_type"` // 草稿所属用户ID (仅草稿类型有值) UserID int64 `gorm:"index" json:"user_id"` UserName string `gorm:"type:varchar(64)" json:"user_name"` // 关联工单ID (1:1关系, 仅草稿类型有值) WorkflowID string `gorm:"type:varchar(64);index" json:"workflow_id"` // 完整快照数据 SnapshotData json.RawMessage `gorm:"type:jsonb" json:"snapshot_data"` // 变更信息 CommitMessage string `gorm:"type:varchar(255)" json:"commit_message"` CommitterID int64 `json:"committer_id"` CommitterName string `gorm:"type:varchar(64)" json:"committer_name"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } ``` ### 6.5 项目工单关联表 DDL - project_workflows ```go // ProjectWorkflow 项目与工单关联表 type ProjectWorkflow struct { ID int64 `gorm:"primaryKey;autoIncrement" json:"id"` ProjectID string `gorm:"type:varchar(64);index;not null" json:"project_id"` WorkflowID string `gorm:"type:varchar(64);uniqueIndex;not null" json:"workflow_id"` // 工单类型: fill(填写)/modify(修改) WorkflowType string `gorm:"type:varchar(32);not null" json:"workflow_type"` // 工单状态 (冗余存储,便于查询) Status string `gorm:"type:varchar(32)" json:"status"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } ``` ### 6.6 权限表 DDL (位于 rmdc-user-auth 模块) ```go // ProjectACL 项目权限表 (模块级别) type ProjectACL struct { ID int64 `gorm:"primaryKey;autoIncrement" json:"id"` ProjectID string `gorm:"type:varchar(64);index;not null" json:"project_id"` UserID int64 `gorm:"index;not null" json:"user_id"` // 模块代码: basic_info/business_info/environment_info/middleware_info/authorization_info ModuleCode string `gorm:"type:varchar(32);not null" json:"module_code"` // 权限类型 CanView bool `gorm:"default:false" json:"can_view"` // 授权信息 GrantedBy int64 `json:"granted_by"` GrantedAt time.Time `json:"granted_at"` UpdatedAt time.Time `json:"updated_at"` } ``` --- ## 7. 接口设计 (API) ### 7.1 项目管理接口 | 方法 | 路径 | 描述 | 权限 | |:---|:---|:---|:---| | POST | `/api/project/list` | 获取项目列表 (自动过滤ACL) | Login | | POST | `/api/project/detail` | 获取项目详情 (Master版本) | View ACL | | POST | `/api/project/create` | 创建项目 | SuperAdmin | | POST | `/api/project/update` | 直接更新项目 | SuperAdmin | | POST | `/api/project/delete` | 删除项目 (软删除) | SuperAdmin | | POST | `/api/project/export` | 导出项目信息 | Export ACL | ### 7.2 版本管理接口 | 方法 | 路径 | 描述 | 权限 | |:---|:---|:---|:---| | POST | `/api/project/version/list` | 获取版本历史列表 | View ACL | | POST | `/api/project/version/detail` | 获取指定版本详情 | View ACL | | POST | `/api/project/version/diff` | 获取版本差异 | View ACL | ### 7.3 草稿管理接口 | 方法 | 路径 | 描述 | 权限 | |:---|:---|:---|:---| | POST | `/api/project/draft/get` | 获取当前用户的草稿 | View ACL | | POST | `/api/project/draft/save` | 保存草稿 | View ACL | | POST | `/api/project/draft/submit` | 提交审核 | View ACL | | POST | `/api/project/draft/discard` | 放弃草稿 | View ACL | ### 7.4 权限管理接口 (SuperAdmin) | 方法 | 路径 | 描述 | 权限 | |:---|:---|:---|:---| | POST | `/api/project/permission/list` | 获取项目权限列表 | SuperAdmin | | POST | `/api/project/permission/grant` | 授予权限 | SuperAdmin | | POST | `/api/project/permission/revoke` | 撤销权限 | SuperAdmin | | POST | `/api/project/permission/batch` | 批量设置权限 | SuperAdmin | --- ## 8. 业务流程 ### 8.1 项目创建流程 ```mermaid sequenceDiagram participant Admin as 超级管理员 participant PM as rmdc-project-management participant WP as rmdc-work-procedure participant User as 填写人 Admin->>PM: POST /api/project/create PM->>PM: 创建Project记录 (status=INIT) PM->>WP: 创建project_detail工单 WP-->>PM: 返回workflow_id PM->>PM: 创建ProjectVersion草稿记录 PM->>PM: 创建ProjectWorkflow关联记录 PM-->>Admin: 返回项目创建成功 PM->>User: 通知填写人 User->>PM: POST /api/project/draft/save PM->>PM: 更新ProjectVersion草稿 User->>PM: POST /api/project/draft/submit PM->>WP: 状态转换为pending_review PM->>PM: 更新lifecycle_status=REVIEWING ``` ### 8.2 项目与工单关系 | 关系类型 | 项目状态 | 说明 | |:---|:---|:---| | 项目:填写工单 = 1:1 | INIT/DRAFTING | 项目创建时只能有一个填写工单 | | 项目:修改工单 = 1:N | RELEASED/MODIFYING | 已发布项目可以有多个修改工单 | | 用户:修改工单 = 1:1 (per project) | - | 非SuperAdmin用户同一项目只能有一个活跃修改工单 | --- ## 9. 安全与规范 ### 9.1 敏感字段加密 遵循系统规范,以下字段必须加密存储 (AES-256): - `DeployBusiness.AdminPassword` - `DeployEnv.SSHPassword` - `DeployEnv.ManagementPassword` - `DeployMiddleware.*.AdminPassword` ### 9.2 审计日志 所有对 `projects` 表的写操作均需通过 `rmdc-audit-log` 记录: - **Resource**: `project` - **Action**: `create`, `update`, `publish_version`, `delete`, `permission_grant` - **Payload**: 记录关键变更字段 --- ## 10. 附录 ### 10.1 基本信息结构体 ### 10.1 基本信息结构体 (BasicInfo) ```go type BasicInfo struct { Province string `json:"province"` // 省份 City string `json:"city"` // 城市 (级联) IndustryContact string `json:"industry_contact"` // 行业组人员姓名 IndustryPhone string `json:"industry_phone"` // 行业组人员电话 ProjectNature string `json:"project_nature"` // 项目性质: research(科研)/test(测试)/trial(试用)/market(市场化)/sub_platform(二级平台) } ``` ### 10.2 业务部署结构体 (DeployBusiness) ```go type DeployBusiness struct { DeployerName string `json:"deployer_name"` // 部署人姓名 DeployerPhone string `json:"deployer_phone"` // 部署人电话 DeployStartTime string `json:"deploy_start_time"` // 部署开始时间 DeployEndTime string `json:"deploy_end_time"` // 部署结束时间 SystemVersion string `json:"system_version"` // 部署系统版本 SystemType string `json:"system_type"` // 系统类型: business/fly-control/supervisor MainEntrance string `json:"main_entrance"` // 业务主要入口URL AdminUsername string `json:"admin_username"` // 系统超管用户名 AdminPassword string `json:"admin_password"` // 系统超管密码 (加密存储) } ``` ### 10.3 部署环境结构体 (DeployEnv) ```go type DeployEnv struct { // 主机信息 Hosts []HostInfo `json:"hosts"` // 网络环境 NetworkType string `json:"network_type"` // internal(完全内网)/single_public(单主机公网)/full_public(全访问公网) MainPublicIP string `json:"main_public_ip"` // 主要公网IP DomainURL string `json:"domain_url"` // 域名URL SSLEnabled bool `json:"ssl_enabled"` // 是否开启SSL // 管理方式 ManagementType string `json:"management_type"` // bastion(堡垒机)/whitelist(白名单)/vpn ManagementURL string `json:"management_url"` // 管理后台URL ManagementUser string `json:"management_user"` // 管理后台用户名 ManagementPwd string `json:"management_pwd"` // 管理后台密码 (加密存储) // 统计信息 HostCount int `json:"host_count"` // 主机台数 TotalCPU int `json:"total_cpu"` // CPU总核数 CPUModel string `json:"cpu_model"` // CPU型号 TotalMemory int `json:"total_memory"` // 内存总大小(GB) TotalStorage int `json:"total_storage"` // 存储总大小(GB) } type HostInfo struct { Hostname string `json:"hostname"` InternalIP string `json:"internal_ip"` PublicIP string `json:"public_ip"` CanAccessPublic bool `json:"can_access_public"` // 能否访问公网 SSHPort int `json:"ssh_port"` SSHUser string `json:"ssh_user"` SSHPwd string `json:"ssh_pwd"` // SSH密码 (加密存储) Role string `json:"role"` // master/worker/storage } ``` ### 10.4 部署中间件结构体 (DeployMiddleware) ```go type DeployMiddleware struct { MySQL MiddlewareInfo `json:"mysql"` Redis MiddlewareInfo `json:"redis"` EMQX MiddlewareInfo `json:"emqx"` MinIO MiddlewareInfo `json:"minio"` InfluxDB MiddlewareInfo `json:"influxdb"` Nacos MiddlewareInfo `json:"nacos"` K8SDashboard MiddlewareInfo `json:"k8s_dashboard"` } // MiddlewareInfo 通用中间件信息 type MiddlewareInfo struct { PublicIP string `json:"public_ip"` PublicPort int `json:"public_port"` InternalIP string `json:"internal_ip"` InternalPort int `json:"internal_port"` K8SAddress string `json:"k8s_address"` // K8S集群内访问地址 (Service Name) K8SPort int `json:"k8s_port"` AdminUser string `json:"admin_user"` AdminPwd string `json:"admin_pwd"` // 超管密码 (加密存储) Version string `json:"version"` // 中间件版本 } ``` ### 10.5 项目授权信息结构体 (AuthorizationInfo) > **注意**:此结构对应 `project_auth_configs` 表,通常不作为 JSONB 存储在 `projects` 表中,而是通过关联表存储。此处列出仅供各种 DTO 参考。 ```go type AuthorizationInfo struct { TierOneSecret string `json:"tier_one_secret"` // 一级TOTP密钥 TimeOffset int `json:"time_offset"` // 允许时间偏移(秒) TOTPEnabled bool `json:"totp_enabled"` // 是否开启TOTP TierTwoSecret string `json:"tier_two_secret"` // 二级TOTP密钥 (来自Watchdog) AuthType string `json:"auth_type"` // permanent(永久)/time_limited(限时) AuthDays int `json:"auth_days"` // 授权有效期(天) AuthorizedAt time.Time `json:"authorized_at"` // 授权时间 RevokedAt time.Time `json:"revoked_at"` // 撤销授权时间 IsOffline bool `json:"is_offline"` // 是否离线授权 } ``` ### 10.6 相关文档 | 文档 | 说明 | |:---|:---| | [项目管理PRD](1-rmdc-project-management-PRD.md) | 产品需求文档 | | [项目状态说明](4-project-状态说明.md) | 状态转换说明 | | [工单模块DDS](../7-rmdc-work-procedure/1-rmdc-work-procedure-DDS.md) | 工单流程设计 | | [用户权限DDS](../9-rmdc-user-auth/1-user-auth-PRD.md) | 用户权限设计 |