application capa

application-catalog

Forge catalog module. Sprint 60.

Forge catalog module. Sprint 60.

Tierapplication
Roleunclassified (baselined)
Pathcrates/application/catalog
Edition2024
Targetsapplication_catalog, pg_forge_catalog
Public items76 across 6 modules
Tests2

What it is for

application-catalog — Layer 3 module. Sprint 60.

Capabilities

CatalogModule

application-catalog — Layer 3 module. Sprint 60.

Item
pub struct CatalogModule
CatalogModule :: fn new() -> Self
CatalogModule :: fn name(& self) -> & 'static str
CatalogModule :: fn version(& self) -> & 'static str
CatalogModule :: fn migrations(& self) -> Vec <MigrationSet>
CatalogModule :: async fn migrate_pending(& self, pool : & PgPool) -> Result <u32, MigrationError>

api (other)

application-catalog HTTP routers. Sprint 65: extracted from rust-cms-engine.

Item
fn admin_router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,
fn public_router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,

api::catalog_admin (other)

Catalog + inventory + orders admin REST routers.

Item
fn router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,

api::catalog_customer (other)

Customer-facing catalog endpoints: browse catalog, manage

Item
fn router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,

CustomerCatalogItemView

Customer-facing catalog endpoints: browse catalog, manage

Item
CustomerCatalogItemView :: fn from(item : & CatalogItem) -> Self

verb:add

Catalog service — CatalogItem CRUD + basket lifecycle +

Item
async fn add_bundle_child(pool : & PgPool, input : CreateBundleItemInput,) -> Result <BundleItem, CatalogError>

verb:checkout

Catalog service — CatalogItem CRUD + basket lifecycle +

Item
async fn checkout(pool : & PgPool, basket_id : Uuid, party_id : Uuid, quoted_total : Decimal,) -> Result <Order, CatalogError>
async fn checkout_with_discount(pool : & PgPool, basket_id : Uuid, party_id : Uuid, quoted_total : Decimal, discount_rate : Decimal,) -> Result <Order, CatalogError>

verb:create

Catalog service — CatalogItem CRUD + basket lifecycle +

Item
async fn create_item(pool : & PgPool, input : CreateCatalogItemInput,) -> Result <CatalogItem, CatalogError>

verb:get

Catalog service — CatalogItem CRUD + basket lifecycle +

Item
async fn get_item(pool : & PgPool, id : Uuid) -> Result <CatalogItem, CatalogError>
async fn get_public_catalog_item(pool : & PgPool, id : Uuid) -> Result <CatalogItem, CatalogError>
async fn get_public_catalog_item_by_slug(pool : & PgPool, slug : & str,) -> Result <CatalogItem, CatalogError>

verb:list

Catalog service — CatalogItem CRUD + basket lifecycle +

Item
async fn list_items(pool : & PgPool, active_only : bool,) -> Result <Vec <CatalogItem>, CatalogError>
async fn list_public_catalog(pool : & PgPool) -> Result <Vec <CatalogItem>, CatalogError>
async fn list_bundle_children(pool : & PgPool, parent_item_id : Uuid,) -> Result <Vec <BundleItem>, CatalogError>
async fn list_category_attributes(pool : & PgPool, category_tag_id : Uuid,) -> Result <Vec <CategoryAttribute>, CatalogError>

verb:update

Catalog service — CatalogItem CRUD + basket lifecycle +

Item
async fn update_item(pool : & PgPool, id : Uuid, input : UpdateCatalogItemInput,) -> Result <CatalogItem, CatalogError>

verb:upsert

Catalog service — CatalogItem CRUD + basket lifecycle +

Item
async fn upsert_category_attribute(pool : & PgPool, input : UpsertCategoryAttributeInput,) -> Result <CategoryAttribute, CatalogError>

Basket

Catalog service — CatalogItem CRUD + basket lifecycle +

