1use axum::response::Html;
6use axum::{Json, Router, routing::get};
7use utoipa::OpenApi;
8
9use crate::dto::{
10 AddressDto, CreateCustomerRequest, CreateInvoiceRequest, CreateOrderItemRequest,
11 CreateOrderRequest, CreatePaymentRequest, CreateProductRequest, CreateRefundRequest,
12 CreateReturnItemRequest, CreateReturnRequest, CreateShipmentRequest, CustomerListResponse,
13 CustomerResponse, HealthResponse, InventoryAdjustRequest, InventoryItemResponse,
14 InventoryListResponse, InventoryResponse, InvoiceListResponse, InvoiceResponse,
15 OrderItemResponse, OrderListResponse, OrderResponse, PaymentListResponse, PaymentResponse,
16 ProductListResponse, ProductResponse, ReadyResponse, RecordInvoicePaymentRequest,
17 ReturnListResponse, ReturnResponse, ShipmentListResponse, ShipmentResponse,
18 TenantCacheResponse, UpdateCustomerRequest, UpdateProductRequest, VersionResponse,
19};
20use crate::error::ErrorBody;
21use crate::routes::a2a_credit::{
22 CreateCreditTermsRequest, CreditAmountRequest, CreditTermsResponse,
23};
24use crate::routes::a2a_messaging::{MessageResponse, SendMessageRequest};
25use crate::routes::currency::{
26 ConversionResponse, ConvertCurrencyRequest, ExchangeRateListResponse, ExchangeRateResponse,
27 SetExchangeRateRequest,
28};
29use crate::routes::gift_cards::{CreateGiftCardRequest, GiftCardListResponse, GiftCardResponse};
30use crate::routes::loyalty::{
31 CreateLoyaltyProgramRequest, EnrollCustomerRequest, LoyaltyAccountResponse,
32 LoyaltyProgramListResponse, LoyaltyProgramResponse,
33};
34use crate::routes::negotiations::{
35 CounterOfferRequest, CreateNegotiationRequest, NegotiationResponse,
36};
37use crate::routes::promotions::{CreatePromotionRequest, PromotionListResponse, PromotionResponse};
38use crate::routes::reviews::{CreateReviewRequest, ReviewListResponse, ReviewResponse};
39use crate::routes::segments::{CreateSegmentRequest, SegmentListResponse, SegmentResponse};
40use crate::routes::shipping_zones::{
41 CreateShippingZoneRequest, ShippingZoneListResponse, ShippingZoneResponse,
42};
43use crate::routes::store_credits::{
44 AdjustStoreCreditRequest, CreateStoreCreditRequest, StoreCreditListResponse,
45 StoreCreditResponse,
46};
47use crate::routes::subscriptions::{
48 CreateSubscriptionRequest, SubscriptionListResponse, SubscriptionResponse,
49};
50use crate::routes::warranties::{CreateWarrantyRequest, WarrantyListResponse, WarrantyResponse};
51use crate::routes::wishlists::{
52 AddWishlistItemRequest, CreateWishlistRequest, WishlistItemResponse, WishlistListResponse,
53 WishlistResponse,
54};
55use crate::state::AppState;
56
57#[derive(OpenApi)]
59#[openapi(
60 info(
61 title = "StateSet Commerce API",
62 description = "REST API for the StateSet embedded commerce engine.",
63 version = "1.0.4",
64 contact(name = "StateSet", url = "https://stateset.io"),
65 license(name = "MIT", url = "https://opensource.org/licenses/MIT"),
66 ),
67 paths(
68 crate::routes::health::health,
70 crate::routes::health::readiness,
71 crate::routes::health::deep_health,
72 crate::routes::health::metrics,
73 crate::routes::health::version,
74 crate::routes::orders::create_order,
76 crate::routes::orders::get_order,
77 crate::routes::orders::list_orders,
78 crate::routes::orders::cancel_order,
79 crate::routes::orders::ship_order,
80 crate::routes::customers::create_customer,
82 crate::routes::customers::get_customer,
83 crate::routes::customers::list_customers,
84 crate::routes::customers::update_customer,
85 crate::routes::customers::delete_customer,
86 crate::routes::products::create_product,
88 crate::routes::products::get_product,
89 crate::routes::products::list_products,
90 crate::routes::products::update_product,
91 crate::routes::products::delete_product,
92 crate::routes::inventory::list_inventory,
94 crate::routes::inventory::get_stock,
95 crate::routes::inventory::adjust_stock,
96 crate::routes::returns::create_return,
98 crate::routes::returns::get_return,
99 crate::routes::returns::list_returns,
100 crate::routes::returns::approve_return,
101 crate::routes::shipments::create_shipment,
103 crate::routes::shipments::list_shipments,
104 crate::routes::shipments::get_shipment,
105 crate::routes::shipments::deliver_shipment,
106 crate::routes::payments::create_payment,
108 crate::routes::payments::list_payments,
109 crate::routes::payments::get_payment,
110 crate::routes::payments::complete_payment,
111 crate::routes::payments::create_refund,
112 crate::routes::invoices::create_invoice,
114 crate::routes::invoices::list_invoices,
115 crate::routes::invoices::get_invoice,
116 crate::routes::invoices::send_invoice,
117 crate::routes::invoices::record_invoice_payment,
118 crate::routes::reviews::create_review,
120 crate::routes::reviews::get_review,
121 crate::routes::reviews::list_reviews,
122 crate::routes::reviews::delete_review,
123 crate::routes::wishlists::create_wishlist,
125 crate::routes::wishlists::get_wishlist,
126 crate::routes::wishlists::list_wishlists,
127 crate::routes::wishlists::delete_wishlist,
128 crate::routes::wishlists::add_item,
129 crate::routes::wishlists::remove_item,
130 crate::routes::gift_cards::create_gift_card,
132 crate::routes::gift_cards::get_gift_card,
133 crate::routes::gift_cards::list_gift_cards,
134 crate::routes::gift_cards::charge_gift_card,
135 crate::routes::gift_cards::refund_gift_card,
136 crate::routes::gift_cards::disable_gift_card,
137 crate::routes::loyalty::create_program,
139 crate::routes::loyalty::list_programs,
140 crate::routes::loyalty::enroll_customer,
141 crate::routes::loyalty::get_account,
142 crate::routes::negotiations::create_negotiation,
144 crate::routes::negotiations::get_negotiation,
145 crate::routes::negotiations::counter_offer,
146 crate::routes::negotiations::accept_negotiation,
147 crate::routes::negotiations::reject_negotiation,
148 crate::routes::a2a_messaging::send_message,
150 crate::routes::a2a_messaging::list_messages,
151 crate::routes::a2a_messaging::acknowledge_message,
152 crate::routes::a2a_credit::create_terms,
154 crate::routes::a2a_credit::list_terms,
155 crate::routes::a2a_credit::get_terms,
156 crate::routes::a2a_credit::charge_credit,
157 crate::routes::a2a_credit::record_payment,
158 crate::routes::subscriptions::create_subscription,
160 crate::routes::subscriptions::list_subscriptions,
161 crate::routes::subscriptions::get_subscription,
162 crate::routes::subscriptions::pause_subscription,
163 crate::routes::subscriptions::resume_subscription,
164 crate::routes::subscriptions::cancel_subscription,
165 crate::routes::store_credits::create_store_credit,
167 crate::routes::store_credits::list_store_credits,
168 crate::routes::store_credits::get_store_credit,
169 crate::routes::store_credits::adjust_store_credit,
170 crate::routes::store_credits::apply_store_credit,
171 crate::routes::promotions::create_promotion,
173 crate::routes::promotions::list_promotions,
174 crate::routes::promotions::get_promotion,
175 crate::routes::promotions::activate_promotion,
176 crate::routes::promotions::deactivate_promotion,
177 crate::routes::currency::list_rates,
179 crate::routes::currency::set_rate,
180 crate::routes::currency::convert_currency,
181 crate::routes::warranties::create_warranty,
183 crate::routes::warranties::list_warranties,
184 crate::routes::warranties::get_warranty,
185 crate::routes::segments::create_segment,
187 crate::routes::segments::list_segments,
188 crate::routes::segments::get_segment,
189 crate::routes::segments::delete_segment,
190 crate::routes::segments::add_member,
191 crate::routes::segments::remove_member,
192 crate::routes::shipping_zones::create_zone,
194 crate::routes::shipping_zones::list_zones,
195 crate::routes::shipping_zones::get_zone,
196 crate::routes::shipping_zones::delete_zone,
197 crate::routes::events::event_stream,
199 crate::routes::channels::create,
202 crate::routes::channels::list,
203 crate::routes::channels::get_one,
204 crate::routes::channels::update,
205 crate::routes::channels::delete_one,
206 crate::routes::channels::set_lock,
207 crate::routes::companies::create,
209 crate::routes::companies::list,
210 crate::routes::companies::get_one,
211 crate::routes::companies::delete_one,
212 crate::routes::companies::create_contact,
213 crate::routes::companies::list_contacts,
214 crate::routes::transfer_orders::create,
216 crate::routes::transfer_orders::list,
217 crate::routes::transfer_orders::get_one,
218 crate::routes::transfer_orders::ship,
219 crate::routes::transfer_orders::receive,
220 crate::routes::transfer_orders::cancel,
221 crate::routes::units_of_measure::create_class,
223 crate::routes::units_of_measure::list_classes,
224 crate::routes::units_of_measure::create_uom,
225 crate::routes::units_of_measure::list_uoms,
226 crate::routes::units_of_measure::create_rule,
227 crate::routes::units_of_measure::list_rules,
228 crate::routes::production_batches::create,
230 crate::routes::production_batches::list,
231 crate::routes::production_batches::get_one,
232 crate::routes::production_batches::delete_one,
233 crate::routes::production_batches::add_work_orders,
234 crate::routes::supplier_skus::create,
236 crate::routes::supplier_skus::list,
237 crate::routes::supplier_skus::get_one,
238 crate::routes::supplier_skus::delete_one,
239 crate::routes::vendor_returns::create,
241 crate::routes::vendor_returns::list,
242 crate::routes::vendor_returns::get_one,
243 crate::routes::vendor_returns::submit,
244 crate::routes::vendor_returns::process,
245 crate::routes::vendor_returns::cancel,
246 crate::routes::vendor_credits::create,
248 crate::routes::vendor_credits::list,
249 crate::routes::vendor_credits::get_one,
250 crate::routes::vendor_credits::apply,
251 crate::routes::vendor_credits::cancel,
252 crate::routes::payment_obligations::create,
254 crate::routes::payment_obligations::list,
255 crate::routes::payment_obligations::dashboard,
256 crate::routes::payment_obligations::get_one,
257 crate::routes::payment_obligations::record_payment,
258 crate::routes::payment_obligations::set_status,
259 crate::routes::payment_obligations::link_bill,
260 crate::routes::prepayments::create,
262 crate::routes::prepayments::list,
263 crate::routes::prepayments::get_one,
264 crate::routes::prepayments::apply,
265 crate::routes::prepayments::refund,
266 crate::routes::price_levels::create,
268 crate::routes::price_levels::list,
269 crate::routes::price_levels::get_one,
270 crate::routes::price_levels::update,
271 crate::routes::price_levels::delete_one,
272 crate::routes::price_levels::set_entry,
273 crate::routes::price_levels::list_entries,
274 crate::routes::price_schedules::create,
276 crate::routes::price_schedules::list,
277 crate::routes::price_schedules::resolve,
278 crate::routes::price_schedules::get_one,
279 crate::routes::price_schedules::delete_one,
280 crate::routes::price_schedules::set_entry,
281 crate::routes::price_schedules::list_entries,
282 crate::routes::activity_logs::record,
284 crate::routes::activity_logs::list,
285 crate::routes::activity_logs::get_one,
286 crate::routes::activity_logs::history,
287 crate::routes::integration_mappings::create,
289 crate::routes::integration_mappings::bulk_create,
290 crate::routes::integration_mappings::list,
291 crate::routes::integration_mappings::resolve,
292 crate::routes::integration_mappings::get_one,
293 crate::routes::integration_mappings::update,
294 crate::routes::integration_mappings::delete_one,
295 crate::routes::integration_field_mappings::create,
297 crate::routes::integration_field_mappings::bulk_create,
298 crate::routes::integration_field_mappings::bulk_delete,
299 crate::routes::integration_field_mappings::list,
300 crate::routes::integration_field_mappings::groups,
301 crate::routes::integration_field_mappings::get_one,
302 crate::routes::integration_field_mappings::update,
303 crate::routes::integration_field_mappings::delete_one,
304 crate::routes::inbound_shipments::create,
306 crate::routes::inbound_shipments::list,
307 crate::routes::inbound_shipments::get_one,
308 crate::routes::inbound_shipments::mark_in_transit,
309 crate::routes::inbound_shipments::mark_arrived,
310 crate::routes::inbound_shipments::receive,
311 crate::routes::inbound_shipments::cancel,
312 crate::routes::purgatory::ingest,
314 crate::routes::purgatory::list,
315 crate::routes::purgatory::get_one,
316 crate::routes::purgatory::post_order,
317 crate::routes::purgatory::map_line,
318 crate::routes::purgatory::delete_one,
319 crate::routes::print_stations::pair,
321 crate::routes::print_stations::list_stations,
322 crate::routes::print_stations::revoke,
323 crate::routes::print_stations::enqueue,
324 crate::routes::print_stations::next_job,
325 crate::routes::print_stations::list_jobs,
326 crate::routes::print_stations::complete_job,
327 crate::routes::edi_documents::create,
329 crate::routes::edi_documents::list,
330 crate::routes::edi_documents::summary,
331 crate::routes::edi_documents::get_one,
332 crate::routes::edi_documents::set_status,
333 crate::routes::topology_snapshots::capture,
335 crate::routes::topology_snapshots::list,
336 crate::routes::topology_snapshots::latest,
337 crate::routes::topology_snapshots::get_one,
338 crate::routes::topology_snapshots::delete_one,
339 crate::routes::stock_snapshots::capture,
341 crate::routes::stock_snapshots::list,
342 crate::routes::stock_snapshots::latest,
343 crate::routes::stock_snapshots::get_one,
344 crate::routes::stock_snapshots::delete_one,
345 crate::routes::reports::inventory_aging,
347 crate::routes::reports::sales_by_channel,
348 crate::routes::reports::transaction_cogs,
349 crate::routes::reports::close_the_books,
350 crate::routes::reports::consumption,
351 crate::routes::carts::create,
353 crate::routes::carts::list,
354 crate::routes::carts::get_one,
355 crate::routes::carts::add_item,
356 crate::routes::carts::update_item,
357 crate::routes::carts::remove_item,
358 crate::routes::carts::set_shipping,
359 crate::routes::carts::set_payment,
360 crate::routes::carts::complete,
361 crate::routes::carts::cancel,
362 crate::routes::backorders::create,
364 crate::routes::backorders::list,
365 crate::routes::backorders::get_one,
366 crate::routes::backorders::fulfill,
367 crate::routes::backorders::cancel,
368 crate::routes::purchase_orders::create,
370 crate::routes::purchase_orders::list,
371 crate::routes::purchase_orders::get_one,
372 crate::routes::purchase_orders::update,
373 crate::routes::purchase_orders::submit,
374 crate::routes::purchase_orders::approve,
375 crate::routes::purchase_orders::send,
376 crate::routes::purchase_orders::acknowledge,
377 crate::routes::purchase_orders::hold,
378 crate::routes::purchase_orders::complete,
379 crate::routes::purchase_orders::cancel,
380 crate::routes::purchase_orders::receive,
381 crate::routes::purchase_orders::get_items,
382 crate::routes::purchase_orders::create_supplier,
383 crate::routes::purchase_orders::list_suppliers,
384 crate::routes::purchase_orders::get_supplier,
385 crate::routes::purchase_orders::update_supplier,
386 crate::routes::purchase_orders::delete_supplier,
387 crate::routes::general_ledger::create_account,
389 crate::routes::general_ledger::list_accounts,
390 crate::routes::general_ledger::get_account,
391 crate::routes::general_ledger::create_journal_entry,
392 crate::routes::general_ledger::list_journal_entries,
393 crate::routes::general_ledger::get_journal_entry,
394 crate::routes::general_ledger::post_journal_entry,
395 crate::routes::general_ledger::void_journal_entry,
396 crate::routes::general_ledger::reverse_journal_entry,
397 crate::routes::general_ledger::trial_balance,
398 crate::routes::general_ledger::balance_sheet,
399 crate::routes::general_ledger::income_statement,
400 crate::routes::general_ledger::create_period,
401 crate::routes::general_ledger::list_periods,
402 crate::routes::general_ledger::open_period,
403 crate::routes::general_ledger::close_period,
404 crate::routes::general_ledger::lock_period,
405 crate::routes::general_ledger::reopen_period,
406 crate::routes::general_ledger::revalue,
407 crate::routes::general_ledger::close_month,
408 crate::routes::fixed_assets::create,
410 crate::routes::fixed_assets::list,
411 crate::routes::fixed_assets::get_one,
412 crate::routes::fixed_assets::update,
413 crate::routes::fixed_assets::place_in_service,
414 crate::routes::fixed_assets::dispose,
415 crate::routes::fixed_assets::write_off,
416 crate::routes::fixed_assets::generate_schedule,
417 crate::routes::fixed_assets::get_schedule,
418 crate::routes::fixed_assets::post_depreciation,
419 crate::routes::revenue_recognition::create_contract,
421 crate::routes::revenue_recognition::list_contracts,
422 crate::routes::revenue_recognition::get_contract,
423 crate::routes::revenue_recognition::update_contract,
424 crate::routes::revenue_recognition::list_obligations,
425 crate::routes::revenue_recognition::generate_schedule,
426 crate::routes::revenue_recognition::get_schedule,
427 crate::routes::revenue_recognition::recognize,
428 crate::routes::accounts_payable::create_bill,
430 crate::routes::accounts_payable::list_bills,
431 crate::routes::accounts_payable::get_bill,
432 crate::routes::accounts_payable::approve_bill,
433 crate::routes::accounts_payable::cancel_bill,
434 crate::routes::accounts_payable::dispute_bill,
435 crate::routes::accounts_payable::create_payment,
436 crate::routes::accounts_payable::void_payment,
437 crate::routes::accounts_payable::create_payment_run,
438 crate::routes::accounts_payable::approve_payment_run,
439 crate::routes::accounts_payable::process_payment_run,
440 crate::routes::accounts_payable::cancel_payment_run,
441 crate::routes::accounts_payable::aging,
442 crate::routes::accounts_payable::three_way_match_bill,
443 crate::routes::accounts_receivable::aging_summary,
445 crate::routes::accounts_receivable::aging_report,
446 crate::routes::accounts_receivable::customer_aging,
447 crate::routes::accounts_receivable::apply_payment,
448 crate::routes::accounts_receivable::unapply_payment,
449 crate::routes::accounts_receivable::create_credit_memo,
450 crate::routes::accounts_receivable::list_credit_memos,
451 crate::routes::accounts_receivable::apply_credit_memo,
452 crate::routes::accounts_receivable::create_write_off,
453 crate::routes::accounts_receivable::reverse_write_off,
454 crate::routes::accounts_receivable::send_dunning,
455 crate::routes::accounts_receivable::customer_statement,
456 crate::routes::accounts_receivable::record_collection_activity,
457 crate::routes::accounts_receivable::list_collection_activities,
458 crate::routes::accounts_receivable::invoices_due_for_dunning,
459 crate::routes::warehouse::create_warehouse,
461 crate::routes::warehouse::list_warehouses,
462 crate::routes::warehouse::get_warehouse,
463 crate::routes::warehouse::update_warehouse,
464 crate::routes::warehouse::delete_warehouse,
465 crate::routes::warehouse::create_location,
466 crate::routes::warehouse::list_locations,
467 crate::routes::warehouse::get_location,
468 crate::routes::warehouse::get_location_inventory,
469 crate::routes::warehouse::adjust_inventory,
470 crate::routes::warehouse::move_inventory,
471 crate::routes::warehouse::create_cycle_count,
472 crate::routes::warehouse::list_cycle_counts,
473 crate::routes::warehouse::get_cycle_count,
474 crate::routes::warehouse::start_cycle_count,
475 crate::routes::warehouse::record_cycle_counts,
476 crate::routes::warehouse::complete_cycle_count,
477 crate::routes::warehouse::cancel_cycle_count,
478 crate::routes::fulfillment::create_wave,
480 crate::routes::fulfillment::list_waves,
481 crate::routes::fulfillment::get_wave,
482 crate::routes::fulfillment::release_wave,
483 crate::routes::fulfillment::list_picks,
484 crate::routes::fulfillment::assign_pick,
485 crate::routes::fulfillment::complete_pick,
486 crate::routes::fulfillment::list_packs,
487 crate::routes::fulfillment::complete_pack,
488 crate::routes::fulfillment::add_carton,
489 crate::routes::fulfillment::list_cartons,
490 crate::routes::fulfillment::list_ships,
491 crate::routes::fulfillment::complete_ship,
492 crate::routes::receiving::create_receipt,
494 crate::routes::receiving::list_receipts,
495 crate::routes::receiving::get_receipt,
496 crate::routes::receiving::list_receipt_items,
497 crate::routes::receiving::start_receiving,
498 crate::routes::receiving::receive_items,
499 crate::routes::receiving::complete_receiving,
500 crate::routes::receiving::cancel_receipt,
501 crate::routes::receiving::create_put_away,
502 crate::routes::receiving::list_put_aways,
503 crate::routes::receiving::get_put_away,
504 crate::routes::receiving::complete_put_away,
505 crate::routes::work_orders::create,
507 crate::routes::work_orders::list,
508 crate::routes::work_orders::get_one,
509 crate::routes::work_orders::update,
510 crate::routes::work_orders::start,
511 crate::routes::work_orders::complete,
512 crate::routes::work_orders::hold,
513 crate::routes::work_orders::resume,
514 crate::routes::work_orders::cancel,
515 crate::routes::work_orders::add_task,
516 crate::routes::work_orders::list_tasks,
517 crate::routes::work_orders::start_task,
518 crate::routes::work_orders::complete_task,
519 crate::routes::quality::create_inspection,
521 crate::routes::quality::list_inspections,
522 crate::routes::quality::get_inspection,
523 crate::routes::quality::start_inspection,
524 crate::routes::quality::record_inspection_result,
525 crate::routes::quality::complete_inspection,
526 crate::routes::quality::create_ncr,
527 crate::routes::quality::list_ncrs,
528 crate::routes::quality::get_ncr,
529 crate::routes::quality::disposition_ncr,
530 crate::routes::quality::close_ncr,
531 crate::routes::quality::create_hold,
532 crate::routes::quality::list_holds,
533 crate::routes::quality::get_hold,
534 crate::routes::quality::release_hold,
535 crate::routes::bom::create,
537 crate::routes::bom::list,
538 crate::routes::bom::get_one,
539 crate::routes::bom::update,
540 crate::routes::bom::delete_one,
541 crate::routes::bom::activate,
542 crate::routes::bom::add_component,
543 crate::routes::bom::list_components,
544 crate::routes::lots::create,
546 crate::routes::lots::list,
547 crate::routes::lots::expiring,
548 crate::routes::lots::get_one,
549 crate::routes::lots::consume,
550 crate::routes::lots::reserve,
551 crate::routes::lots::release_reservation,
552 crate::routes::lots::quarantine,
553 crate::routes::lots::release_quarantine,
554 crate::routes::serials::create,
556 crate::routes::serials::list,
557 crate::routes::serials::get_one,
558 crate::routes::serials::reserve,
559 crate::routes::serials::release_reservation,
560 crate::routes::serials::ship,
561 crate::routes::serials::mark_returned,
562 crate::routes::serials::scrap,
563 ),
564 components(schemas(
565 CreateOrderRequest,
567 CreateOrderItemRequest,
568 AddressDto,
569 CreateCustomerRequest,
570 CreateProductRequest,
571 InventoryAdjustRequest,
572 CreateReturnRequest,
573 CreateReturnItemRequest,
574 UpdateCustomerRequest,
575 UpdateProductRequest,
576 CreateShipmentRequest,
577 CreatePaymentRequest,
578 CreateRefundRequest,
579 CreateInvoiceRequest,
580 RecordInvoicePaymentRequest,
581 OrderResponse,
583 OrderItemResponse,
584 OrderListResponse,
585 CustomerResponse,
586 CustomerListResponse,
587 ProductResponse,
588 ProductListResponse,
589 InventoryResponse,
590 InventoryItemResponse,
591 InventoryListResponse,
592 ShipmentResponse,
593 ShipmentListResponse,
594 PaymentResponse,
595 PaymentListResponse,
596 InvoiceResponse,
597 InvoiceListResponse,
598 ReturnResponse,
599 ReturnListResponse,
600 HealthResponse,
601 ReadyResponse,
602 VersionResponse,
603 TenantCacheResponse,
604 CreateReviewRequest,
606 ReviewResponse,
607 ReviewListResponse,
608 CreateWishlistRequest,
610 AddWishlistItemRequest,
611 WishlistResponse,
612 WishlistItemResponse,
613 WishlistListResponse,
614 CreateGiftCardRequest,
616 GiftCardResponse,
617 GiftCardListResponse,
618 CreateLoyaltyProgramRequest,
620 EnrollCustomerRequest,
621 LoyaltyProgramResponse,
622 LoyaltyProgramListResponse,
623 LoyaltyAccountResponse,
624 CreateNegotiationRequest,
626 CounterOfferRequest,
627 NegotiationResponse,
628 SendMessageRequest,
630 MessageResponse,
631 CreateCreditTermsRequest,
633 CreditAmountRequest,
634 CreditTermsResponse,
635 CreateSubscriptionRequest,
637 SubscriptionResponse,
638 SubscriptionListResponse,
639 CreateStoreCreditRequest,
641 AdjustStoreCreditRequest,
642 StoreCreditResponse,
643 StoreCreditListResponse,
644 CreatePromotionRequest,
646 PromotionResponse,
647 PromotionListResponse,
648 SetExchangeRateRequest,
650 ConvertCurrencyRequest,
651 ExchangeRateResponse,
652 ExchangeRateListResponse,
653 ConversionResponse,
654 CreateWarrantyRequest,
656 WarrantyResponse,
657 WarrantyListResponse,
658 CreateSegmentRequest,
660 SegmentResponse,
661 SegmentListResponse,
662 CreateShippingZoneRequest,
664 ShippingZoneResponse,
665 ShippingZoneListResponse,
666 ErrorBody,
668 )),
669 tags(
670 (name = "health", description = "Health check endpoints"),
671 (name = "orders", description = "Order lifecycle management"),
672 (name = "customers", description = "Customer management"),
673 (name = "products", description = "Product catalog"),
674 (name = "inventory", description = "Stock and inventory management"),
675 (name = "returns", description = "Return request processing"),
676 (name = "shipments", description = "Shipment tracking and management"),
677 (name = "payments", description = "Payment transaction management"),
678 (name = "invoices", description = "Invoice management"),
679 (name = "reviews", description = "Product review management"),
680 (name = "wishlists", description = "Customer wishlist management"),
681 (name = "gift_cards", description = "Gift card management"),
682 (name = "loyalty", description = "Loyalty program management"),
683 (name = "negotiations", description = "Agent-to-agent price negotiation"),
684 (name = "a2a", description = "Agent-to-agent messaging and credit terms"),
685 (name = "subscriptions", description = "Recurring subscription management"),
686 (name = "store_credits", description = "Store credit management"),
687 (name = "promotions", description = "Promotion and discount management"),
688 (name = "currency", description = "Exchange rates and currency conversion"),
689 (name = "warranties", description = "Product warranty management"),
690 (name = "segments", description = "Customer segment management"),
691 (name = "shipping", description = "Shipping zone management"),
692 (name = "events", description = "Real-time event streaming"),
693 (name = "activity_logs", description = "Record-level activity history"),
694 (name = "channels", description = "Sales channel management"),
695 (name = "companies", description = "B2B company account management"),
696 (name = "edi_documents", description = "EDI document exchange"),
697 (name = "inbound_shipments", description = "Inbound shipment receiving"),
698 (name = "integration_field_mappings", description = "Integration field-level mappings"),
699 (name = "integration_mappings", description = "External integration record mappings"),
700 (name = "payment_obligations", description = "Payment obligation tracking"),
701 (name = "prepayments", description = "Customer and vendor prepayments"),
702 (name = "price_levels", description = "Customer price level management"),
703 (name = "price_schedules", description = "Scheduled pricing management"),
704 (name = "print_stations", description = "Warehouse print station management"),
705 (name = "production_batches", description = "Production batch tracking"),
706 (name = "purgatory", description = "Quarantined record review"),
707 (name = "reports", description = "Computed business reports"),
708 (name = "stock_snapshots", description = "Point-in-time inventory snapshots"),
709 (name = "supplier_skus", description = "Supplier SKU catalog"),
710 (name = "topology_snapshots", description = "Network topology snapshots"),
711 (name = "transfer_orders", description = "Inter-warehouse transfer orders"),
712 (name = "units_of_measure", description = "Unit of measure definitions"),
713 (name = "vendor_credits", description = "Vendor credit management"),
714 (name = "vendor_returns", description = "Return-to-vendor processing"),
715 (name = "purchase_orders", description = "Supplier procurement: purchase order lifecycle (draft → approval → send → acknowledge → receive → complete) and supplier management"),
716 (name = "general_ledger", description = "Chart of accounts, journal entries, accounting periods, and financial reports (trial balance, balance sheet, income statement)"),
717 (name = "accounts_payable", description = "Supplier bills, AP payments and allocations, payment runs, and AP aging"),
718 (name = "accounts_receivable", description = "AR aging, payment application, credit memos, write-offs, dunning, and customer statements"),
719 (name = "warehouse", description = "Warehouses, storage locations, and location-level inventory (adjust/move)"),
720 (name = "fulfillment", description = "Outbound fulfillment: waves, pick tasks, pack tasks and cartons, ship tasks"),
721 (name = "receiving", description = "Inbound receiving: goods receipts, item receipt, and put-away tasks"),
722 (name = "work_orders", description = "Manufacturing work order lifecycle and shop-floor tasks"),
723 (name = "quality", description = "Quality control: inspections, non-conformance reports, and quality holds"),
724 (name = "bom", description = "Bills of materials: BOM revisions, components, and status control"),
725 (name = "lots", description = "Lot/batch tracking: creation, consumption, reservations, quarantine, and expiry queries"),
726 (name = "serials", description = "Serial number tracking: creation, lookup, reservations, and lifecycle transitions"),
727 (name = "fixed_assets", description = "Fixed-asset register: acquisition, depreciation schedules, disposal, and write-off"),
728 (name = "revenue_recognition", description = "Revenue contracts, performance obligations, and recognition schedules (ASC 606)"),
729 (name = "carts", description = "Cart and checkout sessions: items, shipping, payment, completion"),
730 (name = "backorders", description = "Backorder creation, fulfillment, and cancellation"),
731 )
732)]
733#[derive(Debug)]
734pub struct ApiDoc;
735
736pub(crate) fn router() -> Router<AppState> {
738 Router::new().route("/openapi.json", get(openapi_json)).route("/docs", get(docs_ui))
739}
740
741async fn openapi_json() -> Json<utoipa::openapi::OpenApi> {
743 Json(ApiDoc::openapi())
744}
745
746async fn docs_ui() -> Html<&'static str> {
748 Html(
749 r#"<!doctype html>
750<html>
751<head>
752 <title>StateSet Commerce API</title>
753 <meta charset="utf-8" />
754 <meta name="viewport" content="width=device-width, initial-scale=1" />
755</head>
756<body>
757 <script id="api-reference" data-url="/api/v1/openapi.json"></script>
758 <script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
759</body>
760</html>"#,
761 )
762}
763
764#[cfg(test)]
765mod tests {
766 use super::*;
767
768 #[test]
769 fn openapi_spec_serializes_to_json() {
770 let spec = ApiDoc::openapi();
771 let json = serde_json::to_value(&spec).unwrap();
772 assert_eq!(json["info"]["title"], "StateSet Commerce API");
773 assert_eq!(json["info"]["version"], "1.0.4");
774 }
775
776 #[test]
777 fn openapi_spec_has_all_paths() {
778 let spec = ApiDoc::openapi();
779 let json = serde_json::to_value(&spec).unwrap();
780 let paths = json["paths"].as_object().unwrap();
781
782 assert!(paths.contains_key("/health"), "missing /health");
783 assert!(paths.contains_key("/health/ready"), "missing /health/ready");
784 assert!(paths.contains_key("/metrics"), "missing /metrics");
785 assert!(paths.contains_key("/version"), "missing /version");
786 assert!(paths.contains_key("/api/v1/orders"), "missing /api/v1/orders");
787 assert!(paths.contains_key("/api/v1/orders/{id}"), "missing /api/v1/orders/{{id}}");
788 assert!(paths.contains_key("/api/v1/customers"), "missing /api/v1/customers");
789 assert!(paths.contains_key("/api/v1/products"), "missing /api/v1/products");
790 assert!(paths.contains_key("/api/v1/inventory"), "missing /api/v1/inventory");
791 assert!(paths.contains_key("/api/v1/inventory/{sku}"), "missing /api/v1/inventory/{{sku}}");
792 assert!(paths.contains_key("/api/v1/returns"), "missing /api/v1/returns");
793 assert!(
794 paths.contains_key("/api/v1/returns/{id}/approve"),
795 "missing /api/v1/returns/{{id}}/approve"
796 );
797 assert!(paths.contains_key("/api/v1/shipments"), "missing /api/v1/shipments");
798 assert!(paths.contains_key("/api/v1/shipments/{id}"), "missing /api/v1/shipments/{{id}}");
799 assert!(paths.contains_key("/api/v1/payments"), "missing /api/v1/payments");
800 assert!(paths.contains_key("/api/v1/payments/{id}"), "missing /api/v1/payments/{{id}}");
801 assert!(paths.contains_key("/api/v1/invoices"), "missing /api/v1/invoices");
802 assert!(paths.contains_key("/api/v1/invoices/{id}"), "missing /api/v1/invoices/{{id}}");
803
804 for path in [
806 "/api/v1/channels",
807 "/api/v1/companies",
808 "/api/v1/transfer-orders",
809 "/api/v1/unit-classes",
810 "/api/v1/production-batches",
811 "/api/v1/supplier-skus",
812 "/api/v1/vendor-returns",
813 "/api/v1/vendor-credits",
814 "/api/v1/payment-obligations",
815 "/api/v1/prepayments",
816 "/api/v1/price-levels",
817 "/api/v1/price-schedules",
818 "/api/v1/activity-logs",
819 "/api/v1/integration-mappings",
820 "/api/v1/integration-field-mappings",
821 "/api/v1/inbound-shipments",
822 "/api/v1/purgatory/orders",
823 "/api/v1/print-stations",
824 "/api/v1/edi-documents",
825 "/api/v1/topology-snapshots",
826 "/api/v1/stock-snapshots",
827 "/api/v1/reports/inventory-aging",
828 "/api/v1/reports/consumption",
829 ] {
830 assert!(paths.contains_key(path), "missing {path}");
831 }
832 }
833
834 #[test]
835 fn openapi_spec_has_all_schemas() {
836 let spec = ApiDoc::openapi();
837 let json = serde_json::to_value(&spec).unwrap();
838 let schemas = json["components"]["schemas"].as_object().unwrap();
839
840 let expected = [
841 "CreateOrderRequest",
842 "OrderResponse",
843 "CustomerResponse",
844 "ProductResponse",
845 "InventoryResponse",
846 "InventoryItemResponse",
847 "ShipmentResponse",
848 "PaymentResponse",
849 "InvoiceResponse",
850 "ReturnResponse",
851 "HealthResponse",
852 "TenantCacheResponse",
853 "ErrorBody",
854 ];
855 for name in expected {
856 assert!(schemas.contains_key(name), "missing schema: {name}");
857 }
858 }
859
860 #[test]
861 fn openapi_spec_has_tags() {
862 let spec = ApiDoc::openapi();
863 let json = serde_json::to_value(&spec).unwrap();
864 let tags: Vec<String> = json["tags"]
865 .as_array()
866 .unwrap()
867 .iter()
868 .map(|t| t["name"].as_str().unwrap().to_string())
869 .collect();
870 assert!(tags.contains(&"orders".to_string()));
871 assert!(tags.contains(&"customers".to_string()));
872 assert!(tags.contains(&"health".to_string()));
873 }
874}