Add the Healthcare platform backend (phases 13.0–13.7) with Alembic migration revision fix, production deploy script, validation reports, shared UI exports, and loyalty list page client directives so Next.js build succeeds. Co-authored-by: Cursor <cursoragent@cursor.com>
151 lines
4.6 KiB
Python
151 lines
4.6 KiB
Python
"""Healthcare foundation repositories."""
|
|
from __future__ import annotations
|
|
|
|
from typing import Sequence
|
|
from uuid import UUID
|
|
|
|
from sqlalchemy import select
|
|
|
|
from app.models.foundation import (
|
|
Branch,
|
|
Clinic,
|
|
Department,
|
|
ExternalProviderConfig,
|
|
HealthcareAuditLog,
|
|
HealthcareConfiguration,
|
|
HealthcarePermission,
|
|
HealthcareRole,
|
|
HealthcareSetting,
|
|
)
|
|
from app.repositories.base import TenantBaseRepository
|
|
|
|
|
|
class ClinicRepository(TenantBaseRepository[Clinic]):
|
|
model = Clinic
|
|
|
|
async def get_by_code(self, tenant_id: UUID, code: str) -> Clinic | None:
|
|
stmt = select(self.model).where(
|
|
self.model.tenant_id == tenant_id,
|
|
self.model.code == code,
|
|
self.model.is_deleted.is_(False),
|
|
)
|
|
result = await self.session.execute(stmt)
|
|
return result.scalar_one_or_none()
|
|
|
|
|
|
class BranchRepository(TenantBaseRepository[Branch]):
|
|
model = Branch
|
|
|
|
async def list_by_clinic(
|
|
self, tenant_id: UUID, clinic_id: UUID, *, offset: int = 0, limit: int = 20
|
|
) -> Sequence[Branch]:
|
|
stmt = (
|
|
select(self.model)
|
|
.where(
|
|
self.model.tenant_id == tenant_id,
|
|
self.model.clinic_id == clinic_id,
|
|
self.model.is_deleted.is_(False),
|
|
)
|
|
.offset(offset)
|
|
.limit(limit)
|
|
)
|
|
result = await self.session.execute(stmt)
|
|
return result.scalars().all()
|
|
|
|
|
|
class DepartmentRepository(TenantBaseRepository[Department]):
|
|
model = Department
|
|
|
|
async def get_by_code(
|
|
self, tenant_id: UUID, clinic_id: UUID, code: str
|
|
) -> Department | None:
|
|
stmt = select(self.model).where(
|
|
self.model.tenant_id == tenant_id,
|
|
self.model.clinic_id == clinic_id,
|
|
self.model.code == code,
|
|
self.model.is_deleted.is_(False),
|
|
)
|
|
result = await self.session.execute(stmt)
|
|
return result.scalar_one_or_none()
|
|
|
|
|
|
class HealthcareRoleRepository(TenantBaseRepository[HealthcareRole]):
|
|
model = HealthcareRole
|
|
|
|
|
|
class HealthcarePermissionRepository(TenantBaseRepository[HealthcarePermission]):
|
|
model = HealthcarePermission
|
|
|
|
|
|
class ExternalProviderConfigRepository(TenantBaseRepository[ExternalProviderConfig]):
|
|
model = ExternalProviderConfig
|
|
|
|
async def get_by_code(
|
|
self, tenant_id: UUID, code: str
|
|
) -> ExternalProviderConfig | None:
|
|
stmt = select(self.model).where(
|
|
self.model.tenant_id == tenant_id,
|
|
self.model.code == code,
|
|
self.model.is_deleted.is_(False),
|
|
)
|
|
result = await self.session.execute(stmt)
|
|
return result.scalar_one_or_none()
|
|
|
|
|
|
class HealthcareConfigurationRepository(TenantBaseRepository[HealthcareConfiguration]):
|
|
model = HealthcareConfiguration
|
|
|
|
|
|
class HealthcareSettingRepository(TenantBaseRepository[HealthcareSetting]):
|
|
model = HealthcareSetting
|
|
|
|
async def get_by_key(
|
|
self,
|
|
tenant_id: UUID,
|
|
key: str,
|
|
*,
|
|
clinic_id: UUID | None = None,
|
|
branch_id: UUID | None = None,
|
|
) -> HealthcareSetting | None:
|
|
clauses = [
|
|
self.model.tenant_id == tenant_id,
|
|
self.model.key == key,
|
|
self.model.is_deleted.is_(False),
|
|
]
|
|
if clinic_id is None:
|
|
clauses.append(self.model.clinic_id.is_(None))
|
|
else:
|
|
clauses.append(self.model.clinic_id == clinic_id)
|
|
if branch_id is None:
|
|
clauses.append(self.model.branch_id.is_(None))
|
|
else:
|
|
clauses.append(self.model.branch_id == branch_id)
|
|
stmt = select(self.model).where(*clauses)
|
|
result = await self.session.execute(stmt)
|
|
return result.scalar_one_or_none()
|
|
|
|
|
|
class HealthcareAuditLogRepository(TenantBaseRepository[HealthcareAuditLog]):
|
|
model = HealthcareAuditLog
|
|
|
|
async def list_for_entity(
|
|
self,
|
|
tenant_id: UUID,
|
|
entity_type: str,
|
|
entity_id: UUID,
|
|
*,
|
|
limit: int = 100,
|
|
) -> Sequence[HealthcareAuditLog]:
|
|
stmt = (
|
|
select(self.model)
|
|
.where(
|
|
self.model.tenant_id == tenant_id,
|
|
self.model.entity_type == entity_type,
|
|
self.model.entity_id == entity_id,
|
|
)
|
|
.order_by(self.model.created_at.desc())
|
|
.limit(limit)
|
|
)
|
|
result = await self.session.execute(stmt)
|
|
return result.scalars().all()
|