Item
pub struct Basket
async fn get_or_create_basket(pool : & PgPool, owner_id : Uuid, currency : & str,) -> Result <Basket, CatalogError>
async fn list_basket_items(pool : & PgPool, basket_id : Uuid,) -> Result <Vec <BasketItem>, CatalogError>
async fn add_basket_item(pool : & PgPool, basket_id : Uuid, catalog_item_id : Uuid, quantity : Decimal,) -> Result <BasketItem, CatalogError>
async fn remove_basket_item(pool : & PgPool, basket_item_id : Uuid) -> Result <(), CatalogError>

BasketItem

Catalog service — CatalogItem CRUD + basket lifecycle +

Item
pub struct BasketItem

BundleItem

Catalog service — CatalogItem CRUD + basket lifecycle +

Item
pub struct BundleItem

CatalogError

Catalog service — CatalogItem CRUD + basket lifecycle +

Item
pub enum CatalogError
async fn remove_bundle_child(pool : & PgPool, bundle_item_id : Uuid) -> Result <(), CatalogError>
async fn delete_category_attribute(pool : & PgPool, category_tag_id : Uuid, attribute_key : & str,) -> Result <(), CatalogError>
async fn soft_delete_item(pool : & PgPool, id : Uuid) -> Result <(), CatalogError>

CatalogItem

Catalog service — CatalogItem CRUD + basket lifecycle +

Item
pub struct CatalogItem
CatalogItem :: fn public_title_or_name(& self) -> & str
CatalogItem :: fn public_description_or_description(& self) -> & str
CatalogItem :: fn is_available(& self) -> bool

CategoryAttribute

Catalog service — CatalogItem CRUD + basket lifecycle +

Item
pub struct CategoryAttribute

CreateBundleItemInput

Catalog service — CatalogItem CRUD + basket lifecycle +

Item
pub struct CreateBundleItemInput

CreateCatalogItemInput

Catalog service — CatalogItem CRUD + basket lifecycle +

Item
pub struct CreateCatalogItemInput

Order

Catalog service — CatalogItem CRUD + basket lifecycle +

Item
pub struct Order
async fn list_orders(pool : & PgPool, status_filter : Option <& str>,) -> Result <Vec <Order>, CatalogError>
async fn get_order(pool : & PgPool, id : Uuid) -> Result <Order, CatalogError>
async fn process_order(pool : & PgPool, id : Uuid) -> Result <Order, CatalogError>
async fn fulfill_order(pool : & PgPool, id : Uuid) -> Result <Order, CatalogError>
async fn cancel_order(pool : & PgPool, id : Uuid) -> Result <Order, CatalogError>
async fn refund_order(pool : & PgPool, id : Uuid) -> Result <Order, CatalogError>

OrderItem

Catalog service — CatalogItem CRUD + basket lifecycle +

Item
pub struct OrderItem

UpdateCatalogItemInput

Catalog service — CatalogItem CRUD + basket lifecycle +

Item
pub struct UpdateCatalogItemInput

UpsertCategoryAttributeInput

Catalog service — CatalogItem CRUD + basket lifecycle +

Item
pub struct UpsertCategoryAttributeInput

services::inventory (other)

Inventory service — StockPlacement CRUD + reserve/release/

Item
async fn create_location(pool : & PgPool, input : CreateLocationInput,) -> Result <StorageLocation, CatalogError>
async fn build_breadcrumb(pool : & PgPool, id : Uuid) -> Result <String, CatalogError>
async fn is_descendant(pool : & PgPool, ancestor_id : Uuid, candidate_id : Uuid,) -> Result <bool, CatalogError>
async fn collect_subtree(pool : & PgPool, root_id : Uuid) -> Result <Vec <Uuid>, CatalogError>
async fn force_delete(pool : & PgPool, root_id : Uuid) -> Result <i64, CatalogError>
async fn create_placement(pool : & PgPool, input : CreatePlacementInput,) -> Result <StockPlacement, CatalogError>
async fn available_quantity(pool : & PgPool, item_id : Uuid) -> Result <i32, CatalogError>
async fn reserve_for_order(tx : & mut Transaction <'_, Postgres>, item_id : Uuid, qty : i32, order_id : Uuid,) -> Result <(), CatalogError>
async fn decrement_reservation(tx : & mut Transaction <'_, Postgres>, item_id : Uuid, _qty : i32, order_id : Uuid,) -> Result <(), CatalogError>
async fn release_reservations_for_order(tx : & mut Transaction <'_, Postgres>, order_id : Uuid,) -> Result <(), CatalogError>

BulkMoveError

Inventory service — StockPlacement CRUD + reserve/release/

Item
pub struct BulkMoveError

BulkMoveResponse

Inventory service — StockPlacement CRUD + reserve/release/

Item
pub struct BulkMoveResponse
async fn bulk_move(pool : & PgPool, location_ids : & Uuid, new_parent_id : Option <Uuid>,) -> Result <BulkMoveResponse, CatalogError>

CreateLocationInput

Inventory service — StockPlacement CRUD + reserve/release/

Item
pub struct CreateLocationInput

CreatePlacementInput

Inventory service — StockPlacement CRUD + reserve/release/

Item
pub struct CreatePlacementInput

InventoryLocation

Inventory service — StockPlacement CRUD + reserve/release/

Item
pub type InventoryLocation: StorageLocation

LocationSearchResult

Inventory service — StockPlacement CRUD + reserve/release/

Item
pub struct LocationSearchResult
async fn search_locations(pool : & PgPool, query : & str,) -> Result <Vec <LocationSearchResult>, CatalogError>

LocationWithCounts

Inventory service — StockPlacement CRUD + reserve/release/

Item
pub struct LocationWithCounts
async fn get_location_with_counts(pool : & PgPool, id : Uuid,) -> Result <LocationWithCounts, CatalogError>

StockPlacement

Inventory service — StockPlacement CRUD + reserve/release/

Item
pub struct StockPlacement
async fn list_placements_for_item(pool : & PgPool, item_id : Uuid,) -> Result <Vec <StockPlacement>, CatalogError>

StorageLocation

Inventory service — StockPlacement CRUD + reserve/release/

Item
pub struct StorageLocation
async fn list_locations(pool : & PgPool) -> Result <Vec <StorageLocation>, CatalogError>

How to use it

No examples/ target and no doctest in this crate's rustdoc. The tests listed under Verification are the closest executable usage.

Module structure

application_catalog

flowchart TD
  n_application_catalog["application_catalog"]
  n_application_catalog --> n_api["api"]
  n_api --> n_api__catalog_admin["catalog_admin"]
  n_api --> n_api__catalog_customer["catalog_customer"]
  n_application_catalog --> n_services["services"]
  n_services --> n_services__catalog["catalog"]
  n_services --> n_services__inventory["inventory"]

Public surface

`crate root`

ItemWhat it is
pub struct CatalogModule
CatalogModule :: fn new() -> Self
CatalogModule :: fn name(& self) -> & 'static str
CatalogModule :: fn version(& self) -> & 'static str
CatalogModule :: fn migrations(& self) -> Vec <MigrationSet>
CatalogModule :: async fn migrate_pending(& self, pool : & PgPool) -> Result <u32, MigrationError>

`api`

ItemWhat it is
fn admin_router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,Admin catalog/inventory/orders routes (mount under /api/v1/admin/*).
fn public_router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,Customer-facing catalog/basket/order routes (mount under /api/v1/customer/*).

`api::catalog_admin`

ItemWhat it is
fn router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,

`api::catalog_customer`

ItemWhat it is
CustomerCatalogItemView :: fn from(item : & CatalogItem) -> Self
fn router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,

`services::catalog`

ItemWhat it is
pub enum CatalogError
pub struct CatalogItem
CatalogItem :: fn public_title_or_name(& self) -> & strCustomer-facing title (public_title) when set; else falls back to the internal name.
CatalogItem :: fn public_description_or_description(& self) -> & strCustomer-facing description (public_description) when set; else falls back to the internal description.
CatalogItem :: fn is_available(& self) -> boolSprint 41 — replaces the prior is_active boolean
pub struct CreateCatalogItemInput
pub struct UpdateCatalogItemInput
pub struct Basket
pub struct BasketItem
pub struct Order
pub struct OrderItem
async fn list_items(pool : & PgPool, active_only : bool,) -> Result <Vec <CatalogItem>, CatalogError>
async fn get_item(pool : & PgPool, id : Uuid) -> Result <CatalogItem, CatalogError>
async fn list_public_catalog(pool : & PgPool) -> Result <Vec <CatalogItem>, CatalogError>
async fn get_public_catalog_item(pool : & PgPool, id : Uuid) -> Result <CatalogItem, CatalogError>
async fn get_public_catalog_item_by_slug(pool : & PgPool, slug : & str,) -> Result <CatalogItem, CatalogError>Slug-based lookup for storefront URLs (Sprint 41 — Gate 1.5 Q5)
async fn create_item(pool : & PgPool, input : CreateCatalogItemInput,) -> Result <CatalogItem, CatalogError>
async fn update_item(pool : & PgPool, id : Uuid, input : UpdateCatalogItemInput,) -> Result <CatalogItem, CatalogError>
pub struct BundleItem
pub struct CreateBundleItemInput
async fn add_bundle_child(pool : & PgPool, input : CreateBundleItemInput,) -> Result <BundleItem, CatalogError>
async fn list_bundle_children(pool : & PgPool, parent_item_id : Uuid,) -> Result <Vec <BundleItem>, CatalogError>
async fn remove_bundle_child(pool : & PgPool, bundle_item_id : Uuid) -> Result <(), CatalogError>
pub struct CategoryAttribute
pub struct UpsertCategoryAttributeInput
async fn list_category_attributes(pool : & PgPool, category_tag_id : Uuid,) -> Result <Vec <CategoryAttribute>, CatalogError>
async fn upsert_category_attribute(pool : & PgPool, input : UpsertCategoryAttributeInput,) -> Result <CategoryAttribute, CatalogError>Upsert by (category_tag_id, attribute_key)
async fn delete_category_attribute(pool : & PgPool, category_tag_id : Uuid, attribute_key : & str,) -> Result <(), CatalogError>
async fn soft_delete_item(pool : & PgPool, id : Uuid) -> Result <(), CatalogError>
async fn get_or_create_basket(pool : & PgPool, owner_id : Uuid, currency : & str,) -> Result <Basket, CatalogError>
async fn list_basket_items(pool : & PgPool, basket_id : Uuid,) -> Result <Vec <BasketItem>, CatalogError>
async fn add_basket_item(pool : & PgPool, basket_id : Uuid, catalog_item_id : Uuid, quantity : Decimal,) -> Result <BasketItem, CatalogError>
async fn remove_basket_item(pool : & PgPool, basket_item_id : Uuid) -> Result <(), CatalogError>
async fn checkout(pool : & PgPool, basket_id : Uuid, party_id : Uuid, quoted_total : Decimal,) -> Result <Order, CatalogError>Confirm a basket into an Order
async fn checkout_with_discount(pool : & PgPool, basket_id : Uuid, party_id : Uuid, quoted_total : Decimal, discount_rate : Decimal,) -> Result <Order, CatalogError>Same as checkout but freezes discount_rate onto the order at placement time
async fn list_orders(pool : & PgPool, status_filter : Option <& str>,) -> Result <Vec <Order>, CatalogError>
async fn get_order(pool : & PgPool, id : Uuid) -> Result <Order, CatalogError>
async fn process_order(pool : & PgPool, id : Uuid) -> Result <Order, CatalogError>
async fn fulfill_order(pool : & PgPool, id : Uuid) -> Result <Order, CatalogError>
async fn cancel_order(pool : & PgPool, id : Uuid) -> Result <Order, CatalogError>
async fn refund_order(pool : & PgPool, id : Uuid) -> Result <Order, CatalogError>

`services::inventory`

ItemWhat it is
pub struct StorageLocationStorage location — aligned with domain_storage_locations::StorageLocation (Sprint 42 — Gate 1.5 Q1)
pub type InventoryLocation: StorageLocationDeprecated alias retained for back-compat — Sprint 25's flat InventoryLocation was replaced by StorageLocation in Sprint 42
pub struct StockPlacement
pub struct CreatePlacementInput
pub struct CreateLocationInput
async fn list_locations(pool : & PgPool) -> Result <Vec <StorageLocation>, CatalogError>
async fn create_location(pool : & PgPool, input : CreateLocationInput,) -> Result <StorageLocation, CatalogError>
pub struct LocationWithCountsView-model: a storage location enriched with denormalized counts + primary photo URL
pub struct LocationSearchResultView-model: a typeahead search hit with formatted breadcrumb path.
pub struct BulkMoveResponseView-model: outcome of a bulk-move operation
pub struct BulkMoveError
async fn build_breadcrumb(pool : & PgPool, id : Uuid) -> Result <String, CatalogError>Build a breadcrumb path string by walking parent_id up to the root
async fn is_descendant(pool : & PgPool, ancestor_id : Uuid, candidate_id : Uuid,) -> Result <bool, CatalogError>Cycle-detection helper: returns true if candidate_id is a descendant of ancestor_id (or equals it)
async fn collect_subtree(pool : & PgPool, root_id : Uuid) -> Result <Vec <Uuid>, CatalogError>Collect all descendant ids (inclusive of root) via WITH RECURSIVE
async fn search_locations(pool : & PgPool, query : & str,) -> Result <Vec <LocationSearchResult>, CatalogError>4-tier ranked typeahead search across name + code: 1
async fn get_location_with_counts(pool : & PgPool, id : Uuid,) -> Result <LocationWithCounts, CatalogError>Single-location fetch enriched with denormalized counts.
async fn bulk_move(pool : & PgPool, location_ids : & Uuid, new_parent_id : Option <Uuid>,) -> Result <BulkMoveResponse, CatalogError>Bulk-move N locations under a new parent
async fn force_delete(pool : & PgPool, root_id : Uuid) -> Result <i64, CatalogError>Force-delete a location and all descendants (soft-delete cascade)
async fn list_placements_for_item(pool : & PgPool, item_id : Uuid,) -> Result <Vec <StockPlacement>, CatalogError>
async fn create_placement(pool : & PgPool, input : CreatePlacementInput,) -> Result <StockPlacement, CatalogError>
async fn available_quantity(pool : & PgPool, item_id : Uuid) -> Result <i32, CatalogError>Total active quantity available for sale (sums all active placements for an item, ignoring reserved + removed).
async fn reserve_for_order(tx : & mut Transaction <'_, Postgres>, item_id : Uuid, qty : i32, order_id : Uuid,) -> Result <(), CatalogError>Reserve qty units of item_id for the given order
async fn decrement_reservation(tx : & mut Transaction <'_, Postgres>, item_id : Uuid, _qty : i32, order_id : Uuid,) -> Result <(), CatalogError>Decrement (remove) the reservation created for an order on fulfill
async fn release_reservations_for_order(tx : & mut Transaction <'_, Postgres>, order_id : Uuid,) -> Result <(), CatalogError>Release ALL reservations for an order (cancel flow)

No pub use re-exports: every item above is declared in this crate.

Boundary

Reaches into domain, platform.

Shares tier application with 120 other crates: application-agreements, application-ai, application-analytics, application-approvals, application-assessments, application-audit-log, application-auth, application-billing, … (120 total).

_What this crate deliberately does NOT own is a judgment. No committed registry records one for it, so none is stated here._

Where it sits

Tier (ontology)application
Architectural role (taxonomy)unclassified (baselined)
Locationcrates/application/catalog
Vocabulary in force (lexicon)current

Tier flow. Which tiers this crate's own edges cross.

flowchart LR
  n_application["application"] --> n_domain["domain"]
  n_application["application"] --> n_platform["platform"]

Dependencies

Runtime, in this workspace.

CrateTierOptionalOnly on
`application-auth`applicationnoalways
`application-core`applicationnoalways
`domain-catalog`domainnoalways
`domain-storage-locations`domainnoalways
`platform-dto`platformnoalways

Runtime, from outside the workspace.

CrateRequirementFeaturesOptionalOnly on
async-trait^0.1noalways
axum^0.7multipartnoalways
chrono^0.4serdenoalways
rust_decimal^1serdenoalways
serde^1derivenoalways
serde_json^1noalways
sqlx^0.8runtime-tokio, postgres, chrono, uuid, json, rust_decimal, … (7 total)noalways
thiserror^2noalways
tower-sessions^0.13noalways
tracing^0.1noalways
uuid^1v4, v7, serde, jsnoalways

Development, in this workspace.

CrateTierOptionalOnly on
`application-engine`applicationnoalways
`application-parties`applicationnoalways

Development, from outside the workspace.

CrateRequirementFeaturesOptionalOnly on
tokio^1fullnoalways

Build. None.

Depended on by. 2 workspace crates.

Signal flow — what reaches this crate, and what it reaches.

flowchart LR
  n_application_fulfillment["application-fulfillment"] -->|uses| SELF
  n_application_pricing["application-pricing"] -->|uses| SELF
  SELF["application-catalog"]
  SELF -->|development| n_application_engine["application-engine"]
  SELF -->|development| n_application_parties["application-parties"]
  SELF -->|runtime| n_application_auth["application-auth"]
  SELF -->|runtime| n_application_core["application-core"]
  SELF -->|runtime| n_domain_catalog["domain-catalog"]
  SELF -->|runtime| n_domain_storage_locations["domain-storage-locations"]
  SELF -->|runtime| n_platform_dto["platform-dto"]
  classDef self fill:#1f883d,stroke:#1f883d,color:#fff;
  class SELF self;

Feature flags

No Cargo features are defined: every capability is unconditional, so no consumer can receive a half-wired crate.

Targets

KindNameSource
libapplication_catalog`src/lib.rs`
testpg_forge_catalog`tests/pg_forge_catalog.rs`

Error model

Error typeNamed by
BulkMoveErrordeclared, no public signature returns it
CatalogErroradd_basket_item, add_bundle_child, available_quantity, build_breadcrumb, bulk_move, cancel_order, … (41 total)

Operational characteristics

PropertyEvidence
async public surfaceyes
async runtimenone detected
database accessyes
network I/Oyes
unsafe codenone detected
environment variablesyes

No unsafe block, unsafe fn, unsafe impl or unsafe trait was found by the parser anywhere in this crate's source.

Configuration

VariableRead in
CARGO_PKG_VERSIONsrc/lib.rs

2 workspace crates depend on this one: application-fulfillment, application-pricing.

Verification

KindCount
Unit tests1
Integration tests1
Examples0
Doctests0

Evidence by module. How often each public module is named by something executable.

ModuleTestsExamplesConsumers
crate root100
api200
api::catalog_admin100
api::catalog_customer100
services::catalog3808
services::inventory2400

What the tests establish, by name:

Documentation coverage

MeasureDocumentedTotal
Public items with rustdoc2576
Public modules with a //! block56
pie showData
    title Public items with rustdoc
    "Documented" : 25
    "No rustdoc detected" : 51

Metrics

MetricValue
Rust source files7
Source lines2742
Code lines2170
Public API items76
Public modules6
Tests2
Examples0
Cargo features0
Direct runtime dependencies16
Workspace reverse dependencies2
pie showData
    title Public API by kind
    "enum" : 1
    "function" : 45
    "method" : 9
    "struct" : 20
    "type alias" : 1
pie showData
    title Rust source composition
    "Code" : 2170
    "Blank or comment" : 572

Generation

Rendered by tools-corpus corpus readme from repository evidence alone, renderer schema 2, lexicon current. No model, network service or database was consulted. Regenerate with tools-corpus corpus readme --write; verify with --check.

Todas las application · Manual