{"version":3,"sources":["../src/shared/errors.ts","../src/shared/result.ts","../src/idempotency/with-idempotency.ts","../src/http/request-handler.ts","../src/http/respond.ts","../src/http/status.ts","../src/domain/aggregate.ts","../src/application/command/handler.ts","../src/application/command/types.ts","../src/application/policies.ts","../src/application/projection/manager.ts","../src/application/repos/abstract.crud.repository.ts","../src/application/repos/abstract.es.repository.ts","../src/domain/invariants.ts","../src/memory/console-event-publisher.memory.ts","../src/memory/idempotency-store.memory.ts","../src/memory/unit-of-work.memory.ts"],"names":["z","zod","deepEqual","ok","err"],"mappings":"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","file":"index.cjs","sourcesContent":["// ## File: packages/ddd-kit/src/shared/errors.ts\n\n/**\n * A constant array holding all possible kinds of EdgeErrors.\n * This is the single source of truth for the entire error system.\n */\nexport const EDGE_ERROR_KINDS = [\n  \"Unauthorized\",\n  \"BadRequest\",\n  \"NotFound\",\n  \"InvariantViolation\",\n  \"Conflict\",\n  \"Infrastructure\",\n] as const;\n\n// We infer the union type of kind strings directly from our constant array.\ntype EdgeErrorKind = (typeof EDGE_ERROR_KINDS)[number];\n\nexport class DomainInvariantError extends Error {\n  /** Stable error code that clients/tests can rely on. */\n  public readonly code = \"DOMAIN_INVARIANT_VIOLATION\";\n\n  constructor(message: string, public readonly details?: unknown) {\n    super(message);\n    this.name = \"DomainInvariantError\";\n  }\n}\n\n/**\n * This is a \"map\" that defines the unique properties for each kind of error.\n * For example, a 'NotFound' error has optional 'entity' and 'id' fields,\n * while 'Unauthorized' has only an optional 'message'.\n */\ntype EdgeErrorPayloads = {\n  Unauthorized: { message?: string };\n  BadRequest: { message: string; details?: unknown };\n  NotFound: { entity?: string; id?: string };\n  InvariantViolation: { message: string; details?: unknown };\n  Conflict: { message: string };\n  Infrastructure: { message: string };\n};\n\n/**\n * EdgeError\n * This is the final, programmatically generated discriminated union.\n * Here's how it works:\n * 1. `[K in EdgeErrorKind]`: We iterate over each string in our `EdgeErrorKind` union (e.g., \"Unauthorized\", \"BadRequest\").\n * 2. `{ kind: K } & EdgeErrorPayloads[K]`: For each kind `K`, we create an object type. It has a `kind` property with the literal type `K`, and we merge (`&`) the corresponding payload from our `EdgeErrorPayloads` map.\n * 3. `[EdgeErrorKind]`: This final step takes all the generated object types and turns them into a single union type.\n *\n * The result is identical to writing it out by hand, but now it's generated automatically from our single source of truth.\n */\nexport type EdgeError = {\n  [K in EdgeErrorKind]: { kind: K } & EdgeErrorPayloads[K];\n}[EdgeErrorKind];\n","// ## File: packages/ddd-kit/src/shared/result.ts\n\n/**\n * Result type helpers\n * -------------------\n * A tiny alternative to exceptions: every function can return either:\n * - ok(value): success path\n * - err(error): failure path\n *\n * Why?\n * - Callers can handle both outcomes explicitly.\n * - Easier to test and to map into HTTP responses later.\n */\n\nimport z from \"zod\";\n// Import the single source of truth for error kinds.\nimport { EDGE_ERROR_KINDS } from \"./errors\";\n\nexport type Ok<T> = { ok: true; value: T };\nexport type Err<E> = { ok: false; error: E };\nexport type Result<T, E = any> = Ok<T> | Err<E>;\n\n/** Wrap a value into a success Result. */\nexport const ok = <T>(value: T): Ok<T> => ({ ok: true, value });\n\n/** Wrap an error payload into a failure Result. */\nexport const err = <E>(error: E): Err<E> => ({ ok: false, error });\n\n// --- Standardized OpenAPI Schemas ---\n\n/**\n * A standard Zod schema for successful API responses, typically used with HTTP 2xx statuses.\n * It provides a consistent shape that clients can rely on.\n */\nexport const SuccessResponseSchema = z.object({\n  id: z.string().describe(\"The unique identifier of the resource.\"),\n  ok: z.boolean().optional().describe(\"Indicates success.\"),\n});\n\n/**\n * A standard Zod schema for client-side API errors, mapping directly to the `EdgeError` type.\n * This is used for generating consistent OpenAPI documentation for HTTP 4xx/5xx responses.\n */\nexport const ErrorResponseSchema = z.object({\n  // By using the imported EDGE_ERROR_KINDS constant, this enum will now\n  // update automatically whenever you change the source array in errors.ts.\n  kind: z.enum(EDGE_ERROR_KINDS).describe(\"The category of the error.\"),\n  message: z.string().describe(\"A human-readable error message.\"),\n  details: z.any().optional().describe(\"Optional structured error details.\"),\n});\n\n// --- EXPORTED TYPES ---\n\n/**\n * A TypeScript type representing a standardized successful API response payload.\n * Inferred directly from the Zod schema for 100% consistency.\n */\nexport type SuccessResponse = z.infer<typeof SuccessResponseSchema>;\n\n/**\n * A TypeScript type representing a standardized error API response payload.\n * Inferred directly from the Zod schema.\n */\nexport type ErrorResponse = z.infer<typeof ErrorResponseSchema>;\n\n/**\n * Creates specialized `ok` and `err` helper functions with pre-defined types.\n * This is a factory that you call once per command to get helpers that\n * understand the specific success (TValue) and error (TError) shapes for that command.\n * This allows for strong type-checking of return values without explicit annotation.\n *\n * @returns An object with typed `ok` and `err` functions.\n */\nexport const createCommandResultHelpers = <TValue, TError>() => {\n  return {\n    ok: (value: TValue): Ok<TValue> => ({ ok: true, value }),\n    err: (error: TError): Err<TError> => ({ ok: false, error }),\n  };\n};\n","import type { Tx } from \"../infra/unit-of-work\";\nimport { ok, type Result } from \"../shared/result\";\nimport type { IdempotencyConfigOptions, IdempotencyInfra } from \"./types\";\n\n/**\n * withIdempotency\n * ---------------\n * Wrap a command execution so retries return the same result instead of\n * performing the action again.\n *\n * Flow:\n * 1) If options.key is null → skip idempotency; just run inside a transaction.\n * 2) Else:\n *    a) tryClaim:\n *        - if {response} → return it (short-circuit, no side-effects)\n *        - if \"claimed\"  → proceed to run the command\n *    b) run(tx) → your real command logic (returns Result<T>)\n *    c) if ok → saveResponse with a canonical object; return result\n *       if err → return error (we don't cache failures)\n */\nexport async function withIdempotency<T>(\n  config: { options: IdempotencyConfigOptions<T> },\n  infra: IdempotencyInfra,\n  run: (tx: Tx) => Promise<Result<T>>\n): Promise<Result<T>> {\n  const { options } = config;\n  const { uow, store, hash } = infra;\n\n  // Fast path: no idempotency\n  if (options.key === null) {\n    return uow.withTransaction(run);\n  }\n\n  // Compute hashes (small stable strings) to scope and identify \"same\" payloads.\n  const now = options.clock?.now() ?? new Date();\n  const scopeHash = hash(JSON.stringify(options.scope));\n  const payloadHash = hash(JSON.stringify(options.payload));\n\n  return uow.withTransaction(async (tx) => {\n    // Step a) Claim or short-circuit if result exists\n    const claimed = await store.tryClaim({\n      key: options.key!,\n      command: options.command,\n      scopeHash,\n      payloadHash,\n      now,\n      tx,\n    });\n\n    if (claimed !== \"claimed\") {\n      // Cached response → build the value and return\n      const revive = options.reviveOnHit ?? ((r: unknown) => r as T);\n      return ok(revive(claimed.response));\n    }\n\n    // Step b) Execute the real work\n    const res = await run(tx);\n    if (!res.ok) return res; // On failure, do not cache\n\n    // Step c) Canonicalize and persist the response for future retries\n    const toResp = options.toResponse ?? ((v: T) => v);\n    await store.saveResponse({\n      key: options.key!,\n      command: options.command,\n      scopeHash,\n      response: toResp(res.value),\n      tx,\n    });\n\n    return res;\n  });\n}\n","// ddd-kit/src/http/request-handler.ts\n\nimport type * as Z from \"zod\";\nimport { type ZodType } from \"zod\";\nimport type { EdgeError } from \"../shared/errors\";\nimport { err, ok, type Result } from \"../shared/result\";\n\n/**\n * AuthFn\n * ------\n * Reads authentication/identity info from the HTTP framework context.\n * Return:\n * - ok(payload) on success (e.g., { userId })\n * - err({ kind: \"Unauthorized\" }) if not authenticated\n */\nexport type AuthFn<C, A> = (\n  c: C\n) => Result<A, EdgeError> | Promise<Result<A, EdgeError>>;\n\n/**\n * BodyReader\n * ------\n * an overridable function to read the request body\n */\nexport type BodyReader<C> = (c: C) => Promise<unknown>;\n\n/**\n * makeRequestHandler\n * ------------------\n * A small reusable wrapper for HTTP request handling.\n *\n * It does three things in order:\n *  1) Auth check\n *  2) JSON body parse + Zod validate\n *  3) Map ({ c, auth, body }) -> your DTO/result\n *\n * Generics:\n *   C = framework context type (e.g., Hono Context<{ Variables: Vars }>)\n *   A = Auth payload type (e.g., { userId: string })\n *   S = Zod schema type\n *   O = Output payload type\n *\n * Why this pattern?\n * - Keeps all edge concerns in one place and consistent across routes.\n * - Makes your route handlers tiny and easy to read.\n *\n */\nexport function makeRequestHandler<\n  C = any,\n  A = unknown,\n  S extends ZodType = ZodType,\n  O = unknown\n>(opts: {\n  auth: AuthFn<C, A>;\n  bodySchema: S; // any Zod schema\n  map: (ctx: {\n    c: C;\n    auth: A;\n    body: Z.infer<S>; // <- body type derives from schema\n  }) => Result<O, EdgeError> | Promise<Result<O, EdgeError>>;\n  readBody?: BodyReader<C>;\n}) {\n  const readBody: BodyReader<C> =\n    opts.readBody ?? (async (c) => (c as any).req.json()); // default keeps Hono happy\n\n  return async function requestHandler(c: C): Promise<Result<O, EdgeError>> {\n    // 1) IAM / auth\n    const auth = await opts.auth(c);\n    if (!auth.ok) return auth;\n\n    // 2) JSON body parsing\n    let raw: unknown;\n    try {\n      raw = await readBody(c); // using the pluggable reader\n    } catch (e) {\n      return err({\n        kind: \"BadRequest\",\n        message: \"Invalid JSON body\",\n        details: String(e),\n      });\n    }\n\n    // 3) Zod validation\n    const parsed = opts.bodySchema.safeParse(raw);\n    if (!parsed.success) {\n      return err({\n        kind: \"BadRequest\",\n        message: \"Invalid body\",\n        details: parsed.error.flatten(),\n      });\n    }\n\n    // 4) Mapping to your executor DTO; may also fail (e.g., more checks)\n    return opts.map({ c, auth: auth.value, body: parsed.data });\n  };\n}\n\n/**\n * authFromContext(\"userId\")\n * -------------------------\n * Convenience for reading a simple identity from the request context.\n * If the context doesn't have that key → Unauthorized.\n */\n/** authFromContext(\"userId\"): read a simple identity from c.get(key) */\ntype HasGet = { get: (key: string) => unknown };\n\nexport const authFromContext =\n  <C extends HasGet, K extends string = \"userId\">(key: K = \"userId\" as K) =>\n  (c: C): Result<{ [P in K]: string }, EdgeError> => {\n    const uid = c.get(key) as string | undefined;\n    return uid ? ok({ [key]: uid } as any) : err({ kind: \"Unauthorized\" });\n  };\n","import type { EdgeError } from \"../shared/errors\";\nimport type { Result } from \"../shared/result\";\n\n/**\n * statusOf\n * --------\n * Maps an EdgeError shape into an HTTP status code.\n * Adjust this mapping per service if needed.\n */\nexport function statusOf(e: EdgeError): number {\n  switch (e.kind) {\n    case \"Unauthorized\":\n      return 401;\n    case \"BadRequest\":\n      return 400;\n    case \"NotFound\":\n      return 404;\n    case \"InvariantViolation\":\n      return 422; // semantic rule failed\n    case \"Conflict\":\n      return 409;\n    case \"Infrastructure\":\n      return 503;\n    default:\n      return 400;\n  }\n}\n\n/**\n * respond\n * -------\n * Turn a Result<T, EdgeError> into an HTTP response using your framework's \"c\".\n * - Success → json(value, successStatus)\n * - Error   → json({ error }, statusOf(error))\n *\n * This keeps route handlers tiny and consistent.\n */\nexport function respond<T>(\n  c: any,\n  r: Result<T, EdgeError>,\n  successStatus = 200\n) {\n  return r.ok\n    ? c.json(r.value, successStatus)\n    : c.json({ error: r.error }, statusOf(r.error));\n}\n","// ## File: packages/ddd-kit/src/http/status.ts\n\n// This module centralizes and re-exports HTTP utilities from the `stoker` library,\n// providing a single, consistent source for status codes, phrases, and other\n// helpers across all applications that consume this SDK.\n\nimport type { z } from \"@hono/zod-openapi\";\nimport * as HttpStatus from \"stoker/http-status-codes\";\nimport * as HttpPhrases from \"stoker/http-status-phrases\";\nimport { z as zod } from \"zod\";\n\n/**\n * openapiJsonContent: A helper function to create the `content` part of an OpenAPI request/response\n * body, ensuring the example payload is type-safe against the schema.\n *\n * @param description - Description for the OpenAPI content (required)\n * @param schema - Zod schema that defines the structure (required)\n * @param example - Optional example that matches the schema\n */\n\n// The base schema type remains the same.\nexport type ZodSchema = z.ZodType;\nexport type ZodIssue = z.core.$ZodIssue;\n\n// Let's define the return type once to keep things DRY.\ntype OpenApiContentResult<T extends ZodSchema> = {\n  content: {\n    \"application/json\": {\n      schema: T;\n      example?: z.input<T>;\n    };\n  };\n  description: string;\n};\n\n// --- Function Overloads ---\n\n// SIGNATURE 1: Called with (description, schema, example)\n// This is for when you want to provide a specific payload.\nfunction openapiJsonContent<T extends ZodSchema>(\n  description: string,\n  schema: T,\n  example: z.input<T>\n): OpenApiContentResult<T>;\n\n// SIGNATURE 2: Called with (description, schema)\n// This is the simpler version for when an example isn't needed.\nfunction openapiJsonContent<T extends ZodSchema>(\n  description: string,\n  schema: T\n): OpenApiContentResult<T>;\n\n// --- The Single Implementation ---\n\n// This is the actual function body with the new parameter order.\nfunction openapiJsonContent<T extends ZodSchema>(\n  description: string,\n  schema: T,\n  example?: z.input<T>\n): OpenApiContentResult<T> {\n  return {\n    content: {\n      \"application/json\": example ? { schema, example } : { schema },\n    },\n    description,\n  };\n}\n\n/**\n * Creates a reusable Zod schema object for the `Idempotency-Key` header.\n * This is designed to be spread into a `z.object({})` schema.\n * @param purpose - A short, specific description of what the key prevents (e.g., \"Prevents creating duplicate assets.\")\n * @returns An object with the \"idempotency-key\" schema.\n */\nconst idempotencyKeyHeader = (purpose: string) => {\n  const baseDescription =\n    \"A unique key to safely retry this request without performing the operation twice.\";\n\n  return {\n    \"Idempotency-Key\": zod\n      .string()\n      .optional()\n      .describe(`${baseDescription} ${purpose}`),\n  };\n};\n\nexport { HttpPhrases, HttpStatus, idempotencyKeyHeader, openapiJsonContent };\n","// ## File: packages/ddd-kit/src/domain/aggregate.ts\n\nimport { deepEqual } from \"node:assert\";\nimport type { DomainEvent } from \"../application/command\";\n\n/**\n * Re-exports DomainInvariantError and other shared errors from the shared folder.\n * This is a quality-of-life improvement that allows consuming applications to import\n * core domain concepts from a single, consistent location.\n *\n * Example:\n * import { AggregateRoot, DomainInvariantError } from \"ddd-kit/domain\";\n */\nexport * from \"../shared/errors\";\n\n// --- Core DDD Primitives ---\n\n/**\n * A branded type for creating distinct, non-interchangeable Aggregate IDs.\n * By \"branding\" the string with a generic type `T`, TypeScript can differentiate\n * between `AggregateId<\"Order\">` and `AggregateId<\"RealEstate\">`, preventing you\n * from accidentally using one where the other is expected. This is a powerful\n * compile-time safety feature.\n */\nexport type AggregateId<T extends string> = string & { readonly __brand: T };\n\n/**\n * A factory function to create a properly typed `AggregateId` from a raw string.\n * It encapsulates the type assertion, providing a safe and clear way to construct IDs.\n * It also includes an optional prefixing logic, which is a common practice for making\n * IDs more readable and globally unique (e.g., \"ord_12345\").\n *\n * @param id The raw unique identifier (e.g., a ULID or UUID).\n * @param prefix A short string to prepend to the ID (e.g., \"re\" for Real Estate).\n * @returns A strongly-typed, branded AggregateId.\n */\nexport function createAggregateId<T extends string>(\n  id: string,\n  prefix?: string\n): AggregateId<T> {\n  // If a prefix is provided and the ID doesn't already have it, we add it.\n  const finalId =\n    prefix && !id.startsWith(`${prefix}_`) ? `${prefix}_${id}` : id;\n\n  // The type assertion is safely contained within this function.\n  return finalId as AggregateId<T>;\n}\n\n/**\n * An interface marking an object as having a version number.\n * This is crucial for implementing optimistic concurrency control, a pattern that\n * prevents two users from overwriting each other's changes.\n * - In a CRUD system, this typically maps to a `version` column in a database table.\n * - In an Event Sourcing system, this corresponds to the event number or stream revision.\n */\nexport interface HasVersion {\n  version: number;\n}\n\n/**\n * The base class for an Entity.\n * An Entity is an object defined not by its attributes, but by its unique identity.\n * It has an `id` that remains constant throughout its lifecycle. For example, a \"Person\"\n * is an Entity; they can change their name or address, but they are still the same person.\n */\nexport abstract class Entity<Id extends string = AggregateId<any>> {\n  constructor(public readonly id: Id) {}\n}\n\n/**\n * The base class for a Value Object.\n * A Value Object is an immutable object defined by its attributes, not a unique identity.\n * Two Value Objects are considered equal if all their properties are the same.\n * For example, an \"Address\" or \"Money\" are Value Objects. A €50 note is interchangeable\n * with any other €50 note.\n */\nexport abstract class ValueObject<T extends object> {\n  // The constructor is protected to enforce creation through static factory methods (e.g., `Address.from(...)`).\n  protected constructor(public readonly props: Readonly<T>) {}\n\n  /**\n   * Compares this Value Object to another for equality.\n   * It performs a deep equality check on the `props` object, ensuring that nested\n   * properties are also compared.\n   *\n   * @param other The other Value Object to compare against.\n   * @returns `true` if the Value Objects are equal, `false` otherwise.\n   */\n  equals(other: ValueObject<T>): boolean {\n    try {\n      // We use Node.js's robust deepEqual for a reliable structural comparison.\n      deepEqual(this.props, other.props);\n      return true;\n    } catch {\n      return false;\n    }\n  }\n}\n\n// --- Module Augmentation and Event Typing ---\n\n/**\n * This is the \"socket\" for module augmentation. It's an empty interface by design.\n * Consuming applications (like `finance-api`) will augment this interface to \"plug in\"\n * their own specific event types. This allows `ddd-kit` to be strongly typed with\n * application-specific events without ever knowing they exist.\n */\nexport interface AggregateEvents {\n  // Initially empty. Augmented by the consumer application.\n  // Example augmentation in `finance-api`:\n  // 'RealEstateAssetCreated_V1': RealEstateAssetCreated;\n}\n\n/**\n * A helper type that creates a discriminated union of all event classes defined\n * in the augmented `AggregateEvents` interface.\n * If `AggregateEvents` has not been augmented, it safely defaults to `DomainEvent<unknown>`.\n */\nexport type EventUnion<T extends keyof AggregateEvents> = T extends any\n  ? AggregateEvents[T]\n  : DomainEvent<unknown>;\n\n// --- Aggregate Root ---\n\n/**\n * The base class for an Aggregate Root.\n * The Aggregate Root is the main entry point for all modifications within an aggregate.\n * It acts as a transactional boundary and a guardian for all business rules (invariants)\n * for the objects it contains (Entities and Value Objects).\n */\nexport abstract class AggregateRoot<\n    Id extends string = AggregateId<any>,\n    // The AggregateRoot is now generic over the events it can handle.\n    // This allows a specific aggregate, like `RealEstateAggregate`, to declare\n    // exactly which events it's concerned with, providing strong type safety.\n    TAllEvents extends keyof AggregateEvents = keyof AggregateEvents\n  >\n  extends Entity<Id>\n  implements HasVersion\n{\n  /**\n   * The current version of the aggregate, used for optimistic concurrency control.\n   * A new, in-memory aggregate starts at version 0.\n   */\n  public version = 0;\n\n  /**\n   * An in-memory buffer that stores domain events that have been raised but not yet\n   * persisted. This buffer is now strongly typed using the `EventUnion` helper.\n   */\n  protected readonly _events: Array<EventUnion<TAllEvents>> = [];\n\n  /**\n   * Raises a new domain event, which is the sole mechanism for enacting a state change.\n   * This method orchestrates the \"Raise/Apply\" pattern.\n   *\n   * @param event The strongly-typed domain event to be raised.\n   */\n  protected raise(event: EventUnion<TAllEvents>) {\n    // 1. First, we apply the event to ourself to mutate the current in-memory state.\n    this.apply(event);\n\n    // 2. Then, we buffer the event so the application layer (e.g., a repository) can persist it.\n    this._events.push(event);\n  }\n\n  /**\n   * This is the private event dispatcher. It now ensures that a handler method\n   * exists for every event that is raised. If a handler is missing, it throws a\n   * descriptive error to prevent state inconsistencies.\n   *\n   * @param event The strongly-typed domain event to be dispatched.\n   * @throws {Error} If a corresponding `apply<EventType>` method is not found on the concrete aggregate.\n   */\n  protected apply(event: EventUnion<TAllEvents>): void {\n    const handlerMethodName = `apply${event.type}`;\n    const handler = this[handlerMethodName as keyof this];\n\n    if (typeof handler === \"function\") {\n      // The handler was found, so we call it to apply the state change.\n      handler.call(this, event);\n    } else {\n      // CRITICAL: The handler was not found. This is a developer error.\n      // We throw a loud, descriptive error to fail fast and make the\n      // problem immediately obvious.\n      throw new Error(\n        `Missing apply method: The aggregate '${this.constructor.name}' is missing a handler for the event '${event.type}'. ` +\n          `Please implement the following method: protected ${handlerMethodName}(event: ${event.constructor.name})`\n      );\n    }\n  }\n\n  /**\n   * Drains and returns the pending domain events from the internal buffer.\n   * The repository calls this method after a successful business operation to get\n   * the list of events that need to be saved to the database or published to a message bus.\n   *\n   * @returns An array of the pending domain events.\n   */\n  public pullEvents() {\n    // We create a copy of the events array to return.\n    const out = [...this._events];\n    // We then clear the internal buffer to prevent the same events from being processed twice.\n    this.clearEvents();\n    return out;\n  }\n\n  /**\n   * A private helper method to clear the in-memory event buffer.\n   */\n  private clearEvents() {\n    this._events.length = 0;\n  }\n}\n","// ## File: packages/ddd-kit/src/application/command/handler.ts\n\n/**\n * ========================\n * Abstract Command Handler\n * ========================\n * This class provides a reusable, transactional pipeline for executing commands\n * against an aggregate. It automates the \"load -> execute -> save -> publish\" flow, ensuring\n * that every business operation is handled consistently and atomically.\n *\n * It is designed to be persistence-agnostic by depending on a generic `AggregateRepository`\n * interface. This allows you to inject either a CRUD-based repository or an Event Sourcing-based\n * repository without changing any of the command handling logic.\n */\n\nimport { AggregateRoot, DomainInvariantError } from \"../../domain/aggregate\";\n// The `Tx` type is an opaque handle representing an active database transaction.\nimport type { Tx, UnitOfWork } from \"../../infra\";\nimport { err, ok, type Result } from \"../../shared/result\";\n// The generic repository interface defines a universal contract for finding and saving an aggregate.\nimport type { AggregateRepository } from \"../repos/aggregate.repository\";\nimport type { ICommand } from \"./command\";\n// The EventPublisher interface defines a contract for publishing domain events.\nimport { DomainEvent, type EventPublisher } from \"./types\";\n\n/**\n * Defines the structure of the payload passed to the command handler's `execute` method.\n * It must contain the command payload and, for operations on existing aggregates,\n * the ID of the aggregate to operate on.\n */\nexport type CommandHandlerPayload<T> = {\n  aggregateId?: string;\n  payload: T;\n};\n\n// The CommandHandler is generic over the type of AggregateRoot it manages and the\n// specific type of repository it uses, as long as it fulfills the AggregateRepository contract.\nexport abstract class CommandHandler<\n  TAggregate extends AggregateRoot,\n  TRepo extends AggregateRepository<TAggregate>\n> {\n  // The concrete handler (e.g., `RealEstateCommandHandler`) will provide a map\n  // of command names to their corresponding `ICommand` implementations.\n  protected abstract commands: Record<string, ICommand<any, any, TAggregate>>;\n\n  constructor(\n    // The repository is the gateway to the persistence layer for this aggregate.\n    protected readonly repo: TRepo,\n    // The Unit of Work ensures that all operations within the handler\n    // happen within a single atomic transaction.\n    protected readonly uow: UnitOfWork,\n    // The event publisher is an optional dependency for broadcasting domain events\n    // to other parts of the system after a successful command.\n    protected readonly eventPublisher?: EventPublisher\n  ) {}\n\n  /**\n   * The main public method to execute a command. It orchestrates the entire\n   * operation. If an optional transaction `tx` is provided, it will run within that\n   * transaction. If not, it will create its own, ensuring a consistent execution\n   * boundary for all business logic.\n   *\n   * @param commandName - The name of the command to execute (e.g., \"create-real-estate-asset\").\n   * @param data - The data for the command, including the payload and optional aggregateId.\n   * @param tx - An optional, existing transaction handle. This allows the handler\n   * to participate in a larger, single atomic operation managed by an external caller,\n   * such as an idempotency wrapper.\n   * @returns The result of the command execution, which is the response DTO from the command itself.\n   */\n  public async execute<TPayload, TResponse>(\n    commandName: string,\n    data: CommandHandlerPayload<TPayload>,\n    tx?: Tx\n  ): Promise<Result<TResponse>> {\n    // Find the specific command implementation from our command map.\n    // This allows a single handler to manage multiple operations for an aggregate.\n    const command = this.commands[commandName];\n    if (!command) {\n      // Return a structured error if the command doesn't exist.\n      return err({\n        kind: \"BadRequest\",\n        message: `Command \"${commandName}\" not found on this handler.`,\n      });\n    }\n\n    /**\n     * This inner function encapsulates the core \"load -> execute -> save -> publish\" pipeline.\n     * It's designed to be called within a transaction, which is passed as the `transaction` parameter.\n     * @param transaction - The active transaction for all database operations.\n     */\n    const run = async (transaction: Tx): Promise<Result<TResponse>> => {\n      // We wrap the core logic in a try/catch block to handle domain errors gracefully.\n      try {\n        // STEP 1: LOAD\n        // Fetch the current state of the aggregate if we're updating it.\n        // For creation commands, `data.aggregateId` will be undefined, so the\n        // aggregate correctly starts as `undefined`.\n        let aggregate: TAggregate | undefined = undefined;\n        if (data.aggregateId) {\n          const loadedAggregate = await this.repo.findById(\n            transaction,\n            data.aggregateId\n          );\n          if (!loadedAggregate) {\n            // It's crucial to ensure the aggregate exists before trying to modify it.\n            return err({\n              kind: \"NotFound\",\n              message: `Aggregate with id ${data.aggregateId} not found.`,\n            });\n          }\n          aggregate = loadedAggregate;\n        }\n\n        // STEP 2: EXECUTE\n        // Delegate the core business logic to the specific command object.\n        // The command will run its logic and buffer any new events inside the aggregate.\n        const result = await command.execute(data.payload, aggregate);\n        if (!result.ok) {\n          // If the command's invariants or business rules fail, stop and forward the error.\n          return err(result.error);\n        }\n\n        // STEP 3: DESTRUCTURE\n        // Get the modified aggregate and the response DTO from the command's result.\n        // The aggregate now contains the buffered events, ready for persistence.\n        const { aggregate: nextAggregate, response } = result.value;\n\n        // STEP 4: SAVE & CAPTURE EVENTS\n        // Persist the aggregate's changes. The `save` method is now responsible for\n        // pulling the events, saving them, and returning them. This gives us a\n        // definitive list of what was actually persisted.\n        const savedEvents = await this.repo.save(transaction, nextAggregate);\n\n        // STEP 5: PUBLISH\n        // After successfully saving, publish the events that were returned by the repo.\n        // This ensures we only broadcast events that have been durably stored.\n        if (this.eventPublisher && savedEvents.length > 0) {\n          await this.eventPublisher.publish(\n            savedEvents as DomainEvent<unknown>[],\n            transaction\n          );\n        }\n\n        // STEP 6: RETURN\n        // Finally, return the successful response DTO to the caller.\n        return ok(response);\n      } catch (e) {\n        // STEP 7: CATCH & TRANSFORM\n        // If a DomainInvariantError was thrown during execution, we catch it here.\n        if (e instanceof DomainInvariantError) {\n          // We transform it into a structured 'InvariantViolation' error that\n          // our API's `respond` helper can understand and map to a 422 status code.\n          return err({\n            kind: \"InvariantViolation\",\n            message: e.message,\n            details: e.details,\n          });\n        }\n        // For any other unexpected error, re-throw it to be handled\n        // as a 500 Internal Server Error.\n        throw e;\n      }\n    };\n\n    // If an external transaction `tx` was provided, we run our logic within it.\n    if (tx) {\n      return run(tx);\n    }\n    // Otherwise, we wrap our logic in a new transaction managed by the Unit of Work.\n    else {\n      return this.uow.withTransaction(run);\n    }\n  }\n}\n","/**\n * Common types for command execution across storage styles.\n *\n * This layer is deliberately small, so apps only provide the minimum needed:\n * - How to load the aggregate (or its events)\n * - How to check domain policies (invariants)\n * - How to apply the command to produce either:\n * CRUD: new aggregate state (plus optional events)\n * ES:   new events (plus optional projected value)\n * - How to persist (save state or append events)\n * - How to publish events (optional)\n */\n\nimport type { Tx } from \"../../infra/unit-of-work\";\nimport type { Result } from \"../../shared/result\";\n\n/** A small identity map if you need it; most apps won’t. */\nexport type Context = Record<string, unknown>;\n\n/** Represents the input that reaches the command executor (your DTO). */\nexport type CommandInput = Record<string, unknown>;\n\n/** Policy check result – you can return ok/err, or just throw DomainInvariantError in policies. */\nexport type PolicyResult = Result<true, unknown>;\n\n/** The required, non-negotiable properties of our event metadata. */\ntype EventMeta = {\n  version: number;\n  timestamp: Date;\n  [key: string]: unknown;\n};\n\n/**\n * A plain object representation of a domain event, useful for serialization.\n */\nexport type DomainEventObject<T = unknown> = {\n  type: string;\n  data: T;\n  meta: EventMeta;\n};\n\n/**\n * An abstract base class for creating rich, class-based domain events.\n * It automatically handles metadata and provides a clear structure.\n * @template T - The type of the event's data payload.\n */\nexport abstract class DomainEvent<T> {\n  // Each concrete event MUST define its type.\n  public abstract readonly type: string;\n  // The metadata is handled by the base class.\n  public readonly meta: EventMeta;\n\n  constructor(\n    // The data payload for the event.\n    public readonly data: T,\n    meta?: { version?: number; timestamp?: Date }\n  ) {\n    this.meta = {\n      version: meta?.version ?? 1,\n      timestamp: meta?.timestamp ?? new Date(),\n    };\n  }\n}\n\n/** Optional publisher port */\nexport interface EventPublisher {\n  publish(events: DomainEvent<unknown>[], tx: Tx): Promise<void>;\n}\n","import { err, ok, type Result } from \"../shared/result\";\n\n/**\n * A Policy is a small function that checks a single rule.\n * - If the rule is satisfied → return ok(true)\n * - If the rule is violated → return err(someErrorPayload) OR throw a DomainInvariantError\n *\n * Keep policies tiny and focused. Chain several to cover all invariants.\n */\nexport type Policy<TEnv, TCmd> = (args: {\n  env: TEnv; // your injected deps (repos, read models, caches)\n  cmd: TCmd; // the command DTO\n}) => Promise<Result<true>> | Result<true>;\n\n/**\n * Combine multiple policies into one.\n * - Evaluates in order\n * - Returns first error encountered\n * - Short-circuits on error\n */\nexport function allPolicies<TEnv, TCmd>(\n  policies: Policy<TEnv, TCmd>[]\n): Policy<TEnv, TCmd> {\n  return async ({ env, cmd }) => {\n    for (const p of policies) {\n      const r = await p({ env, cmd });\n      if (!r.ok) return r;\n    }\n    return ok(true);\n  };\n}\n\n/**\n * A tiny helper to adapt a boolean predicate into a Policy.\n * Example:\n *    predicatePolicy(\"Must have items\", () => items.length > 0)\n */\nexport function predicatePolicy<TEnv, TCmd>(\n  message: string,\n  predicate: (args: { env: TEnv; cmd: TCmd }) => boolean | Promise<boolean>\n): Policy<TEnv, TCmd> {\n  return async (args) =>\n    (await predicate(args)) ? ok(true) : err({ message });\n}\n","// File: packages/ddd-kit/src/application/projection/manager.ts\n\nimport type { Tx } from \"../../infra\";\nimport type { EventPublisher } from \"../command\";\nimport type { AllEventUnion, IProjector, KnownEventTypes } from \"./projector\";\n\nexport class ProjectionManager implements EventPublisher {\n  // The map is now correctly typed to work in both contexts.\n  private subscriptionMap = new Map<KnownEventTypes, IProjector[]>();\n\n  public register(projector: IProjector): void {\n    for (const eventType of projector.subscribesTo) {\n      if (!this.subscriptionMap.has(eventType)) {\n        this.subscriptionMap.set(eventType, []);\n      }\n      this.subscriptionMap.get(eventType)!.push(projector);\n    }\n  }\n\n  /**\n   * The `publish` method now uses the conditional `AllEventUnion` type.\n   * This resolves the 'never' error inside the library while providing\n   * strong types in the application.\n   */\n  public async publish(events: AllEventUnion[], tx: Tx): Promise<void> {\n    if (events.length === 0) return;\n\n    console.log(\n      \"📣 [ProjectionManager] Projecting Domain Events...\",\n      events.map((e) => e.type)\n    );\n    const tasks = new Map<IProjector, AllEventUnion[]>();\n\n    for (const event of events) {\n      // The type of `event.type` is now correctly inferred in both contexts.\n      const subscribers = this.subscriptionMap.get(\n        event.type as KnownEventTypes\n      );\n      if (subscribers) {\n        for (const sub of subscribers) {\n          if (!tasks.has(sub)) tasks.set(sub, []);\n          tasks.get(sub)!.push(event);\n        }\n      }\n    }\n\n    await Promise.all(\n      Array.from(tasks.entries()).map(([projector, relevantEvents]) =>\n        projector.project(relevantEvents, tx)\n      )\n    );\n  }\n}\n","// packages/sdk-lite/src/application/repos/abstract.crud.repository.ts\n\nimport type { AggregateRoot } from \"../../domain\";\nimport type { Tx } from \"../../infra\";\nimport { DomainEvent } from \"../command\";\nimport type { AggregateRepository } from \"./aggregate.repository\";\n\n/**\n * An abstract base class for CRUD-style repositories that implements the\n * common logic for saving an aggregate.\n *\n * This class uses the Template Method Pattern. It provides the concrete `save`\n * method, which orchestrates the persistence logic by calling abstract methods\n * (`insert` and `update`) that must be implemented by the subclasses.\n *\n * @template AR - The type of Aggregate Root this repository manages.\n */\nexport abstract class AbstractCrudRepository<AR extends AggregateRoot>\n  implements AggregateRepository<AR>\n{\n  /**\n   * The main entry point for persisting an aggregate.\n   * It checks the aggregate's version to determine if it's a new entity\n   * (version 0) or an existing one, then delegates to the appropriate\n   * protected method (`insert` or `update`).\n   *\n   * Subclasses do not need to implement this method.\n   *\n   * @param tx - The transaction context.\n   * @param agg - The aggregate instance to save.\n   */\n  public async save(tx: Tx, agg: AR): Promise<DomainEvent<unknown>[]> {\n    if (agg.version === 0) {\n      await this.insert(tx, agg);\n    } else {\n      await this.update(tx, agg);\n    }\n    // Pull and return the events after the insert/update operation.\n    return agg.pullEvents();\n  }\n\n  /**\n   * Finds an aggregate by its unique identifier.\n   * Must be implemented by the concrete repository to handle the\n   * specific database query and data-to-domain mapping (rehydration).\n   *\n   * @abstract\n   * @param tx - The transaction context.\n   * @param id - The ID of the aggregate to find.\n   * @returns A promise resolving to the aggregate or null if not found.\n   */\n  abstract findById(tx: Tx, id: string): Promise<AR | null>;\n\n  /**\n   * Inserts a new aggregate into the database.\n   * Must be implemented by the concrete repository to handle the\n   * `INSERT` logic and mapping from the domain to the database schema.\n   * After a successful insert, the aggregate's version should be set to 1.\n   *\n   * @abstract\n   * @protected\n   * @param tx - The transaction context.\n   * @param agg - The new aggregate to insert.\n   */\n  protected abstract insert(tx: Tx, agg: AR): Promise<void>;\n\n  /**\n   * Updates an existing aggregate in the database.\n   * Must be implemented by the concrete repository to handle the\n   * `UPDATE` logic, including optimistic concurrency checks using the\n   * aggregate's version. After a successful update, the version should\n   * be incremented.\n   *\n   * @abstract\n   * @protected\n   * @param tx - The transaction context.\n   * @param agg - The existing aggregate to update.\n   */\n  protected abstract update(tx: Tx, agg: AR): Promise<void>;\n}\n","// packages/ddd-kit/src/application/repos/abstract.es.repository.ts\n\nimport { AggregateRoot } from \"../../domain\";\nimport type { Tx } from \"../../infra\";\nimport { DomainEvent } from \"../command\";\nimport type { AggregateRepository } from \"./aggregate.repository\";\n\n/**\n * Represents the result of loading events for an aggregate.\n */\nexport type EventStream = {\n  events: DomainEvent<unknown>[];\n  // The version is the count of events, used for optimistic concurrency.\n  version: number;\n};\n\n// A new, type-safe contract for our aggregate class.\n// It describes an object (the class constructor itself) that has a static method\n// named `fromHistory`. This is exactly what our repository needs for rehydration.\nexport type RehydratableAggregate<AR extends AggregateRoot> = {\n  fromHistory(id: string, events: DomainEvent<unknown>[]): AR;\n};\n\n/**\n * An abstract base class for Event Sourcing repositories.\n *\n * It fulfills the same `AggregateRepository` contract from the application's\n * point of view, but its internal mechanics are completely different from CRUD.\n * Instead of dealing with state, it deals with streams of historical events.\n *\n * @template AR - The type of Aggregate Root this repository manages.\n */\nexport abstract class AbstractEsRepository<AR extends AggregateRoot>\n  implements AggregateRepository<AR>\n{\n  /**\n   * Finds an aggregate by loading its entire history of events and replaying\n   * them to reconstruct the current state.\n   *\n   * @param tx - The transaction context.\n   * @param id - The ID of the aggregate to find (which corresponds to a stream ID).\n   * @returns A promise resolving to the aggregate or null if its stream is empty.\n   */\n  public async findById(tx: Tx, id: string): Promise<AR | null> {\n    // 1. Load the raw stream of events and the current version from the database.\n    const stream = await this.loadEvents(tx, id);\n\n    // If there are no events, the aggregate has never existed.\n    if (stream.events.length === 0) {\n      return null;\n    }\n\n    // 2. Rehydrate the aggregate by replaying its history.\n    // The aggregate root MUST have a factory method like `fromHistory` for this to work.\n    const AggregateClass = this.getAggregateClass();\n    const aggregate = AggregateClass.fromHistory(id, stream.events);\n    aggregate.version = stream.version;\n\n    return aggregate;\n  }\n\n  /**\n   * The main entry point for persisting an aggregate's changes.\n   * In Event Sourcing, \"saving\" means appending the new, uncommitted events\n   * from the aggregate to its event stream in the database.\n   *\n   * @param tx - The transaction context.\n   * @param agg - The aggregate instance with pending changes (uncommitted events).\n   */\n  public async save(tx: Tx, agg: AR): Promise<DomainEvent<unknown>[]> {\n    // 1. Get the pending events that were generated by the business operation.\n    const uncommittedEvents = agg.pullEvents();\n\n    // If no events were generated, there's nothing to save: return an empty array.\n    if (uncommittedEvents.length === 0) {\n      return [];\n    }\n\n    // 2. Delegate to the concrete implementation to append these events to the store.\n    // We pass the aggregate's current version, which is the expected number of events\n    // already in the stream. This is our optimistic concurrency check.\n    await this.appendEvents(tx, agg.id, agg.version, uncommittedEvents);\n\n    // 3. Update the in-memory aggregate's version.\n    agg.version += uncommittedEvents.length;\n\n    // Return the events that were just appended.\n    return uncommittedEvents;\n  }\n\n  /**\n   * A reference to the aggregate's constructor.\n   * This is needed to call the static `fromHistory` method during rehydration.\n   */\n  protected abstract getAggregateClass(): RehydratableAggregate<AR>;\n\n  /**\n   * Loads the raw event data and stream version from the database.\n   * Must be implemented by the concrete repository.\n   *\n   * @abstract\n   * @protected\n   */\n  protected abstract loadEvents(tx: Tx, id: string): Promise<EventStream>;\n\n  /**\n   * Appends a list of new events to an event stream.\n   * Must be implemented by the concrete repository to handle the `INSERT` logic\n   * and the optimistic concurrency check on the stream version.\n   *\n   * @abstract\n   * @protected\n   */\n  protected abstract appendEvents(\n    tx: Tx,\n    id: string,\n    expectedVersion: number,\n    events: DomainEvent<unknown>[]\n  ): Promise<void>;\n}\n","// ddd-kit/src/domain/invariants.ts\n// -----------------------------------------------------------------------------\n// Invariant DSL for aggregates (domain-only, no I/O)\n//\n// Why this exists\n// ---------------\n// - Invariants are the \"always true\" rules of an aggregate's internal state.\n// - We want them *inside* the domain, but written in a way that's readable\n//   (\"English-like\") and returns *structured* information for the edge layer.\n// - We accumulate *all* violations and throw once, so the UI can show a rich\n//   error (e.g., multiple fields invalid) without trial-and-error.\n// - We reuse the platform's canonical DomainInvariantError so HTTP mappers,\n//   logs, and tests stay consistent across the codebase.\n//\n// What this is NOT\n// ----------------\n// - This is not for external/contextual checks (e.g., plan limits, flags,\n//   uniqueness across the DB). Those belong to application-level *policies*.\n//   Keep a clean separation: \"intrinsic rules\" (invariants) vs \"context rules\"\n//   (policies).\n//\n// Typical usage\n// -------------\n//   invariants({ aggregate: \"RealEstate\", operation: \"create\" })\n//     .ensure(\"Name is required.\", \"real_estate.name_required\", name.trim() !== \"\", { name })\n//     .ensure(\"Purchase currency must match baseCurrency.\", \"real_estate.currency_matches\", purchase.currency === baseCurrency,\n//             { purchaseCurrency: purchase.currency, baseCurrency })\n//     .must(\"Purchase date must be a valid ISO-8601 date.\", \"real_estate.purchase_date_valid\",\n//           () => !Number.isNaN(Date.parse(purchase.date)), { purchaseDate: purchase.date })\n//     .throwIfAny(\"RealEstate.Invalid\");\n// -----------------------------------------------------------------------------\n\nimport { DomainInvariantError } from \"../shared/errors\";\n\n// A single invariant failure, with a readable message and a stable key for i18n/tests.\n// \"details\" are free-form structured data useful for debugging and telemetry.\nexport type InvariantViolation = {\n  message: string; // e.g. \"Name is required.\"\n  key: string; // e.g. \"real_estate.name_required\"\n  details?: Record<string, unknown>;\n};\n\n// Shape of the error.details payload we attach to DomainInvariantError.\n// \"violations\" is what UIs typically render; \"context\" adds high-level info.\nexport type InvariantErrorDetails = {\n  violations: InvariantViolation[]; // all collected violations\n  context?: Record<string, unknown>; // optional: aggregate id, op, etc.\n};\n\n/**\n * Build an invariant collector\n * - Use `.ensure` when you already have a boolean condition\n * - Use `.must` when you want lazy evaluation (we wrap try/catch)\n * - Call `.throwIfAny()` once at the end to throw a single DomainInvariantError\n *\n * @param context optional structured info included in `error.details.context`\n */\nexport function invariants(context?: Record<string, unknown>) {\n  // Internal buffer of violations (we don't throw immediately).\n  const violations: InvariantViolation[] = [];\n\n  // Push a violation into the buffer with a readable message, a stable key,\n  // and optional structured details (useful for logs and UIs).\n  function push(\n    message: string,\n    key: string,\n    details?: Record<string, unknown>\n  ) {\n    violations.push({ message, key, details });\n  }\n\n  /**\n   * Ensure a condition that you've already evaluated.\n   * Prefer this when expressing \"simple truths\" inline without lambdas.\n   *\n   * Example:\n   *   .ensure(\"Name is required.\", \"real_estate.name_required\", name.trim() !== \"\")\n   */\n  function ensure(\n    message: string,\n    key: string,\n    condition: boolean,\n    details?: Record<string, unknown>\n  ) {\n    if (!condition) push(message, key, details);\n    return api;\n  }\n\n  /**\n   * Ensure a condition that's best expressed as a function.\n   * We catch exceptions and convert them into a structured violation,\n   * preventing domain code from leaking stack traces to callers.\n   *\n   * Example:\n   *   .must(\"Purchase date must be ISO-8601.\", \"purchase_date_valid\", () => !Number.isNaN(Date.parse(purchase.date)))\n   */\n  function must(\n    message: string,\n    key: string,\n    predicate: () => boolean,\n    details?: Record<string, unknown>\n  ) {\n    try {\n      const ok = !!predicate();\n      if (!ok) push(message, key, details);\n    } catch (err) {\n      // Convert unexpected predicate errors into a violation with extra context\n      push(message, `${key}.exception`, {\n        ...details,\n        error: (err as Error)?.message,\n      });\n    }\n    return api;\n  }\n\n  /**\n   * Throw a single DomainInvariantError if any violation was recorded.\n   * - Message is compact (first violation + a \"+N more\" suffix) so logs stay tidy.\n   * - The full list lives in `error.details.violations`.\n   * - By default, DomainInvariantError.code is \"DOMAIN_INVARIANT_VIOLATION\";\n   *   pass a custom code to override it for finer-grained client handling.\n   */\n  function throwIfAny(customCode?: string) {\n    if (violations.length === 0) return;\n\n    // Compact, human-friendly message for logs:\n    const first = violations[0]?.message ?? \"Domain invariant(s) violated\";\n    const suffix =\n      violations.length > 1 ? ` (+${violations.length - 1} more)` : \"\";\n    const message = `${first}${suffix}`;\n\n    const details: InvariantErrorDetails = { violations, context };\n    const err = new DomainInvariantError(message, details);\n\n    // Optional override (non-breaking): allow domain code to set a more specific code.\n    if (customCode) (err as any).code = customCode;\n\n    throw err;\n  }\n\n  /**\n   * Expose collected violations without throwing.\n   * Handy for \"dry-run\" validations in tests or pre-checks.\n   */\n  function toArray() {\n    return violations;\n  }\n\n  const api = { ensure, must, throwIfAny, toArray };\n  return api;\n}\n\n/**\n * Userland type guard for narrowing unknown errors in adapters/tests\n * without importing the class in every file. Also works with errors thrown\n * by this DSL, which attach `details.violations`.\n */\nexport function isDomainInvariantError(\n  e: unknown\n): e is DomainInvariantError & { details?: InvariantErrorDetails } {\n  return (\n    !!e &&\n    typeof e === \"object\" &&\n    (e as any).name === \"DomainInvariantError\" &&\n    typeof (e as any).code === \"string\"\n  );\n}\n","// packages/ddd-kit/src/memory/console-event-publisher.memory.ts\n\nimport type { DomainEvent, EventPublisher } from \"../application/command/types\";\nimport type { Tx } from \"../infra/unit-of-work\";\n\n/**\n * A simple EventPublisher implementation that logs events to the console.\n * This is perfect for development and testing to see what events are being\n * produced by the system without setting up complex infrastructure.\n */\nexport class ConsoleEventPublisher implements EventPublisher {\n  /**\n   * \"Publishes\" events by printing them to the standard output.\n   * @param events An array of domain events to publish.\n   * @param tx The transaction context. In this simple implementation, it's not used,\n   * but it's available for more advanced publishers (e.g., that write\n   * to an outbox table within the same transaction).\n   */\n  public async publish(events: DomainEvent<unknown>[], tx: Tx): Promise<void> {\n    if (events.length === 0) {\n      return;\n    }\n    console.log(\n      \"📣 [ConsoleEventPublisher] Publishing Domain Events to console...\"\n    );\n    // We use JSON.stringify with indentation to make the output readable.\n    console.log(JSON.stringify(events, null, 2));\n  }\n}\n","import type { IdempotencyStore } from \"../infra/idempotency-store\";\nimport type { Tx } from \"../infra/unit-of-work\";\n\n/**\n * InMemoryIdempotencyStore\n * ------------------------\n * Test/local adapter for IdempotencyStore. DO NOT use in production:\n * - No TTL cleanup\n * - No cross-process visibility\n * - No durability\n */\nexport class InMemoryIdempotencyStore implements IdempotencyStore {\n  private map = new Map<string, { response?: unknown }>();\n\n  /** Combines command + scope + key into one string. */\n  private keyOf(key: string, command: string, scopeHash: string) {\n    return `${command}::${scopeHash}::${key}`;\n  }\n\n  async tryClaim(args: {\n    key: string;\n    command: string;\n    scopeHash: string;\n    payloadHash: string;\n    now: Date;\n    tx: Tx;\n  }): Promise<\"claimed\" | { response: unknown }> {\n    const k = this.keyOf(args.key, args.command, args.scopeHash);\n\n    // If this is the first time we see the key → \"claim\" it by inserting an empty row.\n    if (!this.map.has(k)) {\n      this.map.set(k, {}); // claimed but no response yet\n      return \"claimed\";\n    }\n\n    // If a response exists → short-circuit retry with the same response.\n    const row = this.map.get(k)!;\n    if (row.response !== undefined) return { response: row.response };\n\n    // Otherwise: already claimed and still in-flight → treat as claimed.\n    return \"claimed\";\n  }\n\n  async saveResponse(args: {\n    key: string;\n    command: string;\n    scopeHash: string;\n    response: unknown;\n    tx: Tx;\n  }): Promise<void> {\n    const k = this.keyOf(args.key, args.command, args.scopeHash);\n    const row = this.map.get(k) ?? {};\n    row.response = args.response;\n    this.map.set(k, row);\n  }\n}\n","import type { Tx, UnitOfWork } from \"../infra/unit-of-work\";\n\n/**\n * InMemoryUoW (InMemoryUnitOfWork)\n * -----------\n * Testing adapter for UnitOfWork:\n * - It doesn't start a real DB transaction.\n * - It simply calls the function with a dummy Tx object.\n *\n * Use this in tests to run command handlers without a database.\n * In production, provide a real UoW (e.g., drizzle.transaction wrapper).\n */\nexport const InMemoryUoW: UnitOfWork = {\n  withTransaction: async <T>(fn: (tx: Tx) => Promise<T>) => fn({} as Tx),\n};\n"]}