feat: audit vocabulary/term/authority creation, attributing the acting user (#21)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,16 +1,23 @@
|
||||
//! Authority records (person / organisation / place).
|
||||
|
||||
use domain::{Authority, AuthorityId, AuthorityKind, AuthorityRef, LocalizedLabel, NewAuthority};
|
||||
use domain::{
|
||||
AuditAction, AuditActor, Authority, AuthorityId, AuthorityKind, AuthorityRef, LocalizedLabel,
|
||||
NewAuditEvent, NewAuthority,
|
||||
};
|
||||
use sqlx::Row;
|
||||
|
||||
use crate::audit;
|
||||
|
||||
/// Labels aggregated per row as JSON, to read an authority and its labels in one query.
|
||||
const LABELS_JSON: &str = "COALESCE(json_agg(json_build_object('lang', al.lang, 'label', al.label) \
|
||||
ORDER BY al.lang) FILTER (WHERE al.authority_id IS NOT NULL), '[]'::json)";
|
||||
|
||||
/// Insert an authority and its labels. Multiple statements — pass a transaction
|
||||
/// connection (`&mut *tx`) for atomicity.
|
||||
/// Insert an authority and its labels, then record a `created` audit entry. Multiple
|
||||
/// statements — pass a transaction connection (`&mut *tx`) so everything commits
|
||||
/// atomically.
|
||||
pub async fn create_authority(
|
||||
conn: &mut sqlx::PgConnection,
|
||||
actor: AuditActor,
|
||||
new: &NewAuthority,
|
||||
) -> Result<AuthorityId, sqlx::Error> {
|
||||
let id = AuthorityId::new();
|
||||
@@ -31,6 +38,18 @@ pub async fn create_authority(
|
||||
.await?;
|
||||
}
|
||||
|
||||
audit::record(
|
||||
&mut *conn,
|
||||
&NewAuditEvent {
|
||||
actor,
|
||||
action: AuditAction::Created,
|
||||
entity_type: "authority".to_owned(),
|
||||
entity_id: id.to_uuid(),
|
||||
changes: Vec::new(),
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user