@cogenta/commerce 0.2.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.
Files changed (98) hide show
  1. package/LICENSE +373 -0
  2. package/dist/admin/permissions.d.ts +57 -0
  3. package/dist/admin/permissions.d.ts.map +1 -0
  4. package/dist/admin/permissions.js +87 -0
  5. package/dist/admin/permissions.js.map +1 -0
  6. package/dist/admin/router.d.ts +53 -0
  7. package/dist/admin/router.d.ts.map +1 -0
  8. package/dist/admin/router.js +476 -0
  9. package/dist/admin/router.js.map +1 -0
  10. package/dist/cart/store.d.ts +91 -0
  11. package/dist/cart/store.d.ts.map +1 -0
  12. package/dist/cart/store.js +342 -0
  13. package/dist/cart/store.js.map +1 -0
  14. package/dist/cart/totals.d.ts +73 -0
  15. package/dist/cart/totals.d.ts.map +1 -0
  16. package/dist/cart/totals.js +65 -0
  17. package/dist/cart/totals.js.map +1 -0
  18. package/dist/catalog/store.d.ts +53 -0
  19. package/dist/catalog/store.d.ts.map +1 -0
  20. package/dist/catalog/store.js +358 -0
  21. package/dist/catalog/store.js.map +1 -0
  22. package/dist/catalog/types.d.ts +95 -0
  23. package/dist/catalog/types.d.ts.map +1 -0
  24. package/dist/catalog/types.js +5 -0
  25. package/dist/catalog/types.js.map +1 -0
  26. package/dist/coupon/store.d.ts +103 -0
  27. package/dist/coupon/store.d.ts.map +1 -0
  28. package/dist/coupon/store.js +181 -0
  29. package/dist/coupon/store.js.map +1 -0
  30. package/dist/customer/store.d.ts +41 -0
  31. package/dist/customer/store.d.ts.map +1 -0
  32. package/dist/customer/store.js +103 -0
  33. package/dist/customer/store.js.map +1 -0
  34. package/dist/index.d.ts +42 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +23 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/invoice/pdf.d.ts +67 -0
  39. package/dist/invoice/pdf.d.ts.map +1 -0
  40. package/dist/invoice/pdf.js +449 -0
  41. package/dist/invoice/pdf.js.map +1 -0
  42. package/dist/invoice/store.d.ts +96 -0
  43. package/dist/invoice/store.d.ts.map +1 -0
  44. package/dist/invoice/store.js +221 -0
  45. package/dist/invoice/store.js.map +1 -0
  46. package/dist/money.d.ts +55 -0
  47. package/dist/money.d.ts.map +1 -0
  48. package/dist/money.js +146 -0
  49. package/dist/money.js.map +1 -0
  50. package/dist/order/store.d.ts +75 -0
  51. package/dist/order/store.d.ts.map +1 -0
  52. package/dist/order/store.js +301 -0
  53. package/dist/order/store.js.map +1 -0
  54. package/dist/order/types.d.ts +67 -0
  55. package/dist/order/types.d.ts.map +1 -0
  56. package/dist/order/types.js +71 -0
  57. package/dist/order/types.js.map +1 -0
  58. package/dist/payment/manual.d.ts +27 -0
  59. package/dist/payment/manual.d.ts.map +1 -0
  60. package/dist/payment/manual.js +105 -0
  61. package/dist/payment/manual.js.map +1 -0
  62. package/dist/payment/registry.d.ts +23 -0
  63. package/dist/payment/registry.d.ts.map +1 -0
  64. package/dist/payment/registry.js +30 -0
  65. package/dist/payment/registry.js.map +1 -0
  66. package/dist/payment/store.d.ts +38 -0
  67. package/dist/payment/store.d.ts.map +1 -0
  68. package/dist/payment/store.js +253 -0
  69. package/dist/payment/store.js.map +1 -0
  70. package/dist/payment/stripe.d.ts +10 -0
  71. package/dist/payment/stripe.d.ts.map +1 -0
  72. package/dist/payment/stripe.js +419 -0
  73. package/dist/payment/stripe.js.map +1 -0
  74. package/dist/payment/types.d.ts +124 -0
  75. package/dist/payment/types.d.ts.map +1 -0
  76. package/dist/payment/types.js +18 -0
  77. package/dist/payment/types.js.map +1 -0
  78. package/dist/rows.d.ts +26 -0
  79. package/dist/rows.d.ts.map +1 -0
  80. package/dist/rows.js +87 -0
  81. package/dist/rows.js.map +1 -0
  82. package/dist/shipping/store.d.ts +88 -0
  83. package/dist/shipping/store.d.ts.map +1 -0
  84. package/dist/shipping/store.js +165 -0
  85. package/dist/shipping/store.js.map +1 -0
  86. package/dist/subscription/store.d.ts +106 -0
  87. package/dist/subscription/store.d.ts.map +1 -0
  88. package/dist/subscription/store.js +310 -0
  89. package/dist/subscription/store.js.map +1 -0
  90. package/dist/tables.d.ts +41 -0
  91. package/dist/tables.d.ts.map +1 -0
  92. package/dist/tables.js +383 -0
  93. package/dist/tables.js.map +1 -0
  94. package/dist/tax/store.d.ts +68 -0
  95. package/dist/tax/store.d.ts.map +1 -0
  96. package/dist/tax/store.js +126 -0
  97. package/dist/tax/store.js.map +1 -0
  98. package/package.json +42 -0
