Extract the **Cart** module from this codebase (Medusa) and describe it as a **standalone DDD aggregate**, suitable for import into Qlerify (an event storming / domain modeling tool).

**Isolating the Aggregate from the Service Layer**

Most commerce platforms have two command layers:

1. **Service layer** — workflows or application services that coordinate commands across multiple aggregates.
2. **Aggregate-level commands** — the actual mutation surface of the aggregate itself.

**When modeling the aggregate in isolation, peel away the service layer to expose the underlying aggregate commands.**

Concretely: if the codebase has a service (called a workflow in Medusa) that coordinates the Promotion module and then calls setLineItemAdjustments() on the Cart module, the aggregate command is setLineItemAdjustments() — not “apply promotions”. The orchestration stays outside; the aggregate only knows about the data it receives.

**What to Capture**

- **Aggregate Root Entity** — the top-level entity through which all mutations enter. Identify it by ownership of children and by being the service entry point.
- **Related Entities** — children with their own identity and individual lifecycle (add/update/remove).
- **Value Objects** — children replaced wholesale (set-replacement semantics), with no independent lifecycle. They may still have technical IDs in the implementation — still treat them as VOs.
- **Commands** — each one representing a distinct state change of the aggregate, with a corresponding domain event. If one command always triggers another command, merge them here. Find a granularity that is coarser than per-attribute changes but finer than just create/update/delete for the whole aggregate. The right level is one where each command/event pair represents a business-meaningful action that stakeholders can reason about in an event storming session. VOs do not have their own lifecycle; they are only fully replaced. For value objects, usually only one command is needed to set the value; clearing or removal can be modeled as setting a blank or empty value. When capturing commands, note which fields are create-only — attributes required on create but not available on update.
- **Domain Events** — one event per command, forming 1:1 pairs. Aim for 8–20 events per aggregate, though this is not a strict rule. Too many will make the event storming board hard for stakeholders to review. Too few will make the system harder to reason about.
- **Read Models / Queries** — queries needed by the client. These can contain computed/derived fields (totals, counts) that exist on API responses but not on entity models. When a field is clearly projection-only (totals, rollups), prefer listing it here instead of also on entity/VO attribute tables. Include short descriptions of calculated fields if not obvious.
- **Attributes** — ALL fields for every entity and VO: name, type, required/optional, defaults, notes. Prefer domain/type definitions over database schema. Describe relationships in type form (for example Cart.items: LineItem[]) rather than database form.
- **Invariants** — business rules: required fields, non-negative amounts, set-replacement semantics (for example “adjustments are always replaced atomically — you cannot patch a single one”), snapshot patterns (for example product data copied at add-time), computed-only fields.
- **Tests** — for each aggregate command, extract tests that validate the command’s behavior at the aggregate boundary. If only service/workflow tests exist, extract only the part that proves aggregate behavior and ignore external orchestration. Use business language, not code identifiers or framework details. Example: "Given no cart exists, When the caller creates a cart with currency code EUR, Then a cart is returned with an assigned id and currency code EUR."
- **External References** — fields pointing to other aggregates by ID only (for example regionId → Region). Do not model the external aggregate’s internals.

**Scope**

Model only the Cart aggregate boundary. Cross-aggregate orchestration (for example cart completion creating an order, promotion evaluation computing adjustments) lives outside — note that it exists, but do not model it. Include a minimal description of the hierarchy of the entity / VO relationships. List cross-aggregate links for reference only.

Include a short description for each entity and each attribute.

Model the aggregate as a **domain/type model**, not a persistence model. Avoid database terms like foreign keys, join tables, and cascade deletes unless they are needed to explain a business rule.

For nested members inside the aggregate, describe ownership only from the parent type (for example Cart.items: LineItem[]) and omit internal back-reference fields like cart_id, item_id, or shipping_method_id unless they are themselves domain-significant.
