molten_api/handlers/document.rs
1//! This module provides the API handlers for Document entity operations.
2//!
3//! It includes functions for creating new documents and retrieving existing ones,
4//! serving as the entry point for interactions with the document service layer.
5use crate::{error::ApiError, state::AppState};
6use axum::{
7 Json,
8 extract::{Path, State},
9};
10use molten_core::document::Document;
11use serde::Deserialize;
12use serde_json::Value;
13use std::collections::HashMap;
14
15/// Request payload for creating a new document.
16///
17/// A document is created against a specific form and workflow. The `data`
18/// field contains the user-provided values for the form and is validated
19/// against the referenced form definition during creation.
20#[derive(Deserialize)]
21pub struct CreateDocumentRequest {
22 /// Unique identifier for the form that governs the document structure
23 pub form_id: String,
24 /// Unique identifier for the workflow that governs the document lifecycle
25 pub workflow_id: String,
26 /// Field values for the document, keyed by form field identifier.
27 ///
28 /// The contents of this map are validated against the referenced form
29 /// definition (required fields, types, and constraints).
30 pub data: HashMap<String, Value>,
31}
32
33/// Create a new document definition.
34///
35/// Accepts a [`CreateDocumentRequest`] and validates it.
36/// If validation succeeds, the document is
37/// persisted and the stored document is returned.
38///
39/// # Route
40/// `POST /documents`
41///
42/// # Errors
43/// - Returns an error if the document definition fails validation.
44/// - Returns an error if persistence fails.
45///
46/// # Notes
47/// This endpoint is intended only for creating new documents.
48/// Updates to existing documents should be handled via a separate endpoint
49/// to allow different validation and lifecycle rules.
50pub async fn create_document(
51 State(state): State<AppState>,
52 Json(payload): Json<CreateDocumentRequest>,
53) -> Result<Json<Document>, ApiError> {
54 let doc = state
55 .document_service
56 .create_document(&payload.form_id, &payload.workflow_id, payload.data)
57 .await?;
58
59 Ok(Json(doc))
60}
61
62/// Retrieve a document definition by id.
63///
64/// # Route
65/// `GET /documents/{id}`
66///
67/// # Errors
68/// - Returns an error if the document does not exist.
69/// - Returns an error if the underlying storage operation fails.
70pub async fn get_document(
71 State(state): State<AppState>,
72 Path(id): Path<String>,
73) -> Result<Json<Document>, ApiError> {
74 let doc = state.document_service.get_document(&id).await?;
75 Ok(Json(doc))
76}
77
78// TODO: POST /documents/{id} for Updates