meraproject/services/user-reader/app/labor_identity.py

58 lines
2.2 KiB
Python
Raw Normal View History

"""Идентичность: acting (X-Acting-Emp-Id) и target (emp_id)."""
from __future__ import annotations
from typing import Annotated
from fastapi import Header, HTTPException
from app.emp_schema import EMP_TABLE_CANONICAL
from app.main import _column_lookup, _quote_ident, _table_columns, resolve_emp_table
def _biz_error(status: int, code: str, message: str) -> HTTPException:
return HTTPException(status_code=status, detail={"code": code, "message": message})
def parse_acting_emp_id(
x_acting_emp_id: Annotated[str | None, Header(alias="X-Acting-Emp-Id")] = None,
) -> int:
if not x_acting_emp_id or not str(x_acting_emp_id).strip():
raise _biz_error(400, "missing_acting_emp", "Требуется заголовок X-Acting-Emp-Id")
try:
v = int(str(x_acting_emp_id).strip())
except ValueError as e:
raise _biz_error(
400, "invalid_acting_emp", "X-Acting-Emp-Id должен быть целым числом"
) from e
if v <= 0:
raise _biz_error(400, "invalid_acting_emp", "X-Acting-Emp-Id должен быть > 0")
return v
def resolve_target_emp_id(acting_emp_id: int, emp_id: int | None) -> int:
return int(emp_id) if emp_id is not None else acting_emp_id
def ensure_emp_exists(cur, db: str, emp_id: int, *, kind: str = "target") -> None:
table = resolve_emp_table(cur, db)
cols = _table_columns(cur, db, table)
lut = _column_lookup(cols)
prefix = EMP_TABLE_CANONICAL.lower()
id_col = lut.get(f"{prefix}_id") or lut.get("id")
removed_col = lut.get(f"{prefix}_removed") or lut.get("removed")
if not id_col:
raise _biz_error(500, "db_error", "Не найдена колонка id в таблице сотрудников")
cond = f"{_quote_ident(id_col)} = %s"
params: list = [emp_id]
if removed_col:
cond += f" AND {_quote_ident(removed_col)} = 0"
cur.execute(
f"SELECT 1 AS ok FROM {_quote_ident(table)} WHERE {cond} LIMIT 1",
params,
)
if not cur.fetchone():
code = "acting_emp_not_found" if kind == "acting" else "target_emp_not_found"
raise _biz_error(404, code, f"Сотрудник {emp_id} не найден")