Audit Logs
Data Entity
Description
Tamper-evident, append-only chronological record of all significant actions performed within the Meander platform, providing compliance traceability for GDPR, Bufdir reporting audits, and internal security investigations across all three products.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Unique identifier for each audit log entry | PKrequiredunique |
action |
string |
The action performed, using dot-notation verb format (e.g., user.create, activity.approve, expense.reject, session.revoke, role.assign) | required |
actor_id |
uuid |
Foreign key to users table identifying the user who performed the action. Nullable for system-initiated actions (e.g., auto-approval, scheduled jobs). | - |
actor_role |
string |
Role the actor was operating under at the time of the action (peer_mentor, coordinator, org_admin, global_admin, system) | required |
organization_id |
uuid |
Foreign key to organizations table scoping the audit entry to a specific tenant. Nullable for cross-org or global admin actions. | - |
resource_type |
string |
The type of entity affected (e.g., user, activity, expense, session, role_assignment, organization, feature_flag, report) | required |
resource_id |
string |
The identifier of the specific resource affected. String type to accommodate UUIDs and composite keys across different entity types. | required |
metadata |
json |
Structured context about the action: changed fields with before/after values, request parameters, batch identifiers, or additional business context. Never contains raw credentials or PII beyond what is necessary for audit reconstruction. | - |
ip_address |
string |
IP address of the client that initiated the action. Stored for security investigation. Nullable for system-initiated actions. | - |
user_agent |
string |
HTTP User-Agent header identifying the client application (Flutter mobile app version, admin portal browser, API client) | - |
session_id |
uuid |
Foreign key to sessions table linking the audit entry to the active session at the time of the action. Nullable for system actions. | - |
severity |
enum |
Severity level for filtering and alerting: info for routine operations, warning for unusual patterns, critical for security-relevant actions | required |
outcome |
enum |
Whether the action succeeded or failed. Failed actions (e.g., denied permission, validation error) are logged for security monitoring. | required |
created_at |
datetime |
Timestamp when the audit entry was created. Set once at insert, never modified. Used as the primary sort and partition key. | required |
Database Indexes
idx_audit_logs_created_at
Columns: created_at
idx_audit_logs_actor_id
Columns: actor_id
idx_audit_logs_organization_id
Columns: organization_id
idx_audit_logs_action
Columns: action
idx_audit_logs_resource
Columns: resource_type, resource_id
idx_audit_logs_severity
Columns: severity, created_at
idx_audit_logs_org_created
Columns: organization_id, created_at
idx_audit_logs_actor_created
Columns: actor_id, created_at
Validation Rules
required_action_format
error
Validation failed
valid_actor_reference
error
Validation failed
valid_organization_reference
error
Validation failed
metadata_size_limit
error
Validation failed
ip_address_format
warning
Validation failed
immutable_after_creation
error
Validation failed
created_at_utc_required
error
Validation failed
resource_id_not_empty
error
Validation failed
Business Rules
append_only_immutability
Audit log entries are append-only. Once created, no entry may be updated or deleted. This ensures tamper-evidence for GDPR compliance and Bufdir audit trails.
tenant_scoped_visibility
Organization Admins can only view audit logs where organization_id matches their own organization. Global Admins can view all entries but with anonymized PII in metadata for organizations they do not directly manage.
transactional_emission
Audit entries must be emitted within the same database transaction as the business operation they record. If the transaction rolls back, the audit entry rolls back with it to prevent phantom entries.
security_action_severity_escalation
Actions involving authentication failures, role changes, session revocations, and bulk operations must be logged with severity 'warning' or 'critical' to ensure they surface in security dashboard alerts.
failed_login_tracking
Failed login attempts must be logged with outcome 'failure' and severity 'warning'. Repeated failures from the same actor or IP address within a time window trigger severity escalation to 'critical'.
gdpr_data_minimization
Metadata field must not contain raw passwords, full credit card numbers, health records (epikriser), or unnecessary PII. Before/after values for sensitive fields should be masked or omitted.
retention_archival
Audit log entries older than 12 months are archived to cold storage. Archived entries remain queryable but with higher latency. Entries are never permanently deleted to satisfy Norwegian regulatory requirements.
system_actor_identification
When an action is performed by an automated system process (auto-approval, scheduled sync, background job), actor_id is null and actor_role is set to 'system'. The metadata field must contain the job identifier or trigger source.