use crate::error::ServiceError;
use molten_core::document::Document;
use molten_core::workflow::WorkflowGraph;
use molten_document::validate_document;
use molten_storage_seaorm::repo::{DocumentRepository, FormRepository, WorkflowRepository};
use sea_orm::DatabaseConnection;
use serde_json::Value;
use std::collections::HashMap;
use uuid::Uuid;
pub struct DocumentService {
db: DatabaseConnection,
}
impl DocumentService {
pub fn new(db: DatabaseConnection) -> Self {
Self { db }
}
pub async fn create_document(
&self,
form_id: &str,
workflow_id: &str,
data: HashMap<String, Value>,
) -> Result<Document, ServiceError> {
let form = FormRepository::find_by_id(&self.db, form_id)
.await
.map_err(ServiceError::Internal)?
.ok_or_else(|| ServiceError::FormNotFound(form_id.to_string()))?;
let workflow = WorkflowRepository::find_by_id(&self.db, workflow_id)
.await
.map_err(ServiceError::Internal)?
.ok_or_else(|| ServiceError::WorkflowNotFound(workflow_id.to_string()))?;
let start_phase = workflow.get_start_phase().ok_or_else(|| {
ServiceError::WorkflowRuleViolation(molten_workflow::WorkflowError::UnknownPhase(
"No start phase defined".into(),
))
})?;
let doc_id = Uuid::new_v4().to_string();
let mut doc = Document::new(&doc_id, form_id, workflow_id);
doc.current_phase = start_phase.id.clone();
doc.data = data;
if let Err(validation_errors) = validate_document(&doc, &form) {
return Err(ServiceError::DocumentValidationErrors(validation_errors));
}
DocumentRepository::create(&self.db, &doc)
.await
.map_err(ServiceError::Internal)?;
Ok(doc)
}
pub async fn get_document(&self, id: &str) -> Result<Document, ServiceError> {
DocumentRepository::find_by_id(&self.db, id)
.await
.map_err(ServiceError::Internal)?
.ok_or_else(|| ServiceError::Internal(anyhow::anyhow!("Document not found")))
}
}