Skip to main content

stateset_http/
openapi.rs

1//! `OpenAPI` specification generation.
2//!
3//! Serves the auto-generated `OpenAPI` 3.1 spec at `GET /api/v1/openapi.json`.
4
5use 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/// Auto-generated `OpenAPI` 3.1 specification for the StateSet Commerce API.
58#[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        // Health
69        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        // Orders
75        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        // Customers
81        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        // Products
87        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        // Inventory
93        crate::routes::inventory::list_inventory,
94        crate::routes::inventory::get_stock,
95        crate::routes::inventory::adjust_stock,
96        // Returns
97        crate::routes::returns::create_return,
98        crate::routes::returns::get_return,
99        crate::routes::returns::list_returns,
100        crate::routes::returns::approve_return,
101        // Shipments
102        crate::routes::shipments::create_shipment,
103        crate::routes::shipments::list_shipments,
104        crate::routes::shipments::get_shipment,
105        crate::routes::shipments::deliver_shipment,
106        // Payments
107        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        // Invoices
113        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        // Reviews
119        crate::routes::reviews::create_review,
120        crate::routes::reviews::get_review,
121        crate::routes::reviews::list_reviews,
122        crate::routes::reviews::delete_review,
123        // Wishlists
124        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        // Gift Cards
131        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        // Loyalty
138        crate::routes::loyalty::create_program,
139        crate::routes::loyalty::list_programs,
140        crate::routes::loyalty::enroll_customer,
141        crate::routes::loyalty::get_account,
142        // Negotiations
143        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        // A2A Messaging
149        crate::routes::a2a_messaging::send_message,
150        crate::routes::a2a_messaging::list_messages,
151        crate::routes::a2a_messaging::acknowledge_message,
152        // A2A Credit
153        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        // Subscriptions
159        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        // Store Credits
166        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        // Promotions
172        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        // Currency
178        crate::routes::currency::list_rates,
179        crate::routes::currency::set_rate,
180        crate::routes::currency::convert_currency,
181        // Warranties
182        crate::routes::warranties::create_warranty,
183        crate::routes::warranties::list_warranties,
184        crate::routes::warranties::get_warranty,
185        // Segments
186        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        // Shipping Zones
193        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        // Events
198        crate::routes::events::event_stream,
199        // --- B2B / ERP-ops domain objects + reports ---
200        // channels
201        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        // companies
208        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        // transfer_orders
215        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        // units_of_measure
222        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        // production_batches
229        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        // supplier_skus
235        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        // vendor_returns
240        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        // vendor_credits
247        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        // payment_obligations
253        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        // prepayments
261        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        // price_levels
267        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        // price_schedules
275        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        // activity_logs
283        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        // integration_mappings
288        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        // integration_field_mappings
296        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        // inbound_shipments
305        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        // purgatory
313        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        // print_stations
320        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        // edi_documents
328        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        // topology_snapshots
334        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        // stock_snapshots
340        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        // reports
346        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        // carts
352        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        // backorders
363        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        // purchase_orders
369        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        // general_ledger
388        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        // fixed_assets
409        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        // revenue_recognition
420        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        // accounts_payable
429        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        // accounts_receivable
444        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        // warehouse
460        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        // fulfillment
479        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        // receiving
493        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        // work_orders
506        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        // quality
520        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        // bom
536        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        // lots
545        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        // serials
555        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        // Request DTOs
566        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        // Response DTOs
582        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        // Reviews
605        CreateReviewRequest,
606        ReviewResponse,
607        ReviewListResponse,
608        // Wishlists
609        CreateWishlistRequest,
610        AddWishlistItemRequest,
611        WishlistResponse,
612        WishlistItemResponse,
613        WishlistListResponse,
614        // Gift Cards
615        CreateGiftCardRequest,
616        GiftCardResponse,
617        GiftCardListResponse,
618        // Loyalty
619        CreateLoyaltyProgramRequest,
620        EnrollCustomerRequest,
621        LoyaltyProgramResponse,
622        LoyaltyProgramListResponse,
623        LoyaltyAccountResponse,
624        // Negotiations
625        CreateNegotiationRequest,
626        CounterOfferRequest,
627        NegotiationResponse,
628        // A2A Messaging
629        SendMessageRequest,
630        MessageResponse,
631        // A2A Credit
632        CreateCreditTermsRequest,
633        CreditAmountRequest,
634        CreditTermsResponse,
635        // Subscriptions
636        CreateSubscriptionRequest,
637        SubscriptionResponse,
638        SubscriptionListResponse,
639        // Store Credits
640        CreateStoreCreditRequest,
641        AdjustStoreCreditRequest,
642        StoreCreditResponse,
643        StoreCreditListResponse,
644        // Promotions
645        CreatePromotionRequest,
646        PromotionResponse,
647        PromotionListResponse,
648        // Currency
649        SetExchangeRateRequest,
650        ConvertCurrencyRequest,
651        ExchangeRateResponse,
652        ExchangeRateListResponse,
653        ConversionResponse,
654        // Warranties
655        CreateWarrantyRequest,
656        WarrantyResponse,
657        WarrantyListResponse,
658        // Segments
659        CreateSegmentRequest,
660        SegmentResponse,
661        SegmentListResponse,
662        // Shipping Zones
663        CreateShippingZoneRequest,
664        ShippingZoneResponse,
665        ShippingZoneListResponse,
666        // Error
667        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
736/// Build the `OpenAPI` spec router.
737pub(crate) fn router() -> Router<AppState> {
738    Router::new().route("/openapi.json", get(openapi_json)).route("/docs", get(docs_ui))
739}
740
741/// `GET /api/v1/openapi.json` — returns the `OpenAPI` spec as JSON.
742async fn openapi_json() -> Json<utoipa::openapi::OpenApi> {
743    Json(ApiDoc::openapi())
744}
745
746/// `GET /api/v1/docs` — interactive API documentation UI (Scalar).
747async 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        // B2B / ERP-ops domain objects + reports must also be in the spec.
805        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}