UNPKG

@invoicing-sdk/application

Version:

Application layer for the invoicing system including use cases, ports, and application services

1 lines 33.7 kB
{"version":3,"sources":["../src/use-cases/RequestInvoice.ts","../src/use-cases/mappers/InvoiceDraftMapper.ts","../src/use-cases/IssueInvoice.ts","../src/use-cases/CreateInvoice.ts","../src/use-cases/ListInvoices.ts","../src/use-cases/GetInvoice.ts","../src/events/event-bus.ts"],"sourcesContent":["import type {\n DomainEventPublisher,\n InvoiceFinancials,\n InvoiceNumberGenerator,\n} from \"@invoicing-sdk/domain\";\nimport {\n Invoice,\n InvoiceAlreadyExistsError,\n InvoiceDraft,\n InvoiceStatus,\n OrderNotFoundError,\n} from \"@invoicing-sdk/domain\";\nimport type { InvoiceRepository, OrderRepository } from \"../ports/index.js\";\nimport type {\n RequestInvoiceCommand,\n RequestInvoiceResult,\n} from \"./commands.js\";\nimport { InvoiceDraftMapper } from \"./mappers/InvoiceDraftMapper.js\";\n\n/**\n * Dependencies required for RequestInvoice use case\n */\nexport interface RequestInvoiceDependencies {\n readonly orderRepository: OrderRepository;\n readonly invoiceRepository: InvoiceRepository;\n readonly invoiceNumberGenerator: InvoiceNumberGenerator;\n readonly eventPublisher?: DomainEventPublisher;\n}\n\n/**\n * Use case for requesting an invoice draft preparation\n * This prepares invoice data without finalizing it, allowing review before creation\n *\n * Requirements: 1.1 - Allow creation of invoice draft from order\n */\nexport function makeRequestInvoice(deps: RequestInvoiceDependencies) {\n return async (\n command: RequestInvoiceCommand\n ): Promise<RequestInvoiceResult> => {\n const { orderRepository, invoiceRepository, invoiceNumberGenerator } = deps;\n const { orderId } = command;\n\n // Check if order exists\n const order = await orderRepository.findById(orderId);\n if (!order) {\n throw new OrderNotFoundError(orderId);\n }\n\n // Check if invoice already exists for this order\n const existingInvoice = await invoiceRepository.findByOrderId(orderId);\n if (existingInvoice) {\n throw new InvoiceAlreadyExistsError(orderId);\n }\n\n // Draft invoice creation\n const financials: InvoiceFinancials = {\n subtotal: order.subtotal,\n taxes: order.taxes,\n shippingCost: order.shippingCost,\n discount: order.discount,\n grandTotal: order.subtotal\n .add(order.taxes)\n .add(order.shippingCost)\n .subtract(order.discount),\n };\n const financialsPO = {\n subtotal: financials.subtotal.toPlainObject(),\n taxes: financials.taxes.toPlainObject(),\n shippingCost: financials.shippingCost.toPlainObject(),\n discount: financials.discount.toPlainObject(),\n grandTotal: financials.grandTotal.toPlainObject(),\n };\n\n const draft = await Invoice.createDraft(\n {\n orderId: order.orderId,\n customerSnapshot: order.customer,\n itemsSnapshot: order.items,\n financials: financials,\n createdBy: command.requestedBy,\n },\n { invoiceNumberGenerator }\n );\n\n // Persist the invoice\n await invoiceRepository.save(draft);\n\n // Create the draft DTO using the mapper\n const draftDTO = InvoiceDraftMapper.toDTO(draft);\n\n // Prepare invoice data from order snapshot (maintaining backwards compatibility)\n const result: RequestInvoiceResult = {\n orderId: order.orderId,\n suggestedInvoiceNumber: draftDTO.invoiceNumber,\n customerInfo: draftDTO.customerSnapshot,\n items: draftDTO.itemsSnapshot,\n financials: draftDTO.financials,\n draft: draftDTO,\n };\n\n if (deps.eventPublisher) {\n draft.publishAllUncommitted(deps.eventPublisher);\n }\n\n return result;\n };\n}\n\n/**\n * Factory function to create RequestInvoice use case with dependencies\n */\nexport function createRequestInvoiceUseCase(\n deps: RequestInvoiceDependencies\n): (command: RequestInvoiceCommand) => Promise<RequestInvoiceResult> {\n return makeRequestInvoice(deps);\n}\n","import type { InvoiceDraft } from \"@invoicing-sdk/domain\";\nimport type { InvoiceDraftDTO } from \"../commands.js\";\n\n/**\n * Mapper utility to convert InvoiceDraft domain entity to DTO\n * Preserves DDD boundaries by not exposing domain methods\n */\nexport class InvoiceDraftMapper {\n /**\n * Converts InvoiceDraft domain entity to InvoiceDraftDTO\n * @param draft - The domain InvoiceDraft entity\n * @returns InvoiceDraftDTO suitable for presentation layer\n */\n static toDTO(draft: InvoiceDraft): InvoiceDraftDTO {\n return {\n invoiceId: draft.invoiceId,\n invoiceNumber: draft.invoiceNumber,\n orderId: draft.orderId,\n customerSnapshot: {\n firstName: draft.customerSnapshot.firstName,\n lastName: draft.customerSnapshot.lastName,\n street: draft.customerSnapshot.street,\n zip: draft.customerSnapshot.zip,\n city: draft.customerSnapshot.city,\n country: draft.customerSnapshot.country,\n email: draft.customerSnapshot.email,\n phone: draft.customerSnapshot.phone,\n },\n itemsSnapshot: draft.itemsSnapshot.map((item) => ({\n name: item.name,\n variant: item.variant,\n productNumber: item.productNumber,\n unitPrice: item.unitPrice.toPlainObject(),\n quantity: item.quantity,\n linePrice: item.linePrice.toPlainObject(),\n })),\n financials: {\n subtotal: draft.financials.subtotal.toPlainObject(),\n taxes: draft.financials.taxes.toPlainObject(),\n shippingCost: draft.financials.shippingCost.toPlainObject(),\n discount: draft.financials.discount.toPlainObject(),\n grandTotal: draft.financials.grandTotal.toPlainObject(),\n },\n status: \"DRAFT\" as const,\n createdOn: draft.createdOn.toISOString(),\n createdBy: draft.createdBy,\n };\n }\n}","import type {\n DomainEventPublisher,\n GermanLegalInfo,\n InvoiceData,\n InvoiceFinancials,\n InvoiceNumberValidator,\n PDFRenderer,\n ShippingCostPolicy,\n ShippingRateProvider,\n} from \"@invoicing-sdk/domain\";\nimport {\n Invoice,\n InvoiceDraftNotFoundError,\n InvoiceIntegrityCheckError,\n InvoiceStateViolationError,\n InvoiceStatus,\n OrderNotFoundError,\n ShippingCost,\n} from \"@invoicing-sdk/domain\";\nimport type { InvoiceRepository, OrderRepository } from \"../ports/index.js\";\nimport type { IssueInvoiceCommand, IssueInvoiceResult } from \"./commands.js\";\n\n/**\n * Dependencies required for IssueInvoice use case\n */\nexport interface IssueInvoiceDependencies {\n readonly orderRepository: OrderRepository;\n readonly invoiceRepository: InvoiceRepository;\n readonly invoiceNumberValidator: InvoiceNumberValidator;\n readonly pdfRenderer: PDFRenderer;\n readonly legalInfo: GermanLegalInfo;\n readonly shippingRateProvider: ShippingRateProvider;\n readonly shippingCostPolicy: ShippingCostPolicy;\n /**\n * Event publisher to publish {@link InvoiceIssued} events to.\n *\n * Can be omitted to not use event publishing.\n */\n readonly eventPublisher?: DomainEventPublisher;\n}\n\n/**\n * Use case for issuing and finalizing an invoice\n * This issues the invoice with validation, PDF generation, and persistence\n *\n * Requirements:\n * - 1.1: Ensure the draft exists\n * - 1.2: Snapshot customer information and order items\n * - 1.3: Validate invoice number format\n * - 1.4: Calculate totals correctly\n * - 1.5: Generate PDF/A-3 compliant PDF\n * - 1.6: Make invoice immutable after issuance\n */\nexport function makeIssueInvoice(deps: IssueInvoiceDependencies) {\n return async (command: IssueInvoiceCommand): Promise<IssueInvoiceResult> => {\n const {\n orderRepository,\n invoiceRepository,\n invoiceNumberValidator,\n shippingRateProvider,\n shippingCostPolicy,\n pdfRenderer,\n legalInfo,\n } = deps;\n const { invoiceNumber, orderId, issuedBy } = command;\n\n // Check if order exists\n const order = await orderRepository.findById(orderId);\n if (!order) {\n throw new OrderNotFoundError(orderId);\n }\n\n // Check if invoice already exists for this order and is a draft.\n const existingInvoice = await invoiceRepository.findDraft({\n by: \"orderId\",\n orderId,\n });\n if (!existingInvoice) {\n throw new InvoiceDraftNotFoundError(orderId);\n }\n // Do the check again, cause input might not be consistent\n if (!existingInvoice.requireStatus(InvoiceStatus.DRAFT)) {\n throw new InvoiceStateViolationError(\n invoiceNumber,\n InvoiceStatus.DRAFT,\n existingInvoice.getStatus()\n );\n }\n // Check if the invoice numbers match to prevent a MITM\n if (existingInvoice.invoiceNumber !== invoiceNumber) {\n throw new InvoiceIntegrityCheckError(\n invoiceNumber,\n \"INVOICE_NUMBER_MISMATCH\" as const,\n `Invoice draft has ${existingInvoice.invoiceNumber} but received ${invoiceNumber}`\n );\n }\n\n // Calculate shipping costs (has business rules)\n const baseTotal = order.subtotal.add(order.taxes).subtract(order.discount);\n const shippingCost = ShippingCost.determine(\n baseTotal,\n shippingRateProvider,\n shippingCostPolicy\n );\n // Now compute the grand total\n const grandTotal = baseTotal.add(shippingCost);\n\n // Prepare invoice financials\n const financials: InvoiceFinancials = {\n subtotal: order.subtotal,\n taxes: order.taxes,\n shippingCost: shippingCost,\n discount: order.discount,\n grandTotal,\n };\n // Prepare invoice data for PDF generation\n const invoiceDataForPdf: InvoiceData = {\n invoiceId: \"\", // Will be set after invoice creation\n invoiceNumber,\n orderId,\n customer: order.customer,\n items: order.items,\n financials,\n createdOn: new Date(),\n createdBy: issuedBy,\n legalInfo,\n };\n\n // Generate PDF\n const pdfBytes = await pdfRenderer.render(invoiceDataForPdf);\n\n // Issue a finalized invoice (which validates, emits event, etc.)\n // The IssueInvoiceData is the same as the existing invoice, which is an invoice draft.\n const invoice = await Invoice.issue(\n {\n orderId,\n invoiceNumber,\n customerSnapshot: existingInvoice.customerSnapshot,\n itemsSnapshot: existingInvoice.itemsSnapshot,\n financials,\n createdBy: issuedBy, // explicit issuer attribution\n status: InvoiceStatus.DRAFT,\n },\n pdfBytes,\n { invoiceNumberValidator }\n );\n\n // Persist invoice\n await invoiceRepository.save(invoice);\n\n // Publish the events\n if (deps.eventPublisher) {\n invoice.publishAllUncommitted(deps.eventPublisher);\n }\n\n // Return result\n const result: IssueInvoiceResult = {\n invoiceId: invoice.invoiceId,\n invoiceNumber: invoice.invoiceNumber,\n orderId: invoice.orderId,\n grandTotal: invoice.financials.grandTotal.toPlainObject(),\n issuedOn: invoice.createdOn,\n issuedBy: invoice.createdBy,\n };\n\n return result;\n };\n}\n\n/**\n * Factory function to create IssueInvoice use case with dependencies\n */\nexport function createIssueInvoiceUseCase(\n deps: IssueInvoiceDependencies\n): (command: IssueInvoiceCommand) => Promise<IssueInvoiceResult> {\n return makeIssueInvoice(deps);\n}\n","import type {\n DomainEventPublisher,\n GermanLegalInfo,\n InvoiceData,\n InvoiceFinancials,\n InvoiceNumberValidator,\n PDFRenderer,\n ShippingCostPolicy,\n ShippingRateProvider,\n} from \"@invoicing-sdk/domain\";\nimport {\n Invoice,\n InvoiceDraftNotFoundError,\n InvoiceStateViolationError,\n InvoiceStatus,\n OrderNotFoundError,\n ShippingCost,\n} from \"@invoicing-sdk/domain\";\nimport type { InvoiceRepository, OrderRepository } from \"../ports/index.js\";\nimport type { CreateInvoiceCommand, CreateInvoiceResult } from \"./commands.js\";\n\n/**\n * Dependencies required for CreateInvoice use case\n */\nexport interface CreateInvoiceDependencies {\n readonly orderRepository: OrderRepository;\n readonly invoiceRepository: InvoiceRepository;\n readonly invoiceNumberValidator: InvoiceNumberValidator;\n readonly pdfRenderer: PDFRenderer;\n readonly legalInfo: GermanLegalInfo;\n readonly shippingRateProvider: ShippingRateProvider;\n readonly shippingCostPolicy: ShippingCostPolicy;\n /**\n * Event publisher to publish {@link InvoiceCreated} events to.\n *\n * Can be omitted to not use event publishing.\n */\n readonly eventPublisher?: DomainEventPublisher;\n}\n\n/**\n * Use case for creating and finalizing an invoice\n * This creates the invoice with validation, PDF generation, and persistence\n *\n * Requirements:\n * - 1.1: Ensure the draft exists\n * - 1.2: Snapshot customer information and order items\n * - 1.3: Validate invoice number format\n * - 1.4: Calculate totals correctly\n * - 1.5: Generate PDF/A-3 compliant PDF\n * - 1.6: Make invoice immutable after creation\n *\n * @deprecated Use {@link makeIssueInvoice} instead.\n * The new API behaves the same, but has a more aligned naming convention.\n * This use case factory will be removed in the next major version.\n */\nexport function makeCreateInvoice(deps: CreateInvoiceDependencies) {\n return async (\n command: CreateInvoiceCommand\n ): Promise<CreateInvoiceResult> => {\n const {\n orderRepository,\n invoiceRepository,\n invoiceNumberValidator,\n shippingRateProvider,\n shippingCostPolicy,\n pdfRenderer,\n legalInfo,\n } = deps;\n const { orderId, invoiceNumber, createdBy } = command;\n\n // Check if order exists\n const order = await orderRepository.findById(orderId);\n if (!order) {\n throw new OrderNotFoundError(orderId);\n }\n\n // Check if invoice already exists for this order and is a draft.\n const existingInvoice = await invoiceRepository.findDraft({\n by: \"invoiceNumber\",\n invoiceNumber,\n });\n if (!existingInvoice) {\n throw new InvoiceDraftNotFoundError(orderId);\n }\n if (!existingInvoice.requireStatus(InvoiceStatus.DRAFT)) {\n throw new InvoiceStateViolationError(\n orderId,\n InvoiceStatus.DRAFT,\n existingInvoice.getStatus()\n );\n }\n\n // Calculate grand total (business rule validation)\n const grandTotal = order.subtotal\n .add(order.taxes)\n .add(order.shippingCost)\n .subtract(order.discount);\n\n // Calculate shipping costs (has business rules)\n const shippingCost = ShippingCost.determine(\n grandTotal,\n shippingRateProvider,\n shippingCostPolicy\n );\n\n // Prepare invoice financials\n const financials: InvoiceFinancials = {\n subtotal: order.subtotal,\n taxes: order.taxes,\n shippingCost: shippingCost,\n discount: order.discount,\n grandTotal,\n };\n\n // Prepare invoice data for PDF generation\n const invoiceDataForPdf: InvoiceData = {\n invoiceId: \"\", // Will be set after invoice creation\n invoiceNumber,\n orderId,\n customer: order.customer,\n items: order.items,\n financials,\n createdOn: new Date(),\n createdBy,\n legalInfo,\n };\n\n // Generate PDF\n const pdfBytes = await pdfRenderer.render(invoiceDataForPdf);\n\n // Issue a finalized invoice (which validates, emits event, etc.)\n // The IssueInvoiceData expects a draft\n const invoice = await Invoice.issue(\n {\n orderId,\n invoiceNumber,\n customerSnapshot: existingInvoice.customerSnapshot,\n itemsSnapshot: existingInvoice.itemsSnapshot,\n financials,\n createdBy: createdBy,\n status: InvoiceStatus.DRAFT, // This is always the case after the check above\n },\n pdfBytes,\n { invoiceNumberValidator: invoiceNumberValidator }\n );\n\n // Persist invoice\n await invoiceRepository.save(invoice);\n\n // Publish the events\n if (deps.eventPublisher) {\n invoice.publishAllUncommitted(deps.eventPublisher);\n }\n\n // Return result\n const result: CreateInvoiceResult = {\n invoiceId: invoice.invoiceId,\n invoiceNumber: invoice.invoiceNumber,\n orderId: invoice.orderId,\n grandTotal: invoice.financials.grandTotal.toPlainObject(),\n createdOn: invoice.createdOn,\n createdBy: invoice.createdBy,\n };\n\n return result;\n };\n}\n\n/**\n * Factory function to create CreateInvoice use case with dependencies\n *\n * @deprecated Use {@link makeIssueInvoice} instead.\n * The new API behaves the same, but has a more aligned naming convention.\n * This use case factory will be removed in the next major version.\n */\nexport function createCreateInvoiceUseCase(\n deps: CreateInvoiceDependencies\n): (command: CreateInvoiceCommand) => Promise<CreateInvoiceResult> {\n return makeCreateInvoice(deps);\n}\n","import type { InvoiceRepository } from \"../ports/index.js\";\nimport type { ListInvoicesQuery, ListInvoicesResult } from \"./queries.js\";\n\n/**\n * Dependencies required for ListInvoices use case\n */\nexport interface ListInvoicesDependencies {\n readonly invoiceRepository: InvoiceRepository;\n}\n\n/**\n * Use case for listing invoices with filtering and pagination\n * \n * Requirements:\n * - 2.1: Support filtering by invoice number, date range, and total amount range\n * - 2.2: Provide paginated results\n * - 2.5: Return results in consistent format with metadata\n */\nexport function makeListInvoices(deps: ListInvoicesDependencies) {\n return async (query: ListInvoicesQuery): Promise<ListInvoicesResult> => {\n const { invoiceRepository } = deps;\n\n // Validate pagination parameters\n if (query.page < 1) {\n throw new Error(\"Page number must be greater than 0\");\n }\n if (query.limit < 1 || query.limit > 100) {\n throw new Error(\"Limit must be between 1 and 100\");\n }\n\n // Validate date range if provided\n if (query.dateFrom && query.dateTo && query.dateFrom > query.dateTo) {\n throw new Error(\"dateFrom must be before or equal to dateTo\");\n }\n\n // Validate amount range if provided\n if (query.minTotal !== undefined && query.maxTotal !== undefined && query.minTotal > query.maxTotal) {\n throw new Error(\"minTotal must be less than or equal to maxTotal\");\n }\n\n // Query invoices from repository\n const paginatedResult = await invoiceRepository.list(query);\n\n // Transform domain entities to result format\n const result: ListInvoicesResult = {\n items: paginatedResult.items.map(invoice => ({\n invoiceId: invoice.invoiceId,\n invoiceNumber: invoice.invoiceNumber,\n orderId: invoice.orderId,\n customerName: `${invoice.customerSnapshot.firstName} ${invoice.customerSnapshot.lastName}`,\n grandTotal: invoice.financials.grandTotal.toPlainObject(),\n createdOn: invoice.createdOn,\n createdBy: invoice.createdBy,\n itemCount: invoice.getTotalItemCount(),\n })),\n totalCount: paginatedResult.totalCount,\n page: paginatedResult.page,\n limit: paginatedResult.limit,\n hasNextPage: paginatedResult.hasNextPage,\n hasPreviousPage: paginatedResult.hasPreviousPage,\n };\n\n return result;\n };\n}\n\n/**\n * Factory function to create ListInvoices use case with dependencies\n */\nexport function createListInvoicesUseCase(\n deps: ListInvoicesDependencies\n): (query: ListInvoicesQuery) => Promise<ListInvoicesResult> {\n return makeListInvoices(deps);\n}","import type { InvoiceRepository } from \"../ports/index.js\";\nimport type { GetInvoiceQuery, GetInvoiceResult } from \"./queries.js\";\nimport type { Invoice } from \"@invoicing-sdk/domain\";\n\n/**\n * Dependencies required for GetInvoice use case\n */\nexport interface GetInvoiceDependencies {\n readonly invoiceRepository: InvoiceRepository;\n}\n\n/**\n * Use case for retrieving a single invoice by ID, invoice number, or order ID\n * \n * Requirements:\n * - 2.3: Allow retrieval by either orderId or invoiceNumber\n * - 2.4: Return either domain data or PDF bytes based on request type\n */\nexport function makeGetInvoice(deps: GetInvoiceDependencies) {\n return async (query: GetInvoiceQuery): Promise<GetInvoiceResult | null> => {\n const { invoiceRepository } = deps;\n const { invoiceId, invoiceNumber, orderId, includePdf = false } = query;\n\n // Validate that at least one identifier is provided\n if (!invoiceId && !invoiceNumber && !orderId) {\n throw new Error(\"At least one of invoiceId, invoiceNumber, or orderId must be provided\");\n }\n\n // Find invoice using the provided identifier\n let invoice: Invoice | null = null;\n\n if (invoiceId) {\n invoice = await invoiceRepository.findById(invoiceId);\n } else if (invoiceNumber) {\n invoice = await invoiceRepository.findByInvoiceNumber(invoiceNumber);\n } else if (orderId) {\n invoice = await invoiceRepository.findByOrderId(orderId);\n }\n\n // Return null if invoice not found\n if (!invoice) {\n return null;\n }\n\n // Transform domain entity to result format\n const result: GetInvoiceResult = {\n invoiceId: invoice.invoiceId,\n invoiceNumber: invoice.invoiceNumber,\n orderId: invoice.orderId,\n customerSnapshot: {\n firstName: invoice.customerSnapshot.firstName,\n lastName: invoice.customerSnapshot.lastName,\n street: invoice.customerSnapshot.street,\n zip: invoice.customerSnapshot.zip,\n city: invoice.customerSnapshot.city,\n country: invoice.customerSnapshot.country,\n email: invoice.customerSnapshot.email,\n phone: invoice.customerSnapshot.phone,\n },\n itemsSnapshot: invoice.itemsSnapshot.map(item => ({\n name: item.name,\n variant: item.variant,\n productNumber: item.productNumber,\n unitPrice: item.unitPrice.toPlainObject(),\n quantity: item.quantity,\n linePrice: item.linePrice.toPlainObject(),\n })),\n financials: {\n subtotal: invoice.financials.subtotal.toPlainObject(),\n taxes: invoice.financials.taxes.toPlainObject(),\n shippingCost: invoice.financials.shippingCost.toPlainObject(),\n discount: invoice.financials.discount.toPlainObject(),\n grandTotal: invoice.financials.grandTotal.toPlainObject(),\n },\n createdOn: invoice.createdOn,\n createdBy: invoice.createdBy,\n // Include PDF bytes only if requested\n pdfBytes: includePdf ? invoice.pdfBytes : undefined,\n };\n\n return result;\n };\n}\n\n/**\n * Factory function to create GetInvoice use case with dependencies\n */\nexport function createGetInvoiceUseCase(\n deps: GetInvoiceDependencies\n): (query: GetInvoiceQuery) => Promise<GetInvoiceResult | null> {\n return makeGetInvoice(deps);\n}","import type { DomainEvent, InvoiceCreatedEvent } from \"@invoicing-sdk/domain\";\n\n/**\n * Event handler function type\n */\nexport type EventHandler<T extends DomainEvent = DomainEvent> = (\n event: T\n) => Promise<void>;\n\n/**\n * Event subscription interface\n */\nexport interface EventSubscription<T extends DomainEvent = DomainEvent> {\n readonly eventType: T[\"eventType\"];\n readonly handler: EventHandler<T>;\n unsubscribe(): Promise<void>;\n}\n\n/**\n * Event bus interface for publishing and subscribing to domain events\n */\nexport interface EventBus {\n /**\n * Publish a domain event to all subscribers\n */\n publish<T extends DomainEvent>(event: T): Promise<void>;\n\n /**\n * Subscribe to a specific event type\n * - eventType is now strictly typed to the discriminant of T\n * - the returned subscription is also typed with T\n */\n subscribe<T extends DomainEvent>(\n eventType: T[\"eventType\"],\n handler: EventHandler<T>\n ): Promise<EventSubscription<T>>;\n\n /**\n * Start the event bus (connect to message broker)\n */\n start(): Promise<void>;\n\n /**\n * Stop the event bus (disconnect from message broker)\n */\n stop(): Promise<void>;\n\n /**\n * Check if the event bus is connected\n */\n isConnected(): Promise<boolean>;\n}\n\n/**\n * Event bus configuration interface\n */\nexport interface EventBusConfig {\n readonly connectionString: string;\n readonly exchangeName?: string;\n readonly queuePrefix?: string;\n readonly retryAttempts?: number;\n readonly retryDelay?: number;\n}\n\n/**\n * Base event bus error\n */\nexport class EventBusError extends Error {\n constructor(message: string, public override readonly cause?: Error) {\n super(message);\n this.name = \"EventBusError\";\n }\n}\n\n/**\n * Event publishing error\n */\nexport class EventPublishError extends EventBusError {\n constructor(eventType: string, cause?: Error) {\n super(`Failed to publish event: ${eventType}`, cause);\n this.name = \"EventPublishError\";\n }\n}\n\n/**\n * Event subscription error\n */\nexport class EventSubscriptionError extends EventBusError {\n constructor(eventType: string, cause?: Error) {\n super(`Failed to subscribe to event: ${eventType}`, cause);\n this.name = \"EventSubscriptionError\";\n }\n}\n"],"mappings":";AAKA;AAAA,EACE;AAAA,EACA;AAAA,EAGA;AAAA,OACK;;;ACJA,IAAM,qBAAN,MAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM9B,OAAO,MAAM,OAAsC;AACjD,WAAO;AAAA,MACL,WAAW,MAAM;AAAA,MACjB,eAAe,MAAM;AAAA,MACrB,SAAS,MAAM;AAAA,MACf,kBAAkB;AAAA,QAChB,WAAW,MAAM,iBAAiB;AAAA,QAClC,UAAU,MAAM,iBAAiB;AAAA,QACjC,QAAQ,MAAM,iBAAiB;AAAA,QAC/B,KAAK,MAAM,iBAAiB;AAAA,QAC5B,MAAM,MAAM,iBAAiB;AAAA,QAC7B,SAAS,MAAM,iBAAiB;AAAA,QAChC,OAAO,MAAM,iBAAiB;AAAA,QAC9B,OAAO,MAAM,iBAAiB;AAAA,MAChC;AAAA,MACA,eAAe,MAAM,cAAc,IAAI,CAAC,UAAU;AAAA,QAChD,MAAM,KAAK;AAAA,QACX,SAAS,KAAK;AAAA,QACd,eAAe,KAAK;AAAA,QACpB,WAAW,KAAK,UAAU,cAAc;AAAA,QACxC,UAAU,KAAK;AAAA,QACf,WAAW,KAAK,UAAU,cAAc;AAAA,MAC1C,EAAE;AAAA,MACF,YAAY;AAAA,QACV,UAAU,MAAM,WAAW,SAAS,cAAc;AAAA,QAClD,OAAO,MAAM,WAAW,MAAM,cAAc;AAAA,QAC5C,cAAc,MAAM,WAAW,aAAa,cAAc;AAAA,QAC1D,UAAU,MAAM,WAAW,SAAS,cAAc;AAAA,QAClD,YAAY,MAAM,WAAW,WAAW,cAAc;AAAA,MACxD;AAAA,MACA,QAAQ;AAAA,MACR,WAAW,MAAM,UAAU,YAAY;AAAA,MACvC,WAAW,MAAM;AAAA,IACnB;AAAA,EACF;AACF;;;ADbO,SAAS,mBAAmB,MAAkC;AACnE,SAAO,OACL,YACkC;AAClC,UAAM,EAAE,iBAAiB,mBAAmB,uBAAuB,IAAI;AACvE,UAAM,EAAE,QAAQ,IAAI;AAGpB,UAAM,QAAQ,MAAM,gBAAgB,SAAS,OAAO;AACpD,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,mBAAmB,OAAO;AAAA,IACtC;AAGA,UAAM,kBAAkB,MAAM,kBAAkB,cAAc,OAAO;AACrE,QAAI,iBAAiB;AACnB,YAAM,IAAI,0BAA0B,OAAO;AAAA,IAC7C;AAGA,UAAM,aAAgC;AAAA,MACpC,UAAU,MAAM;AAAA,MAChB,OAAO,MAAM;AAAA,MACb,cAAc,MAAM;AAAA,MACpB,UAAU,MAAM;AAAA,MAChB,YAAY,MAAM,SACf,IAAI,MAAM,KAAK,EACf,IAAI,MAAM,YAAY,EACtB,SAAS,MAAM,QAAQ;AAAA,IAC5B;AACA,UAAM,eAAe;AAAA,MACnB,UAAU,WAAW,SAAS,cAAc;AAAA,MAC5C,OAAO,WAAW,MAAM,cAAc;AAAA,MACtC,cAAc,WAAW,aAAa,cAAc;AAAA,MACpD,UAAU,WAAW,SAAS,cAAc;AAAA,MAC5C,YAAY,WAAW,WAAW,cAAc;AAAA,IAClD;AAEA,UAAM,QAAQ,MAAM,QAAQ;AAAA,MAC1B;AAAA,QACE,SAAS,MAAM;AAAA,QACf,kBAAkB,MAAM;AAAA,QACxB,eAAe,MAAM;AAAA,QACrB;AAAA,QACA,WAAW,QAAQ;AAAA,MACrB;AAAA,MACA,EAAE,uBAAuB;AAAA,IAC3B;AAGA,UAAM,kBAAkB,KAAK,KAAK;AAGlC,UAAM,WAAW,mBAAmB,MAAM,KAAK;AAG/C,UAAM,SAA+B;AAAA,MACnC,SAAS,MAAM;AAAA,MACf,wBAAwB,SAAS;AAAA,MACjC,cAAc,SAAS;AAAA,MACvB,OAAO,SAAS;AAAA,MAChB,YAAY,SAAS;AAAA,MACrB,OAAO;AAAA,IACT;AAEA,QAAI,KAAK,gBAAgB;AACvB,YAAM,sBAAsB,KAAK,cAAc;AAAA,IACjD;AAEA,WAAO;AAAA,EACT;AACF;AAKO,SAAS,4BACd,MACmE;AACnE,SAAO,mBAAmB,IAAI;AAChC;;;AEzGA;AAAA,EACE,WAAAA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAAC;AAAA,EACA,sBAAAC;AAAA,EACA;AAAA,OACK;AAmCA,SAAS,iBAAiB,MAAgC;AAC/D,SAAO,OAAO,YAA8D;AAC1E,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI;AACJ,UAAM,EAAE,eAAe,SAAS,SAAS,IAAI;AAG7C,UAAM,QAAQ,MAAM,gBAAgB,SAAS,OAAO;AACpD,QAAI,CAAC,OAAO;AACV,YAAM,IAAIA,oBAAmB,OAAO;AAAA,IACtC;AAGA,UAAM,kBAAkB,MAAM,kBAAkB,UAAU;AAAA,MACxD,IAAI;AAAA,MACJ;AAAA,IACF,CAAC;AACD,QAAI,CAAC,iBAAiB;AACpB,YAAM,IAAI,0BAA0B,OAAO;AAAA,IAC7C;AAEA,QAAI,CAAC,gBAAgB,cAAcD,eAAc,KAAK,GAAG;AACvD,YAAM,IAAI;AAAA,QACR;AAAA,QACAA,eAAc;AAAA,QACd,gBAAgB,UAAU;AAAA,MAC5B;AAAA,IACF;AAEA,QAAI,gBAAgB,kBAAkB,eAAe;AACnD,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA,qBAAqB,gBAAgB,aAAa,iBAAiB,aAAa;AAAA,MAClF;AAAA,IACF;AAGA,UAAM,YAAY,MAAM,SAAS,IAAI,MAAM,KAAK,EAAE,SAAS,MAAM,QAAQ;AACzE,UAAM,eAAe,aAAa;AAAA,MAChC;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,aAAa,UAAU,IAAI,YAAY;AAG7C,UAAM,aAAgC;AAAA,MACpC,UAAU,MAAM;AAAA,MAChB,OAAO,MAAM;AAAA,MACb;AAAA,MACA,UAAU,MAAM;AAAA,MAChB;AAAA,IACF;AAEA,UAAM,oBAAiC;AAAA,MACrC,WAAW;AAAA;AAAA,MACX;AAAA,MACA;AAAA,MACA,UAAU,MAAM;AAAA,MAChB,OAAO,MAAM;AAAA,MACb;AAAA,MACA,WAAW,oBAAI,KAAK;AAAA,MACpB,WAAW;AAAA,MACX;AAAA,IACF;AAGA,UAAM,WAAW,MAAM,YAAY,OAAO,iBAAiB;AAI3D,UAAM,UAAU,MAAMD,SAAQ;AAAA,MAC5B;AAAA,QACE;AAAA,QACA;AAAA,QACA,kBAAkB,gBAAgB;AAAA,QAClC,eAAe,gBAAgB;AAAA,QAC/B;AAAA,QACA,WAAW;AAAA;AAAA,QACX,QAAQC,eAAc;AAAA,MACxB;AAAA,MACA;AAAA,MACA,EAAE,uBAAuB;AAAA,IAC3B;AAGA,UAAM,kBAAkB,KAAK,OAAO;AAGpC,QAAI,KAAK,gBAAgB;AACvB,cAAQ,sBAAsB,KAAK,cAAc;AAAA,IACnD;AAGA,UAAM,SAA6B;AAAA,MACjC,WAAW,QAAQ;AAAA,MACnB,eAAe,QAAQ;AAAA,MACvB,SAAS,QAAQ;AAAA,MACjB,YAAY,QAAQ,WAAW,WAAW,cAAc;AAAA,MACxD,UAAU,QAAQ;AAAA,MAClB,UAAU,QAAQ;AAAA,IACpB;AAEA,WAAO;AAAA,EACT;AACF;AAKO,SAAS,0BACd,MAC+D;AAC/D,SAAO,iBAAiB,IAAI;AAC9B;;;ACtKA;AAAA,EACE,WAAAE;AAAA,EACA,6BAAAC;AAAA,EACA,8BAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,sBAAAC;AAAA,EACA,gBAAAC;AAAA,OACK;AAuCA,SAAS,kBAAkB,MAAiC;AACjE,SAAO,OACL,YACiC;AACjC,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI;AACJ,UAAM,EAAE,SAAS,eAAe,UAAU,IAAI;AAG9C,UAAM,QAAQ,MAAM,gBAAgB,SAAS,OAAO;AACpD,QAAI,CAAC,OAAO;AACV,YAAM,IAAID,oBAAmB,OAAO;AAAA,IACtC;AAGA,UAAM,kBAAkB,MAAM,kBAAkB,UAAU;AAAA,MACxD,IAAI;AAAA,MACJ;AAAA,IACF,CAAC;AACD,QAAI,CAAC,iBAAiB;AACpB,YAAM,IAAIH,2BAA0B,OAAO;AAAA,IAC7C;AACA,QAAI,CAAC,gBAAgB,cAAcE,eAAc,KAAK,GAAG;AACvD,YAAM,IAAID;AAAA,QACR;AAAA,QACAC,eAAc;AAAA,QACd,gBAAgB,UAAU;AAAA,MAC5B;AAAA,IACF;AAGA,UAAM,aAAa,MAAM,SACtB,IAAI,MAAM,KAAK,EACf,IAAI,MAAM,YAAY,EACtB,SAAS,MAAM,QAAQ;AAG1B,UAAM,eAAeE,cAAa;AAAA,MAChC;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAGA,UAAM,aAAgC;AAAA,MACpC,UAAU,MAAM;AAAA,MAChB,OAAO,MAAM;AAAA,MACb;AAAA,MACA,UAAU,MAAM;AAAA,MAChB;AAAA,IACF;AAGA,UAAM,oBAAiC;AAAA,MACrC,WAAW;AAAA;AAAA,MACX;AAAA,MACA;AAAA,MACA,UAAU,MAAM;AAAA,MAChB,OAAO,MAAM;AAAA,MACb;AAAA,MACA,WAAW,oBAAI,KAAK;AAAA,MACpB;AAAA,MACA;AAAA,IACF;AAGA,UAAM,WAAW,MAAM,YAAY,OAAO,iBAAiB;AAI3D,UAAM,UAAU,MAAML,SAAQ;AAAA,MAC5B;AAAA,QACE;AAAA,QACA;AAAA,QACA,kBAAkB,gBAAgB;AAAA,QAClC,eAAe,gBAAgB;AAAA,QAC/B;AAAA,QACA;AAAA,QACA,QAAQG,eAAc;AAAA;AAAA,MACxB;AAAA,MACA;AAAA,MACA,EAAE,uBAA+C;AAAA,IACnD;AAGA,UAAM,kBAAkB,KAAK,OAAO;AAGpC,QAAI,KAAK,gBAAgB;AACvB,cAAQ,sBAAsB,KAAK,cAAc;AAAA,IACnD;AAGA,UAAM,SAA8B;AAAA,MAClC,WAAW,QAAQ;AAAA,MACnB,eAAe,QAAQ;AAAA,MACvB,SAAS,QAAQ;AAAA,MACjB,YAAY,QAAQ,WAAW,WAAW,cAAc;AAAA,MACxD,WAAW,QAAQ;AAAA,MACnB,WAAW,QAAQ;AAAA,IACrB;AAEA,WAAO;AAAA,EACT;AACF;AASO,SAAS,2BACd,MACiE;AACjE,SAAO,kBAAkB,IAAI;AAC/B;;;AClKO,SAAS,iBAAiB,MAAgC;AAC/D,SAAO,OAAO,UAA0D;AACtE,UAAM,EAAE,kBAAkB,IAAI;AAG9B,QAAI,MAAM,OAAO,GAAG;AAClB,YAAM,IAAI,MAAM,oCAAoC;AAAA,IACtD;AACA,QAAI,MAAM,QAAQ,KAAK,MAAM,QAAQ,KAAK;AACxC,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AAGA,QAAI,MAAM,YAAY,MAAM,UAAU,MAAM,WAAW,MAAM,QAAQ;AACnE,YAAM,IAAI,MAAM,4CAA4C;AAAA,IAC9D;AAGA,QAAI,MAAM,aAAa,UAAa,MAAM,aAAa,UAAa,MAAM,WAAW,MAAM,UAAU;AACnG,YAAM,IAAI,MAAM,iDAAiD;AAAA,IACnE;AAGA,UAAM,kBAAkB,MAAM,kBAAkB,KAAK,KAAK;AAG1D,UAAM,SAA6B;AAAA,MACjC,OAAO,gBAAgB,MAAM,IAAI,cAAY;AAAA,QAC3C,WAAW,QAAQ;AAAA,QACnB,eAAe,QAAQ;AAAA,QACvB,SAAS,QAAQ;AAAA,QACjB,cAAc,GAAG,QAAQ,iBAAiB,SAAS,IAAI,QAAQ,iBAAiB,QAAQ;AAAA,QACxF,YAAY,QAAQ,WAAW,WAAW,cAAc;AAAA,QACxD,WAAW,QAAQ;AAAA,QACnB,WAAW,QAAQ;AAAA,QACnB,WAAW,QAAQ,kBAAkB;AAAA,MACvC,EAAE;AAAA,MACF,YAAY,gBAAgB;AAAA,MAC5B,MAAM,gBAAgB;AAAA,MACtB,OAAO,gBAAgB;AAAA,MACvB,aAAa,gBAAgB;AAAA,MAC7B,iBAAiB,gBAAgB;AAAA,IACnC;AAEA,WAAO;AAAA,EACT;AACF;AAKO,SAAS,0BACd,MAC2D;AAC3D,SAAO,iBAAiB,IAAI;AAC9B;;;ACvDO,SAAS,eAAe,MAA8B;AAC3D,SAAO,OAAO,UAA6D;AACzE,UAAM,EAAE,kBAAkB,IAAI;AAC9B,UAAM,EAAE,WAAW,eAAe,SAAS,aAAa,MAAM,IAAI;AAGlE,QAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,SAAS;AAC5C,YAAM,IAAI,MAAM,uEAAuE;AAAA,IACzF;AAGA,QAAI,UAA0B;AAE9B,QAAI,WAAW;AACb,gBAAU,MAAM,kBAAkB,SAAS,SAAS;AAAA,IACtD,WAAW,eAAe;AACxB,gBAAU,MAAM,kBAAkB,oBAAoB,aAAa;AAAA,IACrE,WAAW,SAAS;AAClB,gBAAU,MAAM,kBAAkB,cAAc,OAAO;AAAA,IACzD;AAGA,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AAGA,UAAM,SAA2B;AAAA,MAC/B,WAAW,QAAQ;AAAA,MACnB,eAAe,QAAQ;AAAA,MACvB,SAAS,QAAQ;AAAA,MACjB,kBAAkB;AAAA,QAChB,WAAW,QAAQ,iBAAiB;AAAA,QACpC,UAAU,QAAQ,iBAAiB;AAAA,QACnC,QAAQ,QAAQ,iBAAiB;AAAA,QACjC,KAAK,QAAQ,iBAAiB;AAAA,QAC9B,MAAM,QAAQ,iBAAiB;AAAA,QAC/B,SAAS,QAAQ,iBAAiB;AAAA,QAClC,OAAO,QAAQ,iBAAiB;AAAA,QAChC,OAAO,QAAQ,iBAAiB;AAAA,MAClC;AAAA,MACA,eAAe,QAAQ,cAAc,IAAI,WAAS;AAAA,QAChD,MAAM,KAAK;AAAA,QACX,SAAS,KAAK;AAAA,QACd,eAAe,KAAK;AAAA,QACpB,WAAW,KAAK,UAAU,cAAc;AAAA,QACxC,UAAU,KAAK;AAAA,QACf,WAAW,KAAK,UAAU,cAAc;AAAA,MAC1C,EAAE;AAAA,MACF,YAAY;AAAA,QACV,UAAU,QAAQ,WAAW,SAAS,cAAc;AAAA,QACpD,OAAO,QAAQ,WAAW,MAAM,cAAc;AAAA,QAC9C,cAAc,QAAQ,WAAW,aAAa,cAAc;AAAA,QAC5D,UAAU,QAAQ,WAAW,SAAS,cAAc;AAAA,QACpD,YAAY,QAAQ,WAAW,WAAW,cAAc;AAAA,MAC1D;AAAA,MACA,WAAW,QAAQ;AAAA,MACnB,WAAW,QAAQ;AAAA;AAAA,MAEnB,UAAU,aAAa,QAAQ,WAAW;AAAA,IAC5C;AAEA,WAAO;AAAA,EACT;AACF;AAKO,SAAS,wBACd,MAC8D;AAC9D,SAAO,eAAe,IAAI;AAC5B;;;ACxBO,IAAM,gBAAN,cAA4B,MAAM;AAAA,EACvC,YAAY,SAA0C,OAAe;AACnE,UAAM,OAAO;AADuC;AAEpD,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,oBAAN,cAAgC,cAAc;AAAA,EACnD,YAAY,WAAmB,OAAe;AAC5C,UAAM,4BAA4B,SAAS,IAAI,KAAK;AACpD,SAAK,OAAO;AAAA,EACd;AACF;AAKO,IAAM,yBAAN,cAAqC,cAAc;AAAA,EACxD,YAAY,WAAmB,OAAe;AAC5C,UAAM,iCAAiC,SAAS,IAAI,KAAK;AACzD,SAAK,OAAO;AAAA,EACd;AACF;","names":["Invoice","InvoiceStatus","OrderNotFoundError","Invoice","InvoiceDraftNotFoundError","InvoiceStateViolationError","InvoiceStatus","OrderNotFoundError","ShippingCost"]}