фикс правок ревью

This commit is contained in:
Raykov-MS 2026-05-20 17:30:40 +03:00
parent 4a7ac50ca7
commit 8e43920deb
3 changed files with 19 additions and 8 deletions

View File

@ -5,7 +5,7 @@ from src.api.v1.deps import require_admin
from src.db.session import get_db from src.db.session import get_db
# from src.domain.models import Users # from src.domain.models import Users
from src.db.models.app_user import AppUser from src.db.models.app_user import AppUser
from src.domain.schemas import AuditLogListResponse, AuditLogQueryParams from src.domain.schemas import AuditLog, AuditLogQueryParams, BaseListResponse
from src.services.auditlog_service import AuditLogService from src.services.auditlog_service import AuditLogService
router = APIRouter(tags=["audit"]) router = APIRouter(tags=["audit"])
@ -13,7 +13,7 @@ router = APIRouter(tags=["audit"])
@router.get( @router.get(
"/audit-logs", "/audit-logs",
response_model=AuditLogListResponse, response_model=BaseListResponse[AuditLog],
status_code=status.HTTP_200_OK, status_code=status.HTTP_200_OK,
summary="Получение журнала аудита", summary="Получение журнала аудита",
description="Возвращает список записей аудита с возможностью фильтрации. Доступно только администраторам.", description="Возвращает список записей аудита с возможностью фильтрации. Доступно только администраторам.",
@ -26,7 +26,7 @@ async def get_audit_logs(
offset = (params.page - 1) * params.limit offset = (params.page - 1) * params.limit
audit_service = AuditLogService(db) audit_service = AuditLogService(db)
logs = await audit_service.get_all( logs, count = await audit_service.get_all(
user=current_user, user=current_user,
limit=params.limit, limit=params.limit,
offset=offset, offset=offset,
@ -39,4 +39,4 @@ async def get_audit_logs(
date_to=params.date_to, date_to=params.date_to,
) )
result = [audit_service.orm_log_to_response(log) for log in logs] result = [audit_service.orm_log_to_response(log) for log in logs]
return AuditLogListResponse(result=result) return BaseListResponse(result=result, count=count)

View File

@ -3,6 +3,7 @@ from typing import Iterable, Optional
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.sql.functions import func
# from sqlalchemy.orm import selectinload # from sqlalchemy.orm import selectinload
# from app.domain.models import AuditLog # from app.domain.models import AuditLog
@ -38,24 +39,32 @@ class AuditLogRepository:
event_type: str | None = None, event_type: str | None = None,
date_from: datetime | None = None, date_from: datetime | None = None,
date_to: datetime | None = None, date_to: datetime | None = None,
) -> Iterable[AuditLog]: ) -> (Iterable[AuditLog], int):
"""Получение всех записей аудита с опциональной фильтрацией.""" """Получение всех записей аудита с опциональной фильтрацией."""
query = select(AuditLog) query = select(AuditLog)
query_count = select(func.count(AuditLog.id))
if user_id is not None: if user_id is not None:
query = query.where(AuditLog.user_id == user_id) query = query.where(AuditLog.user_id == user_id)
query_count = query_count.where(AuditLog.user_id == user_id)
if org_unit_id is not None: if org_unit_id is not None:
query = query.where(AuditLog.org_unit_id == org_unit_id) query = query.where(AuditLog.org_unit_id == org_unit_id)
query_count = query_count.where(AuditLog.org_unit_id == org_unit_id)
if task_id is not None: if task_id is not None:
query = query.where(AuditLog.task_id == task_id) query = query.where(AuditLog.task_id == task_id)
query_count = query_count.where(AuditLog.task_id == task_id)
if form_id is not None: if form_id is not None:
query = query.where(AuditLog.form_id == form_id) query = query.where(AuditLog.form_id == form_id)
query_count = query_count.where(AuditLog.form_id == form_id)
if event_type is not None: if event_type is not None:
query = query.where(AuditLog.event_type == event_type) query = query.where(AuditLog.event_type == event_type)
query_count = query_count.where(AuditLog.event_type == event_type)
if date_from is not None: if date_from is not None:
query = query.where(AuditLog.event_dt >= date_from) query = query.where(AuditLog.event_dt >= date_from)
query_count = query_count.where(AuditLog.event_dt >= date_from)
if date_to is not None: if date_to is not None:
query = query.where(AuditLog.event_dt <= date_to) query = query.where(AuditLog.event_dt <= date_to)
query_count = query_count.where(AuditLog.event_dt <= date_to)
query = query.order_by(AuditLog.event_dt.desc()) query = query.order_by(AuditLog.event_dt.desc())
@ -64,5 +73,7 @@ class AuditLogRepository:
if offset is not None: if offset is not None:
query = query.offset(offset) query = query.offset(offset)
return (await self.db.execute(query)).scalars().all() return (await self.db.execute(query)).scalars().all(), (
await self.db.execute(query_count)
).scalar_one()

View File

@ -43,7 +43,7 @@ class AuditLogService:
event_type: str | None = None, event_type: str | None = None,
date_from: datetime | None = None, date_from: datetime | None = None,
date_to: datetime | None = None, date_to: datetime | None = None,
) -> Iterable[AuditLog]: ) -> (Iterable[AuditLog], int):
"""Получение всех записей аудита с опциональной фильтрацией.""" """Получение всех записей аудита с опциональной фильтрацией."""
if not self._can_view_audit_logs(user): if not self._can_view_audit_logs(user):
raise AccessDeniedException( raise AccessDeniedException(
@ -66,7 +66,7 @@ class AuditLogService:
"""Проверяет, может ли пользователь просматривать журнал аудита.""" """Проверяет, может ли пользователь просматривать журнал аудита."""
return user.role_id == UserRoleEnum.ADMIN.value return user.role_id == UserRoleEnum.ADMIN.value
def orm_log_to_response(self, log: Any) -> AuditLogSchema: def orm_log_to_response(self, log: AuditLog) -> AuditLogSchema:
"""Маппинг записи ORM audit_log в формат ответа API (entity, entity_id, action, at, payload_json). """Маппинг записи ORM audit_log в формат ответа API (entity, entity_id, action, at, payload_json).
model_validate(orm) не подходит: в БД поля event_dt/event/event_type/event_data, в API at/action/entity/entity_id; entity и entity_id из event_data JSON. model_validate(orm) не подходит: в БД поля event_dt/event/event_type/event_data, в API at/action/entity/entity_id; entity и entity_id из event_data JSON.
""" """