feat: complete moderation history dashboard
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / dependency-audit (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s

This commit is contained in:
ik
2026-09-13 09:07:32 +07:00
parent 392e1e534a
commit c6ffded8d7
7 changed files with 103 additions and 4 deletions
+23
View File
@@ -162,6 +162,29 @@ def admin_moderation_history(
return history[offset:offset + limit]
@app.get("/api/v1/admin/moderation-history-export")
def admin_moderation_history_export(
db: Db,
_: Annotated[str, Depends(_admin)],
limit: int = Query(1000, ge=1, le=5000),
) -> JSONResponse:
"""Return an anonymized, analysis-safe decision export."""
events = admin_moderation_history(db, _, limit=limit, offset=0)
payload = {
"generated_at": datetime.now(timezone.utc).isoformat(),
"count": len(events),
"events": [{
"entity_type": event.entity_type,
"decided_at": event.decided_at.isoformat(),
"action": event.action,
"requires_confirmation": event.requires_confirmation,
} for event in events],
}
return JSONResponse(payload, headers={
"Content-Disposition": "attachment; filename=rf4spotter-moderation-history.json",
})
@app.get("/api/v1/admin/imports", response_model=list[ImportRunOut])
def admin_imports(
db: Db,
+57
View File
@@ -2636,6 +2636,63 @@
"summary": "Admin Moderation History"
}
},
"/api/v1/admin/moderation-history-export": {
"get": {
"description": "Return an anonymized, analysis-safe decision export.",
"operationId": "admin_moderation_history_export_api_v1_admin_moderation_history_export_get",
"parameters": [
{
"in": "query",
"name": "limit",
"required": false,
"schema": {
"default": 1000,
"maximum": 5000,
"minimum": 1,
"title": "Limit",
"type": "integer"
}
},
{
"in": "header",
"name": "authorization",
"required": false,
"schema": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Authorization"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {}
}
},
"description": "Successful Response"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
"description": "Validation Error"
}
},
"summary": "Admin Moderation History Export"
}
},
"/api/v1/baits": {
"get": {
"operationId": "baits_api_v1_baits_get",
+6
View File
@@ -163,6 +163,12 @@ def test_admin_diagnostics_exposes_build_identity_only_to_admin() -> None:
assert history.status_code == 200
for forbidden in ("player_name", "source_url", "raw_payload", "screenshot"):
assert forbidden not in history.text.lower()
export = client.get("/api/v1/admin/moderation-history-export", headers={"Authorization": "Bearer change-me-in-production"})
assert export.status_code == 200
assert export.headers["Content-Disposition"] == "attachment; filename=rf4spotter-moderation-history.json"
assert set(export.json()) == {"generated_at", "count", "events"}
for forbidden in ("entity_id", "moderator", "reason", "player_name", "source_url", "raw_payload"):
assert forbidden not in export.text.lower()
def test_spot_detail_and_catches() -> None: