backbone-pos 0.5.33

Point of sale — cashier session, ticket + multi-tender; orchestrates billing (revenue) + payment (settlement), posts no GL directly
Documentation
//! Pos Module Routes
//!
//! Generated by metaphor-schema. Do not edit manually.
//!
//! This module provides route composition with dual pattern support:
//! - Stateless routes: `create_stateless_routes()` -> `Router<()>`
//! - Stateful routes: `create_stateful_routes()` -> `Router<AppState>`

use axum::Router;
use std::sync::Arc;

// Import handlers
use crate::presentation::http::{
    create_pos_closing_entry_routes,
    create_pos_closing_entry_read_routes,
    create_pos_invoice_routes,
    create_pos_invoice_read_routes,
    create_pos_invoice_item_routes,
    create_pos_invoice_item_read_routes,
    create_pos_payment_routes,
    create_pos_payment_read_routes,
    create_pos_profile_routes,
    create_pos_profile_read_routes,
    create_pos_opening_entry_routes,
    create_pos_opening_entry_read_routes,
    create_pos_cash_movement_routes,
    create_pos_cash_movement_read_routes
};

// Import AppState for stateful routes
use crate::handlers::AppState;

// ============================================================
// PATTERN 1: STATELESS ROUTES
// ============================================================

/// Create stateless routes for the Pos module.
///
/// These routes don't require shared state and are simpler to use.
/// Use this when you only need standard CRUD operations.
///
/// # Example
///
/// ```ignore
/// let module = PosModule::builder().with_database(pool).build()?;
/// let routes = create_stateless_routes(&module);
/// let app = Router::new().merge(routes);
/// ```
pub fn create_stateless_routes(module: &crate::PosModule) -> Router<()> {
    Router::new()
        .merge(create_pos_closing_entry_routes(module.pos_closing_entry_service.clone()))
        .merge(create_pos_invoice_routes(module.pos_invoice_service.clone()))
        .merge(create_pos_invoice_item_routes(module.pos_invoice_item_service.clone()))
        .merge(create_pos_payment_routes(module.pos_payment_service.clone()))
        .merge(create_pos_profile_routes(module.pos_profile_service.clone()))
        .merge(create_pos_opening_entry_routes(module.pos_opening_entry_service.clone()))
        .merge(create_pos_cash_movement_routes(module.pos_cash_movement_service.clone()))
}

/// Read-only routes for the Pos module — every entity mounted READ-ONLY (the guarded base).
///
/// The generic `create_stateless_routes` exposes full mutable CRUD with no domain
/// validation; this exposes only reads, so generic mutation can't bypass a write
/// service's invariants. Extend it: `create_readonly_pos_routes(m).merge(my_validated_writes)`.
pub fn create_readonly_pos_routes(module: &crate::PosModule) -> Router<()> {
    Router::new()
        .merge(create_pos_closing_entry_read_routes(module.pos_closing_entry_service.clone()))
        .merge(create_pos_invoice_read_routes(module.pos_invoice_service.clone()))
        .merge(create_pos_invoice_item_read_routes(module.pos_invoice_item_service.clone()))
        .merge(create_pos_payment_read_routes(module.pos_payment_service.clone()))
        .merge(create_pos_profile_read_routes(module.pos_profile_service.clone()))
        .merge(create_pos_opening_entry_read_routes(module.pos_opening_entry_service.clone()))
        .merge(create_pos_cash_movement_read_routes(module.pos_cash_movement_service.clone()))
}

/// Get all routes (stateless) for the Pos module.
///
/// This is a convenience function that wraps routes with API versioning.
pub fn get_routes(module: &crate::PosModule) -> Router<()> {
    Router::new()
        .nest("/api/v1", create_stateless_routes(module))
}

// ============================================================
// PATTERN 2: STATEFUL ROUTES (WITH APPSTATE)
// ============================================================

/// Create stateful routes for the Pos module.
///
/// These routes require AppState and support custom handlers
/// that need access to services via dependency injection.
///
/// # Example
///
/// ```ignore
/// let module = PosModule::builder().with_database(pool).build()?;
/// let state = AppState::from_module(&module);
/// let routes = create_stateful_routes();
/// let app = Router::new().merge(routes).with_state(state);
/// ```
pub fn create_stateful_routes() -> Router<AppState> {
    Router::new()
        // Add custom handlers here that need AppState
        // .route("/custom", get(custom_handler))
}

/// Create combined routes (stateless CRUD + stateful custom handlers).
///
/// This merges both stateless CRUD routes and stateful custom routes.
pub fn create_combined_routes(module: &crate::PosModule) -> Router<AppState> {
    // First create stateless routes
    let crud_routes: Router<()> = create_stateless_routes(module);

    // Convert to stateful by adding state requirement
    // Note: The CRUD routes don't actually use the state,
    // but this allows them to be merged with stateful routes.
    let crud_routes_stateful: Router<AppState> = crud_routes.with_state(()).into();

    // Merge with stateful routes
    Router::new()
        .merge(crud_routes_stateful)
        .merge(create_stateful_routes())
}

/// Get all routes (stateful) for the Pos module.
///
/// This is a convenience function that wraps routes with API versioning.
pub fn get_routes_with_state(module: &crate::PosModule) -> Router<AppState> {
    Router::new()
        .nest("/api/v1", create_combined_routes(module))
}

// ============================================================
// CUSTOM HANDLERS
// ============================================================

// <<< CUSTOM HANDLERS START >>>
// Add custom route handlers here
// Example:
//
// use axum::extract::State;
// use axum::response::IntoResponse;
//
// pub async fn custom_handler(
//     State(state): State<AppState>,
// ) -> impl IntoResponse {
//     // Use state.user_service, etc.
//     "Custom response"
// }
// <<< CUSTOM HANDLERS END >>>