use axum::http::StatusCode;
use serde_json::Value;
use tracing::info;
use vta_sdk::protocols::join_requests::manifest::v0_2::ResponseRequestedAttributesItem as RequestedAttribute;
use vti_common::audit::{AuditEvent, CommunityRequestedAttributesUpdatedData};
use vti_common::error::AppError;
use crate::community::requested_attributes::{diff, load_requested, store_requested};
use crate::server::AppState;
pub(crate) async fn update_requested_attributes(
state: &AppState,
actor: &str,
body: Value,
) -> Result<Vec<RequestedAttribute>, AppError> {
let requested: Vec<RequestedAttribute> = serde_json::from_value(body)
.map_err(|e| AppError::Validation(format!("requested attributes: {e}")))?;
let writer = state
.audit_writer
.as_ref()
.ok_or_else(|| AppError::ServiceError {
status: StatusCode::SERVICE_UNAVAILABLE,
message: "audit writer not configured".into(),
})?;
let before = load_requested(&state.community_ks).await?;
store_requested(&state.community_ks, &requested).await?;
let (added, removed) = diff(&before, &requested);
if !added.is_empty() || !removed.is_empty() {
writer
.write(
actor,
None,
AuditEvent::CommunityRequestedAttributesUpdated(
CommunityRequestedAttributesUpdatedData {
added: added.clone(),
removed: removed.clone(),
},
),
)
.await?;
info!(?added, ?removed, "community requested attributes updated");
}
Ok(requested)
}