@comity/order 0.9.3 → 0.10.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/README.md +75 -18
- package/dist/contracts/customer-snapshot.d.ts +4 -4
- package/dist/contracts/line.d.ts +51 -0
- package/dist/contracts/line.js +2 -0
- package/dist/contracts/order.d.ts +46 -46
- package/dist/entities/order.d.ts +97 -74
- package/dist/entities/order.js +463 -200
- package/dist/errors/order.d.ts +7 -1
- package/dist/errors/order.js +11 -3
- package/dist/index.d.ts +2 -2
- package/dist/repositories/memory.js +11 -1
- package/package.json +4 -4
- package/dist/contracts/item.d.ts +0 -107
- package/dist/contracts/item.js +0 -2
package/dist/errors/order.d.ts
CHANGED
|
@@ -7,8 +7,14 @@ import { BaseError } from "@comity/primitives/errors";
|
|
|
7
7
|
* a `null` repository result, never an error; infrastructure and
|
|
8
8
|
* cross-module failures (`repository_error`, `insufficient_stock`,
|
|
9
9
|
* `product_not_available`, coupon validation) belong to other layers/modules.
|
|
10
|
+
*
|
|
11
|
+
* The four `currency_mismatch`, `price_incoherent`, `commitment_immutable` and
|
|
12
|
+
* `payment_fact_conflict` reasons are additive (errors.md §10): no existing
|
|
13
|
+
* reason changed its meaning, and no other reason exists. The former
|
|
14
|
+
* `invalid_buyer` reason is removed with O-11, whose commercial/fiscal buyer
|
|
15
|
+
* coherence belongs to Commerce.
|
|
10
16
|
*/
|
|
11
|
-
export type OrderErrorReason = "invalid_quantity" | "invalid_item" | "invalid_status_transition" | "shipping_destination_immutable" | "ambiguous_shipping_destination" | "duplicate_item_id";
|
|
17
|
+
export type OrderErrorReason = "invalid_quantity" | "invalid_item" | "invalid_status_transition" | "shipping_destination_immutable" | "ambiguous_shipping_destination" | "duplicate_item_id" | "currency_mismatch" | "price_incoherent" | "commitment_immutable" | "payment_fact_conflict";
|
|
12
18
|
/**
|
|
13
19
|
* Order error metadata.
|
|
14
20
|
*/
|
package/dist/errors/order.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { BaseError } from "@comity/primitives/errors";
|
|
2
2
|
const REASON_MESSAGES = {
|
|
3
|
-
invalid_quantity: "Invalid order
|
|
4
|
-
invalid_item: "Order
|
|
3
|
+
invalid_quantity: "Invalid order line quantity",
|
|
4
|
+
invalid_item: "Order line not found",
|
|
5
5
|
invalid_status_transition: "Invalid order status transition",
|
|
6
6
|
shipping_destination_immutable: "Shipping destination cannot be changed in the current order status",
|
|
7
7
|
ambiguous_shipping_destination: "Order must contain exactly one shipping destination",
|
|
8
|
-
duplicate_item_id: "Duplicate order
|
|
8
|
+
duplicate_item_id: "Duplicate order line identifier",
|
|
9
|
+
currency_mismatch: "Order lines and price must share one currency",
|
|
10
|
+
price_incoherent: "Order price is not coherent with its lines",
|
|
11
|
+
commitment_immutable: "Committed lines and price cannot be changed outside draft",
|
|
12
|
+
payment_fact_conflict: "Payment fact conflicts with the recorded payment facts",
|
|
9
13
|
};
|
|
10
14
|
const REASON_HTTP_STATUS = {
|
|
11
15
|
invalid_quantity: 400,
|
|
@@ -14,6 +18,10 @@ const REASON_HTTP_STATUS = {
|
|
|
14
18
|
shipping_destination_immutable: 409,
|
|
15
19
|
ambiguous_shipping_destination: 409,
|
|
16
20
|
duplicate_item_id: 400,
|
|
21
|
+
currency_mismatch: 409,
|
|
22
|
+
price_incoherent: 409,
|
|
23
|
+
commitment_immutable: 409,
|
|
24
|
+
payment_fact_conflict: 409,
|
|
17
25
|
};
|
|
18
26
|
/**
|
|
19
27
|
* Order operation error with typed reasons.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export type { OrderAddressRole, OrderAddressSnapshot } from "./contracts/address-snapshot.js";
|
|
2
2
|
export type { OrderContact } from "./contracts/contact.js";
|
|
3
3
|
export type { OrderCustomerSnapshot } from "./contracts/customer-snapshot.js";
|
|
4
|
-
export type {
|
|
4
|
+
export type { OrderLine, OrderLineSubject } from "./contracts/line.js";
|
|
5
5
|
export type { OrderRepository, OrderRepositoryContext, OrderSearchCriteria, OrderSearchResult, } from "./contracts/order-repository.js";
|
|
6
|
-
export type { OrderCreate, OrderData,
|
|
6
|
+
export type { OrderCreate, OrderData, OrderSnapshot, OrderState, OrderStatus, OrderUpdate, } from "./contracts/order.js";
|
|
7
7
|
export type { OrderPaymentSnapshot, OrderPaymentStatus } from "./contracts/payment-snapshot.js";
|
|
8
8
|
export { Order } from "./entities/order.js";
|
|
9
9
|
export { OrderId } from "./value-objects/order-id.js";
|
|
@@ -8,6 +8,14 @@ import { success } from "@comity/primitives/result";
|
|
|
8
8
|
export class MemoryOrderRepository {
|
|
9
9
|
/** Internal storage keyed by tenant + order ID */
|
|
10
10
|
#orders = new Map();
|
|
11
|
+
/**
|
|
12
|
+
* Builds the tenant-scoped storage key.
|
|
13
|
+
*
|
|
14
|
+
* @param tenant - The tenant identifier.
|
|
15
|
+
* @param id - The order identifier.
|
|
16
|
+
*
|
|
17
|
+
* @returns The storage key.
|
|
18
|
+
*/
|
|
11
19
|
#makeKey(tenant, id) {
|
|
12
20
|
return `${tenant.toString()}\u0000${id.toString()}`;
|
|
13
21
|
}
|
|
@@ -47,8 +55,10 @@ export class MemoryOrderRepository {
|
|
|
47
55
|
status: o.status,
|
|
48
56
|
createdAt: o.createdAt,
|
|
49
57
|
updatedAt: o.updatedAt,
|
|
50
|
-
|
|
58
|
+
version: o.version,
|
|
59
|
+
lines: o.lines,
|
|
51
60
|
price: o.price,
|
|
61
|
+
currency: o.currency,
|
|
52
62
|
channelId: o.channelId,
|
|
53
63
|
...(o.customer !== undefined ? { customer: o.customer } : {}),
|
|
54
64
|
...(o.addresses !== undefined ? { addresses: o.addresses } : {}),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@comity/order",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Order domain contracts for Comity commerce modules.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
@@ -65,9 +65,9 @@
|
|
|
65
65
|
},
|
|
66
66
|
"sideEffects": false,
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@comity/organization": "^0.9.
|
|
69
|
-
"@comity/pricing": "^0.
|
|
70
|
-
"@comity/primitives": "^0.9.
|
|
68
|
+
"@comity/organization": "^0.9.4",
|
|
69
|
+
"@comity/pricing": "^0.10.0",
|
|
70
|
+
"@comity/primitives": "^0.9.3"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
73
|
"@types/node": "^24.19.2",
|
package/dist/contracts/item.d.ts
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import type { Price } from "@comity/pricing";
|
|
2
|
-
/**
|
|
3
|
-
* Product attribute snapshot associated with an order item.
|
|
4
|
-
*
|
|
5
|
-
* A frozen copy of a product attribute at purchase time. It mirrors
|
|
6
|
-
* `ProductAttribute` from `@comity/catalog` without importing catalog types:
|
|
7
|
-
* the order stays independent of the catalog read model.
|
|
8
|
-
*/
|
|
9
|
-
export interface OrderProductAttribute {
|
|
10
|
-
/** Attribute code. */
|
|
11
|
-
readonly code: string;
|
|
12
|
-
/** Display name of the attribute. */
|
|
13
|
-
readonly label?: string;
|
|
14
|
-
/** Attribute value. */
|
|
15
|
-
readonly value: string | number | boolean;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Selected option snapshot for an order item (e.g. size = "M", color = "blue").
|
|
19
|
-
*
|
|
20
|
-
* A frozen copy of a chosen product option at purchase time. It mirrors
|
|
21
|
-
* `ProductOptionSelection` from `@comity/catalog` without importing catalog
|
|
22
|
-
* types; the `label` is preserved so the selection stays renderable without
|
|
23
|
-
* the catalog.
|
|
24
|
-
*/
|
|
25
|
-
export interface OrderProductOption {
|
|
26
|
-
/** Option code. */
|
|
27
|
-
readonly code: string;
|
|
28
|
-
/** Display name of the option. */
|
|
29
|
-
readonly label?: string;
|
|
30
|
-
/** Selected option value. */
|
|
31
|
-
readonly value: string;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Product variant snapshot associated with an order item.
|
|
35
|
-
*
|
|
36
|
-
* A frozen copy of the purchased product variant at purchase time. It mirrors
|
|
37
|
-
* `ProductVariant` from `@comity/catalog` without importing catalog types and
|
|
38
|
-
* carries no pricing or inventory — those belong to their owning modules.
|
|
39
|
-
*/
|
|
40
|
-
export interface OrderVariantSnapshot {
|
|
41
|
-
/** Variant identifier. */
|
|
42
|
-
readonly id: string;
|
|
43
|
-
/** Stock Keeping Unit of the variant. */
|
|
44
|
-
readonly sku?: string;
|
|
45
|
-
/** Display name of the variant. */
|
|
46
|
-
readonly name?: string;
|
|
47
|
-
/** Variant attribute snapshots. */
|
|
48
|
-
readonly attributes?: ReadonlyArray<OrderProductAttribute>;
|
|
49
|
-
/** Selected option snapshots of the variant. */
|
|
50
|
-
readonly options?: ReadonlyArray<OrderProductOption>;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Immutable product snapshot associated with an order item.
|
|
54
|
-
*
|
|
55
|
-
* A self-contained representation of the product as it was at purchase time.
|
|
56
|
-
* It is NOT `ProductProjection` from `@comity/catalog` and it is NOT a
|
|
57
|
-
* reference to the catalog: once the order is created it MUST NOT depend on
|
|
58
|
-
* the catalog for its content. Historical order rendering, customer support,
|
|
59
|
-
* invoice generation, and returns workflows rely exclusively on this record.
|
|
60
|
-
*/
|
|
61
|
-
export interface OrderProductSnapshot {
|
|
62
|
-
/** Reference to the catalog product identifier, if still known. */
|
|
63
|
-
readonly productId?: string;
|
|
64
|
-
/** Stock Keeping Unit. */
|
|
65
|
-
readonly sku: string;
|
|
66
|
-
/** Product name. */
|
|
67
|
-
readonly name: string;
|
|
68
|
-
/** The purchased variant, if the product is variant-based. */
|
|
69
|
-
readonly variant?: OrderVariantSnapshot;
|
|
70
|
-
/** Product attribute snapshots. */
|
|
71
|
-
readonly attributes?: ReadonlyArray<OrderProductAttribute>;
|
|
72
|
-
/** Selected option snapshots. */
|
|
73
|
-
readonly options?: ReadonlyArray<OrderProductOption>;
|
|
74
|
-
/** Free-form metadata (e.g. image URL, page URL). */
|
|
75
|
-
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Order line item.
|
|
79
|
-
*
|
|
80
|
-
* Embedded value structure of the Order aggregate: it has no independent
|
|
81
|
-
* identity, lifecycle, or repository.
|
|
82
|
-
*/
|
|
83
|
-
export interface OrderItem {
|
|
84
|
-
/**
|
|
85
|
-
* Stable technical key for one occurrence within the order.
|
|
86
|
-
*
|
|
87
|
-
* The key identifies the occurrence, not the product: it carries no
|
|
88
|
-
* commercial equivalence meaning and must never be derived by comparing
|
|
89
|
-
* product data. Occurrence keys are unique within the order, preserved
|
|
90
|
-
* across retention/updates, and never reassigned after removal.
|
|
91
|
-
*/
|
|
92
|
-
readonly id: string;
|
|
93
|
-
/** Associated product snapshot. */
|
|
94
|
-
readonly product: OrderProductSnapshot;
|
|
95
|
-
/** Requested quantity. */
|
|
96
|
-
readonly quantity: number;
|
|
97
|
-
/**
|
|
98
|
-
* Full line price (subtotal, applied modifiers, total).
|
|
99
|
-
*
|
|
100
|
-
* `@comity/pricing` is the single owner of price composition data: price
|
|
101
|
-
* modifiers are accessed exclusively through `price.modifiers`. The order
|
|
102
|
-
* stores the immutable `Price` value and never duplicates modifier storage.
|
|
103
|
-
*/
|
|
104
|
-
readonly price: Price;
|
|
105
|
-
/** Custom metadata. */
|
|
106
|
-
readonly meta?: Record<string, unknown>;
|
|
107
|
-
}
|
package/dist/contracts/item.js
DELETED