Skip to main content

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