@@ -0,0 +1,358 @@
1
+ import { CogentaError, identifier, limit, newId, sql, } from '@cogenta/core';
2
+ import { assertCurrency, assertMinor } from '../money.js';
3
+ import { fromBool, toBool, toInt, toNullableText, toText } from '../rows.js';
4
+ import { TABLES } from '../tables.js';
5
+ function decodeProduct(row) {
6
+ const collection = toNullableText(row.content_collection);
7
+ const entryId = toNullableText(row.content_entry_id);
8
+ const ref = collection !== null && entryId !== null ? { collection, entryId } : null;
9
+ return {
10
+ id: toText(row.id, 'product.id'),
11
+ handle: toText(row.handle, 'product.handle'),
12
+ title: toText(row.title, 'product.title'),
13
+ status: toText(row.status, 'product.status'),
14
+ contentRef: ref,
15
+ createdAt: toText(row.created_at, 'product.created_at'),
16
+ updatedAt: toText(row.updated_at, 'product.updated_at'),
17
+ };
18
+ }
19
+ function decodeVariant(row) {
20
+ return {
21
+ id: toText(row.id, 'variant.id'),
22
+ productId: toText(row.product_id, 'variant.product_id'),
23
+ sku: toText(row.sku, 'variant.sku'),
24
+ title: toText(row.title, 'variant.title'),
25
+ priceMinor: toInt(row.price_minor, 'variant.price_minor'),
26
+ currency: toText(row.currency, 'variant.currency'),
27
+ onHand: toInt(row.on_hand, 'variant.on_hand'),
28
+ allowBackorder: toBool(row.allow_backorder),
29
+ weightGrams: toInt(row.weight_grams, 'variant.weight_grams'),
30
+ taxCategory: toText(row.tax_category, 'variant.tax_category'),
31
+ position: toInt(row.position, 'variant.position'),
32
+ createdAt: toText(row.created_at, 'variant.created_at'),
33
+ updatedAt: toText(row.updated_at, 'variant.updated_at'),
34
+ };
35
+ }
36
+ const HANDLE_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/u;
37
+ function assertHandle(handle) {
38
+ const value = handle.trim().toLowerCase();
39
+ if (!HANDLE_PATTERN.test(value) || value.length > 200) {
40
+ throw new CogentaError({
41
+ code: 'COMMERCE_PRODUCT_INVALID',
42
+ // The offending value goes in `details`, never in the message: the
43
+ // message is what a route serialises back to whoever sent it, and
44
+ // echoing a caller's string into a response is how reflected content
45
+ // gets somewhere it was never meant to be.
46
+ message: 'That is not a usable product handle.',
47
+ hint: 'Use lower-case letters, digits and single hyphens, like "wool-scarf".',
48
+ details: { handle },
49
+ });
50
+ }
51
+ return value;
52
+ }
53
+ function assertQuantity(quantity, what) {
54
+ if (!Number.isInteger(quantity) || quantity <= 0) {
55
+ throw new CogentaError({
56
+ code: 'COMMERCE_QUANTITY_INVALID',
57
+ message: `${what} must be a whole number greater than zero, got ${String(quantity)}.`,
58
+ hint: 'To remove a line, delete it. A quantity of zero is not a line.',
59
+ });
60
+ }
61
+ return quantity;
62
+ }
63
+ /**
64
+ * Merges repeated variants in one request.
65
+ *
66
+ * Two lines for the same variant would otherwise each pass their own
67
+ * `on_hand >= quantity` guard while together exceeding stock — the classic way
68
+ * a per-line check quietly oversells. Summing first makes the guard mean what
69
+ * it says.
70
+ */
71
+ function coalesce(requests) {
72
+ const totals = new Map();
73
+ for (const request of requests) {
74
+ assertQuantity(request.quantity, 'A stock quantity');
75
+ totals.set(request.variantId, (totals.get(request.variantId) ?? 0) + request.quantity);
76
+ }
77
+ return [...totals].map(([variantId, quantity]) => ({ variantId, quantity }));
78
+ }
79
+ export function createCatalogStore(db, now = Date.now) {
80
+ const d = db.dialect;
81
+ const products = identifier(TABLES.products, d);
82
+ const variants = identifier(TABLES.variants, d);
83
+ const stamp = () => new Date(now()).toISOString();
84
+ async function loadProduct(id) {
85
+ const found = await readProduct(id);
86
+ if (found === null) {
87
+ throw new CogentaError({
88
+ code: 'COMMERCE_PRODUCT_NOT_FOUND',
89
+ message: 'This product does not exist.',
90
+ hint: 'It may have been deleted. Refresh the product list.',
91
+ });
92
+ }
93
+ return found;
94
+ }
95
+ async function readProduct(id) {
96
+ const result = await db.query(sql `select * from ${products} where id = ${id}`);
97
+ const row = result.rows[0];
98
+ return row === undefined ? null : decodeProduct(row);
99
+ }
100
+ async function loadVariant(id, executor = db) {
101
+ const result = await executor.query(sql `select * from ${variants} where id = ${id}`);
102
+ const row = result.rows[0];
103
+ if (row === undefined) {
104
+ throw new CogentaError({
105
+ code: 'COMMERCE_VARIANT_NOT_FOUND',
106
+ message: 'This product variant does not exist.',
107
+ hint: 'It may have been deleted while the cart was open. Remove the line and try again.',
108
+ });
109
+ }
110
+ return decodeVariant(row);
111
+ }
112
+ async function skuTaken(sku, exceptId) {
113
+ const result = exceptId === undefined
114
+ ? await db.query(sql `select id from ${variants} where sku = ${sku}`)
115
+ : await db.query(sql `select id from ${variants} where sku = ${sku} and id <> ${exceptId}`);
116
+ return result.rows.length > 0;
117
+ }
118
+ /**
119
+ * Lowers stock for one line, and reports whether it actually happened.
120
+ *
121
+ * `on_hand >= quantity` inside the UPDATE is the whole safety property. A
122
+ * read followed by a write would be correct in a test and wrong in
123
+ * production; this is correct in both, on all three dialects, because
124
+ * `rowsAffected` is the one thing they all agree on.
125
+ */
126
+ async function takeOne(tx, variant, quantity) {
127
+ if (variant.allowBackorder) {
128
+ const result = await tx.query(sql `update ${variants} set on_hand = on_hand - ${quantity}, updated_at = ${stamp()} where id = ${variant.id}`);
129
+ return result.rowsAffected > 0;
130
+ }
131
+ const result = await tx.query(sql `update ${variants} set on_hand = on_hand - ${quantity}, updated_at = ${stamp()}
132
+ where id = ${variant.id} and on_hand >= ${quantity}`);
133
+ return result.rowsAffected > 0;
134
+ }
135
+ async function takeStock(requests, tx) {
136
+ const wanted = coalesce(requests);
137
+ if (wanted.length === 0)
138
+ return { kind: 'taken' };
139
+ const run = async (executor) => {
140
+ const shortfalls = [];
141
+ // Ordered by id so two concurrent multi-line orders take the same rows
142
+ // in the same order. Different orders is how two transactions deadlock
143
+ // on Postgres and MySQL, and it is invisible until the day it isn't.
144
+ for (const request of [...wanted].sort((a, b) => a.variantId.localeCompare(b.variantId))) {
145
+ const variant = await loadVariant(request.variantId, executor);
146
+ const taken = await takeOne(executor, variant, request.quantity);
147
+ if (!taken) {
148
+ shortfalls.push({
149
+ variantId: request.variantId,
150
+ requested: request.quantity,
151
+ available: Math.max(0, variant.onHand),
152
+ });
153
+ }
154
+ }
155
+ if (shortfalls.length > 0) {
156
+ // Throwing is what rolls the whole thing back — all lines or none.
157
+ throw new StockShortfallSignal(shortfalls);
158
+ }
159
+ return { kind: 'taken' };
160
+ };
161
+ try {
162
+ // `immediate: true` takes SQLite's write lock at BEGIN. Without it a
163
+ // read-then-write transaction can fail with SQLITE_BUSY under exactly
164
+ // the concurrency this method exists to survive.
165
+ return tx === undefined ? await db.transaction(run, { immediate: true }) : await run(tx);
166
+ }
167
+ catch (error) {
168
+ if (error instanceof StockShortfallSignal) {
169
+ return { kind: 'short', shortfalls: error.shortfalls };
170
+ }
171
+ throw error;
172
+ }
173
+ }
174
+ return {
175
+ createProduct: async (input) => {
176
+ const id = newId(now);
177
+ const at = stamp();
178
+ const handle = assertHandle(input.handle);
179
+ await db.query(sql `
180
+ insert into ${products} (id, handle, title, status, content_collection, content_entry_id, created_at, updated_at)
181
+ values (${id}, ${handle}, ${input.title}, ${input.status ?? 'active'},
182
+ ${input.contentRef?.collection ?? null}, ${input.contentRef?.entryId ?? null},
183
+ ${at}, ${at})`);
184
+ return loadProduct(id);
185
+ },
186
+ readProduct,
187
+ readProductByHandle: async (handle) => {
188
+ const result = await db.query(sql `select * from ${products} where handle = ${handle.trim().toLowerCase()}`);
189
+ const row = result.rows[0];
190
+ return row === undefined ? null : decodeProduct(row);
191
+ },
192
+ updateProduct: async (id, input) => {
193
+ const current = await loadProduct(id);
194
+ const handle = input.handle === undefined ? current.handle : assertHandle(input.handle);
195
+ const ref = input.contentRef === undefined ? current.contentRef : input.contentRef;
196
+ await db.query(sql `
197
+ update ${products}
198
+ set handle = ${handle},
199
+ title = ${input.title ?? current.title},
200
+ status = ${input.status ?? current.status},
201
+ content_collection = ${ref?.collection ?? null},
202
+ content_entry_id = ${ref?.entryId ?? null},
203
+ updated_at = ${stamp()}
204
+ where id = ${id}`);
205
+ return loadProduct(id);
206
+ },
207
+ archiveProduct: async (id) => {
208
+ await loadProduct(id);
209
+ await db.query(sql `update ${products} set status = ${'archived'}, updated_at = ${stamp()} where id = ${id}`);
210
+ return loadProduct(id);
211
+ },
212
+ deleteProduct: async (id) => {
213
+ await db.transaction(async (tx) => {
214
+ await tx.query(sql `delete from ${variants} where product_id = ${id}`);
215
+ await tx.query(sql `delete from ${products} where id = ${id}`);
216
+ });
217
+ },
218
+ listProducts: async (options) => {
219
+ const conditions = [];
220
+ if (options?.status !== undefined) {
221
+ conditions.push(sql `status = ${options.status}`);
222
+ }
223
+ if (options?.search !== undefined && options.search.trim() !== '') {
224
+ const pattern = `%${options.search.trim().toLowerCase()}%`;
225
+ conditions.push(sql `(lower(handle) like ${pattern} or lower(title) like ${pattern})`);
226
+ }
227
+ let statement = sql `select * from ${products}`;
228
+ for (const [index, condition] of conditions.entries()) {
229
+ statement =
230
+ index === 0 ? sql `${statement} where ${condition}` : sql `${statement} and ${condition}`;
231
+ }
232
+ statement = sql `${statement} order by created_at desc, id desc`;
233
+ // `limit()` inlines the count: MySQL prepared statements reject a
234
+ // placeholder there, and the helper validates it so inlining is safe.
235
+ statement = sql `${statement} limit ${limit(options?.limit ?? 100)} offset ${limit(options?.offset ?? 0)}`;
236
+ const result = await db.query(statement);
237
+ return result.rows.map(decodeProduct);
238
+ },
239
+ createVariant: async (input) => {
240
+ await loadProduct(input.productId);
241
+ const sku = input.sku.trim();
242
+ if (sku === '') {
243
+ throw new CogentaError({
244
+ code: 'COMMERCE_SKU_TAKEN',
245
+ message: 'A variant needs a SKU.',
246
+ hint: 'The SKU is what an order line keeps after the product is gone. It cannot be empty.',
247
+ });
248
+ }
249
+ if (await skuTaken(sku)) {
250
+ throw new CogentaError({
251
+ code: 'COMMERCE_SKU_TAKEN',
252
+ message: `The SKU "${sku}" is already used by another variant.`,
253
+ hint: 'A SKU identifies one sellable thing. Pick another, or edit the existing variant.',
254
+ });
255
+ }
256
+ const id = newId(now);
257
+ const at = stamp();
258
+ const onHand = input.onHand ?? 0;
259
+ if (!Number.isInteger(onHand) || onHand < 0) {
260
+ throw new CogentaError({
261
+ code: 'COMMERCE_QUANTITY_INVALID',
262
+ message: `Stock must be a whole number of units, got ${String(onHand)}.`,
263
+ hint: 'Use allowBackorder if this variant should sell past zero.',
264
+ });
265
+ }
266
+ await db.query(sql `
267
+ insert into ${variants} (id, product_id, sku, title, price_minor, currency, on_hand,
268
+ allow_backorder, weight_grams, tax_category, position, created_at, updated_at)
269
+ values (${id}, ${input.productId}, ${sku}, ${input.title},
270
+ ${assertMinor(input.priceMinor, 'A variant price')}, ${assertCurrency(input.currency)},
271
+ ${onHand}, ${fromBool(input.allowBackorder ?? false, d)},
272
+ ${input.weightGrams ?? 0}, ${input.taxCategory ?? 'standard'},
273
+ ${input.position ?? 0}, ${at}, ${at})`);
274
+ return loadVariant(id);
275
+ },
276
+ readVariant: async (id) => {
277
+ const result = await db.query(sql `select * from ${variants} where id = ${id}`);
278
+ const row = result.rows[0];
279
+ return row === undefined ? null : decodeVariant(row);
280
+ },
281
+ readVariantBySku: async (sku) => {
282
+ const result = await db.query(sql `select * from ${variants} where sku = ${sku}`);
283
+ const row = result.rows[0];
284
+ return row === undefined ? null : decodeVariant(row);
285
+ },
286
+ updateVariant: async (id, input) => {
287
+ const current = await loadVariant(id);
288
+ const sku = input.sku === undefined ? current.sku : input.sku.trim();
289
+ if (sku !== current.sku && (await skuTaken(sku, id))) {
290
+ throw new CogentaError({
291
+ code: 'COMMERCE_SKU_TAKEN',
292
+ message: `The SKU "${sku}" is already used by another variant.`,
293
+ hint: 'A SKU identifies one sellable thing. Pick another.',
294
+ });
295
+ }
296
+ // Stock is deliberately absent from this method. Setting it as one field
297
+ // among many is how a concurrent sale gets overwritten by a form that
298
+ // was rendered a minute ago; setStock/restock/takeStock say what they do.
299
+ await db.query(sql `
300
+ update ${variants}
301
+ set sku = ${sku},
302
+ title = ${input.title ?? current.title},
303
+ price_minor = ${assertMinor(input.priceMinor ?? current.priceMinor, 'A variant price')},
304
+ currency = ${assertCurrency(input.currency ?? current.currency)},
305
+ allow_backorder = ${fromBool(input.allowBackorder ?? current.allowBackorder, d)},
306
+ weight_grams = ${input.weightGrams ?? current.weightGrams},
307
+ tax_category = ${input.taxCategory ?? current.taxCategory},
308
+ position = ${input.position ?? current.position},
309
+ updated_at = ${stamp()}
310
+ where id = ${id}`);
311
+ return loadVariant(id);
312
+ },
313
+ deleteVariant: async (id) => {
314
+ await db.query(sql `delete from ${variants} where id = ${id}`);
315
+ },
316
+ listVariants: async (productId) => {
317
+ const result = await db.query(sql `select * from ${variants} where product_id = ${productId} order by position asc, created_at asc, id asc`);
318
+ return result.rows.map(decodeVariant);
319
+ },
320
+ setStock: async (variantId, onHand) => {
321
+ if (!Number.isInteger(onHand) || onHand < 0) {
322
+ throw new CogentaError({
323
+ code: 'COMMERCE_QUANTITY_INVALID',
324
+ message: `Stock must be a whole number of units, got ${String(onHand)}.`,
325
+ hint: 'A stock take sets what is on the shelf. It is never negative.',
326
+ });
327
+ }
328
+ await loadVariant(variantId);
329
+ await db.query(sql `update ${variants} set on_hand = ${onHand}, updated_at = ${stamp()} where id = ${variantId}`);
330
+ return loadVariant(variantId);
331
+ },
332
+ restock: async (requests, tx) => {
333
+ const wanted = coalesce(requests);
334
+ if (wanted.length === 0)
335
+ return;
336
+ const run = async (executor) => {
337
+ for (const request of [...wanted].sort((a, b) => a.variantId.localeCompare(b.variantId))) {
338
+ await executor.query(sql `update ${variants} set on_hand = on_hand + ${request.quantity}, updated_at = ${stamp()} where id = ${request.variantId}`);
339
+ }
340
+ };
341
+ if (tx === undefined)
342
+ await db.transaction(run, { immediate: true });
343
+ else
344
+ await run(tx);
345
+ },
346
+ takeStock,
347
+ };
348
+ }
349
+ /** Internal. Rolls a partial reservation back by unwinding the transaction. */
350
+ class StockShortfallSignal extends Error {
351
+ shortfalls;
352
+ constructor(shortfalls) {
353
+ super('stock shortfall');
354
+ this.name = 'StockShortfallSignal';
355
+ this.shortfalls = shortfalls;
356
+ }
357
+ }
358
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/catalog/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ /** A product is either sellable or it is not. There is no draft: the draft of
2
+ * a product is its content entry (contract A), which has a real editorial
3
+ * workflow. The commercial record only has to say whether it can be bought. */
4
+ export declare const PRODUCT_STATUSES: readonly ['active', 'archived'];
5
+ export type ProductStatus = (typeof PRODUCT_STATUSES)[number];
6
+ /**
7
+ * The link to the editorial face of a product.
8
+ *
9
+ * Optional in both directions (ADR draft 0023): a product with no entry sells
10
+ * perfectly well from a back office, and a content entry with no product is
11
+ * just a page. Not a foreign key — the entries table belongs to contract A's
12
+ * migration engine and is named after a collection this package cannot know.
13
+ */
14
+ export interface ContentRef {
15
+ readonly collection: string;
16
+ readonly entryId: string;
17
+ }
18
+ export interface Product {
19
+ readonly id: string;
20
+ readonly handle: string;
21
+ /** A fallback name for admin lists and order lines. The *displayed* title of
22
+ * a product with a content entry comes from that entry. */
23
+ readonly title: string;
24
+ readonly status: ProductStatus;
25
+ readonly contentRef: ContentRef | null;
26
+ readonly createdAt: string;
27
+ readonly updatedAt: string;
28
+ }
29
+ export interface Variant {
30
+ readonly id: string;
31
+ readonly productId: string;
32
+ readonly sku: string;
33
+ readonly title: string;
34
+ readonly priceMinor: number;
35
+ readonly currency: string;
36
+ readonly onHand: number;
37
+ readonly allowBackorder: boolean;
38
+ readonly weightGrams: number;
39
+ /** Names a tax category, matched by the tax rules. `standard` by default. */
40
+ readonly taxCategory: string;
41
+ readonly position: number;
42
+ readonly createdAt: string;
43
+ readonly updatedAt: string;
44
+ }
45
+ export interface CreateProductInput {
46
+ readonly handle: string;
47
+ readonly title: string;
48
+ readonly status?: ProductStatus;
49
+ readonly contentRef?: ContentRef | null;
50
+ }
51
+ export interface UpdateProductInput {
52
+ readonly handle?: string;
53
+ readonly title?: string;
54
+ readonly status?: ProductStatus;
55
+ readonly contentRef?: ContentRef | null;
56
+ }
57
+ export interface CreateVariantInput {
58
+ readonly productId: string;
59
+ readonly sku: string;
60
+ readonly title: string;
61
+ readonly priceMinor: number;
62
+ readonly currency: string;
63
+ readonly onHand?: number;
64
+ readonly allowBackorder?: boolean;
65
+ readonly weightGrams?: number;
66
+ readonly taxCategory?: string;
67
+ readonly position?: number;
68
+ }
69
+ export interface UpdateVariantInput {
70
+ readonly sku?: string;
71
+ readonly title?: string;
72
+ readonly priceMinor?: number;
73
+ readonly currency?: string;
74
+ readonly allowBackorder?: boolean;
75
+ readonly weightGrams?: number;
76
+ readonly taxCategory?: string;
77
+ readonly position?: number;
78
+ }
79
+ /** What one reservation asked for. */
80
+ export interface StockRequest {
81
+ readonly variantId: string;
82
+ readonly quantity: number;
83
+ }
84
+ /**
85
+ * Why a stock movement failed, per variant.
86
+ *
87
+ * A list rather than a single failure: a basket of five lines where two are
88
+ * short must tell the shopper about both, not make them retry five times.
89
+ */
90
+ export interface StockShortfall {
91
+ readonly variantId: string;
92
+ readonly requested: number;
93
+ readonly available: number;
94
+ }
95
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/catalog/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /** A product is either sellable or it is not. There is no draft: the draft of
2
+ * a product is its content entry (contract A), which has a real editorial
3
+ * workflow. The commercial record only has to say whether it can be bought. */
4
+ export const PRODUCT_STATUSES = ['active', 'archived'];
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/catalog/types.ts"],"names":[],"mappings":"AAAA;;+EAE+E;AAC/E,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAU,CAAA"}
@@ -0,0 +1,103 @@
1
+ import { type DatabaseHandle, type SqlExecutor } from '@cogenta/core';
2
+ /**
3
+ * Three kinds, and no more.
4
+ *
5
+ * "Buy two get one free", tiered discounts and per-collection promotions all
6
+ * belong to a rules engine, and a rules engine is exactly what a shop does not
7
+ * need on day one. These three cover the overwhelming majority of real
8
+ * coupons, and each has an unambiguous arithmetic — which matters more here
9
+ * than range, because a discount that is a percent of something ambiguous is a
10
+ * dispute with a customer.
11
+ */
12
+ export declare const COUPON_KINDS: readonly ['percentage', 'fixed', 'free_shipping'];
13
+ export type CouponKind = (typeof COUPON_KINDS)[number];
14
+ export interface Coupon {
15
+ readonly code: string;
16
+ readonly kind: CouponKind;
17
+ /** Basis points for `percentage`, minor units for `fixed`, ignored otherwise. */
18
+ readonly value: number;
19
+ readonly currency: string | null;
20
+ readonly minSubtotalMinor: number;
21
+ readonly startsAt: string | null;
22
+ readonly endsAt: string | null;
23
+ /** Null is unlimited. Zero is exhausted — never a synonym for unlimited. */
24
+ readonly maxRedemptions: number | null;
25
+ readonly redemptions: number;
26
+ readonly active: boolean;
27
+ readonly createdAt: string;
28
+ }
29
+ export interface CreateCouponInput {
30
+ readonly code: string;
31
+ readonly kind: CouponKind;
32
+ readonly value?: number;
33
+ readonly currency?: string | null;
34
+ readonly minSubtotalMinor?: number;
35
+ readonly startsAt?: string | null;
36
+ readonly endsAt?: string | null;
37
+ readonly maxRedemptions?: number | null;
38
+ readonly active?: boolean;
39
+ }
40
+ /**
41
+ * Why a coupon did not apply — as a case, not a boolean.
42
+ *
43
+ * "This code has expired" and "this code needs a £30 basket" send a shopper to
44
+ * completely different next steps, and a checkout that says only "invalid
45
+ * code" for both is the reason people abandon baskets.
46
+ */
47
+ export type CouponCheck = {
48
+ readonly kind: 'ok';
49
+ readonly coupon: Coupon;
50
+ } | {
51
+ readonly kind: 'unknown';
52
+ } | {
53
+ readonly kind: 'inactive';
54
+ } | {
55
+ readonly kind: 'not_yet';
56
+ readonly startsAt: string;
57
+ } | {
58
+ readonly kind: 'expired';
59
+ readonly endsAt: string;
60
+ } | {
61
+ readonly kind: 'exhausted';
62
+ } | {
63
+ readonly kind: 'below_minimum';
64
+ readonly minSubtotalMinor: number;
65
+ } | {
66
+ readonly kind: 'wrong_currency';
67
+ readonly currency: string;
68
+ };
69
+ export interface CouponStore {
70
+ create(input: CreateCouponInput): Promise<Coupon>;
71
+ read(code: string): Promise<Coupon | null>;
72
+ deactivate(code: string): Promise<void>;
73
+ list(): Promise<readonly Coupon[]>;
74
+ /** Checks without consuming. Safe to call on every cart recalculation. */
75
+ check(code: string, subtotalMinor: number, currency: string): Promise<CouponCheck>;
76
+ /**
77
+ * Consumes one redemption for an order, atomically.
78
+ *
79
+ * The count is claimed with `update … set redemptions = redemptions + 1
80
+ * where code = ? and (max_redemptions is null or redemptions < max)`, and
81
+ * `rowsAffected` decides. Two shoppers spending the last redemption of a
82
+ * one-shot code at the same instant get one success and one refusal, not two
83
+ * discounts — the same guard shape as stock, for the same reason.
84
+ */
85
+ redeem(code: string, orderId: string, customerId: string | null, tx?: SqlExecutor): Promise<boolean>;
86
+ /** Gives a redemption back when an order is cancelled before payment. */
87
+ release(orderId: string, tx?: SqlExecutor): Promise<void>;
88
+ }
89
+ /** Upper case, trimmed. A coupon typed in lower case is the same coupon. */
90
+ export declare function normaliseCode(code: string): string;
91
+ export declare function createCouponStore(db: DatabaseHandle, now?: () => number): CouponStore;
92
+ /**
93
+ * What a coupon takes off a subtotal, and whether it makes shipping free.
94
+ *
95
+ * Never more than the subtotal: a £20 coupon on a £15 basket takes £15, not
96
+ * £20, because the alternative is an order with a negative total — and a
97
+ * negative total in a payment request is a refund a shop did not intend.
98
+ */
99
+ export declare function discountFor(coupon: Coupon, subtotalMinor: number): {
100
+ readonly discountMinor: number;
101
+ readonly freeShipping: boolean;
102
+ };
103
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/coupon/store.ts"],"names":[],"mappings":"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"}