feat(platform): close AI expense value loop
Add tenant-safe value, telemetry, connector, commercial, and production-readiness foundations.
This commit is contained in:
@@ -7,11 +7,13 @@ from app.models.employee import Employee
|
||||
from app.models.organization import OrganizationUnit
|
||||
from app.models.role import Role
|
||||
from app.services.pagination import PageResult, paginate_select
|
||||
from app.services.tenant_registry import required_tenant_id
|
||||
|
||||
|
||||
class EmployeeRepository:
|
||||
def __init__(self, db: Session) -> None:
|
||||
def __init__(self, db: Session, *, tenant_id: str) -> None:
|
||||
self.db = db
|
||||
self.tenant_id = required_tenant_id(tenant_id)
|
||||
|
||||
def _list_stmt(self, status: str | None = None, keyword: str | None = None):
|
||||
stmt = (
|
||||
@@ -22,6 +24,7 @@ class EmployeeRepository:
|
||||
selectinload(Employee.roles),
|
||||
selectinload(Employee.change_logs),
|
||||
)
|
||||
.where(Employee.tenant_id == self.tenant_id)
|
||||
.order_by(Employee.updated_at.desc(), Employee.name.asc())
|
||||
)
|
||||
|
||||
@@ -65,16 +68,25 @@ class EmployeeRepository:
|
||||
selectinload(Employee.roles),
|
||||
selectinload(Employee.change_logs),
|
||||
)
|
||||
.where(Employee.id == employee_id)
|
||||
.where(
|
||||
Employee.tenant_id == self.tenant_id,
|
||||
Employee.id == employee_id,
|
||||
)
|
||||
)
|
||||
return self.db.execute(stmt).scalars().unique().first()
|
||||
|
||||
def get_by_employee_no(self, employee_no: str) -> Employee | None:
|
||||
stmt = select(Employee).where(Employee.employee_no == employee_no)
|
||||
stmt = select(Employee).where(
|
||||
Employee.tenant_id == self.tenant_id,
|
||||
Employee.employee_no == employee_no,
|
||||
)
|
||||
return self.db.execute(stmt).scalars().first()
|
||||
|
||||
def get_by_email(self, email: str) -> Employee | None:
|
||||
stmt = select(Employee).where(Employee.email == email)
|
||||
stmt = select(Employee).where(
|
||||
Employee.tenant_id == self.tenant_id,
|
||||
Employee.email == email,
|
||||
)
|
||||
return self.db.execute(stmt).scalars().first()
|
||||
|
||||
def list_roles(self) -> list[Role]:
|
||||
@@ -86,15 +98,24 @@ class EmployeeRepository:
|
||||
return self.db.execute(stmt).scalars().first()
|
||||
|
||||
def list_organization_units(self) -> list[OrganizationUnit]:
|
||||
stmt = select(OrganizationUnit)
|
||||
stmt = select(OrganizationUnit).where(
|
||||
OrganizationUnit.tenant_id == self.tenant_id
|
||||
)
|
||||
return list(self.db.execute(stmt).scalars().all())
|
||||
|
||||
def get_organization_by_code(self, unit_code: str) -> OrganizationUnit | None:
|
||||
stmt = select(OrganizationUnit).where(OrganizationUnit.unit_code == unit_code)
|
||||
stmt = select(OrganizationUnit).where(
|
||||
OrganizationUnit.tenant_id == self.tenant_id,
|
||||
OrganizationUnit.unit_code == unit_code,
|
||||
)
|
||||
return self.db.execute(stmt).scalars().first()
|
||||
|
||||
def count_employees(self) -> int:
|
||||
stmt = select(func.count()).select_from(Employee)
|
||||
stmt = (
|
||||
select(func.count())
|
||||
.select_from(Employee)
|
||||
.where(Employee.tenant_id == self.tenant_id)
|
||||
)
|
||||
return int(self.db.execute(stmt).scalar_one())
|
||||
|
||||
def count_roles(self) -> int:
|
||||
@@ -102,17 +123,27 @@ class EmployeeRepository:
|
||||
return int(self.db.execute(stmt).scalar_one())
|
||||
|
||||
def count_organization_units(self) -> int:
|
||||
stmt = select(func.count()).select_from(OrganizationUnit)
|
||||
stmt = (
|
||||
select(func.count())
|
||||
.select_from(OrganizationUnit)
|
||||
.where(OrganizationUnit.tenant_id == self.tenant_id)
|
||||
)
|
||||
return int(self.db.execute(stmt).scalar_one())
|
||||
|
||||
def create(self, employee: Employee) -> Employee:
|
||||
self._require_employee_tenant(employee)
|
||||
self.db.add(employee)
|
||||
self.db.commit()
|
||||
self.db.refresh(employee)
|
||||
return employee
|
||||
|
||||
def save(self, employee: Employee) -> Employee:
|
||||
self._require_employee_tenant(employee)
|
||||
self.db.add(employee)
|
||||
self.db.commit()
|
||||
self.db.refresh(employee)
|
||||
return employee
|
||||
|
||||
def _require_employee_tenant(self, employee: Employee) -> None:
|
||||
if required_tenant_id(employee.tenant_id) != self.tenant_id:
|
||||
raise ValueError("员工记录不属于当前可信租户。")
|
||||
|
||||
Reference in New Issue
Block a user