cfa12c9b7f
- 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 家海淀区门店)
7.7 KiB
7.7 KiB
当前数据库是本机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) |
.env 中 ADMIN_DB_* |
tenantPool |
bill_query(业务库) |
127.0.0.1:15432(FRP 隧道 → 本机 PG) |
trust(用户 freedak,无需密码) |
tenant_configs.db_port=15432 |
pool |
bill_query(业务库) |
127.0.0.1:15432(FRP 隧道 → 本机 PG) |
trust(用户 freedak,无需密码) |
.env 中 DB_* |
⚠️
tenant_configs表中db_port必须为15432(FRP 隧道),db_password为 NULL(trust 认证)。 ⚠️adminPool连接服务器本地 5432,需要ADMIN_DB_PASSWORD=sbrain2026。
数据库分布
| 数据库 | 位置 | 存储内容 |
|---|---|---|
sbrain_admin |
服务器本地 PostgreSQL(5432) | 平台管理员、租户配置(tenant_configs)、所有租户用户(tenant_users) |
bill_query |
本机 PostgreSQL(通过 frp 暴露为 15432) | 租户业务数据(销售、任务、成本分析等) |
多租户数据隔离
- 认证流程:用户登录 → 查
sbrain_admin.tenant_users→ bcrypt 验证 → JWT 含tenantId - 数据隔离:业务请求 →
tenantDbMiddleware根据 JWT 中的tenantId查tenant_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,连接本地 PostgreSQL(localhost:5432,数据库 bill_query)。
前端开发
cd client && npm run dev
访问 http://localhost:5173(Vite proxy 自动转发 /api 到 localhost: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在服务器本地 PostgreSQL(5432),业务库bill_query在本机 PostgreSQL(通过 frp 暴露为 15432) adminPool连服务器本地 5432 的sbrain_admin(SCRAM 认证,用户sbrain_admin,密码sbrain2026)tenantPool/pool连 FRP 隧道 15432 的bill_query(trust 认证,用户freedak,无需密码)tenant_configs表中db_port必须为15432,db_password为 NULL(trust 认证)pg库在password为空字符串时会触发 SCRAM 认证失败,因此admin-pool.ts、database.ts、tenant-db.ts中空密码时不传password参数deploy.sh每次部署会覆盖服务器.env,其中包含ADMIN_DB_*配置(ADMIN_DB_PORT=5432,ADMIN_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/.env中DB_PORT=15432连接 frp 隧道端口 - frpc 断开后线上前端 API 会失效,需重新启动 frpc
- launchd 服务开机自启,关闭 IDE/终端不影响;仅注销/关机时停止,下次登录/开机自动恢复