feat: consolidate ticket domain baseline

This commit is contained in:
hailin
2026-07-27 18:57:51 +08:00
parent 5015e4407d
commit 96452934a3
25 changed files with 4236 additions and 218 deletions

View File

@@ -11,6 +11,8 @@ router = Router(tags=["audit"])
class OperationAuditLogOut(Schema):
id: int
user_id: int | None
username: str | None
module: str
action: str
target_type: str
@@ -23,6 +25,49 @@ class OperationAuditLogOut(Schema):
@router.get("/operation-logs", response=list[OperationAuditLogOut])
def list_operation_logs(request):
def list_operation_logs(
request,
module: str | None = None,
action: str | None = None,
target_type: str | None = None,
target_id: str | None = None,
result: str | None = None,
user_id: int | None = None,
created_from: datetime | None = None,
created_to: datetime | None = None,
limit: int = 100,
):
require_permission(request, "system.audit.view")
return OperationAuditLog.objects.all()[:100]
queryset = OperationAuditLog.objects.select_related("user")
filters = {
"module": module,
"action": action,
"target_type": target_type,
"target_id": target_id,
"result": result,
"user_id": user_id,
}
for field, value in filters.items():
if value not in (None, ""):
queryset = queryset.filter(**{field: value})
if created_from:
queryset = queryset.filter(created_at__gte=created_from)
if created_to:
queryset = queryset.filter(created_at__lte=created_to)
return [
{
"id": item.id,
"user_id": item.user_id,
"username": item.user.username if item.user_id else None,
"module": item.module,
"action": item.action,
"target_type": item.target_type,
"target_id": item.target_id,
"request_snapshot": item.request_snapshot,
"result": item.result,
"ip_address": item.ip_address,
"user_agent": item.user_agent,
"created_at": item.created_at,
}
for item in queryset[: min(max(limit, 1), 500)]
]

View File

@@ -18,3 +18,27 @@ def test_list_operation_logs_returns_recent_logs(admin_client, db):
assert len(payload) == 1
assert payload[0]["module"] == "system"
assert payload[0]["action"] == "health_check"
def test_list_operation_logs_supports_business_object_filters(admin_client, db):
OperationAuditLog.objects.create(
module="tickets",
action="status_transition",
target_type="ticket",
target_id="42",
result="success",
)
OperationAuditLog.objects.create(
module="agents",
action="run_started",
target_type="agent_run",
target_id="run-1",
result="success",
)
response = admin_client.get(
"/api/audit/operation-logs?module=tickets&target_type=ticket&target_id=42"
)
assert response.status_code == 200
assert [item["target_id"] for item in response.json()] == ["42"]