9.1 KiB
9.1 KiB
GVSDSDK 问题报告
基于
gvsdsdk包源码审查(2026-08-10),结合本会话代码阅读与项目既有文档(SAAS_ARCHITECTURE.md、项目记忆)。 范围:d:\SMANAGE\gvsdsdk(约 15k 行 Python,55 个文件)。 说明:问题按严重度分级,标注可定位位置与修复建议;部分问题为设计取舍,标注"既定决策"。
1. 问题总览
| # | 等级 | 分类 | 问题 |
|---|---|---|---|
| 1 | 高 | 事务 | _call_service 响应非 JSON 时事务卡死(Running 悬挂) |
| 2 | 高 | 事务 | 补偿失败后无重试补偿入口,事务只能人工兜底 |
| 3 | 高 | 架构 | 非托管模型与主库 schema 同步靠人工,migrations 冻结后漂移风险 |
| 4 | 中 | 架构 | User/Dept/Workgroup/Shop 无 TenantUUID,跨租户查询需 JOIN |
| 5 | 中 | 事务 | MaxRetries 无自动重试;RetryStep 无行锁 |
| 6 | 中 | 事务 | 无步骤间数据流(StepResult 不注入后续步骤) |
| 7 | 中 | 事务 | 超时以 CreateTime 起算,非空闲超时 |
| 8 | 中 | 权限 | ABAC 名实不符(本质是 RBAC 字符串集合) |
| 9 | 中 | 架构 | CompanyUUID 全链路冗余无 DB 约束,一致性靠应用层 |
| 10 | 中 | 工程 | 核心链路(Saga/分佣/支付/鉴权)零自动化测试 |
| 11 | 低 | 架构 | UserRole 遗留废弃字段 DeptUUID/WorkgroupUUID 仍在 schema |
| 12 | 低 | 事务 | TransactionResult 恒为空 |
| 13 | 低 | 事务 | 无幂等键,重复执行副作用靠业务自觉 |
| 14 | 低 | 工程 | 惰性加载 130+ 符号 → 无静态类型、IDE 跳转弱 |
| 15 | 低 | 工程 | 类型注解缺失(auth/managers.py 自认暂缓) |
| 16 | 低 | 文档 | SAAS_ARCHITECTURE.md 技术债描述与实际现状漂移 |
2. 详细问题
2.1 高风险
#1 响应非 JSON 时事务卡死(Saga)
- 位置:
gvsdsdk/msync/transaction.py→gvsds/apps/msync/transaction.py_call_service(L538-566) - 问题:
resp.json()解析失败抛 JSONDecodeError,未被任何异常分支捕获;Execute 循环中断,事务永久停在Running,不触发补偿,只能等 300s 超时兜底。 - 建议:捕获
(ValueError, requests.RequestException)统一转StepExecutionError,确保失败必进补偿链路。
#2 补偿失败无法重试补偿(Saga)
- 位置:
gvsds/apps/msync/transaction.pyCompensate(L256-314) - 问题:补偿异常时步骤状态停留在
Compensating(非 Completed),再次 Compensate 的 completed_steps 查询不到该步骤 → 永远补不回来,事务 FAILED 待人工;无 re-compensate 接口。 - 建议:补偿失败步骤状态改
Failed,新增RetryCompensate入口(复用 RetryStep 骨架 +select_for_update)。
#3 非托管模型与主库 schema 同步靠人工
- 位置:
gvsdsdk/models.py(全部模型managed=False) - 问题:SDK 只映射不迁移,主库表结构由 gvsds 侧维护;migrations 冻结后(gvsdsdk/migrations 仅 1 个
0001_drop_userdept),字段新增/改名需人工双端同步,漏改一端即运行时静默漂移。 - 证据:gvsds 侧已无
class Role/Permission/UserRole定义(gerp/models.py L778 从 gvsdsdk import,双份模型实际已收敛),收敛后 SDK 成为唯一模型源,但其结构约束力仅靠约定。 - 建议:建立 SDK 模型 ↔ 主库 schema 的一致性校验(如启动时
_check_schema对照 db_table 字段清单),或恢复按 SDK 生成迁移。
2.2 中风险
#4 部分表无 TenantUUID
- 位置:
gvsdsdk/models.pyUser(L186)/ Department(L500)/ Workgroup(L1302)/ Shop(L831) - 问题:跨租户查询需经 Company→Tenant JOIN;租户删除/隔离审计困难(SAAS_ARCHITECTURE.md 6.2 已列)。
- 建议:向租户语义表补
TenantUUID列并回填存量(迁移脚本),简化EnsureDefaultRoleForUser等处的租户解析链。
#5 MaxRetries 无自动重试;RetryStep 无行锁
- 位置:
gvsds/apps/msync/transaction.pyExecute(L211-244)/ RetryStep(L316-359) - 问题:正向流程失败直接补偿,
MaxRetries/CanRetry仅约束手动重试;RetryStep 无select_for_update,并发重试竞态。 - 建议:Execute 内按
CanRetry内联重试(可配置开关);RetryStep 加行锁。
#6 无步骤间数据流
- 位置:
gvsds/apps/msync/transaction.py - 问题:
StepResult不注入后续步骤 payload;TransactionPayload创建后不参与执行链。真实 Saga 的"A 输出 → B 输入"场景只能创建时预置全部数据。 - 建议:执行时将上一步 StepResult 合并进下一步 ActionPayload(向后兼容可选)。
#7 超时以 CreateTime 起算
- 位置:
gvsds/apps/msync/models.pyIsTimedOut(L232-239) - 问题:事务总预算 = 创建后 300s,非"最近活动空闲超时";多步骤慢事务易误伤,无活动推进重置机制。
- 建议:改为基于
UpdateTime空闲判定,或事务级 heartbeat 推进。
#8 ABAC 名实不符
- 位置:
gvsdsdk/models.pyUserABAC(L798-810);gvsdsdk/auth/permissions.py - 问题:
HierarchicalPermissionIdentifiers为逗号分隔字符串集合,本质是简化 RBAC,无属性(时间/IP/资源所有者/字段级)判定能力;对外宣称 ABAC,扩展受限。 - 建议:短期文档更正为"属性标识符补充层";中期按策略表重构为真 ABAC。
#9 CompanyUUID 冗余无 DB 约束
- 位置:
gvsdsdk/models.pyUserRole/RolePermission/UserRoleDepartment/UserRoleWorkgroup/RoleShop - 问题:冗余隔离列无数据库级一致性约束,删公司/改归属时应用层漏写即脏数据;且各表隔离语义靠"约定一致"。
- 建议:至少对高频路径(UserRole/UserRoleDepartment)加索引与清理任务;长期考虑外键约束。
#10 核心链路零自动化测试
- 位置:
gvsdsdk无 tests 目录;gvsds/tests仅 test_ip_filter/test_money/test_storage 三文件 - 问题:Saga 编排/补偿、分佣计算、支付网关、鉴权链路均无回归保障;本报告 #1/#2 类缺陷正是无测试的产物。
- 建议:优先补:Saga 状态机转换、补偿幂等、RoleManager 鉴权链路、金额计算四组单测。
2.3 低风险
#11 UserRole 遗留废弃字段
- 位置:
gvsdsdk/models.pyUserRole(L759-760) - 问题:DeptUUID/WorkgroupUUID 已废弃(注释禁止写入),但 schema 仍在,易被旧代码误写,语义歧义残留。
- 建议:迁移清理列,或至少全库扫描确认零写入后移除。
#12 TransactionResult 恒为空
- 位置:
gvsds/apps/msync/transaction.py - 问题:模型字段存在,Execute/Compensate 从不写入,
GetDetail().Result恒 null。 - 建议:终态统一写入步骤汇总。
#13 无幂等键
- 位置:
gvsds/apps/msync/transaction.py_call_service - 问题:无 Idempotency-Key;崩溃窗口内重复执行 action 的副作用靠业务补偿函数兜底。
- 建议:HTTP 头携带事务码+步骤号幂等键,工作服务侧去重(可选)。
#14 惰性加载无静态类型
- 位置:
gvsdsdk/__init__.py(PEP 562__getattr__,130+ 符号) - 问题:动态属性解析:IDE 跳转/补全弱、运行时属性访问有开销、
__all__未精确导出。 - 建议:保留惰性加载同时补充
.pyi类型桩或精确__all__。
#15 类型注解缺失
- 位置:
gvsdsdk/auth/managers.py(L12 注释自认"类型注解暂缓") - 问题:~14k 行 Python 大面积无注解,与"双类导出"(自有实现/服务端转发)叠加后调用侧无类型保障。
- 建议:对公开 Manager 方法渐进补注解,优先 RoleManager/OrderManager。
#16 架构文档漂移
- 位置:
SAAS_ARCHITECTURE.md6.2 节 - 问题:仍记录"Role/Permission 模型双份定义未收敛",实际 gvsds 侧已改为
from gvsdsdk.models import(gerp/models.py L778),双份已收敛;文档未同步。 - 建议:更新技术债表,标注已收敛项,避免误导后续维护。
3. 优先级建议
| 优先级 | 动作 | 对应问题 |
|---|---|---|
| P0 | _call_service 异常兜底,失败必进补偿 |
#1 |
| P0 | 补偿失败可重试(RetryCompensate + 行锁) | #2 |
| P1 | SDK 模型 ↔ 主库 schema 一致性校验 | #3 |
| P1 | Saga/鉴权/分佣/支付核心链路补单测 | #10 |
| P2 | 自动重试、步骤数据流、空闲超时、TransactionResult 写入 | #5/#6/#7/#12 |
| P2 | 补 TenantUUID、清理 UserRole 遗留列 | #4/#11 |
| P3 | 文档更正 ABAC 定位、更新架构文档、补类型桩 | #8/#14/#15/#16 |
4. 结论
GVSDSDK 已从"薄封装"演进为通用 SAAS 服务层(P0/P1/P2 服务层化迁移完成),架构方向正确、收敛彻底;当前主要风险集中在事务可靠性与工程保障:2 项高风险缺陷(#1/#2)会直接造成线上事务悬挂或补偿不完整,建议优先修复;其次为模型层 schema 同步靠人工(#3)与核心链路零测试(#10)带来的长期回归风险。
报告人:TraeCode(2026-08-10)