@cosmneo/onion-lasagna 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/backend/core/global.cjs +283 -0
- package/dist/backend/core/global.cjs.map +1 -0
- package/dist/backend/core/global.d.cts +294 -0
- package/dist/backend/core/global.d.ts +294 -0
- package/dist/backend/core/global.js +39 -0
- package/dist/backend/core/global.js.map +1 -0
- package/dist/backend/core/onion-layers.cjs +2302 -0
- package/dist/backend/core/onion-layers.cjs.map +1 -0
- package/dist/backend/core/onion-layers.d.cts +1675 -0
- package/dist/backend/core/onion-layers.d.ts +1675 -0
- package/dist/backend/core/onion-layers.js +1158 -0
- package/dist/backend/core/onion-layers.js.map +1 -0
- package/dist/backend/core/presentation.cjs +573 -0
- package/dist/backend/core/presentation.cjs.map +1 -0
- package/dist/backend/core/presentation.d.cts +5 -0
- package/dist/backend/core/presentation.d.ts +5 -0
- package/dist/backend/core/presentation.js +28 -0
- package/dist/backend/core/presentation.js.map +1 -0
- package/dist/backend/core/validators/arktype.cjs +947 -0
- package/dist/backend/core/validators/arktype.cjs.map +1 -0
- package/dist/backend/core/validators/arktype.d.cts +188 -0
- package/dist/backend/core/validators/arktype.d.ts +188 -0
- package/dist/backend/core/validators/arktype.js +287 -0
- package/dist/backend/core/validators/arktype.js.map +1 -0
- package/dist/backend/core/validators/typebox.cjs +939 -0
- package/dist/backend/core/validators/typebox.cjs.map +1 -0
- package/dist/backend/core/validators/typebox.d.cts +189 -0
- package/dist/backend/core/validators/typebox.d.ts +189 -0
- package/dist/backend/core/validators/typebox.js +281 -0
- package/dist/backend/core/validators/typebox.js.map +1 -0
- package/dist/backend/core/validators/valibot.cjs +942 -0
- package/dist/backend/core/validators/valibot.cjs.map +1 -0
- package/dist/backend/core/validators/valibot.d.cts +160 -0
- package/dist/backend/core/validators/valibot.d.ts +160 -0
- package/dist/backend/core/validators/valibot.js +294 -0
- package/dist/backend/core/validators/valibot.js.map +1 -0
- package/dist/backend/core/validators/zod.cjs +934 -0
- package/dist/backend/core/validators/zod.cjs.map +1 -0
- package/dist/backend/core/validators/zod.d.cts +188 -0
- package/dist/backend/core/validators/zod.d.ts +188 -0
- package/dist/backend/core/validators/zod.js +278 -0
- package/dist/backend/core/validators/zod.js.map +1 -0
- package/dist/backend/frameworks/elysia.cjs +715 -0
- package/dist/backend/frameworks/elysia.cjs.map +1 -0
- package/dist/backend/frameworks/elysia.d.cts +208 -0
- package/dist/backend/frameworks/elysia.d.ts +208 -0
- package/dist/backend/frameworks/elysia.js +251 -0
- package/dist/backend/frameworks/elysia.js.map +1 -0
- package/dist/backend/frameworks/fastify.cjs +677 -0
- package/dist/backend/frameworks/fastify.cjs.map +1 -0
- package/dist/backend/frameworks/fastify.d.cts +201 -0
- package/dist/backend/frameworks/fastify.d.ts +201 -0
- package/dist/backend/frameworks/fastify.js +213 -0
- package/dist/backend/frameworks/fastify.js.map +1 -0
- package/dist/backend/frameworks/hono.cjs +715 -0
- package/dist/backend/frameworks/hono.cjs.map +1 -0
- package/dist/backend/frameworks/hono.d.cts +163 -0
- package/dist/backend/frameworks/hono.d.ts +163 -0
- package/dist/backend/frameworks/hono.js +249 -0
- package/dist/backend/frameworks/hono.js.map +1 -0
- package/dist/backend/frameworks/nestjs.cjs +260 -0
- package/dist/backend/frameworks/nestjs.cjs.map +1 -0
- package/dist/backend/frameworks/nestjs.d.cts +168 -0
- package/dist/backend/frameworks/nestjs.d.ts +168 -0
- package/dist/backend/frameworks/nestjs.js +193 -0
- package/dist/backend/frameworks/nestjs.js.map +1 -0
- package/dist/base-dto.class-D7W9iqoU.d.cts +146 -0
- package/dist/base-dto.class-D7W9iqoU.d.ts +146 -0
- package/dist/base-uuid-v7.vo-BPGEIWLM.d.ts +799 -0
- package/dist/base-uuid-v7.vo-BjqKX44G.d.cts +799 -0
- package/dist/chunk-74IKUOSE.js +116 -0
- package/dist/chunk-74IKUOSE.js.map +1 -0
- package/dist/chunk-BKZOLGQW.js +29 -0
- package/dist/chunk-BKZOLGQW.js.map +1 -0
- package/dist/chunk-CGZBV6BD.js +54 -0
- package/dist/chunk-CGZBV6BD.js.map +1 -0
- package/dist/chunk-DDAHJZVK.js +258 -0
- package/dist/chunk-DDAHJZVK.js.map +1 -0
- package/dist/chunk-MQD5GXMT.js +171 -0
- package/dist/chunk-MQD5GXMT.js.map +1 -0
- package/dist/chunk-OKFXZHBC.js +43 -0
- package/dist/chunk-OKFXZHBC.js.map +1 -0
- package/dist/chunk-RLLWYFPI.js +168 -0
- package/dist/chunk-RLLWYFPI.js.map +1 -0
- package/dist/chunk-VCHFXT5W.js +425 -0
- package/dist/chunk-VCHFXT5W.js.map +1 -0
- package/dist/chunk-ZWLYNGO3.js +40 -0
- package/dist/chunk-ZWLYNGO3.js.map +1 -0
- package/dist/http-response-BAhi8lF4.d.cts +124 -0
- package/dist/http-response-BAhi8lF4.d.ts +124 -0
- package/dist/index-DingXh7B.d.cts +1187 -0
- package/dist/index-tOH7XBa3.d.ts +1187 -0
- package/dist/routing.type-DB4pt-d9.d.ts +184 -0
- package/dist/routing.type-DF2BIL7x.d.cts +184 -0
- package/dist/validation-error.type-kD4_qNZ9.d.cts +199 -0
- package/dist/validation-error.type-kD4_qNZ9.d.ts +199 -0
- package/package.json +191 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/backend/core/onion-layers/index.ts","../../../src/backend/core/global/exceptions/coded-error.error.ts","../../../src/backend/core/global/exceptions/error-codes.const.ts","../../../src/backend/core/global/exceptions/object-validation.error.ts","../../../src/backend/core/global/utils/wrap-error.util.ts","../../../src/backend/core/onion-layers/app/exceptions/use-case.error.ts","../../../src/backend/core/onion-layers/domain/exceptions/domain.error.ts","../../../src/backend/core/onion-layers/infra/exceptions/infra.error.ts","../../../src/backend/core/onion-layers/app/classes/base-inbound-adapter.class.ts","../../../src/backend/core/onion-layers/app/exceptions/not-found.error.ts","../../../src/backend/core/onion-layers/app/exceptions/conflict.error.ts","../../../src/backend/core/onion-layers/app/exceptions/unprocessable.error.ts","../../../src/backend/core/onion-layers/domain/classes/base-entity.class.ts","../../../src/backend/core/onion-layers/domain/classes/base-aggregate-root.class.ts","../../../src/backend/core/onion-layers/domain/classes/base-domain-event.class.ts","../../../src/backend/core/onion-layers/domain/classes/base-value-object.class.ts","../../../src/backend/core/onion-layers/domain/exceptions/invariant-violation.error.ts","../../../src/backend/core/onion-layers/domain/exceptions/partial-load.error.ts","../../../src/backend/core/onion-layers/domain/value-objects/base-audit-by.vo.ts","../../../src/backend/core/onion-layers/domain/value-objects/base-audit-info.vo.ts","../../../src/backend/core/onion-layers/domain/value-objects/base-audit-on.vo.ts","../../../src/backend/core/onion-layers/domain/value-objects/base-email.vo.ts","../../../src/backend/core/onion-layers/domain/value-objects/base-long-text.vo.ts","../../../src/backend/core/onion-layers/domain/value-objects/base-medium-text.vo.ts","../../../src/backend/core/onion-layers/domain/value-objects/base-pagination.vo.ts","../../../src/backend/core/onion-layers/domain/value-objects/base-short-text.vo.ts","../../../src/backend/core/onion-layers/domain/value-objects/base-uuid-v4.vo.ts","../../../src/backend/core/onion-layers/domain/value-objects/base-uuid-v7.vo.ts","../../../src/backend/core/onion-layers/domain/example-domain/value-objects/money.vo.ts","../../../src/backend/core/onion-layers/domain/example-domain/value-objects/order-id.vo.ts","../../../src/backend/core/onion-layers/domain/example-domain/value-objects/order-status.vo.ts","../../../src/backend/core/onion-layers/domain/example-domain/events/order-cancelled.event.ts","../../../src/backend/core/onion-layers/domain/example-domain/events/order-placed.event.ts","../../../src/backend/core/onion-layers/domain/example-domain/aggregates/order/policies/value/default-order-status.policy.ts","../../../src/backend/core/onion-layers/domain/example-domain/aggregates/order/policies/business/can-add-order-item.policy.ts","../../../src/backend/core/onion-layers/domain/example-domain/aggregates/order/policies/business/can-cancel-order.policy.ts","../../../src/backend/core/onion-layers/domain/example-domain/aggregates/order/order.aggregate.ts","../../../src/backend/core/onion-layers/domain/example-domain/entities/order-item-id.vo.ts","../../../src/backend/core/onion-layers/domain/example-domain/entities/order-item.entity.ts","../../../src/backend/core/onion-layers/domain/example-domain/exceptions/order-already-shipped.error.ts","../../../src/backend/core/onion-layers/infra/classes/base-outbound-adapter.class.ts","../../../src/backend/core/onion-layers/infra/exceptions/db.error.ts","../../../src/backend/core/onion-layers/infra/exceptions/network.error.ts","../../../src/backend/core/onion-layers/infra/exceptions/timeout.error.ts","../../../src/backend/core/onion-layers/infra/exceptions/external-service.error.ts","../../../src/backend/core/onion-layers/presentation/exceptions/controller.error.ts","../../../src/backend/core/onion-layers/presentation/exceptions/invalid-request.error.ts","../../../src/backend/core/onion-layers/presentation/classes/base-controller.class.ts","../../../src/backend/core/onion-layers/presentation/exceptions/access-denied.error.ts","../../../src/backend/core/onion-layers/presentation/classes/guarded-controller.class.ts","../../../src/backend/core/onion-layers/presentation/interfaces/types/metadata/system-metadata.type.ts","../../../src/backend/core/onion-layers/presentation/routing/compute-route-path.util.ts","../../../src/backend/core/onion-layers/presentation/utils/http-response.util.ts"],"sourcesContent":["export * from './app';\nexport * from './domain';\nexport * from './infra';\nexport * from './presentation';\n","import type { ErrorCode } from './error-codes.const';\n\n/**\n * Base error class for all application errors with a machine-readable code.\n *\n * Abstract class that extends the native `Error` with:\n * - A `code` property for programmatic error handling\n * - Optional `cause` for error chaining (ES2022 compatible)\n * - A `fromError` static factory pattern for error transformation\n *\n * **Why abstract:** Prevents non-declarative error usage. All errors must\n * be explicitly defined as subclasses to ensure consistent error taxonomy.\n *\n * @example Subclass implementation\n * ```typescript\n * class DbError extends InfraError {\n * static override fromError(cause: unknown): DbError {\n * return new DbError({\n * message: cause instanceof Error ? cause.message : 'Database error',\n * cause,\n * });\n * }\n * }\n * ```\n *\n * @example Usage with wrapErrorAsync\n * ```typescript\n * await wrapErrorAsync(\n * () => this.db.query(...),\n * DbError.fromError,\n * );\n * ```\n */\nexport abstract class CodedError extends Error {\n /** Machine-readable error code for programmatic handling. */\n public readonly code: ErrorCode | string;\n\n /**\n * Creates a new CodedError instance.\n *\n * @param options - Error configuration\n * @param options.message - Human-readable error message\n * @param options.code - Machine-readable error code from ErrorCodes registry or custom string\n * @param options.cause - Optional underlying error that caused this error\n */\n constructor({\n message,\n code,\n cause,\n }: {\n message: string;\n code: ErrorCode | string;\n cause?: unknown;\n }) {\n super(message);\n this.name = this.constructor.name;\n this.code = code;\n if (cause !== undefined) {\n Object.defineProperty(this, 'cause', {\n value: cause,\n writable: false,\n enumerable: false,\n configurable: true,\n });\n }\n }\n\n /**\n * Factory method to create a typed error from a caught error.\n *\n * Subclasses should override this to provide proper error transformation.\n * Designed for use with {@link wrapErrorAsync} and {@link wrapError}.\n *\n * @param _cause - The original caught error\n * @returns A new CodedError instance\n * @throws {Error} If not overridden by subclass\n *\n * @example\n * ```typescript\n * class NotFoundError extends UseCaseError {\n * static override fromError(cause: unknown): NotFoundError {\n * return new NotFoundError({\n * message: 'Resource not found',\n * cause,\n * });\n * }\n * }\n * ```\n */\n static fromError(_cause: unknown): CodedError {\n throw new Error(`${this.name}.fromError() must be implemented by subclass`);\n }\n}\n","/**\n * Centralized registry of all error codes used across the application.\n *\n * Error codes are grouped by architectural layer to maintain clear boundaries\n * and make it easy to identify where an error originated.\n *\n * @example Using error codes in custom errors\n * ```typescript\n * import { ErrorCodes } from '@cosmneo/onion-lasagna/backend/core/global';\n *\n * throw new NotFoundError({\n * message: 'User not found',\n * code: ErrorCodes.App.NOT_FOUND,\n * });\n * ```\n *\n * @example Checking error codes programmatically\n * ```typescript\n * if (error.code === ErrorCodes.App.NOT_FOUND) {\n * // Handle not found case\n * }\n * ```\n */\nexport const ErrorCodes = {\n /**\n * Domain layer error codes.\n * Used for business rule violations and invariant failures.\n */\n Domain: {\n /** Generic domain error */\n DOMAIN_ERROR: 'DOMAIN_ERROR',\n /** Business invariant was violated */\n INVARIANT_VIOLATION: 'INVARIANT_VIOLATION',\n /** Aggregate was partially loaded (missing required relations) */\n PARTIAL_LOAD: 'PARTIAL_LOAD',\n },\n\n /**\n * Application layer (use case) error codes.\n * Used for orchestration failures and business operation errors.\n */\n App: {\n /** Generic use case error */\n USE_CASE_ERROR: 'USE_CASE_ERROR',\n /** Requested resource was not found */\n NOT_FOUND: 'NOT_FOUND',\n /** Resource state conflict (e.g., duplicate, already exists) */\n CONFLICT: 'CONFLICT',\n /** Request is valid but cannot be processed due to business rules */\n UNPROCESSABLE: 'UNPROCESSABLE',\n },\n\n /**\n * Infrastructure layer error codes.\n * Used for data access, external services, and I/O failures.\n */\n Infra: {\n /** Generic infrastructure error */\n INFRA_ERROR: 'INFRA_ERROR',\n /** Database operation failed */\n DB_ERROR: 'DB_ERROR',\n /** Network connectivity or communication error */\n NETWORK_ERROR: 'NETWORK_ERROR',\n /** Operation timed out */\n TIMEOUT_ERROR: 'TIMEOUT_ERROR',\n /** External/third-party service error */\n EXTERNAL_SERVICE_ERROR: 'EXTERNAL_SERVICE_ERROR',\n },\n\n /**\n * Presentation layer error codes.\n * Used for controller, request handling, and authorization errors.\n */\n Presentation: {\n /** Generic controller error */\n CONTROLLER_ERROR: 'CONTROLLER_ERROR',\n /** Request denied due to authorization failure */\n ACCESS_DENIED: 'ACCESS_DENIED',\n /** Request validation failed (malformed input) */\n INVALID_REQUEST: 'INVALID_REQUEST',\n },\n\n /**\n * Global/cross-cutting error codes.\n * Used for validation and other cross-layer concerns.\n */\n Global: {\n /** Object/schema validation failed */\n OBJECT_VALIDATION_ERROR: 'OBJECT_VALIDATION_ERROR',\n },\n} as const;\n\n/**\n * Type representing all possible domain error codes.\n */\nexport type DomainErrorCode = (typeof ErrorCodes.Domain)[keyof typeof ErrorCodes.Domain];\n\n/**\n * Type representing all possible application error codes.\n */\nexport type AppErrorCode = (typeof ErrorCodes.App)[keyof typeof ErrorCodes.App];\n\n/**\n * Type representing all possible infrastructure error codes.\n */\nexport type InfraErrorCode = (typeof ErrorCodes.Infra)[keyof typeof ErrorCodes.Infra];\n\n/**\n * Type representing all possible presentation error codes.\n */\nexport type PresentationErrorCode =\n (typeof ErrorCodes.Presentation)[keyof typeof ErrorCodes.Presentation];\n\n/**\n * Type representing all possible global error codes.\n */\nexport type GlobalErrorCode = (typeof ErrorCodes.Global)[keyof typeof ErrorCodes.Global];\n\n/**\n * Union type of all error codes across all layers.\n *\n * Use this when you need to accept any valid error code.\n *\n * @example\n * ```typescript\n * function logError(code: ErrorCode, message: string) {\n * console.error(`[${code}] ${message}`);\n * }\n * ```\n */\nexport type ErrorCode =\n | DomainErrorCode\n | AppErrorCode\n | InfraErrorCode\n | PresentationErrorCode\n | GlobalErrorCode;\n","import { CodedError } from './coded-error.error';\nimport { ErrorCodes, type GlobalErrorCode } from './error-codes.const';\nimport type { ValidationError } from '../interfaces/types/validation-error.type';\n\n/**\n * Error thrown when object validation fails.\n *\n * Contains structured validation errors with field paths and messages,\n * making it easy to report specific validation failures to clients.\n * Thrown by all validator implementations (Zod, ArkType, TypeBox, Valibot).\n *\n * **Flow:**\n * 1. Validator throws `ObjectValidationError` with field-level errors\n * 2. Controller catches and converts to {@link InvalidRequestError}\n * 3. HTTP layer maps to 400 Bad Request with error details\n *\n * @example\n * ```typescript\n * try {\n * const dto = CreateUserDto.create(invalidData);\n * } catch (error) {\n * if (error instanceof ObjectValidationError) {\n * console.log(error.validationErrors);\n * // [\n * // { field: 'email', message: 'Invalid email format' },\n * // { field: 'age', message: 'Must be a positive number' }\n * // ]\n * }\n * }\n * ```\n */\nexport class ObjectValidationError extends CodedError {\n /**\n * Array of field-level validation errors.\n *\n * Each entry contains:\n * - `field`: Dot-notation path to the invalid field (e.g., 'user.email')\n * - `message`: Human-readable validation failure message\n */\n validationErrors: ValidationError[];\n\n /**\n * Creates a new ObjectValidationError instance.\n *\n * @param options - Error configuration\n * @param options.message - Human-readable summary message\n * @param options.code - Machine-readable error code (default: 'OBJECT_VALIDATION_ERROR')\n * @param options.cause - Optional underlying error from validation library\n * @param options.validationErrors - Array of field-level validation errors\n */\n constructor({\n message,\n code = ErrorCodes.Global.OBJECT_VALIDATION_ERROR,\n cause,\n validationErrors,\n }: {\n message: string;\n code?: GlobalErrorCode | string;\n cause?: unknown;\n validationErrors: ValidationError[];\n }) {\n super({ message, code, cause });\n this.validationErrors = validationErrors;\n }\n\n /**\n * Creates an ObjectValidationError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new ObjectValidationError instance with the cause attached\n */\n static override fromError(cause: unknown): ObjectValidationError {\n return new ObjectValidationError({\n message: cause instanceof Error ? cause.message : 'Validation failed',\n cause,\n validationErrors: [],\n });\n }\n}\n","/**\n * Error wrapping utilities for boundary error handling.\n *\n * Provides functions to wrap code execution with error transformation,\n * converting caught errors into typed Error instances.\n * Useful at layer boundaries (infra, use case, controller) to normalize errors.\n *\n * @example Wrapping async database calls\n * ```typescript\n * const user = await wrapErrorAsync(\n * () => this.db.query('SELECT * FROM users WHERE id = ?', [id]),\n * (cause) => new DbError({ message: 'Failed to fetch user', cause }),\n * );\n * ```\n *\n * @example Wrapping sync operations\n * ```typescript\n * const parsed = wrapError(\n * () => JSON.parse(data),\n * (cause) => new InvariantViolationError({\n * message: 'Invalid JSON format',\n * cause,\n * }),\n * );\n * ```\n *\n * @module\n */\n\n/**\n * Factory function that creates an Error from a caught error.\n *\n * @typeParam E - The specific Error subclass to create\n * @param cause - The original caught error\n * @returns A new Error instance\n */\nexport type ErrorFactory<E extends Error> = (cause: unknown) => E;\n\n/**\n * Wraps a synchronous function with error transformation.\n *\n * Executes the provided function and catches any thrown errors,\n * transforming them using the error factory.\n *\n * @typeParam T - The return type of the wrapped function\n * @typeParam E - The Error subclass to throw on error\n * @param fn - The function to execute\n * @param errorFactory - Factory to create the typed error from the caught error\n * @returns The result of the function if successful\n * @throws {E} The transformed error if the function throws\n *\n * @example\n * ```typescript\n * const config = wrapError(\n * () => JSON.parse(configString),\n * (cause) => new InvariantViolationError({\n * message: 'Invalid configuration format',\n * code: 'CONFIG_PARSE_ERROR',\n * cause,\n * }),\n * );\n * ```\n */\nexport function wrapError<T, E extends Error>(fn: () => T, errorFactory: ErrorFactory<E>): T {\n try {\n return fn();\n } catch (error) {\n throw errorFactory(error);\n }\n}\n\n/**\n * Wraps an asynchronous function with error transformation.\n *\n * Executes the provided async function and catches any thrown errors,\n * transforming them using the error factory.\n *\n * @typeParam T - The return type of the wrapped function\n * @typeParam E - The Error subclass to throw on error\n * @param fn - The async function to execute\n * @param errorFactory - Factory to create the typed error from the caught error\n * @returns A promise resolving to the result if successful\n * @throws {E} The transformed error if the function throws\n *\n * @example Repository usage\n * ```typescript\n * async findById(id: string): Promise<User | null> {\n * return wrapErrorAsync(\n * () => this.db.users.findUnique({ where: { id } }),\n * (cause) => new DbError({\n * message: `Failed to find user by ID: ${id}`,\n * cause,\n * }),\n * );\n * }\n * ```\n *\n * @example External service usage\n * ```typescript\n * async sendEmail(to: string, body: string): Promise<void> {\n * await wrapErrorAsync(\n * () => this.emailClient.send({ to, body }),\n * (cause) => new ExternalServiceError({\n * message: 'Email delivery failed',\n * code: 'EMAIL_SEND_FAILED',\n * cause,\n * }),\n * );\n * }\n * ```\n */\nexport async function wrapErrorAsync<T, E extends Error>(\n fn: () => Promise<T>,\n errorFactory: ErrorFactory<E>,\n): Promise<T> {\n try {\n return await fn();\n } catch (error) {\n throw errorFactory(error);\n }\n}\n\n/**\n * Constructor type for error classes (including abstract classes).\n *\n * Used to specify error types that should pass through without transformation.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type ErrorConstructor = abstract new (...args: any[]) => Error;\n\n/**\n * Wraps a synchronous function with conditional error transformation.\n *\n * Executes the provided function and catches any thrown errors.\n * Errors matching any of the passthrough types are re-thrown as-is.\n * All other errors are transformed using the error factory.\n *\n * @typeParam T - The return type of the wrapped function\n * @typeParam E - The Error subclass to throw for unknown errors\n * @param fn - The function to execute\n * @param errorFactory - Factory to create the typed error from unknown errors\n * @param passthroughTypes - Array of error classes to re-throw without transformation\n * @returns The result of the function if successful\n * @throws The original error if it matches a passthrough type\n * @throws {E} The transformed error for unknown error types\n *\n * @example Controller boundary\n * ```typescript\n * const result = wrapErrorUnless(\n * () => this.requestMapper(input),\n * (cause) => new ControllerError({ message: 'Mapping failed', cause }),\n * [CodedError],\n * );\n * ```\n */\nexport function wrapErrorUnless<T, E extends Error>(\n fn: () => T,\n errorFactory: ErrorFactory<E>,\n passthroughTypes: ErrorConstructor[],\n): T {\n try {\n return fn();\n } catch (error) {\n if (passthroughTypes.some((Type) => error instanceof Type)) {\n throw error;\n }\n throw errorFactory(error);\n }\n}\n\n/**\n * Wraps an asynchronous function with conditional error transformation.\n *\n * Executes the provided async function and catches any thrown errors.\n * Errors matching any of the passthrough types are re-thrown as-is.\n * All other errors are transformed using the error factory.\n *\n * @typeParam T - The return type of the wrapped function\n * @typeParam E - The Error subclass to throw for unknown errors\n * @param fn - The async function to execute\n * @param errorFactory - Factory to create the typed error from unknown errors\n * @param passthroughTypes - Array of error classes to re-throw without transformation\n * @returns A promise resolving to the result if successful\n * @throws The original error if it matches a passthrough type\n * @throws {E} The transformed error for unknown error types\n *\n * @example Use case boundary\n * ```typescript\n * return wrapErrorUnlessAsync(\n * () => this.handle(input),\n * (cause) => new UseCaseError({ message: 'Unexpected error', cause }),\n * [ObjectValidationError, UseCaseError, DomainError, InfraError],\n * );\n * ```\n *\n * @example Controller boundary\n * ```typescript\n * return wrapErrorUnlessAsync(\n * async () => {\n * const result = await this.useCase.execute(input);\n * return this.responseMapper(result);\n * },\n * (cause) => new ControllerError({ message: 'Controller failed', cause }),\n * [CodedError],\n * );\n * ```\n */\nexport async function wrapErrorUnlessAsync<T, E extends Error>(\n fn: () => Promise<T>,\n errorFactory: ErrorFactory<E>,\n passthroughTypes: ErrorConstructor[],\n): Promise<T> {\n try {\n return await fn();\n } catch (error) {\n if (passthroughTypes.some((Type) => error instanceof Type)) {\n throw error;\n }\n throw errorFactory(error);\n }\n}\n","import { CodedError } from '../../../global/exceptions/coded-error.error';\nimport { ErrorCodes, type AppErrorCode } from '../../../global/exceptions/error-codes.const';\n\n/**\n * Base error class for application layer (use case) failures.\n *\n * Use case errors represent failures in the application's business logic\n * orchestration, such as resource conflicts, missing entities, or\n * unprocessable requests. They bridge domain errors to the presentation layer.\n *\n * **When to throw:**\n * - Resource not found (e.g., \"User with ID X not found\")\n * - Conflict states (e.g., \"Email already registered\")\n * - Unprocessable business operations\n *\n * **Child classes:**\n * - {@link ConflictError} - Resource state conflicts (HTTP 409)\n * - {@link NotFoundError} - Resource not found (HTTP 404)\n * - {@link UnprocessableError} - Valid but unprocessable request (HTTP 422)\n *\n * @example\n * ```typescript\n * const user = await this.userRepo.findById(id);\n * if (!user) {\n * throw new NotFoundError({\n * message: `User with ID ${id} not found`,\n * code: 'USER_NOT_FOUND',\n * });\n * }\n * ```\n */\nexport class UseCaseError extends CodedError {\n /**\n * Creates a new UseCaseError instance.\n *\n * @param options - Error configuration\n * @param options.message - Human-readable error description\n * @param options.code - Machine-readable error code (default: 'USE_CASE_ERROR')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.App.USE_CASE_ERROR,\n cause,\n }: {\n message: string;\n code?: AppErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates a UseCaseError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new UseCaseError instance with the cause attached\n */\n static override fromError(cause: unknown): UseCaseError {\n return new UseCaseError({\n message: cause instanceof Error ? cause.message : 'Use case error',\n cause,\n });\n }\n}\n","import { CodedError } from '../../../global/exceptions/coded-error.error';\nimport { ErrorCodes, type DomainErrorCode } from '../../../global/exceptions/error-codes.const';\n\n/**\n * Base error class for domain layer failures.\n *\n * Domain errors represent violations of business rules, invariants,\n * or aggregate consistency. They originate from the core domain logic\n * and should be caught and handled by the application layer.\n *\n * **When to throw:**\n * - Business rule violations (e.g., \"Cannot withdraw more than balance\")\n * - Invariant violations (e.g., \"Email format invalid\")\n * - Aggregate consistency failures\n *\n * **Child classes:**\n * - {@link InvariantViolationError} - Value object or entity invariant failures\n * - {@link PartialLoadError} - Incomplete aggregate reconstitution\n *\n * @example\n * ```typescript\n * if (account.balance < amount) {\n * throw new DomainError({\n * message: 'Insufficient funds for withdrawal',\n * code: 'INSUFFICIENT_FUNDS',\n * });\n * }\n * ```\n */\nexport class DomainError extends CodedError {\n /**\n * Creates a new DomainError instance.\n *\n * @param options - Error configuration\n * @param options.message - Human-readable error description\n * @param options.code - Machine-readable error code (default: 'DOMAIN_ERROR')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.Domain.DOMAIN_ERROR,\n cause,\n }: {\n message: string;\n code?: DomainErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates a DomainError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new DomainError instance with the cause attached\n */\n static override fromError(cause: unknown): DomainError {\n return new DomainError({\n message: cause instanceof Error ? cause.message : 'Domain error',\n cause,\n });\n }\n}\n","import { CodedError } from '../../../global/exceptions/coded-error.error';\nimport { ErrorCodes, type InfraErrorCode } from '../../../global/exceptions/error-codes.const';\n\n/**\n * Base error class for infrastructure layer failures.\n *\n * Infrastructure errors represent failures in external dependencies\n * such as databases, network services, file systems, or third-party APIs.\n * They are automatically created by {@link BaseOutboundAdapter} when\n * repository or gateway methods fail.\n *\n * **When to throw:**\n * - Database connection or query failures\n * - Network timeouts or connection errors\n * - External API failures\n * - File system errors\n *\n * **Child classes:**\n * - {@link DbError} - Database operation failures\n * - {@link NetworkError} - Network connectivity issues\n * - {@link TimeoutError} - Operation timeout\n * - {@link ExternalServiceError} - Third-party service failures\n *\n * @example\n * ```typescript\n * // In a repository extending BaseOutboundAdapter\n * protected override createInfraError(error: unknown, methodName: string): InfraError {\n * return new DbError({\n * message: `Database error in ${methodName}`,\n * cause: error,\n * });\n * }\n * ```\n */\nexport class InfraError extends CodedError {\n /**\n * Creates a new InfraError instance.\n *\n * @param options - Error configuration\n * @param options.message - Human-readable error description\n * @param options.code - Machine-readable error code (default: 'INFRA_ERROR')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.Infra.INFRA_ERROR,\n cause,\n }: {\n message: string;\n code?: InfraErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates an InfraError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new InfraError instance with the cause attached\n */\n static override fromError(cause: unknown): InfraError {\n return new InfraError({\n message: cause instanceof Error ? cause.message : 'Infrastructure error',\n cause,\n });\n }\n}\n","import type { BaseDto } from '../../../global/classes/base-dto.class';\nimport type { BaseInboundPort } from '../interfaces/ports/base-inbound.port';\nimport { ObjectValidationError } from '../../../global/exceptions/object-validation.error';\nimport { wrapErrorUnlessAsync } from '../../../global/utils/wrap-error.util';\nimport { UseCaseError } from '../exceptions/use-case.error';\nimport { DomainError } from '../../domain/exceptions/domain.error';\nimport { InfraError } from '../../infra/exceptions/infra.error';\n\n/**\n * Abstract base class for use case handlers (inbound adapters).\n *\n * Implements the {@link BaseInboundPort} interface and provides:\n * - Automatic error wrapping for unexpected exceptions\n * - Pass-through for known error types (UseCaseError, DomainError, InfraError)\n *\n * Subclasses implement the `handle` method with the actual use case logic.\n *\n * @typeParam TInDto - Input DTO type, must extend BaseDto\n * @typeParam TOutDto - Output DTO type, must extend BaseDto\n *\n * @example\n * ```typescript\n * class CreateUserUseCase extends BaseInboundAdapter<CreateUserInputDto, CreateUserOutputDto> {\n * protected async handle(input: CreateUserInputDto): Promise<CreateUserOutputDto> {\n * const user = await this.userRepo.create(input.value);\n * return CreateUserOutputDto.create(user);\n * }\n * }\n * ```\n */\nexport abstract class BaseInboundAdapter<\n TInDto extends BaseDto<unknown>,\n TOutDto extends BaseDto<unknown>,\n> implements BaseInboundPort<TInDto, TOutDto> {\n /**\n * Implements the use case logic. Override this method in subclasses.\n *\n * @param input - Validated input DTO\n * @returns Promise resolving to the output DTO\n */\n protected abstract handle(input: TInDto): Promise<TOutDto>;\n\n /**\n * Executes the use case with error boundary protection.\n *\n * Known error types are re-thrown as-is to preserve error semantics.\n * Unknown errors are wrapped in a UseCaseError to maintain error hierarchy.\n *\n * @param input - Validated input DTO\n * @returns Promise resolving to the output DTO\n * @throws {ObjectValidationError} For validation failures (propagated to controller)\n * @throws {UseCaseError} For use case failures or wrapped unknown errors\n * @throws {DomainError} For domain invariant violations\n * @throws {InfraError} For infrastructure failures\n */\n public async execute(input: TInDto): Promise<TOutDto> {\n return wrapErrorUnlessAsync(\n () => this.handle(input),\n (cause) => new UseCaseError({ message: 'Unexpected use case handler error', cause }),\n [ObjectValidationError, UseCaseError, DomainError, InfraError],\n );\n }\n}\n","import { ErrorCodes, type AppErrorCode } from '../../../global/exceptions/error-codes.const';\nimport { UseCaseError } from './use-case.error';\n\n/**\n * Error thrown when a requested resource does not exist.\n *\n * Indicates that the entity or resource referenced by the request\n * could not be found in the system.\n *\n * **When to throw:**\n * - Entity lookup by ID returns null\n * - Referenced resource doesn't exist\n * - Parent entity for a child operation not found\n *\n * @example\n * ```typescript\n * const user = await this.userRepo.findById(userId);\n * if (!user) {\n * throw new NotFoundError({\n * message: `User with ID ${userId} not found`,\n * code: 'USER_NOT_FOUND',\n * });\n * }\n * ```\n *\n * @extends UseCaseError\n */\nexport class NotFoundError extends UseCaseError {\n /**\n * Creates a new NotFoundError instance.\n *\n * @param options - Error configuration\n * @param options.message - Description of what was not found\n * @param options.code - Machine-readable error code (default: 'NOT_FOUND')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.App.NOT_FOUND,\n cause,\n }: {\n message: string;\n code?: AppErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates a NotFoundError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new NotFoundError instance with the cause attached\n */\n static override fromError(cause: unknown): NotFoundError {\n return new NotFoundError({\n message: cause instanceof Error ? cause.message : 'Resource not found',\n cause,\n });\n }\n}\n","import { ErrorCodes, type AppErrorCode } from '../../../global/exceptions/error-codes.const';\nimport { UseCaseError } from './use-case.error';\n\n/**\n * Error thrown when an operation conflicts with existing state.\n *\n * Indicates that the requested operation cannot be completed because\n * it would violate uniqueness constraints or cause state conflicts.\n *\n * **When to throw:**\n * - Duplicate unique field (e.g., email already registered)\n * - Optimistic locking conflict (stale version)\n * - Concurrent modification detected\n *\n * @example\n * ```typescript\n * const existing = await this.userRepo.findByEmail(email);\n * if (existing) {\n * throw new ConflictError({\n * message: 'Email already registered',\n * code: 'EMAIL_ALREADY_EXISTS',\n * });\n * }\n * ```\n *\n * @extends UseCaseError\n */\nexport class ConflictError extends UseCaseError {\n /**\n * Creates a new ConflictError instance.\n *\n * @param options - Error configuration\n * @param options.message - Description of the conflict\n * @param options.code - Machine-readable error code (default: 'CONFLICT')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.App.CONFLICT,\n cause,\n }: {\n message: string;\n code?: AppErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates a ConflictError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new ConflictError instance with the cause attached\n */\n static override fromError(cause: unknown): ConflictError {\n return new ConflictError({\n message: cause instanceof Error ? cause.message : 'Conflict error',\n cause,\n });\n }\n}\n","import { ErrorCodes, type AppErrorCode } from '../../../global/exceptions/error-codes.const';\nimport { UseCaseError } from './use-case.error';\n\n/**\n * Error thrown when a request is valid but cannot be processed.\n *\n * The request is syntactically correct and passes validation, but\n * business logic prevents the operation from being completed.\n *\n * **When to throw:**\n * - Business rule prevents operation (e.g., insufficient balance)\n * - Invalid state transition (e.g., canceling a completed order)\n * - Preconditions not met for the operation\n *\n * @example\n * ```typescript\n * if (account.balance < amount) {\n * throw new UnprocessableError({\n * message: 'Insufficient balance for withdrawal',\n * code: 'INSUFFICIENT_BALANCE',\n * });\n * }\n * ```\n *\n * @extends UseCaseError\n */\nexport class UnprocessableError extends UseCaseError {\n /**\n * Creates a new UnprocessableError instance.\n *\n * @param options - Error configuration\n * @param options.message - Description of why the request cannot be processed\n * @param options.code - Machine-readable error code (default: 'UNPROCESSABLE')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.App.UNPROCESSABLE,\n cause,\n }: {\n message: string;\n code?: AppErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates an UnprocessableError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new UnprocessableError instance with the cause attached\n */\n static override fromError(cause: unknown): UnprocessableError {\n return new UnprocessableError({\n message: cause instanceof Error ? cause.message : 'Unprocessable request',\n cause,\n });\n }\n}\n","import type { BaseValueObject } from './base-value-object.class';\n\n/**\n * Base class for Domain-Driven Design Entities.\n *\n * Entities are domain objects that have a distinct identity that runs through\n * time and different states. Unlike Value Objects (compared by value),\n * Entities are compared by their identity (ID).\n *\n * **Note:** Entities should be composed of Value Objects, which are self-validating.\n * Therefore, entity-level validation is not needed - VOs validate themselves\n * at construction time. Cross-property invariants should be checked in factory methods.\n *\n * Key characteristics:\n * - **Identity**: Each entity has a unique identifier (must be a Value Object)\n * - **Equality by identity**: Two entities with the same ID are considered equal\n * - **Mutable state**: Entity properties can change while identity remains\n * - **Composed of VOs**: Properties should be Value Objects (self-validating)\n * - **Versioning**: Optional version field for optimistic locking\n *\n * @typeParam TId - The identity type (must extend BaseValueObject)\n * @typeParam TProps - The properties type containing entity state (must be an object)\n *\n * @example\n * ```typescript\n * interface UserProps {\n * name: PersonName;\n * email: Email;\n * createdAt: DateVo;\n * }\n *\n * class User extends BaseEntity<UserId, UserProps> {\n * private constructor(id: UserId, props: UserProps, version?: number) {\n * super(id, props, version);\n * }\n *\n * static create(name: PersonName, email: Email): User {\n * const id = UserId.create();\n * return new User(id, {\n * name,\n * email,\n * createdAt: DateVo.now(),\n * });\n * }\n *\n * static fromPersistence(id: UserId, props: UserProps, version: number): User {\n * return new User(id, props, version);\n * }\n *\n * get name(): PersonName {\n * return this.props.name;\n * }\n *\n * get email(): Email {\n * return this.props.email;\n * }\n *\n * changeName(newName: PersonName): void {\n * this._props.name = newName;\n * }\n * }\n *\n * const user1 = User.create(PersonName.create('John'), Email.create('john@example.com'));\n * const user2 = User.fromPersistence(user1.id, { ...user1.props }, user1.version);\n * user1.equals(user2); // true - same ID\n * ```\n */\nexport abstract class BaseEntity<TId extends BaseValueObject<unknown>, TProps extends object> {\n private readonly _id: TId;\n protected _props: TProps;\n private readonly _version: number;\n\n /**\n * Creates a new Entity instance.\n *\n * @param id - The unique identifier for this entity\n * @param props - The entity's properties/state (should be composed of Value Objects)\n * @param version - Optional version number for optimistic locking (defaults to 0)\n */\n protected constructor(id: TId, props: TProps, version = 0) {\n this._id = id;\n this._props = props;\n this._version = version;\n }\n\n /**\n * The unique identifier for this entity.\n *\n * @returns The entity's ID of type TId\n */\n public get id(): TId {\n return this._id;\n }\n\n /**\n * The entity's properties/state.\n *\n * Protected to encourage encapsulation via specific getters.\n * Subclasses should expose individual properties as needed.\n *\n * @returns The entity's properties of type TProps\n */\n protected get props(): TProps {\n return this._props;\n }\n\n /**\n * The version number for optimistic locking.\n *\n * Use this to detect concurrent modifications:\n * - Load entity with version N\n * - Attempt to save with \"WHERE version = N\"\n * - If rows affected = 0, another process modified the entity\n *\n * @returns The current version number\n */\n public get version(): number {\n return this._version;\n }\n\n /**\n * Compares this Entity with another for equality.\n *\n * Entities are equal if they have the same identity (ID).\n * This differs from Value Objects which compare by value.\n *\n * @param other - The Entity to compare with\n * @returns `true` if the IDs are equal, `false` otherwise\n *\n * @example\n * ```typescript\n * const user1 = User.create(PersonName.create('John'), Email.create('john@example.com'));\n * const user2 = User.fromPersistence(user1.id, { name: PersonName.create('John Updated'), ... }, 1);\n * user1.equals(user2); // true - same ID, different state\n * ```\n */\n public equals(other: BaseEntity<TId, TProps>): boolean {\n if (this === other) return true;\n return this.idEquals(this._id, other._id);\n }\n\n /**\n * Compares two IDs for equality.\n *\n * Since TId must extend BaseValueObject, we use the value object's\n * `equals` method for comparison.\n *\n * @param a - First ID to compare\n * @param b - Second ID to compare\n * @returns `true` if IDs are equal, `false` otherwise\n */\n protected idEquals(a: TId, b: TId): boolean {\n if (a === b) return true;\n return a.equals(b);\n }\n\n /**\n * Returns the next version number.\n *\n * Call this when persisting changes to implement optimistic locking.\n * The repository should save with version + 1.\n *\n * @returns The next version number (current + 1)\n *\n * @example\n * ```typescript\n * // In repository\n * async save(entity: User): Promise<void> {\n * await this.db.update({\n * ...entity.toPersistence(),\n * version: entity.nextVersion(),\n * }).where({ id: entity.id, version: entity.version });\n * }\n * ```\n */\n protected nextVersion(): number {\n return this._version + 1;\n }\n}\n","import type { BaseValueObject } from './base-value-object.class';\nimport { BaseEntity } from './base-entity.class';\nimport type { BaseDomainEvent } from './base-domain-event.class';\n\n/**\n * Base class for Aggregate Roots in Domain-Driven Design.\n *\n * An Aggregate Root is a special Entity that serves as the entry point to an\n * aggregate - a cluster of domain objects that are treated as a single unit\n * for data changes. The Aggregate Root enforces invariants across the entire\n * aggregate and manages domain events.\n *\n * **Note:** Like entities, aggregate roots should be composed of Value Objects,\n * which are self-validating. Cross-property invariants should be checked in\n * factory methods or domain methods.\n *\n * Key characteristics:\n * - **Entry point**: External objects can only reference the Aggregate Root\n * - **Consistency boundary**: All changes within the aggregate are atomic\n * - **Invariant enforcement**: The root ensures all business rules are satisfied\n * - **Event management**: Collects domain events raised during operations\n *\n * @typeParam TId - The identity type (must extend BaseValueObject)\n * @typeParam TProps - The properties type containing aggregate state (must be an object)\n *\n * @example\n * ```typescript\n * interface OrderProps {\n * customerId: CustomerId;\n * items: OrderItem[];\n * status: OrderStatus;\n * placedAt: DateVo;\n * }\n *\n * class Order extends BaseAggregateRoot<OrderId, OrderProps> {\n * private constructor(id: OrderId, props: OrderProps, version?: number) {\n * super(id, props, version);\n * }\n *\n * static create(customerId: CustomerId, items: OrderItem[]): Order {\n * const id = OrderId.create();\n * const order = new Order(id, {\n * customerId,\n * items,\n * status: OrderStatus.pending(),\n * placedAt: DateVo.now(),\n * });\n *\n * // Raise domain event\n * order.addDomainEvent(new OrderPlacedEvent({\n * orderId: id.value,\n * customerId: customerId.value,\n * itemCount: items.length,\n * }));\n *\n * return order;\n * }\n *\n * static fromPersistence(id: OrderId, props: OrderProps, version: number): Order {\n * return new Order(id, props, version);\n * }\n *\n * addItem(item: OrderItem): void {\n * if (!this.props.status.isPending()) {\n * throw new InvariantViolationError({\n * message: 'Cannot add items to a non-pending order',\n * });\n * }\n * this._props.items.push(item);\n * this.addDomainEvent(new OrderItemAddedEvent({\n * orderId: this.id.value,\n * productId: item.productId.value,\n * }));\n * }\n *\n * confirm(): void {\n * this._props.status = OrderStatus.confirmed();\n * this.addDomainEvent(new OrderConfirmedEvent({ orderId: this.id.value }));\n * }\n * }\n *\n * // In repository after save:\n * async save(order: Order): Promise<void> {\n * await this.db.save(order.toPersistence());\n * const events = order.pullDomainEvents();\n * await this.eventPublisher.publishAll(events);\n * }\n * ```\n */\nexport abstract class BaseAggregateRoot<\n TId extends BaseValueObject<unknown>,\n TProps extends object,\n> extends BaseEntity<TId, TProps> {\n private _domainEvents: BaseDomainEvent[] = [];\n\n /**\n * Creates a new Aggregate Root instance.\n *\n * @param id - The unique identifier for this aggregate\n * @param props - The aggregate's properties/state (should be composed of Value Objects)\n * @param version - Optional version number for optimistic locking (defaults to 0)\n */\n protected constructor(id: TId, props: TProps, version?: number) {\n super(id, props, version);\n }\n\n /**\n * Adds a domain event to be published after persistence.\n *\n * Call this method when a significant domain action occurs.\n * Events are collected and should be published by the repository\n * after successfully persisting the aggregate.\n *\n * @param event - The domain event to add\n *\n * @example\n * ```typescript\n * confirm(): void {\n * this._props.status = OrderStatus.confirmed();\n * this.addDomainEvent(new OrderConfirmedEvent({\n * orderId: this.id.value,\n * confirmedAt: new Date(),\n * }));\n * }\n * ```\n */\n protected addDomainEvent(event: BaseDomainEvent): void {\n this._domainEvents.push(event);\n }\n\n /**\n * Returns and clears all pending domain events.\n *\n * This method should be called by the repository after successfully\n * persisting the aggregate. The events are cleared to prevent\n * duplicate publishing.\n *\n * @returns Array of domain events that were pending\n *\n * @example\n * ```typescript\n * // In repository\n * async save(order: Order): Promise<void> {\n * await this.db.transaction(async (tx) => {\n * await tx.orders.upsert(order.toPersistence());\n * });\n *\n * // Only publish after successful persistence\n * const events = order.pullDomainEvents();\n * for (const event of events) {\n * await this.eventBus.publish(event);\n * }\n * }\n * ```\n */\n public pullDomainEvents(): BaseDomainEvent[] {\n const events = [...this._domainEvents];\n this._domainEvents = [];\n return events;\n }\n\n /**\n * Returns pending domain events without clearing them.\n *\n * Useful for inspection or testing without affecting the event queue.\n *\n * @returns Array of pending domain events\n */\n public peekDomainEvents(): readonly BaseDomainEvent[] {\n return [...this._domainEvents];\n }\n\n /**\n * Checks if there are any pending domain events.\n *\n * @returns `true` if there are events waiting to be published\n *\n * @example\n * ```typescript\n * if (order.hasDomainEvents) {\n * const events = order.pullDomainEvents();\n * await eventBus.publishAll(events);\n * }\n * ```\n */\n public get hasDomainEvents(): boolean {\n return this._domainEvents.length > 0;\n }\n\n /**\n * Clears all pending domain events without returning them.\n *\n * Use with caution - this discards events that haven't been published.\n * Useful in testing or when intentionally discarding events.\n */\n protected clearDomainEvents(): void {\n this._domainEvents = [];\n }\n}\n","/**\n * Base class for Domain Events in Domain-Driven Design.\n *\n * Domain Events represent something meaningful that happened in the domain.\n * They are immutable records of past occurrences that other parts of the\n * system can react to.\n *\n * Key characteristics:\n * - **Immutable**: Events are facts about the past, they cannot change\n * - **Named in past tense**: e.g., OrderPlaced, UserRegistered, PaymentReceived\n * - **Contain relevant data**: Include all information needed by handlers\n * - **Raised by Aggregate Roots**: Events are collected and published after persistence\n *\n * @typeParam TPayload - The event-specific data payload type\n *\n * @example\n * ```typescript\n * interface OrderPlacedPayload {\n * orderId: string;\n * customerId: string;\n * items: Array<{ productId: string; quantity: number }>;\n * totalAmount: number;\n * }\n *\n * class OrderPlacedEvent extends BaseDomainEvent<OrderPlacedPayload> {\n * constructor(payload: OrderPlacedPayload) {\n * super('OrderPlaced', payload.orderId, payload);\n * }\n * }\n *\n * // In aggregate root\n * class Order extends BaseAggregateRoot<OrderId, OrderProps> {\n * static create(customerId: string, items: OrderItem[]): Order {\n * const order = new Order(...);\n * order.addDomainEvent(new OrderPlacedEvent({\n * orderId: order.id.value,\n * customerId,\n * items: items.map(i => ({ productId: i.productId, quantity: i.quantity })),\n * totalAmount: order.totalAmount,\n * }));\n * return order;\n * }\n * }\n * ```\n */\nexport abstract class BaseDomainEvent<TPayload = unknown> {\n private readonly _eventId: string;\n private readonly _eventName: string;\n private readonly _aggregateId: string;\n private readonly _occurredOn: Date;\n private readonly _payload: TPayload;\n\n /**\n * Deep clones an object, handling Date objects specially.\n *\n * @param obj - The object to clone\n * @returns A deep copy of the object\n */\n private static deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as T;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => BaseDomainEvent.deepClone(item)) as T;\n }\n\n const cloned = {} as Record<string, unknown>;\n for (const key of Object.keys(obj)) {\n cloned[key] = BaseDomainEvent.deepClone((obj as Record<string, unknown>)[key]);\n }\n return cloned as T;\n }\n\n /**\n * Recursively freezes an object and all nested objects.\n *\n * @param obj - The object to deep freeze\n * @returns The frozen object\n */\n private static deepFreeze<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n // Freeze arrays and their elements\n if (Array.isArray(obj)) {\n obj.forEach((item) => BaseDomainEvent.deepFreeze(item));\n return Object.freeze(obj) as T;\n }\n\n // Freeze object properties recursively\n for (const key of Object.keys(obj)) {\n const value = (obj as Record<string, unknown>)[key];\n if (value !== null && typeof value === 'object') {\n BaseDomainEvent.deepFreeze(value);\n }\n }\n\n return Object.freeze(obj);\n }\n\n /**\n * Creates an immutable copy of the payload.\n *\n * Clones the payload first to avoid mutating the original object,\n * then deep-freezes the clone to ensure immutability.\n *\n * @param payload - The payload to clone and freeze\n * @returns An immutable copy of the payload\n */\n private static cloneAndFreeze<T>(payload: T): T {\n const cloned = BaseDomainEvent.deepClone(payload);\n return BaseDomainEvent.deepFreeze(cloned);\n }\n\n /**\n * Creates a new Domain Event.\n *\n * The payload is cloned and deep-frozen to ensure immutability. The original\n * object passed in remains unmodified. Any attempt to modify the event's\n * payload after creation will throw a TypeError in strict mode.\n *\n * @param eventName - The name of the event (e.g., 'OrderPlaced', 'UserRegistered')\n * @param aggregateId - The ID of the aggregate that raised this event\n * @param payload - The event-specific data (will be cloned and deep-frozen)\n * @param eventId - Optional custom event ID (defaults to crypto.randomUUID())\n * @param occurredOn - Optional timestamp (defaults to now)\n */\n protected constructor(\n eventName: string,\n aggregateId: string,\n payload: TPayload,\n eventId?: string,\n occurredOn?: Date,\n ) {\n this._eventId = eventId ?? crypto.randomUUID();\n this._eventName = eventName;\n this._aggregateId = aggregateId;\n this._occurredOn = occurredOn ?? new Date();\n this._payload = BaseDomainEvent.cloneAndFreeze(payload);\n }\n\n /**\n * Unique identifier for this event instance.\n *\n * Useful for idempotency checks and event deduplication.\n */\n public get eventId(): string {\n return this._eventId;\n }\n\n /**\n * The name/type of this event.\n *\n * Used for routing events to appropriate handlers.\n * Should be in PastTense format (e.g., 'OrderPlaced', 'UserRegistered').\n */\n public get eventName(): string {\n return this._eventName;\n }\n\n /**\n * The ID of the aggregate that raised this event.\n *\n * Useful for event sourcing and aggregate-specific event streams.\n */\n public get aggregateId(): string {\n return this._aggregateId;\n }\n\n /**\n * Timestamp when this event occurred.\n *\n * Represents the moment the domain action happened.\n */\n public get occurredOn(): Date {\n return this._occurredOn;\n }\n\n /**\n * The event-specific data payload.\n *\n * Contains all information needed by event handlers.\n */\n public get payload(): TPayload {\n return this._payload;\n }\n\n /**\n * Serializes the event to a plain object for persistence or messaging.\n *\n * @returns A plain object representation of the event\n *\n * @example\n * ```typescript\n * const event = new OrderPlacedEvent({ orderId: '123', ... });\n * const serialized = event.toJSON();\n * // {\n * // eventId: 'uuid',\n * // eventName: 'OrderPlaced',\n * // aggregateId: '123',\n * // occurredOn: '2024-01-15T10:30:00.000Z',\n * // payload: { orderId: '123', ... }\n * // }\n * ```\n */\n public toJSON(): {\n eventId: string;\n eventName: string;\n aggregateId: string;\n occurredOn: string;\n payload: TPayload;\n } {\n return {\n eventId: this._eventId,\n eventName: this._eventName,\n aggregateId: this._aggregateId,\n occurredOn: this._occurredOn.toISOString(),\n payload: this._payload,\n };\n }\n}\n","import type { BoundValidator } from '../../../global/interfaces/ports/object-validator.port';\n\n/**\n * Sentinel value to skip validation in Value Object constructors.\n *\n * Use this when creating a Value Object from already-validated data,\n * such as when reconstituting from a database or creating derived VOs.\n *\n * @example\n * ```typescript\n * // In a VO that wraps a validated value\n * class Email extends BaseValueObject<string> {\n * private constructor(value: string, validator: BoundValidator<string> | SkipValueObjectValidation) {\n * super(value, validator);\n * }\n *\n * // Public factory validates\n * static create(value: string): Email {\n * return new Email(value, emailValidator);\n * }\n *\n * // Internal factory skips validation (data already validated)\n * static fromPersistence(value: string): Email {\n * return new Email(value, SKIP_VALUE_OBJECT_VALIDATION);\n * }\n * }\n * ```\n */\nexport const SKIP_VALUE_OBJECT_VALIDATION = 'skip value object validation' as const;\n\n/** Type for the skip validation sentinel. */\nexport type SkipValueObjectValidation = typeof SKIP_VALUE_OBJECT_VALIDATION;\n\n/**\n * Deep equality comparison for value objects.\n * Handles primitives, Dates, Arrays, and nested Objects.\n * @internal\n */\nfunction deepEquals(a: unknown, b: unknown): boolean {\n // Same reference or both primitives with same value\n if (a === b) return true;\n\n // Handle null/undefined\n if (a === null || a === undefined || b === null || b === undefined) {\n return a === b;\n }\n\n // Handle Date objects\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime();\n }\n\n // Handle Arrays\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n return a.every((item, index) => deepEquals(item, b[index]));\n }\n\n // Handle Objects\n if (typeof a === 'object' && typeof b === 'object') {\n const aObj = a as Record<string, unknown>;\n const bObj = b as Record<string, unknown>;\n\n const aKeys = Object.keys(aObj);\n const bKeys = Object.keys(bObj);\n\n if (aKeys.length !== bKeys.length) return false;\n\n return aKeys.every((key) => deepEquals(aObj[key], bObj[key]));\n }\n\n // Different types or values\n return false;\n}\n\n/**\n * Base class for Domain-Driven Design Value Objects.\n *\n * Value Objects are immutable domain primitives that are compared by value,\n * not by reference. They encapsulate validation and domain logic for\n * primitive concepts like Email, Money, Address, etc.\n *\n * Key characteristics:\n * - **Immutable**: Value cannot be changed after construction\n * - **Equality by value**: Two VOs with the same value are considered equal\n * - **Self-validating**: Validation runs at construction time\n *\n * @typeParam T - The underlying value type\n *\n * @example\n * ```typescript\n * class Email extends BaseValueObject<string> {\n * private constructor(value: string, validator: BoundValidator<string> | SkipValueObjectValidation) {\n * super(value, validator);\n * }\n *\n * static create(value: string): Email {\n * return new Email(value, emailValidator);\n * }\n *\n * get domain(): string {\n * return this.value.split('@')[1];\n * }\n * }\n *\n * const email1 = Email.create('user@example.com');\n * const email2 = Email.create('user@example.com');\n * email1.equals(email2); // true\n * ```\n */\nexport class BaseValueObject<T> {\n private readonly _value: T;\n\n /**\n * Creates a new Value Object instance.\n *\n * @param value - The raw value to wrap\n * @param validator - A bound validator or SKIP_VALUE_OBJECT_VALIDATION to bypass\n * @throws {ObjectValidationError} When validation fails\n */\n protected constructor(\n value: T,\n validator: BoundValidator<T> | typeof SKIP_VALUE_OBJECT_VALIDATION,\n ) {\n this._value = validator === SKIP_VALUE_OBJECT_VALIDATION ? value : validator.validate(value);\n }\n\n /**\n * Compares this Value Object with another for equality.\n *\n * Uses deep equality comparison to handle nested objects, arrays, and dates.\n * Two Value Objects are equal if their underlying values are deeply equal.\n *\n * @param other - The Value Object to compare with\n * @returns `true` if the values are deeply equal, `false` otherwise\n */\n public equals(other: BaseValueObject<T>): boolean {\n // Fast path: same reference\n if (this === other) return true;\n\n // Deep equality comparison\n return deepEquals(this.value, other.value);\n }\n\n /**\n * The underlying immutable value.\n *\n * @returns The wrapped value of type T\n */\n public get value(): T {\n return this._value;\n }\n}\n","import { ErrorCodes, type DomainErrorCode } from '../../../global/exceptions/error-codes.const';\nimport { DomainError } from './domain.error';\n\n/**\n * Error thrown when a domain invariant is violated.\n *\n * Invariants are business rules that must always be true. This error\n * indicates a programming error or corrupted state—if inputs are\n * properly validated, this should never occur in production.\n *\n * **When to throw:**\n * - Business rule violations (e.g., `updatedAt < createdAt`)\n * - Assert-style guards in domain logic\n * - Invalid state transitions\n *\n * @example\n * ```typescript\n * if (order.status === 'shipped' && order.items.length === 0) {\n * throw new InvariantViolationError({\n * message: 'Shipped order must have at least one item',\n * code: 'EMPTY_SHIPPED_ORDER',\n * });\n * }\n * ```\n *\n * @extends DomainError\n */\nexport class InvariantViolationError extends DomainError {\n /**\n * Creates a new InvariantViolationError instance.\n *\n * @param options - Error configuration\n * @param options.message - Description of the violated invariant\n * @param options.code - Machine-readable error code (default: 'INVARIANT_VIOLATION')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.Domain.INVARIANT_VIOLATION,\n cause,\n }: {\n message: string;\n code?: DomainErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates an InvariantViolationError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new InvariantViolationError instance with the cause attached\n */\n static override fromError(cause: unknown): InvariantViolationError {\n return new InvariantViolationError({\n message: cause instanceof Error ? cause.message : 'Invariant violation',\n cause,\n });\n }\n}\n","import { ErrorCodes, type DomainErrorCode } from '../../../global/exceptions/error-codes.const';\nimport { DomainError } from './domain.error';\n\n/**\n * Error thrown when an entity or aggregate is partially loaded.\n *\n * Indicates that required data is missing, typically due to incomplete\n * database queries or lazy loading issues. This error should not escape\n * the application boundary—it represents an internal system failure.\n *\n * **When to throw:**\n * - Required relation not loaded\n * - Aggregate missing expected child entities\n * - Incomplete projection from data layer\n *\n * @example\n * ```typescript\n * if (!order.customer) {\n * throw new PartialLoadError({\n * message: 'Order customer relation not loaded',\n * code: 'ORDER_CUSTOMER_NOT_LOADED',\n * });\n * }\n * ```\n *\n * @extends DomainError\n */\nexport class PartialLoadError extends DomainError {\n /**\n * Creates a new PartialLoadError instance.\n *\n * @param options - Error configuration\n * @param options.message - Description of what was not loaded\n * @param options.code - Machine-readable error code (default: 'PARTIAL_LOAD')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.Domain.PARTIAL_LOAD,\n cause,\n }: {\n message: string;\n code?: DomainErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates a PartialLoadError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new PartialLoadError instance with the cause attached\n */\n static override fromError(cause: unknown): PartialLoadError {\n return new PartialLoadError({\n message: cause instanceof Error ? cause.message : 'Partial load error',\n cause,\n });\n }\n}\n","/**\n * Base audit user tracking value object.\n *\n * Tracks which user created and last updated an entity. User IDs are\n * optional to support system-initiated operations where no user context\n * is available.\n *\n * @example Extending for a validator-specific implementation\n * ```typescript\n * class AuditByVo extends BaseAuditByVo {\n * static create(opts?: {\n * createdBy?: UuidV4Vo;\n * updatedBy?: UuidV4Vo;\n * }): AuditByVo {\n * return new AuditByVo({\n * createdBy: opts?.createdBy,\n * updatedBy: opts?.updatedBy ?? opts?.createdBy,\n * }, SKIP_VALUE_OBJECT_VALIDATION);\n * }\n *\n * update(updatedBy: UuidV4Vo): AuditByVo {\n * return new AuditByVo({\n * createdBy: this.createdBy,\n * updatedBy,\n * }, SKIP_VALUE_OBJECT_VALIDATION);\n * }\n * }\n * ```\n */\nimport type { BoundValidator } from '../../../global/interfaces/ports/object-validator.port';\nimport type { SkipValueObjectValidation } from '../classes/base-value-object.class';\nimport { BaseValueObject } from '../classes/base-value-object.class';\nimport type { BaseUuidV4Vo } from './base-uuid-v4.vo';\n\n/**\n * Abstract base class for audit user tracking value objects.\n *\n * @extends BaseValueObject\n */\nexport abstract class BaseAuditByVo extends BaseValueObject<{\n createdBy?: BaseUuidV4Vo;\n updatedBy?: BaseUuidV4Vo;\n}> {\n /**\n * Creates a new BaseAuditByVo instance.\n *\n * @param value - The user tracking values\n * @param value.createdBy - User who created the entity (optional for system ops)\n * @param value.updatedBy - User who last updated the entity (optional)\n * @param validator - Bound validator or skip validation symbol\n */\n protected constructor(\n value: { createdBy?: BaseUuidV4Vo; updatedBy?: BaseUuidV4Vo },\n validator:\n | BoundValidator<{ createdBy?: BaseUuidV4Vo; updatedBy?: BaseUuidV4Vo }>\n | SkipValueObjectValidation,\n ) {\n super(value, validator);\n }\n\n /**\n * Creates a new audit user tracking with updated user ID.\n *\n * @param updatedBy - The user ID performing the update\n * @returns A new immutable audit user tracking instance\n */\n abstract update(updatedBy: BaseUuidV4Vo): BaseAuditByVo;\n\n /**\n * The user ID who created the entity.\n * Returns `undefined` for system-created entities.\n */\n get createdBy(): BaseUuidV4Vo | undefined {\n return this.value.createdBy;\n }\n\n /**\n * The user ID who last updated the entity.\n * Returns `undefined` for system-updated entities.\n */\n get updatedBy(): BaseUuidV4Vo | undefined {\n return this.value.updatedBy;\n }\n}\n","/**\n * Base audit info value object for entity tracking.\n *\n * Composite value object that combines timestamp tracking ({@link BaseAuditOnVo})\n * and user tracking ({@link BaseAuditByVo}) into a single immutable audit record.\n * Used for tracking entity creation and modification history.\n *\n * **Composition:**\n * - `on`: {@link BaseAuditOnVo} - timestamps (createdAt, updatedAt)\n * - `by`: {@link BaseAuditByVo} - user IDs (createdBy, updatedBy)\n *\n * **Immutability:**\n * Date getters return cloned Date objects to prevent external mutation.\n *\n * @example Extending for a validator-specific implementation\n * ```typescript\n * class AuditInfoVo extends BaseAuditInfoVo {\n * static create(createdBy?: UuidV4Vo): AuditInfoVo {\n * const now = new Date();\n * return new AuditInfoVo({\n * by: AuditByVo.create({ createdBy, updatedBy: createdBy }),\n * on: AuditOnVo.create({ createdAt: now, updatedAt: now }),\n * }, SKIP_VALUE_OBJECT_VALIDATION);\n * }\n *\n * update(updatedBy: UuidV4Vo): AuditInfoVo {\n * return new AuditInfoVo({\n * by: this.value.by.update(updatedBy),\n * on: this.value.on.update(),\n * }, SKIP_VALUE_OBJECT_VALIDATION);\n * }\n * }\n * ```\n *\n * @example Using with an entity\n * ```typescript\n * class User {\n * constructor(\n * public readonly id: UuidV7Vo,\n * public readonly name: string,\n * public readonly audit: AuditInfoVo,\n * ) {}\n *\n * updateName(name: string, updatedBy: UuidV4Vo): User {\n * return new User(this.id, name, this.audit.update(updatedBy));\n * }\n * }\n * ```\n */\nimport type { BoundValidator } from '../../../global/interfaces/ports/object-validator.port';\nimport type { SkipValueObjectValidation } from '../classes/base-value-object.class';\nimport { BaseValueObject } from '../classes/base-value-object.class';\nimport type { BaseAuditByVo } from './base-audit-by.vo';\nimport type { BaseAuditOnVo } from './base-audit-on.vo';\nimport type { BaseUuidV4Vo } from './base-uuid-v4.vo';\n\n/**\n * Abstract base class for audit information value objects.\n *\n * Extend this class and implement the `update()` method with your\n * validator-specific child VOs.\n *\n * @extends BaseValueObject\n */\nexport abstract class BaseAuditInfoVo extends BaseValueObject<{\n by: BaseAuditByVo;\n on: BaseAuditOnVo;\n}> {\n /**\n * Creates a new BaseAuditInfoVo instance.\n *\n * @param value - Composite value containing audit by and on VOs\n * @param value.by - User tracking value object\n * @param value.on - Timestamp tracking value object\n * @param validator - Bound validator or skip validation symbol\n */\n protected constructor(\n value: { by: BaseAuditByVo; on: BaseAuditOnVo },\n validator: BoundValidator<{ by: BaseAuditByVo; on: BaseAuditOnVo }> | SkipValueObjectValidation,\n ) {\n super(value, validator);\n }\n\n /**\n * Creates a new audit info with updated timestamp and user.\n *\n * @param updatedBy - The user ID performing the update\n * @returns A new immutable audit info instance\n */\n abstract update(updatedBy: BaseUuidV4Vo): BaseAuditInfoVo;\n\n /**\n * The user ID who created the entity.\n * Returns `undefined` for system-created entities.\n */\n get createdBy(): BaseUuidV4Vo | undefined {\n return this.value.by.createdBy;\n }\n\n /**\n * The timestamp when the entity was created.\n * Returns a cloned Date to prevent mutation.\n */\n get createdAt(): Date {\n return new Date(this.value.on.createdAt.getTime());\n }\n\n /**\n * The user ID who last updated the entity.\n * Returns `undefined` for system-updated entities.\n */\n get updatedBy(): BaseUuidV4Vo | undefined {\n return this.value.by.updatedBy;\n }\n\n /**\n * The timestamp when the entity was last updated.\n * Returns a cloned Date to prevent mutation.\n */\n get updatedAt(): Date {\n return new Date(this.value.on.updatedAt.getTime());\n }\n\n /**\n * Whether the entity has been modified since creation.\n *\n * Compares both timestamps and user IDs. Returns `true` if either:\n * - The updatedAt timestamp differs from createdAt\n * - The updatedBy user differs from createdBy\n *\n * Note: When both createdBy and updatedBy are undefined (system-created\n * entities), this correctly returns false for the user comparison.\n */\n get isModified(): boolean {\n const timestampChanged = this.updatedAt.getTime() !== this.createdAt.getTime();\n const userChanged = this.updatedBy?.value !== this.createdBy?.value;\n return timestampChanged || userChanged;\n }\n\n /**\n * Alias for `updatedBy` for semantic clarity.\n */\n get lastModifiedBy(): BaseUuidV4Vo | undefined {\n return this.updatedBy;\n }\n\n /**\n * Alias for `updatedAt` for semantic clarity.\n */\n get lastModifiedAt(): Date {\n return this.updatedAt;\n }\n}\n","/**\n * Base audit timestamp value object.\n *\n * Tracks when an entity was created and last updated. Enforces the\n * domain invariant that `updatedAt` cannot be earlier than `createdAt`.\n *\n * **Domain Invariant:**\n * The constructor throws {@link InvariantViolationError} if\n * `updatedAt < createdAt`, ensuring timestamps are always valid.\n *\n * **Immutability:**\n * Date getters return cloned Date objects to prevent external mutation.\n *\n * @example Extending for a validator-specific implementation\n * ```typescript\n * class AuditOnVo extends BaseAuditOnVo {\n * static create(opts?: { createdAt?: Date; updatedAt?: Date }): AuditOnVo {\n * const now = new Date();\n * return new AuditOnVo({\n * createdAt: opts?.createdAt ?? now,\n * updatedAt: opts?.updatedAt ?? now,\n * }, SKIP_VALUE_OBJECT_VALIDATION);\n * }\n *\n * update(): AuditOnVo {\n * return new AuditOnVo({\n * createdAt: this.createdAt,\n * updatedAt: new Date(),\n * }, SKIP_VALUE_OBJECT_VALIDATION);\n * }\n * }\n * ```\n */\nimport type { BoundValidator } from '../../../global/interfaces/ports/object-validator.port';\nimport type { SkipValueObjectValidation } from '../classes/base-value-object.class';\nimport { BaseValueObject } from '../classes/base-value-object.class';\nimport { InvariantViolationError } from '../exceptions/invariant-violation.error';\n\n/**\n * Abstract base class for audit timestamp value objects.\n *\n * @extends BaseValueObject\n * @throws {InvariantViolationError} When `updatedAt` is earlier than `createdAt`\n */\nexport abstract class BaseAuditOnVo extends BaseValueObject<{\n createdAt: Date;\n updatedAt: Date;\n}> {\n /**\n * Creates a new BaseAuditOnVo instance.\n *\n * @param value - The timestamp values\n * @param value.createdAt - When the entity was created\n * @param value.updatedAt - When the entity was last updated\n * @param validator - Bound validator or skip validation symbol\n * @throws {InvariantViolationError} When `updatedAt < createdAt`\n */\n protected constructor(\n value: { createdAt: Date; updatedAt: Date },\n validator: BoundValidator<{ createdAt: Date; updatedAt: Date }> | SkipValueObjectValidation,\n ) {\n // Domain enforces its own invariant\n if (value.updatedAt < value.createdAt) {\n throw new InvariantViolationError({\n message: 'UpdatedAt cannot be earlier than createdAt',\n code: 'INVALID_AUDIT_TIMESTAMPS',\n });\n }\n super(value, validator);\n }\n\n /**\n * Creates a new audit timestamp with current time as updatedAt.\n *\n * @returns A new immutable audit timestamp instance\n */\n abstract update(): BaseAuditOnVo;\n\n /**\n * When the entity was created.\n * Returns a cloned Date to prevent mutation.\n */\n get createdAt(): Date {\n return new Date(this.value.createdAt);\n }\n\n /**\n * When the entity was last updated.\n * Returns a cloned Date to prevent mutation.\n */\n get updatedAt(): Date {\n return new Date(this.value.updatedAt);\n }\n}\n","/**\n * Base email value object.\n *\n * Represents a validated email address. Extend this class and provide\n * a validator that enforces email format rules.\n *\n * @example Extending with Zod validation\n * ```typescript\n * import { z } from 'zod';\n * import { createZodValidator } from '@cosmneo/onion-lasagna/backend/core/validators/zod';\n *\n * const emailSchema = z.string().email();\n * const emailValidator = createZodValidator(emailSchema);\n *\n * class EmailVo extends BaseEmailVo {\n * static create(value: string): EmailVo {\n * return new EmailVo(value, emailValidator);\n * }\n * }\n * ```\n *\n * @example Usage\n * ```typescript\n * const email = EmailVo.create('user@example.com');\n * console.log(email.value); // \"user@example.com\"\n * ```\n */\nimport type { BoundValidator } from '../../../global/interfaces/ports/object-validator.port';\nimport type { SKIP_VALUE_OBJECT_VALIDATION } from '../classes/base-value-object.class';\nimport { BaseValueObject } from '../classes/base-value-object.class';\n\n/**\n * Value object for email addresses.\n *\n * @extends BaseValueObject<string>\n */\nexport class BaseEmailVo extends BaseValueObject<string> {\n /**\n * Creates a new BaseEmailVo instance.\n *\n * @param value - The email address string\n * @param validator - Bound validator or skip validation symbol\n */\n protected constructor(\n value: string,\n validator: BoundValidator<string> | typeof SKIP_VALUE_OBJECT_VALIDATION,\n ) {\n super(value, validator);\n }\n}\n","/**\n * Base long text value object.\n *\n * Represents long-form text fields like articles, content bodies, or notes.\n * Typically validated with a maximum length constraint (e.g., 5000+ chars).\n *\n * **Suggested Length:** 1-5000+ characters\n *\n * **Use Cases:**\n * - Article content\n * - Blog posts\n * - Detailed notes\n * - Rich text content\n *\n * @example Extending with length validation\n * ```typescript\n * import { z } from 'zod';\n * import { createZodValidator } from '@cosmneo/onion-lasagna/backend/core/validators/zod';\n *\n * const longTextSchema = z.string().min(1).max(10000);\n * const longTextValidator = createZodValidator(longTextSchema);\n *\n * class ArticleContentVo extends BaseLongTextVo {\n * static create(value: string): ArticleContentVo {\n * return new ArticleContentVo(value, longTextValidator);\n * }\n * }\n * ```\n */\nimport type { BoundValidator } from '../../../global/interfaces/ports/object-validator.port';\nimport type { SKIP_VALUE_OBJECT_VALIDATION } from '../classes/base-value-object.class';\nimport { BaseValueObject } from '../classes/base-value-object.class';\n\n/**\n * Value object for long-form text strings.\n *\n * @extends BaseValueObject<string>\n */\nexport class BaseLongTextVo extends BaseValueObject<string> {\n /**\n * Creates a new BaseLongTextVo instance.\n *\n * @param value - The long text string\n * @param validator - Bound validator or skip validation symbol\n */\n protected constructor(\n value: string,\n validator: BoundValidator<string> | typeof SKIP_VALUE_OBJECT_VALIDATION,\n ) {\n super(value, validator);\n }\n}\n","/**\n * Base medium text value object.\n *\n * Represents medium-length text fields like descriptions or summaries.\n * Typically validated with a maximum length constraint (e.g., 500 chars).\n *\n * **Suggested Length:** 1-500 characters\n *\n * **Use Cases:**\n * - Product descriptions\n * - User bios\n * - Short summaries\n * - Comments\n *\n * @example Extending with length validation\n * ```typescript\n * import { z } from 'zod';\n * import { createZodValidator } from '@cosmneo/onion-lasagna/backend/core/validators/zod';\n *\n * const mediumTextSchema = z.string().min(1).max(500);\n * const mediumTextValidator = createZodValidator(mediumTextSchema);\n *\n * class DescriptionVo extends BaseMediumTextVo {\n * static create(value: string): DescriptionVo {\n * return new DescriptionVo(value, mediumTextValidator);\n * }\n * }\n * ```\n */\nimport type { BoundValidator } from '../../../global/interfaces/ports/object-validator.port';\nimport type { SKIP_VALUE_OBJECT_VALIDATION } from '../classes/base-value-object.class';\nimport { BaseValueObject } from '../classes/base-value-object.class';\n\n/**\n * Value object for medium-length text strings.\n *\n * @extends BaseValueObject<string>\n */\nexport class BaseMediumTextVo extends BaseValueObject<string> {\n /**\n * Creates a new BaseMediumTextVo instance.\n *\n * @param value - The medium text string\n * @param validator - Bound validator or skip validation symbol\n */\n protected constructor(\n value: string,\n validator: BoundValidator<string> | typeof SKIP_VALUE_OBJECT_VALIDATION,\n ) {\n super(value, validator);\n }\n}\n","/**\n * Base pagination value object.\n *\n * Represents pagination parameters for list queries. Validates that\n * page numbers and page sizes are positive integers within bounds.\n *\n * **Properties:**\n * - `page`: The current page number (typically 1-indexed)\n * - `pageSize`: Number of items per page\n *\n * @example Extending with validation\n * ```typescript\n * import { z } from 'zod';\n * import { createZodValidator } from '@cosmneo/onion-lasagna/backend/core/validators/zod';\n *\n * const paginationSchema = z.object({\n * page: z.number().int().min(1),\n * pageSize: z.number().int().min(1).max(100),\n * });\n * const paginationValidator = createZodValidator(paginationSchema);\n *\n * class PaginationVo extends BasePaginationVo {\n * static create(page: number, pageSize: number): PaginationVo {\n * return new PaginationVo({ page, pageSize }, paginationValidator);\n * }\n * }\n * ```\n *\n * @example Usage in a use case\n * ```typescript\n * class ListUsersUseCase {\n * async execute(pagination: PaginationVo): Promise<User[]> {\n * const offset = (pagination.page - 1) * pagination.pageSize;\n * return this.userRepo.findAll({\n * offset,\n * limit: pagination.pageSize,\n * });\n * }\n * }\n * ```\n */\nimport type { BoundValidator } from '../../../global/interfaces/ports/object-validator.port';\nimport type { SKIP_VALUE_OBJECT_VALIDATION } from '../classes/base-value-object.class';\nimport { BaseValueObject } from '../classes/base-value-object.class';\n\n/**\n * Value object for pagination parameters.\n *\n * @extends BaseValueObject<{ page: number; pageSize: number }>\n */\nexport class BasePaginationVo extends BaseValueObject<{ page: number; pageSize: number }> {\n /**\n * Creates a new BasePaginationVo instance.\n *\n * @param value - The pagination parameters\n * @param value.page - The page number (typically 1-indexed)\n * @param value.pageSize - The number of items per page\n * @param validator - Bound validator or skip validation symbol\n */\n protected constructor(\n value: { page: number; pageSize: number },\n validator:\n | BoundValidator<{ page: number; pageSize: number }>\n | typeof SKIP_VALUE_OBJECT_VALIDATION,\n ) {\n super(value, validator);\n }\n\n /**\n * The current page number.\n */\n get page(): number {\n return this.value.page;\n }\n\n /**\n * The number of items per page.\n */\n get pageSize(): number {\n return this.value.pageSize;\n }\n}\n","/**\n * Base short text value object.\n *\n * Represents short text fields like names, titles, or labels.\n * Typically validated with a maximum length constraint (e.g., 100 chars).\n *\n * **Suggested Length:** 1-100 characters\n *\n * **Use Cases:**\n * - User names\n * - Product titles\n * - Category names\n * - Short labels\n *\n * @example Extending with length validation\n * ```typescript\n * import { z } from 'zod';\n * import { createZodValidator } from '@cosmneo/onion-lasagna/backend/core/validators/zod';\n *\n * const shortTextSchema = z.string().min(1).max(100);\n * const shortTextValidator = createZodValidator(shortTextSchema);\n *\n * class UserNameVo extends BaseShortTextVo {\n * static create(value: string): UserNameVo {\n * return new UserNameVo(value, shortTextValidator);\n * }\n * }\n * ```\n */\nimport type { BoundValidator } from '../../../global/interfaces/ports/object-validator.port';\nimport type { SKIP_VALUE_OBJECT_VALIDATION } from '../classes/base-value-object.class';\nimport { BaseValueObject } from '../classes/base-value-object.class';\n\n/**\n * Value object for short text strings.\n *\n * @extends BaseValueObject<string>\n */\nexport class BaseShortTextVo extends BaseValueObject<string> {\n /**\n * Creates a new BaseShortTextVo instance.\n *\n * @param value - The short text string\n * @param validator - Bound validator or skip validation symbol\n */\n protected constructor(\n value: string,\n validator: BoundValidator<string> | typeof SKIP_VALUE_OBJECT_VALIDATION,\n ) {\n super(value, validator);\n }\n}\n","/**\n * Base UUID v4 value object for random entity identifiers.\n *\n * UUID v4 is a randomly generated UUID, suitable for identifiers where\n * time-ordering is not required. For time-sortable IDs, use {@link BaseUuidV7Vo}.\n *\n * **Use Cases:**\n * - User IDs (for audit tracking)\n * - Session tokens\n * - Correlation IDs\n * - Any identifier where time-ordering doesn't matter\n *\n * @example Generating a new ID\n * ```typescript\n * const id = BaseUuidV4Vo.generate();\n * console.log(id.value); // e.g., \"550e8400-e29b-41d4-a716-446655440000\"\n * ```\n *\n * @example Extending for validation\n * ```typescript\n * class UserIdVo extends BaseUuidV4Vo {\n * static create(value: string): UserIdVo {\n * return new UserIdVo(value, uuidValidator);\n * }\n *\n * static generate(): UserIdVo {\n * return new UserIdVo(v4(), SKIP_VALUE_OBJECT_VALIDATION);\n * }\n * }\n * ```\n */\nimport type { BoundValidator } from '../../../global/interfaces/ports/object-validator.port';\nimport { BaseValueObject, SKIP_VALUE_OBJECT_VALIDATION } from '../classes/base-value-object.class';\nimport { v4 } from 'uuid';\n\n/**\n * Value object for UUID v4 identifiers.\n *\n * Provides a `generate()` factory method that creates new random UUIDs.\n *\n * @extends BaseValueObject<string>\n */\nexport class BaseUuidV4Vo extends BaseValueObject<string> {\n /**\n * Creates a new BaseUuidV4Vo instance.\n *\n * @param value - The UUID v4 string value\n * @param validator - Bound validator or skip validation symbol\n */\n protected constructor(\n value: string,\n validator: BoundValidator<string> | typeof SKIP_VALUE_OBJECT_VALIDATION,\n ) {\n super(value, validator);\n }\n\n /**\n * Generates a new UUID v4 value object.\n *\n * Creates a random UUID, skipping validation since the\n * `uuid` library guarantees format.\n *\n * @returns A new BaseUuidV4Vo with a freshly generated UUID\n */\n static generate(): BaseUuidV4Vo {\n return new this(v4(), SKIP_VALUE_OBJECT_VALIDATION);\n }\n\n /**\n * Creates a UUID v4 value object from an existing string.\n *\n * **Important:** This base implementation skips validation and accepts\n * any string value. Subclasses should override this method with a\n * validator to ensure UUID format correctness.\n *\n * @param value - The UUID v4 string value (not validated at base level)\n * @returns A new BaseUuidV4Vo with the provided value\n *\n * @example Subclass with validation (recommended)\n * ```typescript\n * class UserId extends BaseUuidV4Vo {\n * static override create(value: string): UserId {\n * return new UserId(value, uuidV4Validator);\n * }\n * }\n * ```\n *\n * @see generate - For creating new UUIDs (always valid)\n */\n static create(value: string): BaseUuidV4Vo {\n return new this(value, SKIP_VALUE_OBJECT_VALIDATION);\n }\n}\n","/**\n * Base UUID v7 value object for time-sortable entity identifiers.\n *\n * UUID v7 is a time-ordered UUID that combines a Unix timestamp with\n * random bits, making it ideal for database primary keys because:\n *\n * **Benefits:**\n * - **Time-sortable**: IDs created later sort after earlier ones\n * - **Database-friendly**: Sequential nature reduces B-tree fragmentation\n * - **Globally unique**: Same uniqueness guarantees as other UUID versions\n * - **Timestamp extractable**: Creation time can be derived from the ID\n *\n * @example Generating a new ID\n * ```typescript\n * const id = BaseUuidV7Vo.generate();\n * console.log(id.value); // e.g., \"018f3b1c-5e7d-7000-8000-000000000001\"\n * ```\n *\n * @example Extending for validation\n * ```typescript\n * class EntityIdVo extends BaseUuidV7Vo {\n * static create(value: string): EntityIdVo {\n * return new EntityIdVo(value, uuidValidator);\n * }\n *\n * static generate(): EntityIdVo {\n * return new EntityIdVo(v7(), SKIP_VALUE_OBJECT_VALIDATION);\n * }\n * }\n * ```\n *\n * @example Using as entity primary key\n * ```typescript\n * class User {\n * constructor(\n * public readonly id: EntityIdVo,\n * public readonly name: string,\n * ) {}\n *\n * static create(name: string): User {\n * return new User(EntityIdVo.generate(), name);\n * }\n * }\n * ```\n */\nimport type { BoundValidator } from '../../../global/interfaces/ports/object-validator.port';\nimport { BaseValueObject, SKIP_VALUE_OBJECT_VALIDATION } from '../classes/base-value-object.class';\nimport { v7 } from 'uuid';\n\n/**\n * Value object for UUID v7 identifiers.\n *\n * Provides a `generate()` factory method that creates new time-ordered UUIDs.\n *\n * @extends BaseValueObject<string>\n */\nexport class BaseUuidV7Vo extends BaseValueObject<string> {\n /**\n * Creates a new BaseUuidV7Vo instance.\n *\n * @param value - The UUID v7 string value\n * @param validator - Bound validator or skip validation symbol\n */\n protected constructor(\n value: string,\n validator: BoundValidator<string> | typeof SKIP_VALUE_OBJECT_VALIDATION,\n ) {\n super(value, validator);\n }\n\n /**\n * Generates a new UUID v7 value object.\n *\n * Creates a time-ordered UUID using the current timestamp,\n * skipping validation since the `uuid` library guarantees format.\n *\n * @returns A new BaseUuidV7Vo with a freshly generated UUID\n */\n static generate(): BaseUuidV7Vo {\n return new this(v7(), SKIP_VALUE_OBJECT_VALIDATION);\n }\n\n /**\n * Creates a UUID v7 value object from an existing string.\n *\n * **Important:** This base implementation skips validation and accepts\n * any string value. Subclasses should override this method with a\n * validator to ensure UUID format correctness.\n *\n * @param value - The UUID v7 string value (not validated at base level)\n * @returns A new BaseUuidV7Vo with the provided value\n *\n * @example Subclass with validation (recommended)\n * ```typescript\n * class OrderId extends BaseUuidV7Vo {\n * static override create(value: string): OrderId {\n * return new OrderId(value, uuidV7Validator);\n * }\n * }\n * ```\n *\n * @see generate - For creating new UUIDs (always valid)\n */\n static create(value: string): BaseUuidV7Vo {\n return new this(value, SKIP_VALUE_OBJECT_VALIDATION);\n }\n}\n","import { BaseValueObject, SKIP_VALUE_OBJECT_VALIDATION } from '../../classes';\nimport { InvariantViolationError } from '../../exceptions/invariant-violation.error';\n\n/**\n * The underlying value structure for Money.\n */\nexport interface MoneyValue {\n amount: number;\n currency: string;\n}\n\n/**\n * Value Object representing a monetary amount with currency.\n *\n * Provides arithmetic operations and comparison methods.\n * Prevents operations between different currencies.\n *\n * @example\n * ```typescript\n * const price = Money.usd(29.99);\n * const tax = Money.usd(2.40);\n * const total = price.add(tax);\n *\n * console.log(total.amount); // 32.39\n * console.log(total.currency); // 'USD'\n *\n * if (total.isGreaterThan(Money.usd(30))) {\n * // Apply discount\n * }\n * ```\n */\nexport class Money extends BaseValueObject<MoneyValue> {\n /**\n * Creates a Money instance with USD currency.\n *\n * @param amount - The monetary amount\n */\n static usd(amount: number): Money {\n return new Money({ amount, currency: 'USD' }, SKIP_VALUE_OBJECT_VALIDATION);\n }\n\n /**\n * Creates a Money instance with EUR currency.\n *\n * @param amount - The monetary amount\n */\n static eur(amount: number): Money {\n return new Money({ amount, currency: 'EUR' }, SKIP_VALUE_OBJECT_VALIDATION);\n }\n\n /**\n * Creates a zero amount in the specified currency.\n *\n * @param currency - The currency code (default: 'USD')\n */\n static zero(currency = 'USD'): Money {\n return new Money({ amount: 0, currency }, SKIP_VALUE_OBJECT_VALIDATION);\n }\n\n /**\n * Reconstitutes a Money from a persisted value.\n *\n * @param value - The money value from persistence\n */\n static fromPersistence(value: MoneyValue): Money {\n return new Money(value, SKIP_VALUE_OBJECT_VALIDATION);\n }\n\n /**\n * The monetary amount.\n */\n get amount(): number {\n return this.value.amount;\n }\n\n /**\n * The currency code.\n */\n get currency(): string {\n return this.value.currency;\n }\n\n /**\n * Adds another Money value to this one.\n *\n * @param other - The Money to add\n * @throws {InvariantViolationError} If currencies don't match\n */\n add(other: Money): Money {\n this.assertSameCurrency(other);\n return new Money(\n { amount: this.amount + other.amount, currency: this.currency },\n SKIP_VALUE_OBJECT_VALIDATION,\n );\n }\n\n /**\n * Subtracts another Money value from this one.\n *\n * @param other - The Money to subtract\n * @throws {InvariantViolationError} If currencies don't match\n */\n subtract(other: Money): Money {\n this.assertSameCurrency(other);\n return new Money(\n { amount: this.amount - other.amount, currency: this.currency },\n SKIP_VALUE_OBJECT_VALIDATION,\n );\n }\n\n /**\n * Multiplies this Money by a factor.\n *\n * @param factor - The multiplication factor\n */\n multiply(factor: number): Money {\n return new Money(\n { amount: this.amount * factor, currency: this.currency },\n SKIP_VALUE_OBJECT_VALIDATION,\n );\n }\n\n /**\n * Checks if this Money is greater than another.\n *\n * @param other - The Money to compare with\n * @throws {InvariantViolationError} If currencies don't match\n */\n isGreaterThan(other: Money): boolean {\n this.assertSameCurrency(other);\n return this.amount > other.amount;\n }\n\n /**\n * Checks if this Money is less than another.\n *\n * @param other - The Money to compare with\n * @throws {InvariantViolationError} If currencies don't match\n */\n isLessThan(other: Money): boolean {\n this.assertSameCurrency(other);\n return this.amount < other.amount;\n }\n\n /**\n * Checks if this Money represents zero.\n */\n isZero(): boolean {\n return this.amount === 0;\n }\n\n /**\n * Asserts that two Money values have the same currency.\n * @internal\n */\n private assertSameCurrency(other: Money): void {\n if (this.currency !== other.currency) {\n throw new InvariantViolationError({\n message: `Cannot operate on different currencies: ${this.currency} vs ${other.currency}`,\n code: 'CURRENCY_MISMATCH',\n });\n }\n }\n}\n","import { BaseUuidV7Vo } from '../../value-objects/base-uuid-v7.vo';\n\n/**\n * Value Object representing an Order's unique identifier.\n *\n * Extends BaseUuidV7Vo to use time-ordered UUIDs for better\n * database indexing and natural ordering.\n *\n * @example\n * ```typescript\n * const orderId = OrderId.create();\n * console.log(orderId.value); // '01902e8a-7c3b-7def-8a1b-...'\n *\n * orderId.equals(anotherOrderId); // true if same value\n * ```\n */\nexport class OrderId extends BaseUuidV7Vo {}\n","import { BaseValueObject, SKIP_VALUE_OBJECT_VALIDATION } from '../../classes';\n\n/**\n * Possible values for an order's status.\n */\nexport type OrderStatusValue = 'pending' | 'confirmed' | 'shipped' | 'cancelled';\n\n/**\n * Value Object representing an Order's status.\n *\n * Provides type-safe status values with behavior methods for checking state.\n * Uses static factory methods to ensure only valid statuses can be created.\n *\n * @example\n * ```typescript\n * const status = OrderStatus.pending();\n *\n * if (status.isPending()) {\n * // Can modify order\n * }\n *\n * if (status.isShipped()) {\n * // Cannot cancel\n * }\n * ```\n */\nexport class OrderStatus extends BaseValueObject<OrderStatusValue> {\n /**\n * Creates a new OrderStatus with 'pending' value.\n * Use when creating new orders.\n */\n static pending(): OrderStatus {\n return new OrderStatus('pending', SKIP_VALUE_OBJECT_VALIDATION);\n }\n\n /**\n * Creates a new OrderStatus with 'confirmed' value.\n * Use when payment is received.\n */\n static confirmed(): OrderStatus {\n return new OrderStatus('confirmed', SKIP_VALUE_OBJECT_VALIDATION);\n }\n\n /**\n * Creates a new OrderStatus with 'shipped' value.\n * Use when order is dispatched.\n */\n static shipped(): OrderStatus {\n return new OrderStatus('shipped', SKIP_VALUE_OBJECT_VALIDATION);\n }\n\n /**\n * Creates a new OrderStatus with 'cancelled' value.\n * Use when order is cancelled by customer or system.\n */\n static cancelled(): OrderStatus {\n return new OrderStatus('cancelled', SKIP_VALUE_OBJECT_VALIDATION);\n }\n\n /**\n * Reconstitutes an OrderStatus from a persisted value.\n *\n * @param value - The status value from persistence\n */\n static fromPersistence(value: OrderStatusValue): OrderStatus {\n return new OrderStatus(value, SKIP_VALUE_OBJECT_VALIDATION);\n }\n\n /**\n * Checks if the order is in pending status.\n */\n isPending(): boolean {\n return this.value === 'pending';\n }\n\n /**\n * Checks if the order is confirmed.\n */\n isConfirmed(): boolean {\n return this.value === 'confirmed';\n }\n\n /**\n * Checks if the order has been shipped.\n */\n isShipped(): boolean {\n return this.value === 'shipped';\n }\n\n /**\n * Checks if the order has been cancelled.\n */\n isCancelled(): boolean {\n return this.value === 'cancelled';\n }\n\n /**\n * Checks if the order can still be modified (pending or confirmed).\n */\n isModifiable(): boolean {\n return this.isPending() || this.isConfirmed();\n }\n}\n","import { BaseDomainEvent } from '../../classes';\n\n/**\n * Payload for the OrderCancelled domain event.\n */\nexport interface OrderCancelledPayload {\n orderId: string;\n reason: string;\n cancelledAt: string;\n}\n\n/**\n * Domain event raised when an order is cancelled.\n *\n * @example\n * ```typescript\n * order.addDomainEvent(new OrderCancelledEvent({\n * orderId: order.id.value,\n * reason: 'Customer requested cancellation',\n * cancelledAt: new Date().toISOString(),\n * }));\n * ```\n */\nexport class OrderCancelledEvent extends BaseDomainEvent<OrderCancelledPayload> {\n constructor(payload: OrderCancelledPayload) {\n super('OrderCancelled', payload.orderId, payload);\n }\n}\n","import { BaseDomainEvent } from '../../classes';\n\n/**\n * Payload for the OrderPlaced domain event.\n */\nexport interface OrderPlacedPayload {\n orderId: string;\n customerId: string;\n itemCount: number;\n totalAmount: number;\n currency: string;\n placedAt: string;\n}\n\n/**\n * Domain event raised when a new order is placed.\n *\n * @example\n * ```typescript\n * order.addDomainEvent(new OrderPlacedEvent({\n * orderId: order.id.value,\n * customerId: order.customerId,\n * itemCount: order.items.length,\n * totalAmount: order.totalAmount.amount,\n * currency: order.totalAmount.currency,\n * placedAt: new Date().toISOString(),\n * }));\n * ```\n */\nexport class OrderPlacedEvent extends BaseDomainEvent<OrderPlacedPayload> {\n constructor(payload: OrderPlacedPayload) {\n super('OrderPlaced', payload.orderId, payload);\n }\n}\n","import { OrderStatus } from '../../../../value-objects';\n\n/**\n * Value Policy: Default order status for new orders.\n *\n * New orders start in 'pending' status, awaiting payment confirmation.\n *\n * @returns The default OrderStatus (pending)\n *\n * @example\n * ```typescript\n * const order = new Order(id, {\n * status: defaultOrderStatus(),\n * // ...\n * });\n * ```\n */\nexport const defaultOrderStatus = (): OrderStatus => {\n return OrderStatus.pending();\n};\n","import type { Order } from '../../order.aggregate';\n\n/**\n * Business Policy: Determines if items can be added to an order.\n *\n * Items can only be added to orders that are still in 'pending' status.\n * Once an order is confirmed, shipped, or cancelled, items cannot be added.\n *\n * @param order - The order to check\n * @returns `true` if items can be added to the order\n *\n * @example\n * ```typescript\n * if (!canAddOrderItem(order)) {\n * throw new InvariantViolationError({\n * message: 'Cannot add items to non-pending order',\n * code: 'ORDER_NOT_PENDING',\n * });\n * }\n * ```\n */\nexport const canAddOrderItem = (order: Order): boolean => {\n return order.status.isPending();\n};\n","import type { Order } from '../../order.aggregate';\n\n/**\n * Business Policy: Determines if an order can be cancelled.\n *\n * Orders can only be cancelled if they have not yet been shipped.\n * Once an order is shipped or delivered, it cannot be cancelled.\n *\n * @param order - The order to check\n * @returns `true` if the order can be cancelled\n *\n * @example\n * ```typescript\n * if (!canCancelOrder(order)) {\n * throw new InvariantViolationError({\n * message: 'Order cannot be cancelled',\n * code: 'ORDER_CANNOT_CANCEL',\n * });\n * }\n * ```\n */\nexport const canCancelOrder = (order: Order): boolean => {\n return order.status.isPending() || order.status.isConfirmed();\n};\n","import { BaseAggregateRoot } from '../../../classes';\nimport { InvariantViolationError } from '../../../exceptions/invariant-violation.error';\nimport { OrderId, OrderStatus, Money } from '../../value-objects';\nimport type { OrderItem } from '../../entities';\nimport { OrderPlacedEvent, OrderCancelledEvent } from '../../events';\nimport { defaultOrderStatus } from './policies/value';\nimport { canCancelOrder, canAddOrderItem } from './policies/business';\n\n/**\n * Properties for the Order aggregate.\n */\nexport interface OrderProps {\n customerId: string;\n items: OrderItem[];\n status: OrderStatus;\n totalAmount: Money;\n placedAt: Date;\n}\n\n/**\n * Order Aggregate Root.\n *\n * Represents a customer's order with line items. The Order is the aggregate root\n * and controls access to its OrderItems. All modifications go through the Order\n * to ensure business invariants are maintained.\n *\n * **Policies used:**\n * - Value: `defaultOrderStatus` - New orders start as 'pending'\n * - Business: `canAddOrderItem` - Items can only be added to pending orders\n * - Business: `canCancelOrder` - Orders can only be cancelled if not shipped\n *\n * **Events raised:**\n * - `OrderPlacedEvent` - When order is created\n * - `OrderCancelledEvent` - When order is cancelled\n *\n * @example\n * ```typescript\n * // Create a new order\n * const order = Order.create('customer-123', [\n * OrderItem.create({\n * productId: 'prod-1',\n * productName: 'Widget',\n * quantity: 2,\n * unitPrice: Money.usd(29.99),\n * }),\n * ]);\n *\n * // Add another item\n * order.addItem(OrderItem.create({\n * productId: 'prod-2',\n * productName: 'Gadget',\n * quantity: 1,\n * unitPrice: Money.usd(49.99),\n * }));\n *\n * // Cancel the order\n * order.cancel('Customer changed their mind');\n *\n * // Get events for publishing\n * const events = order.pullDomainEvents();\n * ```\n */\nexport class Order extends BaseAggregateRoot<OrderId, OrderProps> {\n private constructor(id: OrderId, props: OrderProps, version?: number) {\n super(id, props, version);\n }\n\n /**\n * Creates a new Order.\n *\n * @param customerId - The customer placing the order\n * @param items - Initial order items\n * @returns A new Order instance with OrderPlacedEvent raised\n */\n static create(customerId: string, items: OrderItem[]): Order {\n const id = OrderId.generate();\n const totalAmount = items.reduce((sum, item) => sum.add(item.totalPrice), Money.zero());\n\n const order = new Order(id, {\n customerId,\n items,\n status: defaultOrderStatus(),\n totalAmount,\n placedAt: new Date(),\n });\n\n order.addDomainEvent(\n new OrderPlacedEvent({\n orderId: id.value,\n customerId,\n itemCount: items.length,\n totalAmount: totalAmount.amount,\n currency: totalAmount.currency,\n placedAt: order.placedAt.toISOString(),\n }),\n );\n\n return order;\n }\n\n /**\n * Reconstitutes an Order from persistence.\n *\n * @param id - The order ID\n * @param props - The order properties\n * @param version - The version for optimistic locking\n */\n static fromPersistence(id: OrderId, props: OrderProps, version: number): Order {\n return new Order(id, props, version);\n }\n\n get customerId(): string {\n return this.props.customerId;\n }\n\n get items(): readonly OrderItem[] {\n return this.props.items;\n }\n\n get status(): OrderStatus {\n return this.props.status;\n }\n\n get totalAmount(): Money {\n return this.props.totalAmount;\n }\n\n get placedAt(): Date {\n return this.props.placedAt;\n }\n\n /**\n * Adds an item to the order.\n *\n * Uses the `canAddOrderItem` business policy to check if the operation is allowed.\n *\n * @param item - The item to add\n * @throws {InvariantViolationError} If the order is not in pending status\n */\n addItem(item: OrderItem): void {\n if (!canAddOrderItem(this)) {\n throw new InvariantViolationError({\n message: 'Cannot add items to non-pending order',\n code: 'ORDER_NOT_PENDING',\n });\n }\n\n this._props.items.push(item);\n this._props.totalAmount = this._props.totalAmount.add(item.totalPrice);\n }\n\n /**\n * Confirms the order (e.g., after payment received).\n *\n * @throws {InvariantViolationError} If the order is not in pending status\n */\n confirm(): void {\n if (!this.status.isPending()) {\n throw new InvariantViolationError({\n message: 'Only pending orders can be confirmed',\n code: 'ORDER_NOT_PENDING',\n });\n }\n\n this._props.status = OrderStatus.confirmed();\n }\n\n /**\n * Marks the order as shipped.\n *\n * @throws {InvariantViolationError} If the order is not confirmed\n */\n ship(): void {\n if (!this.status.isConfirmed()) {\n throw new InvariantViolationError({\n message: 'Only confirmed orders can be shipped',\n code: 'ORDER_NOT_CONFIRMED',\n });\n }\n\n this._props.status = OrderStatus.shipped();\n }\n\n /**\n * Cancels the order.\n *\n * Uses the `canCancelOrder` business policy to check if the operation is allowed.\n *\n * @param reason - The reason for cancellation\n * @throws {InvariantViolationError} If the order cannot be cancelled\n */\n cancel(reason: string): void {\n if (!canCancelOrder(this)) {\n throw new InvariantViolationError({\n message: 'Order cannot be cancelled - already shipped or cancelled',\n code: 'ORDER_CANNOT_CANCEL',\n });\n }\n\n this._props.status = OrderStatus.cancelled();\n\n this.addDomainEvent(\n new OrderCancelledEvent({\n orderId: this.id.value,\n reason,\n cancelledAt: new Date().toISOString(),\n }),\n );\n }\n}\n","import { BaseUuidV7Vo } from '../../value-objects/base-uuid-v7.vo';\n\n/**\n * Value Object representing an OrderItem's unique identifier.\n */\nexport class OrderItemId extends BaseUuidV7Vo {}\n","import { BaseEntity } from '../../classes';\nimport { OrderItemId } from './order-item-id.vo';\nimport type { Money } from '../value-objects';\n\n/**\n * Properties for an OrderItem entity.\n */\nexport interface OrderItemProps {\n productId: string;\n productName: string;\n quantity: number;\n unitPrice: Money;\n}\n\n/**\n * Entity representing a line item within an Order aggregate.\n *\n * OrderItem is not an aggregate root - it's accessed through the Order aggregate.\n * It has its own identity but cannot exist independently of an Order.\n *\n * @example\n * ```typescript\n * const item = OrderItem.create({\n * productId: 'prod-123',\n * productName: 'Widget',\n * quantity: 2,\n * unitPrice: Money.usd(29.99),\n * });\n *\n * console.log(item.totalPrice.amount); // 59.98\n * ```\n */\nexport class OrderItem extends BaseEntity<OrderItemId, OrderItemProps> {\n private constructor(id: OrderItemId, props: OrderItemProps) {\n super(id, props);\n }\n\n /**\n * Creates a new OrderItem.\n */\n static create(props: OrderItemProps): OrderItem {\n return new OrderItem(OrderItemId.generate(), props);\n }\n\n /**\n * Reconstitutes an OrderItem from persistence.\n */\n static fromPersistence(id: OrderItemId, props: OrderItemProps): OrderItem {\n return new OrderItem(id, props);\n }\n\n get productId(): string {\n return this.props.productId;\n }\n\n get productName(): string {\n return this.props.productName;\n }\n\n get quantity(): number {\n return this.props.quantity;\n }\n\n get unitPrice(): Money {\n return this.props.unitPrice;\n }\n\n /**\n * Calculates the total price for this line item.\n */\n get totalPrice(): Money {\n return this.props.unitPrice.multiply(this.props.quantity);\n }\n\n /**\n * Updates the quantity of this item.\n */\n updateQuantity(newQuantity: number): void {\n this._props.quantity = newQuantity;\n }\n\n /**\n * Converts to a plain object for events or persistence.\n */\n toPlain(): {\n id: string;\n productId: string;\n productName: string;\n quantity: number;\n unitPrice: { amount: number; currency: string };\n } {\n return {\n id: this.id.value,\n productId: this.props.productId,\n productName: this.props.productName,\n quantity: this.props.quantity,\n unitPrice: {\n amount: this.props.unitPrice.amount,\n currency: this.props.unitPrice.currency,\n },\n };\n }\n}\n","import { InvariantViolationError } from '../../exceptions/invariant-violation.error';\n\n/**\n * Error thrown when attempting to modify an order that has already been shipped.\n *\n * @example\n * ```typescript\n * if (order.status.isShipped()) {\n * throw new OrderAlreadyShippedError(order.id.value);\n * }\n * ```\n */\nexport class OrderAlreadyShippedError extends InvariantViolationError {\n constructor(orderId: string) {\n super({\n message: `Order ${orderId} has already been shipped and cannot be modified`,\n code: 'ORDER_ALREADY_SHIPPED',\n });\n }\n}\n","import { InfraError } from '../exceptions/infra.error';\n\n/** @internal Function signature for wrapped methods. */\ntype UnknownFn = (...args: unknown[]) => unknown;\n\n/** @internal Symbol to mark methods that have been wrapped on a prototype. */\nconst WRAPPED_METHODS_SYMBOL = Symbol.for('onion-lasagna:wrapped-methods');\n\n/** @internal Get or create the set of wrapped method names for a prototype. */\nfunction getWrappedMethods(proto: object): Set<string> {\n const existing = (proto as Record<symbol, Set<string>>)[WRAPPED_METHODS_SYMBOL];\n if (existing) return existing;\n\n const newSet = new Set<string>();\n Object.defineProperty(proto, WRAPPED_METHODS_SYMBOL, {\n value: newSet,\n writable: false,\n enumerable: false,\n configurable: false,\n });\n return newSet;\n}\n\n/**\n * Abstract base class for outbound adapters (secondary/driven ports).\n *\n * Provides automatic error handling for all subclass methods by:\n * - Wrapping synchronous methods with try/catch\n * - Attaching `.catch()` handlers to Promise-returning methods\n * - Converting all errors to {@link InfraError} with the original as `cause`\n *\n * This ensures infrastructure errors are properly typed and don't leak\n * implementation details to the application layer.\n *\n * @example\n * ```typescript\n * class UserRepository extends BaseOutboundAdapter {\n * constructor(private db: Database) {\n * super();\n * }\n *\n * async findById(id: string): Promise<User | null> {\n * return this.db.users.findUnique({ where: { id } });\n * }\n *\n * protected override createInfraError(error: unknown, methodName: string): InfraError {\n * return new DbError({\n * message: `Database error in ${methodName}`,\n * cause: error,\n * });\n * }\n * }\n * ```\n */\nexport abstract class BaseOutboundAdapter {\n /**\n * Initializes the adapter and wraps all subclass methods with error handling.\n * Must be called via `super()` in subclass constructors.\n */\n protected constructor() {\n this.wrapAllSubclassMethods();\n }\n\n /**\n * Factory method for creating infrastructure errors.\n *\n * Override this in subclasses to return specific error types\n * (e.g., `DbError`, `NetworkError`, `ExternalServiceError`).\n *\n * @param error - The original error that was caught\n * @param methodName - Name of the method where the error occurred (for debugging)\n * @returns An InfraError instance wrapping the original error\n */\n protected createInfraError(error: unknown, methodName: string): InfraError {\n return new InfraError({\n message: `Outbound adapter error in ${methodName}`,\n cause: error,\n });\n }\n\n /**\n * Walks the prototype chain and wraps all methods with error handling.\n * Uses prototype-level Symbol markers to prevent re-wrapping across instances.\n * @internal\n */\n private wrapAllSubclassMethods(): void {\n const wrapMethod = (methodName: string, original: UnknownFn) => {\n const wrapped: UnknownFn = (...args: unknown[]) => {\n try {\n const result = Reflect.apply(original, this, args);\n\n // If it's a Promise, preserve rejection handling without turning sync methods into async ones.\n if (result instanceof Promise) {\n return result.catch((error: unknown) => {\n throw this.createInfraError(error, methodName);\n });\n }\n\n return result;\n } catch (error) {\n throw this.createInfraError(error, methodName);\n }\n };\n\n Object.defineProperty(this, methodName, {\n value: wrapped,\n writable: false,\n enumerable: false,\n configurable: false,\n });\n };\n\n // Collect all method names that need wrapping (checking prototype-level markers)\n const methodsToWrap: { name: string; fn: UnknownFn }[] = [];\n\n // Walk the prototype chain until this base class.\n let proto: object | null = Object.getPrototypeOf(this);\n while (proto && proto !== BaseOutboundAdapter.prototype && proto !== Object.prototype) {\n const wrappedOnProto = getWrappedMethods(proto);\n\n for (const key of Object.getOwnPropertyNames(proto)) {\n if (key === 'constructor') continue;\n\n // Check if already wrapped at prototype level (across all instances)\n if (wrappedOnProto.has(key)) continue;\n\n const descriptor = Object.getOwnPropertyDescriptor(proto, key);\n if (!descriptor) continue;\n\n // Skip getters/setters - only wrap regular methods\n if (descriptor.get || descriptor.set) continue;\n if (typeof descriptor.value !== 'function') continue;\n\n methodsToWrap.push({ name: key, fn: descriptor.value as UnknownFn });\n wrappedOnProto.add(key);\n }\n\n proto = Object.getPrototypeOf(proto);\n }\n\n // Apply wrapping to this instance\n for (const { name, fn } of methodsToWrap) {\n wrapMethod(name, fn);\n }\n }\n}\n","import { ErrorCodes, type InfraErrorCode } from '../../../global/exceptions/error-codes.const';\nimport { InfraError } from './infra.error';\n\n/**\n * Error thrown when a database operation fails.\n *\n * Wraps database-specific errors (connection failures, query errors,\n * constraint violations) into a transport-agnostic infrastructure error.\n *\n * **When to throw:**\n * - Database connection lost\n * - Query execution failed\n * - Transaction rollback\n * - Constraint violation (unique, foreign key)\n *\n * @example\n * ```typescript\n * try {\n * await this.db.query('SELECT * FROM users');\n * } catch (error) {\n * throw new DbError({\n * message: 'Failed to fetch users',\n * code: 'USER_QUERY_FAILED',\n * cause: error,\n * });\n * }\n * ```\n *\n * @extends InfraError\n */\nexport class DbError extends InfraError {\n /**\n * Creates a new DbError instance.\n *\n * @param options - Error configuration\n * @param options.message - Description of the database failure\n * @param options.code - Machine-readable error code (default: 'DB_ERROR')\n * @param options.cause - Optional underlying database error\n */\n constructor({\n message,\n code = ErrorCodes.Infra.DB_ERROR,\n cause,\n }: {\n message: string;\n code?: InfraErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates a DbError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new DbError instance with the cause attached\n */\n static override fromError(cause: unknown): DbError {\n return new DbError({\n message: cause instanceof Error ? cause.message : 'Database error',\n cause,\n });\n }\n}\n","import { ErrorCodes, type InfraErrorCode } from '../../../global/exceptions/error-codes.const';\nimport { InfraError } from './infra.error';\n\n/**\n * Error thrown when a network operation fails.\n *\n * Indicates connectivity issues such as DNS resolution failures,\n * connection refused, or network unreachable errors.\n *\n * **When to throw:**\n * - Connection refused\n * - DNS resolution failed\n * - Network unreachable\n * - Socket errors\n *\n * @example\n * ```typescript\n * try {\n * await fetch('https://api.example.com/data');\n * } catch (error) {\n * throw new NetworkError({\n * message: 'Failed to connect to API',\n * code: 'API_CONNECTION_FAILED',\n * cause: error,\n * });\n * }\n * ```\n *\n * @extends InfraError\n */\nexport class NetworkError extends InfraError {\n /**\n * Creates a new NetworkError instance.\n *\n * @param options - Error configuration\n * @param options.message - Description of the network failure\n * @param options.code - Machine-readable error code (default: 'NETWORK_ERROR')\n * @param options.cause - Optional underlying network error\n */\n constructor({\n message,\n code = ErrorCodes.Infra.NETWORK_ERROR,\n cause,\n }: {\n message: string;\n code?: InfraErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates a NetworkError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new NetworkError instance with the cause attached\n */\n static override fromError(cause: unknown): NetworkError {\n return new NetworkError({\n message: cause instanceof Error ? cause.message : 'Network error',\n cause,\n });\n }\n}\n","import { ErrorCodes, type InfraErrorCode } from '../../../global/exceptions/error-codes.const';\nimport { InfraError } from './infra.error';\n\n/**\n * Error thrown when an operation exceeds its time limit.\n *\n * Indicates that a request or operation took longer than the\n * configured timeout threshold.\n *\n * **When to throw:**\n * - Request timeout exceeded\n * - Database query timeout\n * - External API response timeout\n * - Lock acquisition timeout\n *\n * @example\n * ```typescript\n * const controller = new AbortController();\n * setTimeout(() => controller.abort(), 5000);\n *\n * try {\n * await fetch(url, { signal: controller.signal });\n * } catch (error) {\n * throw new TimeoutError({\n * message: 'Request timed out after 5 seconds',\n * code: 'REQUEST_TIMEOUT',\n * cause: error,\n * });\n * }\n * ```\n *\n * @extends InfraError\n */\nexport class TimeoutError extends InfraError {\n /**\n * Creates a new TimeoutError instance.\n *\n * @param options - Error configuration\n * @param options.message - Description of what timed out\n * @param options.code - Machine-readable error code (default: 'TIMEOUT_ERROR')\n * @param options.cause - Optional underlying timeout error\n */\n constructor({\n message,\n code = ErrorCodes.Infra.TIMEOUT_ERROR,\n cause,\n }: {\n message: string;\n code?: InfraErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates a TimeoutError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new TimeoutError instance with the cause attached\n */\n static override fromError(cause: unknown): TimeoutError {\n return new TimeoutError({\n message: cause instanceof Error ? cause.message : 'Operation timed out',\n cause,\n });\n }\n}\n","import { ErrorCodes, type InfraErrorCode } from '../../../global/exceptions/error-codes.const';\nimport { InfraError } from './infra.error';\n\n/**\n * Error thrown when a third-party service call fails.\n *\n * Wraps errors from external APIs, payment gateways, email services,\n * or any other third-party dependency.\n *\n * **When to throw:**\n * - Third-party API returns an error\n * - External service is unavailable\n * - Unexpected response from external service\n * - Rate limiting by external service\n *\n * @example\n * ```typescript\n * try {\n * await this.paymentGateway.charge(amount);\n * } catch (error) {\n * throw new ExternalServiceError({\n * message: 'Payment gateway charge failed',\n * code: 'PAYMENT_GATEWAY_ERROR',\n * cause: error,\n * });\n * }\n * ```\n *\n * @extends InfraError\n */\nexport class ExternalServiceError extends InfraError {\n /**\n * Creates a new ExternalServiceError instance.\n *\n * @param options - Error configuration\n * @param options.message - Description of the external service failure\n * @param options.code - Machine-readable error code (default: 'EXTERNAL_SERVICE_ERROR')\n * @param options.cause - Optional underlying service error\n */\n constructor({\n message,\n code = ErrorCodes.Infra.EXTERNAL_SERVICE_ERROR,\n cause,\n }: {\n message: string;\n code?: InfraErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates an ExternalServiceError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new ExternalServiceError instance with the cause attached\n */\n static override fromError(cause: unknown): ExternalServiceError {\n return new ExternalServiceError({\n message: cause instanceof Error ? cause.message : 'External service error',\n cause,\n });\n }\n}\n","import { CodedError } from '../../../global/exceptions/coded-error.error';\nimport {\n ErrorCodes,\n type PresentationErrorCode,\n} from '../../../global/exceptions/error-codes.const';\n\n/**\n * Base error class for presentation layer (controller) failures.\n *\n * Controller errors represent failures in request handling,\n * such as access control violations or malformed requests.\n * They are the outermost error layer and typically map to HTTP responses.\n *\n * **When to throw:**\n * - Access control failures (unauthorized/forbidden)\n * - Request validation failures\n * - Unexpected controller execution errors\n *\n * **Child classes:**\n * - {@link AccessDeniedError} - Authorization failures (HTTP 403)\n * - {@link InvalidRequestError} - Request validation failures (HTTP 400)\n *\n * @example\n * ```typescript\n * // Thrown automatically by BaseController for unexpected errors\n * throw new ControllerError({\n * message: 'Controller execution failed',\n * cause: originalError,\n * });\n * ```\n */\nexport class ControllerError extends CodedError {\n /**\n * Creates a new ControllerError instance.\n *\n * @param options - Error configuration\n * @param options.message - Human-readable error description\n * @param options.code - Machine-readable error code (default: 'CONTROLLER_ERROR')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.Presentation.CONTROLLER_ERROR,\n cause,\n }: {\n message: string;\n code?: PresentationErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates a ControllerError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new ControllerError instance with the cause attached\n */\n static override fromError(cause: unknown): ControllerError {\n return new ControllerError({\n message: cause instanceof Error ? cause.message : 'Controller error',\n cause,\n });\n }\n}\n","import { CodedError } from '../../../global/exceptions/coded-error.error';\nimport {\n ErrorCodes,\n type PresentationErrorCode,\n} from '../../../global/exceptions/error-codes.const';\nimport type { ValidationError } from '../../../global/interfaces/types/validation-error.type';\n\n/**\n * Error thrown when request validation fails at the controller level.\n *\n * Contains structured validation errors with field paths and messages,\n * converted from {@link ObjectValidationError} by {@link BaseController}.\n * Provides detailed feedback about which fields failed validation.\n *\n * **When thrown:**\n * - Request DTO validation fails\n * - Malformed request data\n * - Missing required fields\n *\n * @example\n * ```typescript\n * // Automatically thrown by BaseController when DTO validation fails\n * // The validationErrors array contains field-level details:\n * // [\n * // { field: 'email', message: 'Invalid email format' },\n * // { field: 'age', message: 'Must be a positive number' }\n * // ]\n * ```\n *\n * @example Manual usage\n * ```typescript\n * throw new InvalidRequestError({\n * message: 'Request validation failed',\n * validationErrors: [\n * { field: 'username', message: 'Username is required' },\n * ],\n * });\n * ```\n *\n * @extends CodedError\n */\nexport class InvalidRequestError extends CodedError {\n /**\n * Array of field-level validation errors.\n *\n * Each entry contains:\n * - `field`: Dot-notation path to the invalid field\n * - `message`: Human-readable validation failure message\n */\n readonly validationErrors: ValidationError[];\n\n /**\n * Creates a new InvalidRequestError instance.\n *\n * @param options - Error configuration\n * @param options.message - Summary of the validation failure\n * @param options.code - Machine-readable error code (default: 'INVALID_REQUEST')\n * @param options.cause - Optional underlying error\n * @param options.validationErrors - Array of field-level validation errors\n */\n constructor({\n message,\n code = ErrorCodes.Presentation.INVALID_REQUEST,\n cause,\n validationErrors,\n }: {\n message: string;\n code?: PresentationErrorCode | string;\n cause?: unknown;\n validationErrors: ValidationError[];\n }) {\n super({ message, code, cause });\n this.validationErrors = validationErrors;\n }\n\n /**\n * Creates an InvalidRequestError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new InvalidRequestError instance with the cause attached\n */\n static override fromError(cause: unknown): InvalidRequestError {\n return new InvalidRequestError({\n message: cause instanceof Error ? cause.message : 'Invalid request',\n cause,\n validationErrors: [],\n });\n }\n}\n","import type { BaseInboundPort } from '../../app/interfaces/ports/base-inbound.port';\nimport type { BaseDto } from '../../../global/classes/base-dto.class';\nimport { CodedError } from '../../../global/exceptions/coded-error.error';\nimport { ObjectValidationError } from '../../../global/exceptions/object-validation.error';\nimport { wrapErrorUnless, wrapErrorUnlessAsync } from '../../../global/utils/wrap-error.util';\nimport { ControllerError } from '../exceptions/controller.error';\nimport { InvalidRequestError } from '../exceptions/invalid-request.error';\n\n/**\n * Configuration for creating a BaseController instance.\n *\n * All types must be DTOs (extending BaseDto) to ensure validation at every boundary:\n * - TRequestDto: Validated HTTP request (body, headers, params, query)\n * - TResponseDto: Validated HTTP response structure\n * - TInDto: Validated use case input\n * - TOutDto: Validated use case output\n *\n * @typeParam TRequestDto - Validated request DTO from the framework layer\n * @typeParam TResponseDto - Validated response DTO to return to the framework\n * @typeParam TInDto - Input DTO type for the use case\n * @typeParam TOutDto - Output DTO type from the use case\n */\nexport interface BaseControllerConfig<\n TRequestDto extends BaseDto<unknown>,\n TResponseDto extends BaseDto<unknown>,\n TInDto extends BaseDto<unknown>,\n TOutDto extends BaseDto<unknown>,\n> {\n /** Maps the validated request DTO to a use case input DTO. */\n requestMapper: (request: TRequestDto) => TInDto;\n /** The use case to execute. */\n useCase: BaseInboundPort<TInDto, TOutDto>;\n /** Maps the use case output DTO to a validated response DTO. */\n responseMapper: (output: TOutDto) => TResponseDto;\n}\n\n/**\n * Base controller implementing the request/response pipeline.\n *\n * Orchestrates the flow: `requestDto → mapRequest → executeUseCase → mapResponse → responseDto`\n *\n * All boundaries are validated DTOs:\n * - Input: TRequestDto (validated by framework layer before controller)\n * - Use case input: TInDto (validated by mapRequest)\n * - Use case output: TOutDto (validated by use case)\n * - Output: TResponseDto (validated by mapResponse)\n *\n * Features:\n * - Converts {@link ObjectValidationError} to {@link InvalidRequestError}\n * - Passes through known {@link CodedError} types\n * - Wraps unknown errors in {@link ControllerError}\n *\n * Architecture:\n * - {@link execute} - Public entry point with error wrapping (do not override)\n * - {@link pipeline} - Protected pipeline orchestration (override for custom flow)\n * - {@link mapRequest} - Request-to-input transformation\n * - {@link executeUseCase} - Use case execution\n * - {@link mapResponse} - Output-to-response transformation\n *\n * @typeParam TRequestDto - Validated request DTO from the framework layer\n * @typeParam TResponseDto - Validated response DTO to return to the framework\n * @typeParam TInDto - Input DTO type for the use case\n * @typeParam TOutDto - Output DTO type from the use case\n *\n * @example Basic usage\n * ```typescript\n * const controller = BaseController.create({\n * requestMapper: (req) => CreateUserInputDto.create(req.data),\n * useCase: createUserUseCase,\n * responseMapper: (output) => CreateUserResponseDto.create({ id: output.data.id }),\n * });\n *\n * // Framework layer creates the request DTO\n * const requestDto = CreateUserRequestDto.create(httpRequest);\n * const responseDto = await controller.execute(requestDto);\n * ```\n *\n * @example Custom controller overriding pipeline\n * ```typescript\n * class LoggingController extends BaseController<...> {\n * protected override async pipeline(input: TRequestDto): Promise<TResponseDto> {\n * console.log('Request received:', input);\n * const result = await super.pipeline(input);\n * console.log('Response:', result);\n * return result;\n * }\n * }\n * ```\n *\n * @example Custom controller overriding individual methods\n * ```typescript\n * class CachingController extends BaseController<...> {\n * private cache = new Map();\n *\n * protected override async executeUseCase(input: TInDto): Promise<TOutDto> {\n * const key = JSON.stringify(input.data);\n * if (this.cache.has(key)) return this.cache.get(key);\n * const result = await super.executeUseCase(input);\n * this.cache.set(key, result);\n * return result;\n * }\n * }\n * ```\n */\nexport class BaseController<\n TRequestDto extends BaseDto<unknown>,\n TResponseDto extends BaseDto<unknown>,\n TInDto extends BaseDto<unknown>,\n TOutDto extends BaseDto<unknown>,\n> {\n /**\n * Creates a new BaseController instance.\n *\n * @param requestMapper - Function to map request DTO to use case input DTO\n * @param useCase - The use case port to execute\n * @param responseMapper - Function to map use case output DTO to response DTO\n */\n constructor(\n protected readonly requestMapper: (request: TRequestDto) => TInDto,\n protected readonly useCase: BaseInboundPort<TInDto, TOutDto>,\n protected readonly responseMapper: (output: TOutDto) => TResponseDto,\n ) {}\n\n /**\n * Factory method to create a controller from a configuration object.\n *\n * @param config - Controller configuration\n * @returns A new BaseController instance\n */\n static create<\n TRequestDto extends BaseDto<unknown>,\n TResponseDto extends BaseDto<unknown>,\n TInDto extends BaseDto<unknown>,\n TOutDto extends BaseDto<unknown>,\n >(\n config: BaseControllerConfig<TRequestDto, TResponseDto, TInDto, TOutDto>,\n ): BaseController<TRequestDto, TResponseDto, TInDto, TOutDto> {\n return new BaseController(config.requestMapper, config.useCase, config.responseMapper);\n }\n\n /**\n * Executes the controller pipeline with error wrapping.\n *\n * This is the public entry point that ensures consistent error handling.\n * All errors are wrapped in {@link ControllerError} unless they extend {@link CodedError}.\n *\n * **Do not override this method.** Override {@link pipeline} instead for custom pipeline logic.\n *\n * @param input - The validated request DTO\n * @returns Promise resolving to the validated response DTO\n * @throws {InvalidRequestError} When request mapping/validation fails\n * @throws {ControllerError} When an unexpected error occurs\n * @throws {CodedError} When use case throws a known error type\n */\n async execute(input: TRequestDto): Promise<TResponseDto> {\n return wrapErrorUnlessAsync(\n () => this.pipeline(input),\n (cause) =>\n new ControllerError({\n message: cause instanceof Error ? cause.message : 'Controller execution failed',\n cause,\n }),\n [CodedError],\n );\n }\n\n /**\n * Runs the controller pipeline.\n *\n * Orchestrates: `mapRequest → executeUseCase → mapResponse`\n *\n * Override this method to customize the entire pipeline flow, or override\n * individual protected methods ({@link mapRequest}, {@link executeUseCase},\n * {@link mapResponse}) for more granular control.\n *\n * @param input - The validated request DTO\n * @returns Promise resolving to the validated response DTO\n */\n protected async pipeline(input: TRequestDto): Promise<TResponseDto> {\n const mappedInput = this.mapRequest(input);\n const result = await this.executeUseCase(mappedInput);\n return this.mapResponse(result);\n }\n\n /**\n * Maps the request DTO to a use case input DTO.\n *\n * Override to add custom pre-processing, logging, or transformation logic.\n * The default implementation uses the configured `requestMapper` and converts\n * {@link ObjectValidationError} to {@link InvalidRequestError}.\n *\n * @param input - The validated request DTO\n * @returns The use case input DTO\n * @throws {InvalidRequestError} When validation fails\n * @throws {ControllerError} When mapping fails unexpectedly\n */\n protected mapRequest(input: TRequestDto): TInDto {\n return wrapErrorUnless(\n () => this.requestMapper(input),\n (cause) => {\n if (cause instanceof ObjectValidationError) {\n return new InvalidRequestError({\n message: cause.message,\n cause,\n validationErrors: cause.validationErrors,\n });\n }\n return new ControllerError({\n message: cause instanceof Error ? cause.message : 'Request mapping failed',\n cause,\n });\n },\n [CodedError],\n );\n }\n\n /**\n * Executes the use case with the mapped input.\n *\n * Override to add custom logic around use case execution, such as:\n * - Logging/tracing\n * - Caching\n * - Retry logic\n * - Multi-use-case orchestration\n *\n * @param input - The use case input DTO\n * @returns Promise resolving to the use case output DTO\n */\n protected async executeUseCase(input: TInDto): Promise<TOutDto> {\n return this.useCase.execute(input);\n }\n\n /**\n * Maps the use case output DTO to a response DTO.\n *\n * Override to add custom post-processing, logging, or transformation logic.\n * The default implementation uses the configured `responseMapper`.\n *\n * @param output - The use case output DTO\n * @returns The response DTO\n * @throws {ControllerError} When mapping or validation fails\n */\n protected mapResponse(output: TOutDto): TResponseDto {\n return wrapErrorUnless(\n () => this.responseMapper(output),\n (cause) =>\n new ControllerError({\n message:\n cause instanceof ObjectValidationError\n ? 'Response validation failed'\n : cause instanceof Error\n ? cause.message\n : 'Response mapping failed',\n cause,\n }),\n [CodedError],\n );\n }\n}\n","import { CodedError } from '../../../global/exceptions/coded-error.error';\nimport {\n ErrorCodes,\n type PresentationErrorCode,\n} from '../../../global/exceptions/error-codes.const';\n\n/**\n * Error thrown when access to a resource is denied.\n *\n * Indicates that the requester does not have permission to perform\n * the requested operation. Thrown by {@link GuardedController} when\n * an access guard returns `isAllowed: false`.\n *\n * **When thrown:**\n * - Access guard denies the request\n * - User lacks required permissions\n * - Resource ownership check fails\n *\n * @example GuardedController usage\n * ```typescript\n * const controller = GuardedController.create({\n * accessGuard: (req) => ({\n * isAllowed: req.user?.role === 'admin',\n * reason: 'Admin access required',\n * }),\n * // ... other config\n * });\n * ```\n *\n * @example Manual usage\n * ```typescript\n * if (!user.canAccess(resource)) {\n * throw new AccessDeniedError({\n * message: 'You do not have access to this resource',\n * code: 'RESOURCE_ACCESS_DENIED',\n * });\n * }\n * ```\n *\n * @extends CodedError\n */\nexport class AccessDeniedError extends CodedError {\n /**\n * Creates a new AccessDeniedError instance.\n *\n * @param options - Error configuration\n * @param options.message - Description of why access was denied\n * @param options.code - Machine-readable error code (default: 'ACCESS_DENIED')\n * @param options.cause - Optional underlying error\n */\n constructor({\n message,\n code = ErrorCodes.Presentation.ACCESS_DENIED,\n cause,\n }: {\n message: string;\n code?: PresentationErrorCode | string;\n cause?: unknown;\n }) {\n super({ message, code, cause });\n }\n\n /**\n * Creates an AccessDeniedError from a caught error.\n *\n * @param cause - The original caught error\n * @returns A new AccessDeniedError instance with the cause attached\n */\n static override fromError(cause: unknown): AccessDeniedError {\n return new AccessDeniedError({\n message: cause instanceof Error ? cause.message : 'Access denied',\n cause,\n });\n }\n}\n","import type { AccessGuard } from '../interfaces/types/access-guard.type';\nimport type { AccessGuardResult } from '../interfaces/types/access-guard-result.type';\nimport type { BaseInboundPort } from '../../app/interfaces/ports/base-inbound.port';\nimport type { BaseDto } from '../../../global/classes/base-dto.class';\nimport { BaseController } from './base-controller.class';\nimport { AccessDeniedError } from '../exceptions/access-denied.error';\n\n/**\n * Configuration for creating a GuardedController instance.\n *\n * All types must be DTOs (extending BaseDto) to ensure validation at every boundary.\n *\n * @typeParam TRequestDto - Validated request DTO from the framework layer\n * @typeParam TResponseDto - Validated response DTO to return to the framework\n * @typeParam TInDto - Input DTO type for the use case\n * @typeParam TOutDto - Output DTO type from the use case\n */\nexport interface GuardedControllerConfig<\n TRequestDto extends BaseDto<unknown>,\n TResponseDto extends BaseDto<unknown>,\n TInDto extends BaseDto<unknown>,\n TOutDto extends BaseDto<unknown>,\n> {\n /** Maps the validated request DTO to a use case input DTO. */\n requestMapper: (request: TRequestDto) => TInDto;\n /** The use case to execute. */\n useCase: BaseInboundPort<TInDto, TOutDto>;\n /** Maps the use case output DTO to a validated response DTO. */\n responseMapper: (output: TOutDto) => TResponseDto;\n /** Optional access guard; defaults to allowing all requests. */\n accessGuard?: AccessGuard<TRequestDto>;\n}\n\n/**\n * Creates a type-safe default access guard that allows all requests.\n * @internal\n */\nfunction createAllowAllGuard<T>(): AccessGuard<T> {\n return async (): Promise<AccessGuardResult> => ({\n isAllowed: true,\n });\n}\n\n/**\n * Controller with access control.\n *\n * Extends {@link BaseController} with an access guard that runs before\n * the pipeline. If the guard denies access, an {@link AccessDeniedError}\n * is thrown.\n *\n * All types must be DTOs (extending BaseDto) to ensure validation at every boundary.\n *\n * @typeParam TRequestDto - Validated request DTO from the framework layer\n * @typeParam TResponseDto - Validated response DTO to return to the framework\n * @typeParam TInDto - Input DTO type for the use case\n * @typeParam TOutDto - Output DTO type from the use case\n *\n * @example\n * ```typescript\n * const controller = GuardedController.create({\n * requestMapper: (req) => UpdateUserInputDto.create(req.data),\n * useCase: updateUserUseCase,\n * responseMapper: (output) => UpdateUserResponseDto.create(output.data),\n * accessGuard: async (req) => ({\n * isAllowed: req.data.user?.role === 'admin',\n * reason: 'Admin access required',\n * }),\n * });\n * ```\n */\nexport class GuardedController<\n TRequestDto extends BaseDto<unknown>,\n TResponseDto extends BaseDto<unknown>,\n TInDto extends BaseDto<unknown>,\n TOutDto extends BaseDto<unknown>,\n> extends BaseController<TRequestDto, TResponseDto, TInDto, TOutDto> {\n /** The access guard function for this controller. */\n protected readonly accessGuard: AccessGuard<TRequestDto>;\n\n /**\n * Creates a new GuardedController instance.\n *\n * @param requestMapper - Function to map request DTO to use case input DTO\n * @param useCase - The use case port to execute\n * @param responseMapper - Function to map use case output DTO to response DTO\n * @param accessGuard - Optional access guard; defaults to allowing all\n */\n constructor(\n requestMapper: (request: TRequestDto) => TInDto,\n useCase: BaseInboundPort<TInDto, TOutDto>,\n responseMapper: (output: TOutDto) => TResponseDto,\n accessGuard?: AccessGuard<TRequestDto>,\n ) {\n super(requestMapper, useCase, responseMapper);\n this.accessGuard = accessGuard ?? createAllowAllGuard<TRequestDto>();\n }\n\n /**\n * Factory method to create a guarded controller from a configuration object.\n *\n * @param config - Controller configuration including optional access guard\n * @returns A new GuardedController instance\n */\n static override create<\n TRequestDto extends BaseDto<unknown>,\n TResponseDto extends BaseDto<unknown>,\n TInDto extends BaseDto<unknown>,\n TOutDto extends BaseDto<unknown>,\n >(\n config: GuardedControllerConfig<TRequestDto, TResponseDto, TInDto, TOutDto>,\n ): GuardedController<TRequestDto, TResponseDto, TInDto, TOutDto> {\n return new GuardedController(\n config.requestMapper,\n config.useCase,\n config.responseMapper,\n config.accessGuard,\n );\n }\n\n /**\n * Runs the controller pipeline with access control.\n *\n * Checks the access guard before executing the pipeline.\n * If denied, throws {@link AccessDeniedError}.\n *\n * @param input - The validated request DTO\n * @returns Promise resolving to the validated response DTO\n * @throws {AccessDeniedError} When access guard denies the request\n */\n protected override async pipeline(input: TRequestDto): Promise<TResponseDto> {\n await this.checkAccess(input);\n return super.pipeline(input);\n }\n\n /**\n * Checks access using the configured guard.\n *\n * Override to customize access control logic.\n *\n * @param input - The validated request DTO\n * @throws {AccessDeniedError} When access is denied\n */\n protected async checkAccess(input: TRequestDto): Promise<void> {\n const result = await this.accessGuard(input);\n if (!result.isAllowed) {\n throw new AccessDeniedError({\n message: result.reason ?? 'Access denied',\n });\n }\n }\n}\n","/**\n * System metadata.\n *\n * Top-level metadata for the whole API surface (\"the system\"), sitting above\n * individual services/resources/endpoints.\n *\n * This is intentionally stable and serializable so it can be consumed by tools\n * (OpenAPI generation, docs, code generation).\n */\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// Auth Scheme Types\n// ═══════════════════════════════════════════════════════════════════════════════\n\n/**\n * API Key authentication scheme (header, query, or cookie).\n */\nexport interface ApiKeyAuthScheme {\n type: 'apiKey';\n in: 'header' | 'query' | 'cookie';\n /** Header/query/cookie parameter name, e.g. 'x-api-key' */\n name: string;\n description?: string;\n}\n\n/**\n * HTTP Bearer authentication scheme.\n */\nexport interface HttpBearerAuthScheme {\n type: 'http';\n scheme: 'bearer';\n bearerFormat?: string;\n description?: string;\n}\n\n/**\n * HTTP Basic authentication scheme.\n */\nexport interface HttpBasicAuthScheme {\n type: 'http';\n scheme: 'basic';\n description?: string;\n}\n\n/**\n * Union of all supported authentication schemes.\n */\nexport type AuthScheme = ApiKeyAuthScheme | HttpBearerAuthScheme | HttpBasicAuthScheme;\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// System Metadata Type\n// ═══════════════════════════════════════════════════════════════════════════════\n\nexport interface SystemMetadata {\n // ═══════════════════════════════════════════════════════════════════════════\n // IDENTITY (required — routing, logging, code generation)\n // ═══════════════════════════════════════════════════════════════════════════\n\n /**\n * Stable system identifier.\n *\n * Recommendation: kebab-case.\n * Example: `acmp-connector`\n */\n id: string;\n\n /**\n * Short identifier for compact displays/logging.\n *\n * Example: `acmp`\n */\n shortId: string;\n\n /**\n * Human-readable system name.\n *\n * Example: `ACMP Connector`\n */\n name: string;\n\n /**\n * Human-readable description.\n */\n description?: string;\n\n /**\n * System/API version (SemVer recommended).\n *\n * Example: `1.0.0`\n */\n version: string;\n\n // ═══════════════════════════════════════════════════════════════════════════\n // DOMAIN (system-specific — servers, auth)\n // ═══════════════════════════════════════════════════════════════════════════\n\n /**\n * Default servers for the API.\n * Used by OpenAPI generation and client configuration.\n */\n servers?: {\n url: string;\n description?: string;\n }[];\n\n /**\n * Authentication configuration.\n */\n auth?: {\n /**\n * Whether endpoints should be considered secure by default.\n * @default true\n */\n secureByDefault?: boolean;\n\n /**\n * Available authentication schemes.\n *\n * Keyed by scheme name (must be unique within the system).\n * Example: `{ apiKeyAuth: { type: 'apiKey', in: 'header', name: 'x-api-key' } }`\n */\n schemes: Record<string, AuthScheme>;\n\n /**\n * Default security requirements (applies to all secure endpoints).\n *\n * OpenAPI semantics:\n * - Array is OR (any requirement can satisfy)\n * - Object is AND (all schemes required together)\n *\n * Example: `[{ apiKeyAuth: [] }]`\n */\n defaultSecurity?: Record<string, string[]>[];\n };\n\n // ═══════════════════════════════════════════════════════════════════════════\n // OPENAPI (optional — documentation generation)\n // Override pattern: openApi.xxx overrides base xxx\n // ═══════════════════════════════════════════════════════════════════════════\n\n /**\n * OpenAPI-specific overrides for global spec generation.\n */\n openApi?: {\n /**\n * OpenAPI info.title.\n * Overrides `name` if set.\n */\n title?: string;\n\n /**\n * OpenAPI info.description.\n * Overrides `description` if set.\n */\n description?: string;\n\n /**\n * OpenAPI info.termsOfService URL.\n */\n termsOfService?: string;\n\n /**\n * OpenAPI info.contact.\n */\n contact?: {\n name?: string;\n url?: string;\n email?: string;\n };\n\n /**\n * OpenAPI info.license.\n */\n license?: {\n name: string;\n url?: string;\n };\n };\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// Utility Types\n// ═══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Extracts the scheme names (keys) from a SystemMetadata constant.\n *\n * @example\n * const systemMeta = { auth: { schemes: { apiKeyAuth: {...}, bearerAuth: {...} } } } as const;\n * type Names = SchemeNamesOf<typeof systemMeta>; // 'apiKeyAuth' | 'bearerAuth'\n */\nexport type SchemeNamesOf<TSystem> = TSystem extends {\n auth: { schemes: infer S };\n}\n ? keyof S & string\n : never;\n\n/**\n * Creates a typed OpenAPI security requirement array from scheme names.\n *\n * @example\n * type Req = SecurityRequirementOf<'apiKeyAuth' | 'bearerAuth'>;\n * // Array<Partial<Record<'apiKeyAuth' | 'bearerAuth', string[]>>>\n */\nexport type SecurityRequirementOf<TSchemeNames extends string> = Partial<\n Record<TSchemeNames, string[]>\n>[];\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// Helper Function\n// ═══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Input type for defineSystemMetadata helper (with generic auth).\n */\ntype SystemMetadataInput<TSchemeNames extends string> = Omit<SystemMetadata, 'auth'> & {\n auth?: {\n secureByDefault?: boolean;\n schemes: Record<TSchemeNames, AuthScheme>;\n defaultSecurity?: Partial<Record<TSchemeNames, string[]>>[];\n };\n};\n\n/**\n * Defines system metadata with fully-typed `defaultSecurity`.\n *\n * Infers scheme names from the `schemes` object and validates that\n * `defaultSecurity` only references existing scheme names.\n *\n * @example\n * export const systemMetadata = defineSystemMetadata({\n * id: 'my-api',\n * shortId: 'api',\n * name: 'My API',\n * version: '1.0.0',\n * auth: {\n * schemes: {\n * apiKeyAuth: { type: 'apiKey', in: 'header', name: 'x-api-key' },\n * },\n * defaultSecurity: [{ apiKeyAuth: [] }], // ✅ Valid\n * // defaultSecurity: [{ typoAuth: [] }], // ❌ TypeScript error!\n * },\n * });\n */\nexport function defineSystemMetadata<const TSchemeNames extends string>(\n metadata: SystemMetadataInput<TSchemeNames>,\n): SystemMetadataInput<TSchemeNames> & SystemMetadata {\n return metadata as SystemMetadataInput<TSchemeNames> & SystemMetadata;\n}\n","import type { HttpEndpointMetadata } from '../interfaces/types/metadata/http-endpoint-metadata.type';\nimport type { ResourceMetadata } from '../interfaces/types/metadata/resource-metadata.type';\nimport type { ServiceMetadata } from '../interfaces/types/metadata/service-metadata.type';\n\n/**\n * Normalizes a path segment by removing leading/trailing slashes.\n */\nfunction trimSlashes(segment: string): string {\n return segment.replace(/^\\/+|\\/+$/g, '');\n}\n\n/**\n * Computes the full route path from service, resource, and endpoint metadata.\n *\n * Handles path normalization:\n * - Ensures leading slash\n * - Joins segments with single slashes\n * - Removes trailing slash (except for root)\n *\n * @example\n * ```typescript\n * computeRoutePath(\n * { basePath: '/user-service' },\n * { path: '/users' },\n * { path: '/{id}' }\n * ); // => '/user-service/users/{id}'\n * ```\n */\nexport function computeRoutePath(\n service: Pick<ServiceMetadata, 'basePath'>,\n resource: Pick<ResourceMetadata, 'path'>,\n endpoint: Pick<HttpEndpointMetadata, 'path'>,\n): string {\n const segments = [service.basePath, resource.path, endpoint.path]\n .map(trimSlashes)\n .filter((s) => s.length > 0);\n\n if (segments.length === 0) {\n return '/';\n }\n\n return '/' + segments.join('/');\n}\n","import type { HttpResponse } from '../interfaces/types/http/http-response';\n\n/**\n * Type guard to validate that a value is a valid HttpResponse.\n *\n * Checks that the value has the required `statusCode` property as a number.\n * This is used to validate controller outputs before passing to response mappers.\n *\n * @param value - The value to check\n * @returns True if the value is a valid HttpResponse\n *\n * @example\n * ```typescript\n * const output = controller.execute(input);\n * if (!isHttpResponse(output)) {\n * throw new Error('Controller must return an HttpResponse');\n * }\n * ```\n */\nexport function isHttpResponse(value: unknown): value is HttpResponse {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'statusCode' in value &&\n typeof (value as { statusCode: unknown }).statusCode === 'number'\n );\n}\n\n/**\n * Asserts that a value is a valid HttpResponse.\n *\n * Throws a descriptive error if the value is not a valid HttpResponse,\n * making it easier to debug controller output issues.\n *\n * @param value - The value to validate\n * @param context - Optional context for the error message (e.g., 'mapOutput')\n * @throws Error if the value is not a valid HttpResponse\n *\n * @example\n * ```typescript\n * const output = controller.execute(input);\n * assertHttpResponse(output, 'controller output');\n * // Now TypeScript knows output is HttpResponse\n * ```\n */\nexport function assertHttpResponse(\n value: unknown,\n context = 'value',\n): asserts value is HttpResponse {\n if (!isHttpResponse(value)) {\n const actualType = value === null ? 'null' : value === undefined ? 'undefined' : typeof value;\n const hasStatusCode = typeof value === 'object' && value !== null && 'statusCode' in value;\n\n let message = `Expected ${context} to be an HttpResponse with a numeric statusCode, `;\n\n if (hasStatusCode) {\n const statusCodeType = typeof (value as { statusCode: unknown })['statusCode'];\n message += `but statusCode was ${statusCodeType}`;\n } else {\n message += `but got ${actualType}`;\n }\n\n throw new Error(message);\n }\n}\n"],"mappings":"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","names":["import_uuid"]}
|