from enum import Enum from admin_app.db.models import AuditLog from admin_app.repositories import AuditLogRepository class AdminAuditEventType(str, Enum): STAFF_LOGIN_SUCCEEDED = "staff.login.succeeded" STAFF_LOGIN_FAILED = "staff.login.failed" STAFF_LOGOUT_SUCCEEDED = "staff.logout.succeeded" STAFF_ACCOUNT_CREATED = "staff.account.created" STAFF_ACCOUNT_STATUS_UPDATED = "staff.account.status.updated" TOOL_APPROVAL_RECORDED = "tool.approval.recorded" TOOL_PUBLICATION_RECORDED = "tool.publication.recorded" class AdminAuditOutcome(str, Enum): SUCCESS = "success" FAILED = "failed" class AuditService: def __init__(self, repository: AuditLogRepository): self.repository = repository def record_event( self, *, actor_staff_account_id: int | None, event_type: AdminAuditEventType, resource_type: str, resource_id: str | None, outcome: AdminAuditOutcome, message: str | None, payload_json: dict | None, ip_address: str | None, user_agent: str | None, ) -> AuditLog: return self.repository.create( actor_staff_account_id=actor_staff_account_id, event_type=event_type.value, resource_type=resource_type, resource_id=resource_id, outcome=outcome.value, message=message, payload_json=payload_json, ip_address=ip_address, user_agent=user_agent, ) def record_login_succeeded( self, *, actor_staff_account_id: int, session_id: int, email: str, role: str, ip_address: str | None, user_agent: str | None, ) -> AuditLog: return self.record_event( actor_staff_account_id=actor_staff_account_id, event_type=AdminAuditEventType.STAFF_LOGIN_SUCCEEDED, resource_type="staff_account", resource_id=str(actor_staff_account_id), outcome=AdminAuditOutcome.SUCCESS, message="Login administrativo concluido.", payload_json={"session_id": session_id, "email": email, "role": role}, ip_address=ip_address, user_agent=user_agent, ) def record_login_failed( self, *, email: str, ip_address: str | None, user_agent: str | None, ) -> AuditLog: return self.record_event( actor_staff_account_id=None, event_type=AdminAuditEventType.STAFF_LOGIN_FAILED, resource_type="staff_account", resource_id=email, outcome=AdminAuditOutcome.FAILED, message="Tentativa de login administrativo falhou.", payload_json={"email": email}, ip_address=ip_address, user_agent=user_agent, ) def record_logout_succeeded( self, *, actor_staff_account_id: int, session_id: int, ip_address: str | None, user_agent: str | None, ) -> AuditLog: return self.record_event( actor_staff_account_id=actor_staff_account_id, event_type=AdminAuditEventType.STAFF_LOGOUT_SUCCEEDED, resource_type="staff_session", resource_id=str(session_id), outcome=AdminAuditOutcome.SUCCESS, message="Sessao administrativa encerrada.", payload_json={"session_id": session_id}, ip_address=ip_address, user_agent=user_agent, ) def record_staff_account_created( self, *, actor_staff_account_id: int, created_staff_account_id: int, email: str, role: str, ip_address: str | None, user_agent: str | None, ) -> AuditLog: return self.record_event( actor_staff_account_id=actor_staff_account_id, event_type=AdminAuditEventType.STAFF_ACCOUNT_CREATED, resource_type="staff_account", resource_id=str(created_staff_account_id), outcome=AdminAuditOutcome.SUCCESS, message="Conta administrativa de colaborador criada.", payload_json={ "created_staff_account_id": created_staff_account_id, "email": email, "role": role, }, ip_address=ip_address, user_agent=user_agent, ) def record_staff_account_status_updated( self, *, actor_staff_account_id: int, target_staff_account_id: int, is_active: bool, ip_address: str | None, user_agent: str | None, ) -> AuditLog: return self.record_event( actor_staff_account_id=actor_staff_account_id, event_type=AdminAuditEventType.STAFF_ACCOUNT_STATUS_UPDATED, resource_type="staff_account", resource_id=str(target_staff_account_id), outcome=AdminAuditOutcome.SUCCESS, message="Status de colaborador administrativo atualizado.", payload_json={ "target_staff_account_id": target_staff_account_id, "is_active": is_active, }, ip_address=ip_address, user_agent=user_agent, ) def record_tool_approval( self, *, actor_staff_account_id: int, tool_name: str, tool_version: int, ip_address: str | None, user_agent: str | None, ) -> AuditLog: return self.record_event( actor_staff_account_id=actor_staff_account_id, event_type=AdminAuditEventType.TOOL_APPROVAL_RECORDED, resource_type="tool_publication", resource_id=tool_name, outcome=AdminAuditOutcome.SUCCESS, message="Aprovacao de tool registrada.", payload_json={"tool_name": tool_name, "tool_version": tool_version}, ip_address=ip_address, user_agent=user_agent, ) def record_tool_publication( self, *, actor_staff_account_id: int, tool_name: str, tool_version: int, ip_address: str | None, user_agent: str | None, ) -> AuditLog: return self.record_event( actor_staff_account_id=actor_staff_account_id, event_type=AdminAuditEventType.TOOL_PUBLICATION_RECORDED, resource_type="tool_publication", resource_id=tool_name, outcome=AdminAuditOutcome.SUCCESS, message="Publicacao de tool registrada.", payload_json={"tool_name": tool_name, "tool_version": tool_version}, ip_address=ip_address, user_agent=user_agent, ) def list_recent(self, limit: int = 50) -> list[AuditLog]: return self.repository.list_recent(limit=limit)