Files
SBrainCO/run.md
T
freedakgmail cfa12c9b7f feat: 多租户数据权限 + 数据库连接修正
- adminPool 连服务器本地 5432 sbrain_admin (SCRAM 认证)
- tenantPool/pool 连 FRP 隧道 15432 bill_query (trust 认证)
- query() 自动注入 store_code 数据权限 (store/regional 角色)
- 区域经理 region 字段存储逗号分隔的 store_code 列表
- /overview 和 /overview/daily 对 scoped 用户从 bill_fact 聚合
- tenant_users.region 扩展为 VARCHAR(500)
- deploy.sh .env 增加 ADMIN_DB_* 配置
- run.md 更新数据库连接架构说明
- 新增海淀区区域经理用户 (21 家海淀区门店)
2026-08-02 20:10:42 +08:00

7.7 KiB
Raw Blame History

当前数据库是本机Homebrew PostgreSQL 15,数据库名为 bill_query,端口5432,仅监听 localhost;当前用户 freedak 是超级用户,本机认证方式为 trust。这适合本机开发,但不适合直接照搬到服务器生产环境。前端浏览器也不应直接连接PostgreSQL,必须通过后端API访问。

登录账号

平台管理员

用户名 密码 角色 说明
平台管理员 123 platform_admin 管理所有租户,登录后进入平台管理后台

租户用户(存储在服务器 sbrain_admin 数据库)

用户名 密码 角色 租户
总部管理员 123 hq tenant_a(西部马华)

租户管理员(hq)登录后可在系统内创建区域经理、店长、商品部等角色用户。 密码使用 bcrypt 加密存储。

架构(2026-08-02 更新:SaaS 多租户)

浏览器 → https://dm.all8ai.top
       → Nginx(服务器) → /api/ → 127.0.0.1:9333 (服务器后端, pm2管理)
       → 服务器本地 PostgreSQL:5432 → sbrain_admin(平台库:租户配置、用户认证)
       → frp隧道 127.0.0.1:15432 → 本机PostgreSQL:5432 → bill_query(租户业务库)

数据库连接(重要)

后端连接两个不同的数据库,走不同端口:

连接池 目标数据库 连接地址 认证方式 配置来源
adminPool sbrain_admin(平台库) 127.0.0.1:5432(服务器本地 PG scram-sha-256(用户 sbrain_admin,密码 sbrain2026 .envADMIN_DB_*
tenantPool bill_query(业务库) 127.0.0.1:15432FRP 隧道 → 本机 PG trust(用户 freedak,无需密码) tenant_configs.db_port=15432
pool bill_query(业务库) 127.0.0.1:15432FRP 隧道 → 本机 PG trust(用户 freedak,无需密码) .envDB_*

⚠️ tenant_configs 表中 db_port 必须为 15432FRP 隧道),db_password 为 NULLtrust 认证)。 ⚠️ adminPool 连接服务器本地 5432,需要 ADMIN_DB_PASSWORD=sbrain2026

数据库分布

