refactor(repos): 归属留痕共享数据访问,人员在职校验收口单点

- ownership_log_repository:客户/业务两侧逐行同构的 list/count/add
  收口(owner_type 与引用列参数化),双键倒序与被删人员兜底口径
  单点维护;两侧 repository 变薄包装,service 层零改动
- PERSONNEL_STATUS_ACTIVE 单点导出于 models/personnel(对照
  BUSINESS_STATUS_* 先例);业务/客户两侧的「存在且在职」校验收口
  于 personnel_service.ensure_active——此前两份常量+校验仅靠注释
  维持同步,在职判定调整时会两入口口径分叉;校验放 service 层遵守
  「repositories 不抛业务异常」红线

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
liuwenxinandClaude Code committed 2026-10-15 09:49:53 +08:00
1 parent 409e26614f
commit 60f6af6494
7 files changed
+119 -85

No files matched your search

+3 -16
View File
@@ -40,15 +40,11 @@ from app.schemas.customer import (
CustomerUpdateIn,
OwnershipChangeLogOut,
)
from app.services import audit_service
from app.services import audit_service, personnel_service
from app.services.audit_service import AuditRecord, RequestMeta
logger = logging.getLogger(__name__)
# personnel.status 的在职值(列注释口径:1在职 0离职)。离职人员不可再被
# 客户归属引用;人员侧抽出共享常量后此处替换
_PERSONNEL_STATUS_ACTIVE = 1
def _to_out(customer: Customer, owner_name: str | None) -> CustomerOut:
"""ORM 对象转响应模型。禁止把 ORM 对象直接当 response_model。"""
@@ -95,17 +91,8 @@ def _ensure_customer_type(customer_type: str) -> None:
def _ensure_owner_personnel(session: Session, personnel_id: int) -> Personnel:
"""归属人员必须存在且在职,返回人员行。
「不存在」与「已离职」合并为同一文案:人员 ID 是否有效不构成需要
向调用方区分的信息(同登录防枚举的思路)。
:raises BadRequestError: 归属人员不存在或已离职
"""
person = personnel_repository.get_by_id(session, personnel_id)
if person is None or person.status != _PERSONNEL_STATUS_ACTIVE:
raise BadRequestError("归属人员不存在或已离职")
return person
"""归属人员必须存在且在职(共享校验收口于 personnel_service.ensure_active)。"""
return personnel_service.ensure_active(session, personnel_id, label="归属")
def _is_duplicate_entry(exc: IntegrityError) -> bool: