fraiseql_server/usage/events.rs
1//! Mutation audit event type.
2
3/// A single mutation audit event, captured from the `fraiseql::mutation_audit`
4/// tracing target and normalised before aggregation.
5///
6/// The `period` field is a UTC calendar month bucket in `"YYYY-MM"` format,
7/// assigned at the moment the event is recorded by
8/// [`MutationAuditLayer`](super::layer::MutationAuditLayer).
9#[non_exhaustive]
10#[derive(Debug, Clone)]
11pub struct MutationAuditEvent {
12 /// GraphQL mutation field name (e.g. `"create_user"`).
13 pub mutation_name: String,
14 /// Return-type entity name (e.g. `"User"`).
15 pub entity_type: String,
16 /// Mutation operation kind (`"create"`, `"update"`, `"delete"`, `"custom"`).
17 pub operation: String,
18 /// Tenant identifier extracted from the security context; empty string when
19 /// no tenant is present (single-tenant deployments).
20 pub tenant_id: String,
21 /// UTC calendar month in `"YYYY-MM"` format (e.g. `"2026-05"`).
22 pub period: String,
23}
24
25impl MutationAuditEvent {
26 /// Create a new mutation audit event.
27 pub fn new(
28 mutation_name: impl Into<String>,
29 entity_type: impl Into<String>,
30 operation: impl Into<String>,
31 tenant_id: impl Into<String>,
32 period: impl Into<String>,
33 ) -> Self {
34 Self {
35 mutation_name: mutation_name.into(),
36 entity_type: entity_type.into(),
37 operation: operation.into(),
38 tenant_id: tenant_id.into(),
39 period: period.into(),
40 }
41 }
42}