数据库 位置 存储内容
sbrain_admin 服务器本地 PostgreSQL5432 平台管理员、租户配置(tenant_configs)、所有租户用户(tenant_users
bill_query 本机 PostgreSQL(通过 frp 暴露为 15432 租户业务数据(销售、任务、成本分析等)

多租户数据隔离

  • 认证流程:用户登录 → 查 sbrain_admin.tenant_users → bcrypt 验证 → JWT 含 tenantId
  • 数据隔离:业务请求 → tenantDbMiddleware 根据 JWT 中的 tenantIdtenant_configs 获取该租户数据库连接信息 → AsyncLocalStorage 设置租户连接池 → 所有 query() 自动走对应租户数据库
  • 租户用户管理:平台管理员为租户创建管理员(hq),租户管理员在系统内创建区域经理/店长/商品部等用户,均存储在 sbrain_admin.tenant_users 表中,通过 tenant_id 字段区分

关键文件

文件 职责
server/src/config/tenant-db.ts 租户连接池缓存 + AsyncLocalStorage
server/src/config/admin-pool.ts 平台库连接池(通过 ADMIN_DB_* 环境变量配置)
server/src/config/database.ts 主业务库连接池 + 全局 query() 函数(自动注入数据权限)
server/src/middleware/tenant-db.ts 根据 JWT tenantId 动态切换数据库 + 注入用户 scope
server/src/middleware/data-scope.ts 数据权限工具函数(getDataScope / scopeStoreFilter
server/src/routes/auth.ts 租户用户登录(查 tenant_users + bcrypt
server/src/routes/admin.ts 平台管理 API + 租户内用户管理 API
server/sql/11_tenant_management.sql 平台数据库建表 SQL

部署流程

一键部署(前端+后端)

bash deploy.sh          # 全量部署(后端+前端)
bash deploy.sh server   # 只部署后端
bash deploy.sh front    # 只部署前端
  • 后端:rsync 同步到服务器 /opt/sbrain-server + npm install + pm2 重启
  • 前端:构建 + scp 上传到服务器 /var/www/dm.all8ai.top

本机 frp 隧道(launchd 系统级服务)

frpc 配置(/Users/freedak/frp/frpc.toml):

serverAddr = "152.136.182.184"
serverPort = 7000
loginFailExit = false
auth.token = "frp_gitea_2026"

[[proxies]]
name = "dm-db"
type = "tcp"
localIP = "127.0.0.1"
localPort = 5432
remotePort = 15432

已配置为 macOS launchd 系统级服务,开机自动启动,崩溃自动重启,与 IDE 无关。

服务 plist 日志
frp 隧道 (5432→15432) ~/Library/LaunchAgents/com.frp.client.plist ~/Library/Logs/frpc.log

管理命令

# 停止 frpc
launchctl bootout gui/$(id -u)/com.frp.client

# 启动 frpc
launchctl load ~/Library/LaunchAgents/com.frp.client.plist

# 查看日志
tail -f ~/Library/Logs/frpc.log

# 检查状态
pgrep -l frpc
curl -s https://dm.all8ai.top/api/health

手动启动 frpc(备用,launchd 未运行时)

cd /Users/freedak/frp && ./frpc -c frpc.toml &

本地开发

后端开发

cd server && npm run dev

后端运行在 http://localhost:3333,连接本地 PostgreSQLlocalhost:5432,数据库 bill_query)。

前端开发

cd client && npm run dev

访问 http://localhost:5173Vite proxy 自动转发 /apilocalhost:3333)。

服务器后端管理

# 查看后端状态
ssh ubuntu@152.136.182.184 'pm2 status sbrain-server'

# 查看后端日志
ssh ubuntu@152.136.182.184 'pm2 logs sbrain-server --lines 50'

# 重启后端
ssh ubuntu@152.136.182.184 'pm2 restart sbrain-server'

# 查看后端 .env
ssh ubuntu@152.136.182.184 'cat /opt/sbrain-server/.env'

注意事项

  • 平台库 sbrain_admin 在服务器本地 PostgreSQL5432,业务库 bill_query 在本机 PostgreSQL(通过 frp 暴露为 15432
  • adminPool 连服务器本地 5432 的 sbrain_adminSCRAM 认证,用户 sbrain_admin,密码 sbrain2026
  • tenantPool / pool 连 FRP 隧道 15432 的 bill_querytrust 认证,用户 freedak,无需密码)
  • tenant_configs 表中 db_port 必须为 15432db_password 为 NULLtrust 认证)
  • pg 库在 password 为空字符串时会触发 SCRAM 认证失败,因此 admin-pool.tsdatabase.tstenant-db.ts 中空密码时不传 password 参数
  • deploy.sh 每次部署会覆盖服务器 .env,其中包含 ADMIN_DB_* 配置(ADMIN_DB_PORT=5432ADMIN_DB_PASSWORD=sbrain2026),修改 .env 配置必须同步修改 deploy.sh
  • 租户用户统一存储在 sbrain_admin.tenant_users 表,通过 tenant_id 区分租户
  • tenant_users.region 字段为 VARCHAR(500),区域经理的 region 存储逗号分隔的 store_code 列表(如 0010,0011,0014
  • 密码使用 bcrypt 加密,平台管理员密码目前仍为明文(后续可改)
  • 本机只需运行 frpc(launchd 自启),后端已部署到服务器
  • 修改后端代码后执行 bash deploy.sh server 部署到服务器
  • 修改前端代码后执行 bash deploy.sh front 部署到服务器
  • 全量部署执行 bash deploy.sh(后端+前端)
  • server/.env(本机开发用)中 DB_PORT=5432 连接本地数据库,不要改为 5433
  • 服务器 /opt/sbrain-server/.envDB_PORT=15432 连接 frp 隧道端口
  • frpc 断开后线上前端 API 会失效,需重新启动 frpc
  • launchd 服务开机自启,关闭 IDE/终端不影响;仅注销/关机时停止,下次登录/开机自动恢复