first commit

This commit is contained in:
2026-02-28 00:02:02 +01:00
commit 6295c58d33
36 changed files with 7017 additions and 0 deletions

69
backend/services/audit.py Normal file
View File

@@ -0,0 +1,69 @@
"""
Audit logging service.
Gebruik: from services.audit import audit_log
audit_log('user.create', 'user', target_id=str(user.id), detail={'email': email})
"""
import json
from datetime import datetime
from flask import request
from flask_login import current_user
from app import db
def audit_log(action: str, category: str, *,
target_type: str = None, target_id: str = None,
detail: dict = None, school_id: int = None,
user_id: int = None):
"""
Schrijf een audit entry naar de database.
action: korte actienaam, bv. 'user.create', 'school.delete', 'login.success'
category: auth | user | school | class | assessment | doelen | system
target_type: wat er veranderd is, bv. 'user', 'school', 'class'
target_id: identifier van het object (als string)
detail: dict met extra context, wordt als JSON opgeslagen
school_id: override school_id (standaard current_user.school_id)
user_id: override user_id (standaard current_user.id)
"""
from models import AuditLog
try:
uid = user_id
sid = school_id
if uid is None:
try:
uid = current_user.id if current_user.is_authenticated else None
except Exception:
uid = None
if sid is None:
try:
sid = current_user.school_id if current_user.is_authenticated else None
except Exception:
sid = None
ip = None
try:
ip = request.remote_addr
except Exception:
pass
entry = AuditLog(
timestamp = datetime.utcnow(),
user_id = uid,
school_id = sid,
action = action,
category = category,
target_type = target_type,
target_id = str(target_id) if target_id is not None else None,
detail = json.dumps(detail, ensure_ascii=False) if detail else None,
ip_address = ip,
)
db.session.add(entry)
# Geen commit hier — de aanroeper commit zelf (of we flushen mee)
db.session.flush()
except Exception as e:
# Audit failures mogen de hoofdflow nooit blokkeren
import logging
logging.getLogger(__name__).warning(f"Audit log failed: {e}")