from sqlalchemy.ext.asyncio import AsyncSession from exceptions.exception import PermissionException from module_admin.entity.vo.user_vo import CurrentUserModel from module_business.dao.test_batch_dao import TestBatchDao from module_business.domain.enums import TestBatchStatus from module_business.domain.test_batch_scope import TestBatchScope from module_business.entity.do.test_batch_do import BizTestBatch class TestBatchAccessService: """测试批次作用域与管理权限校验。""" @staticmethod def _is_super_admin(current_user: CurrentUserModel) -> bool: return current_user.user is not None and current_user.user.admin is True @staticmethod def _raise_unavailable() -> None: raise PermissionException({'reason': 'TEST_BATCH_UNAVAILABLE'}, '当前测试批次不可用') @staticmethod def _raise_closed() -> None: raise PermissionException({'reason': 'TEST_BATCH_UNAVAILABLE'}, '当前测试批次已关闭') @classmethod def assert_super_admin(cls, current_user: CurrentUserModel) -> None: """确保当前用户由超级管理员标记明确授信。""" if not cls._is_super_admin(current_user): raise PermissionException('', '仅超级管理员可执行测试批次管理操作') @classmethod async def resolve_scope( cls, db: AsyncSession, current_user: CurrentUserModel, batch_id: int | None, *, write: bool = False, ) -> TestBatchScope: """解析并验证业务请求可使用的数据作用域。""" if batch_id is None: return TestBatchScope.formal() batch = await TestBatchDao.get_batch(db, batch_id) if batch is None or batch.status == TestBatchStatus.PURGED.value: cls._raise_unavailable() if not cls._is_super_admin(current_user): user_id = current_user.user.user_id if current_user.user is not None else None if user_id is None or not await TestBatchDao.user_is_authorized(db, batch_id, user_id): cls._raise_unavailable() if batch.status == TestBatchStatus.CLOSED.value: if write: cls._raise_closed() cls._raise_unavailable() if batch.status != TestBatchStatus.ACTIVE.value: cls._raise_unavailable() return TestBatchScope( batch_id=batch_id, mode='TEST', status=TestBatchStatus.ACTIVE, writable=True, ) @classmethod async def lock_active_batch(cls, db: AsyncSession, scope: TestBatchScope) -> BizTestBatch | None: """在写入前锁定并重新确认测试批次仍为 ACTIVE。""" if scope.mode == 'FORMAL': return None batch = await TestBatchDao.get_batch_for_update(db, scope.batch_id) if batch is None or batch.status == TestBatchStatus.PURGED.value: cls._raise_unavailable() if batch.status == TestBatchStatus.CLOSED.value: cls._raise_closed() if batch.status != TestBatchStatus.ACTIVE.value: cls._raise_unavailable() return batch