mirror of
https://github.com/hpd840321/starRiverProperty.git
synced 2026-06-09 16:30:29 +08:00
fix: policy always checked regardless of caller-provided floors
Redesign addVisitor four-phase flow: - Phase1: ALWAYS query person detail (orgIds for policy lookup) - Phase2: candidate = caller floors or org floorList - Phase3: ALWAYS check policy; intersect candidate with allow - Phase4: empty set validation Fixes UC-02 bypass: policy was entirely skipped when caller provided floorIds. Now policy always constrains. Bump v2.0.19
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
# 租户访客默认楼层策略 — 逻辑修正设计
|
||||
|
||||
**日期**:2026-05-05
|
||||
**状态**:待实施
|
||||
**基线版本**:v2.0.18 → v2.0.19
|
||||
|
||||
---
|
||||
|
||||
## 1. 问题
|
||||
|
||||
现有实现在 `PersonRuleServiceImpl.addVisitor` 中将策略查询包裹在 `if (!callerProvidedFloors)` 条件内,导致:
|
||||
|
||||
- **UC-02**(调用方传了 `floorIds`):策略被完全跳过,即使租户配置了生效策略也不会被执行
|
||||
- 违反用户预期:**任何时候都应当查询策略**,有策略且生效就走策略路径
|
||||
|
||||
## 2. 修正后控制流
|
||||
|
||||
```
|
||||
addVisitor(param, context):
|
||||
// 阶段1: 确定候选楼层列表 candidate
|
||||
if (param.floorIds 非空): ← UC-02
|
||||
candidate = param.floorIds
|
||||
else: ← UC-01
|
||||
candidate = personService.detail() → floorList
|
||||
if candidate 为空: 返回 76260531
|
||||
|
||||
// 阶段2: 查询策略(ALWAYS)
|
||||
policy = DAO.selectEnabledByOrgId(orgId) ← enabled=1
|
||||
|
||||
// 阶段3: 策略决定最终楼层
|
||||
if (policy 存在):
|
||||
effective = candidate ∩ policy.allow_zone_ids
|
||||
if effective 为空: 返回 76260532(策略约束下无可用楼层)
|
||||
else:
|
||||
effective = candidate ← 无策略约束,原样使用
|
||||
|
||||
param.floorIds = effective
|
||||
// 继续 zoneService.page → image_rule_ref → batchBind ...
|
||||
```
|
||||
|
||||
## 3. 核心变更
|
||||
|
||||
| 变更点 | 改前 | 改后 |
|
||||
|--------|------|------|
|
||||
| 策略查询条件 | 仅在 `!callerProvidedFloors` 时查 | **ALWAYS 查** |
|
||||
| UC-02 策略行为 | 完全跳过策略 | 策略生效时对 `floorIds` 求交 |
|
||||
| UC-01 策略行为 | 查组织 `floorList` → 查策略 | 查组织 floorList → 查策略(不变) |
|
||||
|
||||
## 4. UC 对照矩阵
|
||||
|
||||
| 场景 | floorIds | 策略 | 改前结果 | 改后结果 |
|
||||
|------|----------|------|---------|---------|
|
||||
| UC-01 无策略 | 空 | 无 | `floorList` 全集 | `floorList` 全集 ✅ |
|
||||
| UC-01 + 策略 | 空 | 有且生效 | `allow ∩ floorList` | `allow ∩ floorList` ✅ |
|
||||
| UC-01 无交集 | 空 | allow 与 floorList 无交集 | 失败 76260532 | 失败 76260532 ✅ |
|
||||
| UC-02 无策略 | 非空 | 无 | 按请求楼层 | 按请求楼层 ✅ |
|
||||
| UC-02 + 策略 | 非空 | 有且生效 | **按请求楼层(绕过策略)❌** | **`请求楼层 ∩ allow` ✅** |
|
||||
| UC-02 策略不包含 | 非空 | allow 不含请求楼层 | 成功开通(绕过)❌ | **失败 76260532 ✅** |
|
||||
|
||||
## 5. 错误码
|
||||
|
||||
| 错误码 | 场景 | 说明 |
|
||||
|--------|------|------|
|
||||
| 76260531 | 无可用楼层 | `floorList` 为空 或 求交后为空 |
|
||||
| 76260532 | 策略交集为空 | `candidate ∩ allow` 无交集 |
|
||||
| 76260533 | 策略配置错误 | allow 包含被访人无权访问的 zoneId |
|
||||
|
||||
## 6. 日志完善
|
||||
|
||||
| 关键路径 | 日志级别 | 内容 |
|
||||
|---------|---------|------|
|
||||
| UC-02 分支 | INFO | 调用方已指定楼层,候选楼层为 xxx |
|
||||
| UC-01 分支 | INFO | 未传楼层,查组织 floorList 得到 xxx |
|
||||
| 策略查询 | INFO | 查询 orgId=xxx 的策略 |
|
||||
| 策略存在 | INFO | 找到启用策略 policyId=xxx allow=xxx |
|
||||
| 无策略 | INFO | 未找到启用策略,使用候选楼层原值 |
|
||||
| 求交成功 | INFO | 策略生效,最终楼层为 xxx |
|
||||
| 求交为空 | WARN | 候选楼层与策略无交集,返回 76260532 |
|
||||
| 空楼层 | WARN | 无可用楼层,返回 76260531 |
|
||||
Reference in New Issue
Block a user