// Ressursforbruk-logging — sentralisert hjelpemodul. // // Alle ressurskrevende operasjoner logger til `resource_usage_log`-tabellen // som siste steg etter vellykket operasjon. Feilede jobber logges ikke. // // Ref: docs/features/ressursforbruk.md use sqlx::PgPool; use uuid::Uuid; /// Logger en ressurshendelse til `resource_usage_log`. /// /// - `target_node_id`: Noden som ble behandlet /// - `triggered_by`: Brukeren som utløste det (None for system-jobber) /// - `collection_id`: Samlingen det skjedde i (None hvis ukjent) /// - `resource_type`: "ai", "whisper", "tts", "cas", "bandwidth", "livekit" /// - `detail`: JSONB med type-spesifikke felter (se docs/features/ressursforbruk.md) pub async fn log( db: &PgPool, target_node_id: Uuid, triggered_by: Option, collection_id: Option, resource_type: &str, detail: serde_json::Value, ) -> Result<(), String> { sqlx::query( r#" INSERT INTO resource_usage_log (target_node_id, triggered_by, collection_id, resource_type, detail) VALUES ($1, $2, $3, $4, $5) "#, ) .bind(target_node_id) .bind(triggered_by) .bind(collection_id) .bind(resource_type) .bind(&detail) .execute(db) .await .map_err(|e| format!("Ressurslogging feilet: {e}"))?; tracing::debug!( target_node_id = %target_node_id, resource_type = %resource_type, "Ressursforbruk logget" ); Ok(()) } /// Finn samlings-ID for en node via belongs_to-edge. /// Returnerer None hvis noden ikke tilhører en samling. pub async fn find_collection_for_node(db: &PgPool, node_id: Uuid) -> Option { sqlx::query_scalar::<_, Uuid>( r#" SELECT e.target_id FROM edges e JOIN nodes n ON n.id = e.target_id WHERE e.source_id = $1 AND e.edge_type = 'belongs_to' AND n.node_kind = 'collection' LIMIT 1 "#, ) .bind(node_id) .fetch_optional(db) .await .ok() .flatten() }