左帮右臂多租户架构设计

左帮右臂多租户架构设计

一、架构总览

┌─────────────────────────────────────────────────────────────────┐
│                         SCSAI Agent                           │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │  对象类 (ItemTypes) 均带有 enterprise_id 属性              │   │
│  │  Part, Document, Vendor, BOM, ECR, ECO, User...           │   │
│  │  每个对象创建时自动写入 enterprise_id                       │   │
│  │  每个查询自动追加 enterprise_id 过滤条件                    │   │
│  └──────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────┘
                              ▲
                              │ AML (自动注入 enterprise_id)
                              │
┌─────────────────────────────────────────────────────────────────┐
│                       BossAgents 后端                            │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │  ① 认证中间件: JWT → 提取 enterprise_id + user_id        │   │
│  │  ② AML 拦截器: 所有 sendAML() 自动追加 enterprise_id     │   │
│  │  ③ 本地数据库: enterprises, users, audit 表              │   │
│  │  ④ 邮件推送: 携带 enterprise_id 发往 Coze 统一邮箱        │   │
│  └──────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────┘
                              ▲
                              │ API (携带 JWT)
                              │
┌─────────────────────────────────────────────────────────────────┐
│                       前端 / Coze 智能体                          │
│  登录时选择企业,所有请求自动携带 enterprise_id                    │
└─────────────────────────────────────────────────────────────────┘

二、数据模型

2.1 BossAgents 本地数据库 (SQLite)

enterprises                          users
┌──────────────────┐                ┌──────────────────────┐
│ id (TEXT, PK)    │                │ id (TEXT, PK)        │
│ name (TEXT)      │──┐            │ enterprise_id (FK)   │
│ admin_email (TXT)│  └─────────── │ email (TEXT, UNIQUE)  │
│ coze_email (TXT) │               │ password_hash (TEXT)  │
│ SCSAI_db (TEXT)   │               │ role (TEXT)           │
│ created_at (TXT) │               │  'super_admin'        │
│ status (TEXT)    │               │  'enterprise_admin'   │
│ config (JSON)    │               │  'enterprise_user'    │
└──────────────────┘               │ display_name (TEXT)   │
                                   │ created_at (TEXT)     │
                                   │ last_login (TEXT)     │
                                   └──────────────────────┘

2.2 SCSAI 对象类扩展 (所有 ItemType 增加 enterprise_id)

所有业务对象类增加一个属性 enterprise_id (string, 255):

| SCSAI ItemType | 说明 | 是否需注入 enterprise_id |

|--------------|------|------------------------|

| Part | 零件/物料 | ✅ |

| Document | 文档 | ✅ |

| Vendor | 供应商 | ✅ |

| Customer | 客户 | ✅ |

| BOM (BillOfMaterial) | BOM 结构 | ✅ |

| ECR | 工程变更请求 | ✅ |

| ECO | 工程变更指令 | ✅ |

| ECN | 工程变更通知 | ✅ |

| QualityPlan | 质量计划 | ✅ |

| WorkOrder | 工单 | ✅ |

| User (SCSAI Identity) | 用户 | ❌ (SCSAI 内置) |

三、角色与权限

3.1 三种角色

角色级别能做什么由谁管理
super_admin全局创建企业、管理所有企业用户、查看所有企业数据系统部署者
enterprise_admin企业管理本企业用户、查看本企业所有数据、配置 Coze 邮箱super_admin
enterprise_user企业查看/操作本企业数据,受 SCSAI Permission 限制enterprise_admin

3.2 SCSAI 侧权限映射

SCSAI 使用一个统一的 BossAgents 服务账号 进行所有 API 调用。

数据隔离不依赖 SCSAI Identity/Permission 系统(那样配置太复杂),而是通过 BossAgents 中间层强制 enterprise_id 过滤

BossAgents 服务账号 (admin/xxx)
  ├── 用户 A (enterprise_id: "ent_001") 登录
  │   └── 所有 AML 自动注入 <Item enterprise_id="ent_001" ...>
  ├── 用户 B (enterprise_id: "ent_002") 登录
  │   └── 所有 AML 自动注入 <Item enterprise_id="ent_002" ...>
  └── super_admin 登录
      └── 不注入 enterprise_id 过滤 (可查看全部)

四、核心流程

4.1 用户注册登录

注册流程:
  1. super_admin 创建企业 → 生成 enterprise_id
  2. super_admin 创建企业管理员用户 (含 enterprise_id)
  3. 企业管理员登录 → 创建本企业普通用户

登录流程:
  1. POST /api/auth/login { email, password, enterprise_id }
  2. 验证密码,生成 JWT (payload: { user_id, enterprise_id, role })
  3. 前端存储 JWT,后续所有请求带 Authorization header

4.2 API 中间件认证

// 认证中间件逻辑
function authMiddleware(req, res, next) {
  const token = req.headers.authorization?.replace('Bearer ', '');
  const payload = jwt.verify(token, SECRET);
  
  req.userId = payload.user_id;
  req.enterpriseId = payload.enterprise_id;
  req.userRole = payload.role;
  
  // super_admin 可以指定查看任意企业
  if (req.userRole === 'super_admin' && req.headers['x-target-enterprise']) {
    req.enterpriseId = req.headers['x-target-enterprise'];
  }
  
  next();
}

4.3 AML 自动注入

// SCSAI-client.js 增强
class SCSAIClient {
  async sendAML(aml, options = {}) {
    const enterpriseId = options.enterpriseId || this._contextEnterpriseId;
    
    if (enterpriseId) {
      // 自动注入 enterprise_id 到所有 Item 元素
      aml = this._injectEnterpriseId(aml, enterpriseId);
    }
    
    // 发送到 SCSAI...
  }
  
  _injectEnterpriseId(aml, enterpriseId) {
    // 在第一个 <Item 标签后插入 enterprise_id 属性
    return aml.replace(/<Item\s+/g, `<Item enterprise_id="${enterpriseId}" `);
  }
}

4.4 Coze 邮箱推送带企业标识

邮件推送到 Coze 统一邮箱:
  【左帮右壁】库存预警 - 企业: ent_001
  公司ID: ent_001
  物料A库存不足: 当前 5, 安全线 20

Coze 回调 API:
  POST /api/coze/callback
  Headers: x-company-id: ent_001
  Body: { action: "create_purchase_order", ... }

五、实现清单 (按优先级)

P0: 基础架构 (2天)

  • [ ] 本地数据库: enterprises + users 表
  • [ ] 认证中间件: JWT 签发 + 验证
  • [ ] SCSAI 客户端增强: enterprise_id 自动注入
  • [ ] 注册登录 API

P1: 企业管理 (1天)

  • [ ] super_admin CRUD 企业
  • [ ] enterprise_admin 管理本企业用户
  • [ ] SCSAI 对象类扩展脚本 (给 Part/Document 等加 enterprise_id)

P2: 前端适配 (1天)

  • [ ] 登录页加企业选择
  • [ ] 企业管理后台
  • [ ] 用户管理页面

P3: Coze 打通 (0.5天)

  • [ ] 邮件推送携带 enterprise_id
  • [ ] Coze 回调 API 验证 enterprise_id
← 返回案例列表
分享:
🤖 Try Now →
🤖
🎁