use axum::extract::State;
use axum::Json;
use serde::Deserialize;
use serde_json::Value;
use uuid::Uuid;
use crate::domain::relations::EntityRelation;
use crate::domain::{EntityType, RelationType};
use crate::error::{AppError, AppResult};
use crate::services::relations as svc;
use crate::state::AppState;
#[derive(Debug, Deserialize)]
pub struct CreateRelationBody {
pub from_entity_id: Uuid,
pub from_entity_type: String,
pub to_entity_id: Uuid,
pub to_entity_type: String,
pub relation_type: String,
}
pub async fn create(
State(state): State<AppState>,
Json(body): Json<CreateRelationBody>,
) -> AppResult<Json<EntityRelation>> {
let input = svc::NewRelationInput {
from_entity_id: body.from_entity_id,
from_entity_type: parse_entity_type(&body.from_entity_type)?,
to_entity_id: body.to_entity_id,
to_entity_type: parse_entity_type(&body.to_entity_type)?,
relation_type: parse_relation_type(&body.relation_type)?,
};
let relation = svc::create_relation(&state.pool, input).await?;
Ok(Json(relation))
}
fn parse_entity_type(s: &str) -> AppResult<EntityType> {
serde_json::from_value::<EntityType>(Value::String(s.trim().to_string()))
.map_err(|_| AppError::Validation(format!("unknown entity type `{s}`")))
}
fn parse_relation_type(s: &str) -> AppResult<RelationType> {
serde_json::from_value::<RelationType>(Value::String(s.trim().to_string()))
.map_err(|_| AppError::Validation(format!("unknown relation type `{s}`")))
}