@open-mercato/core 0.8.1-develop.7228.1.b7ea09d2d3 → 0.8.1-develop.7237.1.635faf2c7a
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/.turbo/turbo-build.log +2 -2
- package/dist/generated/entities/availability_policy/index.js +41 -0
- package/dist/generated/entities/availability_policy/index.js.map +7 -0
- package/dist/generated/entities.ids.generated.js +4 -0
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +21 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/modules/attachments/data/entities.js +3 -3
- package/dist/modules/attachments/data/entities.js.map +2 -2
- package/dist/modules/availability/acl.js +16 -0
- package/dist/modules/availability/acl.js.map +7 -0
- package/dist/modules/availability/api/check/route.js +95 -0
- package/dist/modules/availability/api/check/route.js.map +7 -0
- package/dist/modules/availability/api/openapi.js +27 -0
- package/dist/modules/availability/api/openapi.js.map +7 -0
- package/dist/modules/availability/api/policies/resolve-preview/route.js +58 -0
- package/dist/modules/availability/api/policies/resolve-preview/route.js.map +7 -0
- package/dist/modules/availability/api/policies/route.js +188 -0
- package/dist/modules/availability/api/policies/route.js.map +7 -0
- package/dist/modules/availability/backend/availability/check/page.js +185 -0
- package/dist/modules/availability/backend/availability/check/page.js.map +7 -0
- package/dist/modules/availability/backend/availability/check/page.meta.js +16 -0
- package/dist/modules/availability/backend/availability/check/page.meta.js.map +7 -0
- package/dist/modules/availability/backend/availability/policies/ResolutionPreviewPanel.js +79 -0
- package/dist/modules/availability/backend/availability/policies/ResolutionPreviewPanel.js.map +7 -0
- package/dist/modules/availability/backend/availability/policies/ScopeFields.js +53 -0
- package/dist/modules/availability/backend/availability/policies/ScopeFields.js.map +7 -0
- package/dist/modules/availability/backend/availability/policies/[id]/page.js +152 -0
- package/dist/modules/availability/backend/availability/policies/[id]/page.js.map +7 -0
- package/dist/modules/availability/backend/availability/policies/[id]/page.meta.js +12 -0
- package/dist/modules/availability/backend/availability/policies/[id]/page.meta.js.map +7 -0
- package/dist/modules/availability/backend/availability/policies/create/page.js +94 -0
- package/dist/modules/availability/backend/availability/policies/create/page.js.map +7 -0
- package/dist/modules/availability/backend/availability/policies/create/page.meta.js +12 -0
- package/dist/modules/availability/backend/availability/policies/create/page.meta.js.map +7 -0
- package/dist/modules/availability/backend/availability/policies/formGroups.js +75 -0
- package/dist/modules/availability/backend/availability/policies/formGroups.js.map +7 -0
- package/dist/modules/availability/backend/availability/policies/page.js +176 -0
- package/dist/modules/availability/backend/availability/policies/page.js.map +7 -0
- package/dist/modules/availability/backend/availability/policies/page.meta.js +16 -0
- package/dist/modules/availability/backend/availability/policies/page.meta.js.map +7 -0
- package/dist/modules/availability/commands/policies.js +312 -0
- package/dist/modules/availability/commands/policies.js.map +7 -0
- package/dist/modules/availability/commands/scope.js +19 -0
- package/dist/modules/availability/commands/scope.js.map +7 -0
- package/dist/modules/availability/data/entities.js +95 -0
- package/dist/modules/availability/data/entities.js.map +7 -0
- package/dist/modules/availability/data/validators.js +53 -0
- package/dist/modules/availability/data/validators.js.map +7 -0
- package/dist/modules/availability/di.js +41 -0
- package/dist/modules/availability/di.js.map +7 -0
- package/dist/modules/availability/events.js +18 -0
- package/dist/modules/availability/events.js.map +7 -0
- package/dist/modules/availability/index.js +15 -0
- package/dist/modules/availability/index.js.map +7 -0
- package/dist/modules/availability/lib/policyResolution.js +155 -0
- package/dist/modules/availability/lib/policyResolution.js.map +7 -0
- package/dist/modules/availability/lib/tryResolve.js +11 -0
- package/dist/modules/availability/lib/tryResolve.js.map +7 -0
- package/dist/modules/availability/migrations/Migration20260922095844_availability.js +16 -0
- package/dist/modules/availability/migrations/Migration20260922095844_availability.js.map +7 -0
- package/dist/modules/availability/setup.js +12 -0
- package/dist/modules/availability/setup.js.map +7 -0
- package/dist/modules/entities/cli.js +33 -12
- package/dist/modules/entities/cli.js.map +2 -2
- package/dist/modules/inbox_ops/api/settings/route.js +7 -32
- package/dist/modules/inbox_ops/api/settings/route.js.map +2 -2
- package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js +2 -2
- package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js.map +2 -2
- package/dist/modules/inbox_ops/components/proposals/ActionCard.js +1 -1
- package/dist/modules/inbox_ops/components/proposals/ActionCard.js.map +2 -2
- package/dist/modules/inbox_ops/lib/ensure-settings.js +47 -0
- package/dist/modules/inbox_ops/lib/ensure-settings.js.map +7 -0
- package/dist/modules/inbox_ops/lib/executionEngine.js.map +1 -1
- package/dist/modules/inbox_ops/lib/executionHelpers.js +0 -23
- package/dist/modules/inbox_ops/lib/executionHelpers.js.map +2 -2
- package/dist/modules/inbox_ops/lib/payloadEnrichment.js +0 -3
- package/dist/modules/inbox_ops/lib/payloadEnrichment.js.map +2 -2
- package/dist/modules/inbox_ops/setup.js +2 -21
- package/dist/modules/inbox_ops/setup.js.map +2 -2
- package/dist/modules/inbox_ops/subscribers/extractionWorker.js.map +1 -1
- package/dist/modules/sales/data/entities.js +3 -1
- package/dist/modules/sales/data/entities.js.map +2 -2
- package/dist/modules/sales/inbox-actions.js +0 -12
- package/dist/modules/sales/inbox-actions.js.map +2 -2
- package/dist/modules/sales/migrations/Migration20260916120000_sales_payment_allocation_order_idx.js +20 -0
- package/dist/modules/sales/migrations/Migration20260916120000_sales_payment_allocation_order_idx.js.map +7 -0
- package/dist/modules/wms/di.js +3 -0
- package/dist/modules/wms/di.js.map +2 -2
- package/dist/modules/wms/lib/availabilityCache.js +85 -0
- package/dist/modules/wms/lib/availabilityCache.js.map +7 -0
- package/dist/modules/wms/lib/availabilityCalculation.js +178 -0
- package/dist/modules/wms/lib/availabilityCalculation.js.map +7 -0
- package/dist/modules/wms/lib/availabilityProvider.js +14 -0
- package/dist/modules/wms/lib/availabilityProvider.js.map +7 -0
- package/dist/modules/wms/lib/sqlInClause.js +9 -0
- package/dist/modules/wms/lib/sqlInClause.js.map +7 -0
- package/dist/modules/wms/lib/tryResolve.js +11 -0
- package/dist/modules/wms/lib/tryResolve.js.map +7 -0
- package/dist/modules/wms/subscribers/invalidate-availability-cache.js +16 -0
- package/dist/modules/wms/subscribers/invalidate-availability-cache.js.map +7 -0
- package/generated/entities/availability_policy/index.ts +19 -0
- package/generated/entities.ids.generated.ts +4 -0
- package/generated/entity-fields-registry.ts +21 -0
- package/package.json +7 -7
- package/src/modules/attachments/data/entities.ts +5 -3
- package/src/modules/auth/i18n/de.json +3 -0
- package/src/modules/auth/i18n/en.json +3 -0
- package/src/modules/auth/i18n/es.json +3 -0
- package/src/modules/auth/i18n/ko.json +3 -0
- package/src/modules/auth/i18n/pl.json +3 -0
- package/src/modules/availability/acl.ts +12 -0
- package/src/modules/availability/api/check/route.ts +114 -0
- package/src/modules/availability/api/openapi.ts +28 -0
- package/src/modules/availability/api/policies/resolve-preview/route.ts +67 -0
- package/src/modules/availability/api/policies/route.ts +224 -0
- package/src/modules/availability/backend/availability/check/page.meta.ts +12 -0
- package/src/modules/availability/backend/availability/check/page.tsx +223 -0
- package/src/modules/availability/backend/availability/policies/ResolutionPreviewPanel.tsx +106 -0
- package/src/modules/availability/backend/availability/policies/ScopeFields.tsx +55 -0
- package/src/modules/availability/backend/availability/policies/[id]/page.meta.ts +8 -0
- package/src/modules/availability/backend/availability/policies/[id]/page.tsx +182 -0
- package/src/modules/availability/backend/availability/policies/create/page.meta.ts +8 -0
- package/src/modules/availability/backend/availability/policies/create/page.tsx +105 -0
- package/src/modules/availability/backend/availability/policies/formGroups.ts +77 -0
- package/src/modules/availability/backend/availability/policies/page.meta.ts +12 -0
- package/src/modules/availability/backend/availability/policies/page.tsx +196 -0
- package/src/modules/availability/commands/policies.ts +358 -0
- package/src/modules/availability/commands/scope.ts +26 -0
- package/src/modules/availability/data/entities.ts +92 -0
- package/src/modules/availability/data/validators.ts +70 -0
- package/src/modules/availability/di.ts +54 -0
- package/src/modules/availability/events.ts +17 -0
- package/src/modules/availability/i18n/de.json +81 -0
- package/src/modules/availability/i18n/en.json +81 -0
- package/src/modules/availability/i18n/es.json +81 -0
- package/src/modules/availability/i18n/ko.json +81 -0
- package/src/modules/availability/i18n/pl.json +81 -0
- package/src/modules/availability/index.ts +13 -0
- package/src/modules/availability/lib/policyResolution.ts +264 -0
- package/src/modules/availability/lib/tryResolve.ts +8 -0
- package/src/modules/availability/migrations/.snapshot-open-mercato.json +375 -0
- package/src/modules/availability/migrations/Migration20260922095844_availability.ts +13 -0
- package/src/modules/availability/setup.ts +10 -0
- package/src/modules/entities/cli.ts +53 -13
- package/src/modules/inbox_ops/api/settings/route.ts +9 -32
- package/src/modules/inbox_ops/backend/inbox-ops/settings/page.tsx +2 -2
- package/src/modules/inbox_ops/components/proposals/ActionCard.tsx +1 -1
- package/src/modules/inbox_ops/i18n/de.json +1 -1
- package/src/modules/inbox_ops/i18n/en.json +1 -1
- package/src/modules/inbox_ops/i18n/es.json +1 -1
- package/src/modules/inbox_ops/i18n/ko.json +1 -1
- package/src/modules/inbox_ops/i18n/pl.json +1 -1
- package/src/modules/inbox_ops/lib/ensure-settings.ts +77 -0
- package/src/modules/inbox_ops/lib/executionEngine.ts +1 -1
- package/src/modules/inbox_ops/lib/executionHelpers.ts +0 -27
- package/src/modules/inbox_ops/lib/payloadEnrichment.ts +1 -5
- package/src/modules/inbox_ops/setup.ts +2 -21
- package/src/modules/inbox_ops/subscribers/extractionWorker.ts +1 -1
- package/src/modules/sales/data/entities.ts +2 -0
- package/src/modules/sales/inbox-actions.ts +0 -20
- package/src/modules/sales/migrations/.snapshot-open-mercato.json +20 -0
- package/src/modules/sales/migrations/Migration20260916120000_sales_payment_allocation_order_idx.ts +74 -0
- package/src/modules/wms/di.ts +6 -0
- package/src/modules/wms/lib/availabilityCache.ts +136 -0
- package/src/modules/wms/lib/availabilityCalculation.ts +289 -0
- package/src/modules/wms/lib/availabilityProvider.ts +29 -0
- package/src/modules/wms/lib/sqlInClause.ts +21 -0
- package/src/modules/wms/lib/tryResolve.ts +8 -0
- package/src/modules/wms/subscribers/invalidate-availability-cache.ts +30 -0
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import { registerCommand } from "@open-mercato/shared/lib/commands";
|
|
2
|
+
import { requireId } from "@open-mercato/shared/lib/commands/helpers";
|
|
3
|
+
import { extractUndoPayload } from "@open-mercato/shared/lib/commands/undo";
|
|
4
|
+
import { runCrudCommandWrite } from "@open-mercato/shared/lib/commands/runCrudCommandWrite";
|
|
5
|
+
import { CrudHttpError, conflict, isUniqueViolation } from "@open-mercato/shared/lib/crud/errors";
|
|
6
|
+
import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
|
|
7
|
+
import { E } from "../../../generated/entities.ids.generated.js";
|
|
8
|
+
import { AvailabilityPolicy } from "../data/entities.js";
|
|
9
|
+
import {
|
|
10
|
+
availabilityPolicyCreateSchema,
|
|
11
|
+
availabilityPolicyUpdateSchema,
|
|
12
|
+
availabilityPolicyDeleteSchema,
|
|
13
|
+
availabilityPolicyMergedConstraintsSchema
|
|
14
|
+
} from "../data/validators.js";
|
|
15
|
+
import { buildAvailabilityPolicyCommandWhere, ensureAvailabilityPolicyCommandScope } from "./scope.js";
|
|
16
|
+
const AVAILABILITY_POLICY_ENTITY_ID = E.availability.availability_policy;
|
|
17
|
+
const policyCrudEvents = {
|
|
18
|
+
module: "availability",
|
|
19
|
+
entity: "policy",
|
|
20
|
+
persistent: true,
|
|
21
|
+
buildPayload: (ctx) => ({
|
|
22
|
+
id: ctx.identifiers.id,
|
|
23
|
+
organizationId: ctx.identifiers.organizationId,
|
|
24
|
+
tenantId: ctx.identifiers.tenantId
|
|
25
|
+
})
|
|
26
|
+
};
|
|
27
|
+
function toSnapshot(record) {
|
|
28
|
+
return {
|
|
29
|
+
id: record.id,
|
|
30
|
+
organizationId: record.organizationId,
|
|
31
|
+
tenantId: record.tenantId,
|
|
32
|
+
storeId: record.storeId ?? null,
|
|
33
|
+
productId: record.productId ?? null,
|
|
34
|
+
variantId: record.variantId ?? null,
|
|
35
|
+
isStockManaged: !!record.isStockManaged,
|
|
36
|
+
allowBackorder: !!record.allowBackorder,
|
|
37
|
+
backorderLeadTimeDays: record.backorderLeadTimeDays ?? null,
|
|
38
|
+
preorderReleaseAt: record.preorderReleaseAt ? record.preorderReleaseAt.toISOString() : null,
|
|
39
|
+
lowStockThreshold: record.lowStockThreshold ?? null,
|
|
40
|
+
minOrderQuantity: record.minOrderQuantity ?? null,
|
|
41
|
+
maxOrderQuantity: record.maxOrderQuantity ?? null,
|
|
42
|
+
quantityIncrement: record.quantityIncrement ?? null,
|
|
43
|
+
hideWhenOutOfStock: !!record.hideWhenOutOfStock,
|
|
44
|
+
isActive: !!record.isActive,
|
|
45
|
+
createdAt: record.createdAt.toISOString(),
|
|
46
|
+
updatedAt: record.updatedAt.toISOString()
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
async function loadSnapshot(em, id, ctx) {
|
|
50
|
+
const record = await em.findOne(AvailabilityPolicy, buildAvailabilityPolicyCommandWhere(ctx, { id }));
|
|
51
|
+
if (!record) return null;
|
|
52
|
+
ensureAvailabilityPolicyCommandScope(ctx, record);
|
|
53
|
+
return toSnapshot(record);
|
|
54
|
+
}
|
|
55
|
+
function applyUndoSnapshot(record, snapshot) {
|
|
56
|
+
record.storeId = snapshot.storeId;
|
|
57
|
+
record.productId = snapshot.productId;
|
|
58
|
+
record.variantId = snapshot.variantId;
|
|
59
|
+
record.isStockManaged = snapshot.isStockManaged;
|
|
60
|
+
record.allowBackorder = snapshot.allowBackorder;
|
|
61
|
+
record.backorderLeadTimeDays = snapshot.backorderLeadTimeDays;
|
|
62
|
+
record.preorderReleaseAt = snapshot.preorderReleaseAt ? new Date(snapshot.preorderReleaseAt) : null;
|
|
63
|
+
record.lowStockThreshold = snapshot.lowStockThreshold;
|
|
64
|
+
record.minOrderQuantity = snapshot.minOrderQuantity;
|
|
65
|
+
record.maxOrderQuantity = snapshot.maxOrderQuantity;
|
|
66
|
+
record.quantityIncrement = snapshot.quantityIncrement;
|
|
67
|
+
record.hideWhenOutOfStock = snapshot.hideWhenOutOfStock;
|
|
68
|
+
record.isActive = snapshot.isActive;
|
|
69
|
+
record.updatedAt = /* @__PURE__ */ new Date();
|
|
70
|
+
}
|
|
71
|
+
const createPolicyCommand = {
|
|
72
|
+
id: "availability.policies.create",
|
|
73
|
+
async execute(input, ctx) {
|
|
74
|
+
const parsed = availabilityPolicyCreateSchema.parse(input);
|
|
75
|
+
ensureAvailabilityPolicyCommandScope(ctx, parsed);
|
|
76
|
+
const record = new AvailabilityPolicy();
|
|
77
|
+
record.organizationId = parsed.organizationId;
|
|
78
|
+
record.tenantId = parsed.tenantId;
|
|
79
|
+
record.storeId = parsed.storeId ?? null;
|
|
80
|
+
record.productId = parsed.productId ?? null;
|
|
81
|
+
record.variantId = parsed.variantId ?? null;
|
|
82
|
+
record.isStockManaged = parsed.isStockManaged ?? false;
|
|
83
|
+
record.allowBackorder = parsed.allowBackorder ?? false;
|
|
84
|
+
record.backorderLeadTimeDays = parsed.backorderLeadTimeDays ?? null;
|
|
85
|
+
record.preorderReleaseAt = parsed.preorderReleaseAt ?? null;
|
|
86
|
+
record.lowStockThreshold = parsed.lowStockThreshold ?? null;
|
|
87
|
+
record.minOrderQuantity = parsed.minOrderQuantity ?? null;
|
|
88
|
+
record.maxOrderQuantity = parsed.maxOrderQuantity ?? null;
|
|
89
|
+
record.quantityIncrement = parsed.quantityIncrement ?? null;
|
|
90
|
+
record.hideWhenOutOfStock = parsed.hideWhenOutOfStock ?? false;
|
|
91
|
+
record.isActive = parsed.isActive ?? true;
|
|
92
|
+
try {
|
|
93
|
+
await runCrudCommandWrite({
|
|
94
|
+
ctx,
|
|
95
|
+
entityId: AVAILABILITY_POLICY_ENTITY_ID,
|
|
96
|
+
action: "created",
|
|
97
|
+
scope: { tenantId: record.tenantId, organizationId: record.organizationId },
|
|
98
|
+
events: policyCrudEvents,
|
|
99
|
+
sideEffect: () => ({
|
|
100
|
+
entity: record,
|
|
101
|
+
identifiers: { id: record.id, organizationId: record.organizationId, tenantId: record.tenantId }
|
|
102
|
+
}),
|
|
103
|
+
phases: [({ em }) => {
|
|
104
|
+
em.persist(record);
|
|
105
|
+
}]
|
|
106
|
+
});
|
|
107
|
+
} catch (err) {
|
|
108
|
+
if (isUniqueViolation(err, "availability_policies_scope_target_unique")) {
|
|
109
|
+
const { translate } = await resolveTranslations();
|
|
110
|
+
throw conflict(translate("availability.policies.errors.duplicateTarget", "A policy already exists for this store/product/variant combination."));
|
|
111
|
+
}
|
|
112
|
+
throw err;
|
|
113
|
+
}
|
|
114
|
+
return { policyId: record.id };
|
|
115
|
+
},
|
|
116
|
+
captureAfter: async (_input, result, ctx) => {
|
|
117
|
+
const em = ctx.container.resolve("em").fork();
|
|
118
|
+
return loadSnapshot(em, result.policyId, ctx);
|
|
119
|
+
},
|
|
120
|
+
buildLog: async ({ snapshots }) => {
|
|
121
|
+
const after = snapshots.after;
|
|
122
|
+
if (!after) return null;
|
|
123
|
+
const { translate } = await resolveTranslations();
|
|
124
|
+
return {
|
|
125
|
+
actionLabel: translate("availability.audit.create", "Create availability policy"),
|
|
126
|
+
resourceKind: "availability.policy",
|
|
127
|
+
resourceId: after.id,
|
|
128
|
+
tenantId: after.tenantId,
|
|
129
|
+
organizationId: after.organizationId,
|
|
130
|
+
snapshotAfter: after,
|
|
131
|
+
payload: { undo: { after } }
|
|
132
|
+
};
|
|
133
|
+
},
|
|
134
|
+
undo: async ({ logEntry, ctx }) => {
|
|
135
|
+
const payload = extractUndoPayload(logEntry);
|
|
136
|
+
const after = payload?.after ?? null;
|
|
137
|
+
if (!after) return;
|
|
138
|
+
const em = ctx.container.resolve("em").fork();
|
|
139
|
+
const record = await em.findOne(AvailabilityPolicy, { id: after.id });
|
|
140
|
+
if (!record) return;
|
|
141
|
+
record.deletedAt = /* @__PURE__ */ new Date();
|
|
142
|
+
await em.flush();
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
const updatePolicyCommand = {
|
|
146
|
+
id: "availability.policies.update",
|
|
147
|
+
async prepare(input, ctx) {
|
|
148
|
+
requireId(input.id, "Availability policy ID is required");
|
|
149
|
+
const em = ctx.container.resolve("em");
|
|
150
|
+
const before = await loadSnapshot(em, input.id, ctx);
|
|
151
|
+
return { before };
|
|
152
|
+
},
|
|
153
|
+
async execute(input, ctx) {
|
|
154
|
+
const parsed = availabilityPolicyUpdateSchema.parse(input);
|
|
155
|
+
requireId(parsed.id, "Availability policy ID is required");
|
|
156
|
+
const em = ctx.container.resolve("em").fork();
|
|
157
|
+
const record = await em.findOne(AvailabilityPolicy, buildAvailabilityPolicyCommandWhere(ctx, { id: parsed.id }));
|
|
158
|
+
if (!record) throw new CrudHttpError(404, { error: "Availability policy not found" });
|
|
159
|
+
ensureAvailabilityPolicyCommandScope(ctx, record);
|
|
160
|
+
const merged = {
|
|
161
|
+
storeId: parsed.storeId !== void 0 ? parsed.storeId : record.storeId,
|
|
162
|
+
productId: parsed.productId !== void 0 ? parsed.productId : record.productId,
|
|
163
|
+
variantId: parsed.variantId !== void 0 ? parsed.variantId : record.variantId,
|
|
164
|
+
isStockManaged: parsed.isStockManaged !== void 0 ? parsed.isStockManaged : record.isStockManaged,
|
|
165
|
+
allowBackorder: parsed.allowBackorder !== void 0 ? parsed.allowBackorder : record.allowBackorder,
|
|
166
|
+
backorderLeadTimeDays: parsed.backorderLeadTimeDays !== void 0 ? parsed.backorderLeadTimeDays : record.backorderLeadTimeDays,
|
|
167
|
+
minOrderQuantity: parsed.minOrderQuantity !== void 0 ? parsed.minOrderQuantity : record.minOrderQuantity,
|
|
168
|
+
maxOrderQuantity: parsed.maxOrderQuantity !== void 0 ? parsed.maxOrderQuantity : record.maxOrderQuantity
|
|
169
|
+
};
|
|
170
|
+
availabilityPolicyMergedConstraintsSchema.parse(merged);
|
|
171
|
+
try {
|
|
172
|
+
await runCrudCommandWrite({
|
|
173
|
+
ctx,
|
|
174
|
+
em,
|
|
175
|
+
entityId: AVAILABILITY_POLICY_ENTITY_ID,
|
|
176
|
+
action: "updated",
|
|
177
|
+
scope: { tenantId: record.tenantId, organizationId: record.organizationId },
|
|
178
|
+
events: policyCrudEvents,
|
|
179
|
+
sideEffect: () => ({
|
|
180
|
+
entity: record,
|
|
181
|
+
identifiers: { id: record.id, organizationId: record.organizationId, tenantId: record.tenantId }
|
|
182
|
+
}),
|
|
183
|
+
phases: [
|
|
184
|
+
({ em: forkedEm }) => {
|
|
185
|
+
const target = forkedEm.getReference(AvailabilityPolicy, record.id);
|
|
186
|
+
if (parsed.storeId !== void 0) target.storeId = parsed.storeId;
|
|
187
|
+
if (parsed.productId !== void 0) target.productId = parsed.productId;
|
|
188
|
+
if (parsed.variantId !== void 0) target.variantId = parsed.variantId;
|
|
189
|
+
if (parsed.isStockManaged !== void 0) target.isStockManaged = parsed.isStockManaged;
|
|
190
|
+
if (parsed.allowBackorder !== void 0) target.allowBackorder = parsed.allowBackorder;
|
|
191
|
+
if (parsed.backorderLeadTimeDays !== void 0) target.backorderLeadTimeDays = parsed.backorderLeadTimeDays;
|
|
192
|
+
if (parsed.preorderReleaseAt !== void 0) target.preorderReleaseAt = parsed.preorderReleaseAt;
|
|
193
|
+
if (parsed.lowStockThreshold !== void 0) target.lowStockThreshold = parsed.lowStockThreshold;
|
|
194
|
+
if (parsed.minOrderQuantity !== void 0) target.minOrderQuantity = parsed.minOrderQuantity;
|
|
195
|
+
if (parsed.maxOrderQuantity !== void 0) target.maxOrderQuantity = parsed.maxOrderQuantity;
|
|
196
|
+
if (parsed.quantityIncrement !== void 0) target.quantityIncrement = parsed.quantityIncrement;
|
|
197
|
+
if (parsed.hideWhenOutOfStock !== void 0) target.hideWhenOutOfStock = parsed.hideWhenOutOfStock;
|
|
198
|
+
if (parsed.isActive !== void 0) target.isActive = parsed.isActive;
|
|
199
|
+
target.updatedAt = /* @__PURE__ */ new Date();
|
|
200
|
+
}
|
|
201
|
+
]
|
|
202
|
+
});
|
|
203
|
+
} catch (err) {
|
|
204
|
+
if (isUniqueViolation(err, "availability_policies_scope_target_unique")) {
|
|
205
|
+
const { translate } = await resolveTranslations();
|
|
206
|
+
throw conflict(translate("availability.policies.errors.duplicateTarget", "A policy already exists for this store/product/variant combination."));
|
|
207
|
+
}
|
|
208
|
+
throw err;
|
|
209
|
+
}
|
|
210
|
+
return { policyId: record.id };
|
|
211
|
+
},
|
|
212
|
+
captureAfter: async (_input, result, ctx) => {
|
|
213
|
+
const em = ctx.container.resolve("em").fork();
|
|
214
|
+
return loadSnapshot(em, result.policyId, ctx);
|
|
215
|
+
},
|
|
216
|
+
buildLog: async ({ snapshots }) => {
|
|
217
|
+
const before = snapshots.before;
|
|
218
|
+
const after = snapshots.after;
|
|
219
|
+
if (!after) return null;
|
|
220
|
+
const { translate } = await resolveTranslations();
|
|
221
|
+
return {
|
|
222
|
+
actionLabel: translate("availability.audit.update", "Update availability policy"),
|
|
223
|
+
resourceKind: "availability.policy",
|
|
224
|
+
resourceId: after.id,
|
|
225
|
+
tenantId: after.tenantId,
|
|
226
|
+
organizationId: after.organizationId,
|
|
227
|
+
snapshotBefore: before ?? void 0,
|
|
228
|
+
snapshotAfter: after,
|
|
229
|
+
payload: { undo: { before, after } }
|
|
230
|
+
};
|
|
231
|
+
},
|
|
232
|
+
undo: async ({ logEntry, ctx }) => {
|
|
233
|
+
const payload = extractUndoPayload(logEntry);
|
|
234
|
+
const before = payload?.before ?? null;
|
|
235
|
+
if (!before) return;
|
|
236
|
+
const em = ctx.container.resolve("em").fork();
|
|
237
|
+
const record = await em.findOne(AvailabilityPolicy, { id: before.id });
|
|
238
|
+
if (!record) return;
|
|
239
|
+
applyUndoSnapshot(record, before);
|
|
240
|
+
await em.flush();
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
const deletePolicyCommand = {
|
|
244
|
+
id: "availability.policies.delete",
|
|
245
|
+
async prepare(input, ctx) {
|
|
246
|
+
requireId(input.id, "Availability policy ID is required");
|
|
247
|
+
const em = ctx.container.resolve("em");
|
|
248
|
+
const before = await loadSnapshot(em, input.id, ctx);
|
|
249
|
+
return { before };
|
|
250
|
+
},
|
|
251
|
+
async execute(input, ctx) {
|
|
252
|
+
const parsed = availabilityPolicyDeleteSchema.parse(input);
|
|
253
|
+
requireId(parsed.id, "Availability policy ID is required");
|
|
254
|
+
const em = ctx.container.resolve("em").fork();
|
|
255
|
+
const record = await em.findOne(AvailabilityPolicy, buildAvailabilityPolicyCommandWhere(ctx, { id: parsed.id }));
|
|
256
|
+
if (!record) throw new CrudHttpError(404, { error: "Availability policy not found" });
|
|
257
|
+
ensureAvailabilityPolicyCommandScope(ctx, record);
|
|
258
|
+
await runCrudCommandWrite({
|
|
259
|
+
ctx,
|
|
260
|
+
em,
|
|
261
|
+
entityId: AVAILABILITY_POLICY_ENTITY_ID,
|
|
262
|
+
action: "deleted",
|
|
263
|
+
scope: { tenantId: record.tenantId, organizationId: record.organizationId },
|
|
264
|
+
events: policyCrudEvents,
|
|
265
|
+
sideEffect: () => ({
|
|
266
|
+
entity: record,
|
|
267
|
+
identifiers: { id: record.id, organizationId: record.organizationId, tenantId: record.tenantId }
|
|
268
|
+
}),
|
|
269
|
+
phases: [
|
|
270
|
+
({ em: forkedEm }) => {
|
|
271
|
+
const target = forkedEm.getReference(AvailabilityPolicy, record.id);
|
|
272
|
+
target.deletedAt = /* @__PURE__ */ new Date();
|
|
273
|
+
}
|
|
274
|
+
]
|
|
275
|
+
});
|
|
276
|
+
return { policyId: record.id };
|
|
277
|
+
},
|
|
278
|
+
buildLog: async ({ snapshots }) => {
|
|
279
|
+
const before = snapshots.before;
|
|
280
|
+
if (!before) return null;
|
|
281
|
+
const { translate } = await resolveTranslations();
|
|
282
|
+
return {
|
|
283
|
+
actionLabel: translate("availability.audit.delete", "Delete availability policy"),
|
|
284
|
+
resourceKind: "availability.policy",
|
|
285
|
+
resourceId: before.id,
|
|
286
|
+
tenantId: before.tenantId,
|
|
287
|
+
organizationId: before.organizationId,
|
|
288
|
+
snapshotBefore: before,
|
|
289
|
+
payload: { undo: { before } }
|
|
290
|
+
};
|
|
291
|
+
},
|
|
292
|
+
undo: async ({ logEntry, ctx }) => {
|
|
293
|
+
const payload = extractUndoPayload(logEntry);
|
|
294
|
+
const before = payload?.before ?? null;
|
|
295
|
+
if (!before) return;
|
|
296
|
+
const em = ctx.container.resolve("em").fork();
|
|
297
|
+
const record = await em.findOne(AvailabilityPolicy, { id: before.id });
|
|
298
|
+
if (!record) return;
|
|
299
|
+
record.deletedAt = null;
|
|
300
|
+
record.updatedAt = /* @__PURE__ */ new Date();
|
|
301
|
+
await em.flush();
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
registerCommand(createPolicyCommand);
|
|
305
|
+
registerCommand(updatePolicyCommand);
|
|
306
|
+
registerCommand(deletePolicyCommand);
|
|
307
|
+
export {
|
|
308
|
+
createPolicyCommand,
|
|
309
|
+
deletePolicyCommand,
|
|
310
|
+
updatePolicyCommand
|
|
311
|
+
};
|
|
312
|
+
//# sourceMappingURL=policies.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/availability/commands/policies.ts"],
|
|
4
|
+
"sourcesContent": ["import { registerCommand } from '@open-mercato/shared/lib/commands'\nimport type { CommandHandler, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport { requireId } from '@open-mercato/shared/lib/commands/helpers'\nimport { extractUndoPayload, type UndoPayload } from '@open-mercato/shared/lib/commands/undo'\nimport { runCrudCommandWrite } from '@open-mercato/shared/lib/commands/runCrudCommandWrite'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { CrudHttpError, conflict, isUniqueViolation } from '@open-mercato/shared/lib/crud/errors'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport type { CrudEventsConfig } from '@open-mercato/shared/lib/crud/types'\nimport { E } from '#generated/entities.ids.generated'\nimport { AvailabilityPolicy } from '../data/entities'\nimport {\n availabilityPolicyCreateSchema,\n availabilityPolicyUpdateSchema,\n availabilityPolicyDeleteSchema,\n availabilityPolicyMergedConstraintsSchema,\n type AvailabilityPolicyCreateInput,\n type AvailabilityPolicyUpdateInput,\n} from '../data/validators'\nimport { buildAvailabilityPolicyCommandWhere, ensureAvailabilityPolicyCommandScope } from './scope'\n\nconst AVAILABILITY_POLICY_ENTITY_ID = E.availability.availability_policy\n\nconst policyCrudEvents: CrudEventsConfig<AvailabilityPolicy> = {\n module: 'availability',\n entity: 'policy',\n persistent: true,\n buildPayload: (ctx) => ({\n id: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n }),\n}\n\ntype AvailabilityPolicySnapshot = {\n id: string\n organizationId: string\n tenantId: string\n storeId: string | null\n productId: string | null\n variantId: string | null\n isStockManaged: boolean\n allowBackorder: boolean\n backorderLeadTimeDays: number | null\n preorderReleaseAt: string | null\n lowStockThreshold: number | null\n minOrderQuantity: number | null\n maxOrderQuantity: number | null\n quantityIncrement: number | null\n hideWhenOutOfStock: boolean\n isActive: boolean\n createdAt: string\n updatedAt: string\n}\n\ntype AvailabilityPolicyUndoPayload = UndoPayload<AvailabilityPolicySnapshot>\n\nfunction toSnapshot(record: AvailabilityPolicy): AvailabilityPolicySnapshot {\n return {\n id: record.id,\n organizationId: record.organizationId,\n tenantId: record.tenantId,\n storeId: record.storeId ?? null,\n productId: record.productId ?? null,\n variantId: record.variantId ?? null,\n isStockManaged: !!record.isStockManaged,\n allowBackorder: !!record.allowBackorder,\n backorderLeadTimeDays: record.backorderLeadTimeDays ?? null,\n preorderReleaseAt: record.preorderReleaseAt ? record.preorderReleaseAt.toISOString() : null,\n lowStockThreshold: record.lowStockThreshold ?? null,\n minOrderQuantity: record.minOrderQuantity ?? null,\n maxOrderQuantity: record.maxOrderQuantity ?? null,\n quantityIncrement: record.quantityIncrement ?? null,\n hideWhenOutOfStock: !!record.hideWhenOutOfStock,\n isActive: !!record.isActive,\n createdAt: record.createdAt.toISOString(),\n updatedAt: record.updatedAt.toISOString(),\n }\n}\n\nasync function loadSnapshot(\n em: EntityManager,\n id: string,\n ctx: CommandRuntimeContext,\n): Promise<AvailabilityPolicySnapshot | null> {\n const record = await em.findOne(AvailabilityPolicy, buildAvailabilityPolicyCommandWhere<AvailabilityPolicy>(ctx, { id }))\n if (!record) return null\n ensureAvailabilityPolicyCommandScope(ctx, record)\n return toSnapshot(record)\n}\n\nfunction applyUndoSnapshot(record: AvailabilityPolicy, snapshot: AvailabilityPolicySnapshot): void {\n record.storeId = snapshot.storeId\n record.productId = snapshot.productId\n record.variantId = snapshot.variantId\n record.isStockManaged = snapshot.isStockManaged\n record.allowBackorder = snapshot.allowBackorder\n record.backorderLeadTimeDays = snapshot.backorderLeadTimeDays\n record.preorderReleaseAt = snapshot.preorderReleaseAt ? new Date(snapshot.preorderReleaseAt) : null\n record.lowStockThreshold = snapshot.lowStockThreshold\n record.minOrderQuantity = snapshot.minOrderQuantity\n record.maxOrderQuantity = snapshot.maxOrderQuantity\n record.quantityIncrement = snapshot.quantityIncrement\n record.hideWhenOutOfStock = snapshot.hideWhenOutOfStock\n record.isActive = snapshot.isActive\n record.updatedAt = new Date()\n}\n\nconst createPolicyCommand: CommandHandler<AvailabilityPolicyCreateInput, { policyId: string }> = {\n id: 'availability.policies.create',\n async execute(input, ctx) {\n const parsed = availabilityPolicyCreateSchema.parse(input)\n ensureAvailabilityPolicyCommandScope(ctx, parsed)\n\n const record = new AvailabilityPolicy()\n record.organizationId = parsed.organizationId\n record.tenantId = parsed.tenantId\n record.storeId = parsed.storeId ?? null\n record.productId = parsed.productId ?? null\n record.variantId = parsed.variantId ?? null\n record.isStockManaged = parsed.isStockManaged ?? false\n record.allowBackorder = parsed.allowBackorder ?? false\n record.backorderLeadTimeDays = parsed.backorderLeadTimeDays ?? null\n record.preorderReleaseAt = parsed.preorderReleaseAt ?? null\n record.lowStockThreshold = parsed.lowStockThreshold ?? null\n record.minOrderQuantity = parsed.minOrderQuantity ?? null\n record.maxOrderQuantity = parsed.maxOrderQuantity ?? null\n record.quantityIncrement = parsed.quantityIncrement ?? null\n record.hideWhenOutOfStock = parsed.hideWhenOutOfStock ?? false\n record.isActive = parsed.isActive ?? true\n\n try {\n await runCrudCommandWrite({\n ctx,\n entityId: AVAILABILITY_POLICY_ENTITY_ID,\n action: 'created',\n scope: { tenantId: record.tenantId, organizationId: record.organizationId },\n events: policyCrudEvents,\n sideEffect: () => ({\n entity: record,\n identifiers: { id: record.id, organizationId: record.organizationId, tenantId: record.tenantId },\n }),\n phases: [({ em }) => { em.persist(record) }],\n })\n } catch (err) {\n if (isUniqueViolation(err, 'availability_policies_scope_target_unique')) {\n const { translate } = await resolveTranslations()\n throw conflict(translate('availability.policies.errors.duplicateTarget', 'A policy already exists for this store/product/variant combination.'))\n }\n throw err\n }\n\n return { policyId: record.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadSnapshot(em, result.policyId, ctx)\n },\n buildLog: async ({ snapshots }) => {\n const after = snapshots.after as AvailabilityPolicySnapshot | undefined\n if (!after) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('availability.audit.create', 'Create availability policy'),\n resourceKind: 'availability.policy',\n resourceId: after.id,\n tenantId: after.tenantId,\n organizationId: after.organizationId,\n snapshotAfter: after,\n payload: { undo: { after } },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<AvailabilityPolicyUndoPayload>(logEntry)\n const after = payload?.after ?? null\n if (!after) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const record = await em.findOne(AvailabilityPolicy, { id: after.id })\n if (!record) return\n record.deletedAt = new Date()\n await em.flush()\n },\n}\n\nconst updatePolicyCommand: CommandHandler<AvailabilityPolicyUpdateInput, { policyId: string }> = {\n id: 'availability.policies.update',\n async prepare(input, ctx) {\n requireId(input.id, 'Availability policy ID is required')\n const em = ctx.container.resolve('em') as EntityManager\n const before = await loadSnapshot(em, input.id, ctx)\n return { before }\n },\n async execute(input, ctx) {\n const parsed = availabilityPolicyUpdateSchema.parse(input)\n requireId(parsed.id, 'Availability policy ID is required')\n\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const record = await em.findOne(AvailabilityPolicy, buildAvailabilityPolicyCommandWhere<AvailabilityPolicy>(ctx, { id: parsed.id }))\n if (!record) throw new CrudHttpError(404, { error: 'Availability policy not found' })\n ensureAvailabilityPolicyCommandScope(ctx, record)\n\n const merged = {\n storeId: parsed.storeId !== undefined ? parsed.storeId : record.storeId,\n productId: parsed.productId !== undefined ? parsed.productId : record.productId,\n variantId: parsed.variantId !== undefined ? parsed.variantId : record.variantId,\n isStockManaged: parsed.isStockManaged !== undefined ? parsed.isStockManaged : record.isStockManaged,\n allowBackorder: parsed.allowBackorder !== undefined ? parsed.allowBackorder : record.allowBackorder,\n backorderLeadTimeDays:\n parsed.backorderLeadTimeDays !== undefined ? parsed.backorderLeadTimeDays : record.backorderLeadTimeDays,\n minOrderQuantity: parsed.minOrderQuantity !== undefined ? parsed.minOrderQuantity : record.minOrderQuantity,\n maxOrderQuantity: parsed.maxOrderQuantity !== undefined ? parsed.maxOrderQuantity : record.maxOrderQuantity,\n }\n availabilityPolicyMergedConstraintsSchema.parse(merged)\n\n try {\n await runCrudCommandWrite({\n ctx,\n em,\n entityId: AVAILABILITY_POLICY_ENTITY_ID,\n action: 'updated',\n scope: { tenantId: record.tenantId, organizationId: record.organizationId },\n events: policyCrudEvents,\n sideEffect: () => ({\n entity: record,\n identifiers: { id: record.id, organizationId: record.organizationId, tenantId: record.tenantId },\n }),\n phases: [\n ({ em: forkedEm }) => {\n const target = forkedEm.getReference(AvailabilityPolicy, record.id)\n if (parsed.storeId !== undefined) target.storeId = parsed.storeId\n if (parsed.productId !== undefined) target.productId = parsed.productId\n if (parsed.variantId !== undefined) target.variantId = parsed.variantId\n if (parsed.isStockManaged !== undefined) target.isStockManaged = parsed.isStockManaged\n if (parsed.allowBackorder !== undefined) target.allowBackorder = parsed.allowBackorder\n if (parsed.backorderLeadTimeDays !== undefined) target.backorderLeadTimeDays = parsed.backorderLeadTimeDays\n if (parsed.preorderReleaseAt !== undefined) target.preorderReleaseAt = parsed.preorderReleaseAt\n if (parsed.lowStockThreshold !== undefined) target.lowStockThreshold = parsed.lowStockThreshold\n if (parsed.minOrderQuantity !== undefined) target.minOrderQuantity = parsed.minOrderQuantity\n if (parsed.maxOrderQuantity !== undefined) target.maxOrderQuantity = parsed.maxOrderQuantity\n if (parsed.quantityIncrement !== undefined) target.quantityIncrement = parsed.quantityIncrement\n if (parsed.hideWhenOutOfStock !== undefined) target.hideWhenOutOfStock = parsed.hideWhenOutOfStock\n if (parsed.isActive !== undefined) target.isActive = parsed.isActive\n target.updatedAt = new Date()\n },\n ],\n })\n } catch (err) {\n if (isUniqueViolation(err, 'availability_policies_scope_target_unique')) {\n const { translate } = await resolveTranslations()\n throw conflict(translate('availability.policies.errors.duplicateTarget', 'A policy already exists for this store/product/variant combination.'))\n }\n throw err\n }\n\n return { policyId: record.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadSnapshot(em, result.policyId, ctx)\n },\n buildLog: async ({ snapshots }) => {\n const before = snapshots.before as AvailabilityPolicySnapshot | undefined\n const after = snapshots.after as AvailabilityPolicySnapshot | undefined\n if (!after) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('availability.audit.update', 'Update availability policy'),\n resourceKind: 'availability.policy',\n resourceId: after.id,\n tenantId: after.tenantId,\n organizationId: after.organizationId,\n snapshotBefore: before ?? undefined,\n snapshotAfter: after,\n payload: { undo: { before, after } },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<AvailabilityPolicyUndoPayload>(logEntry)\n const before = payload?.before ?? null\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const record = await em.findOne(AvailabilityPolicy, { id: before.id })\n if (!record) return\n applyUndoSnapshot(record, before)\n await em.flush()\n },\n}\n\nconst deletePolicyCommand: CommandHandler<{ id: string; organizationId: string; tenantId: string }, { policyId: string }> = {\n id: 'availability.policies.delete',\n async prepare(input, ctx) {\n requireId(input.id, 'Availability policy ID is required')\n const em = ctx.container.resolve('em') as EntityManager\n const before = await loadSnapshot(em, input.id, ctx)\n return { before }\n },\n async execute(input, ctx) {\n const parsed = availabilityPolicyDeleteSchema.parse(input)\n requireId(parsed.id, 'Availability policy ID is required')\n\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const record = await em.findOne(AvailabilityPolicy, buildAvailabilityPolicyCommandWhere<AvailabilityPolicy>(ctx, { id: parsed.id }))\n if (!record) throw new CrudHttpError(404, { error: 'Availability policy not found' })\n ensureAvailabilityPolicyCommandScope(ctx, record)\n\n await runCrudCommandWrite({\n ctx,\n em,\n entityId: AVAILABILITY_POLICY_ENTITY_ID,\n action: 'deleted',\n scope: { tenantId: record.tenantId, organizationId: record.organizationId },\n events: policyCrudEvents,\n sideEffect: () => ({\n entity: record,\n identifiers: { id: record.id, organizationId: record.organizationId, tenantId: record.tenantId },\n }),\n phases: [\n ({ em: forkedEm }) => {\n const target = forkedEm.getReference(AvailabilityPolicy, record.id)\n target.deletedAt = new Date()\n },\n ],\n })\n\n return { policyId: record.id }\n },\n buildLog: async ({ snapshots }) => {\n const before = snapshots.before as AvailabilityPolicySnapshot | undefined\n if (!before) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('availability.audit.delete', 'Delete availability policy'),\n resourceKind: 'availability.policy',\n resourceId: before.id,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n payload: { undo: { before } },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<AvailabilityPolicyUndoPayload>(logEntry)\n const before = payload?.before ?? null\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const record = await em.findOne(AvailabilityPolicy, { id: before.id })\n if (!record) return\n record.deletedAt = null\n record.updatedAt = new Date()\n await em.flush()\n },\n}\n\nregisterCommand(createPolicyCommand)\nregisterCommand(updatePolicyCommand)\nregisterCommand(deletePolicyCommand)\n\nexport { createPolicyCommand, updatePolicyCommand, deletePolicyCommand }\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { buildScopedWhere } from "@open-mercato/shared/lib/api/crud";
|
|
2
|
+
import { ensureOrganizationScope, ensureTenantScope } from "@open-mercato/shared/lib/commands/scope";
|
|
3
|
+
function buildAvailabilityPolicyCommandWhere(ctx, base) {
|
|
4
|
+
const organizationId = ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? void 0;
|
|
5
|
+
return buildScopedWhere(base, {
|
|
6
|
+
organizationId,
|
|
7
|
+
organizationIds: ctx.organizationIds ?? void 0,
|
|
8
|
+
tenantId: ctx.auth?.tenantId ?? void 0
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
function ensureAvailabilityPolicyCommandScope(ctx, record) {
|
|
12
|
+
ensureTenantScope(ctx, record.tenantId);
|
|
13
|
+
ensureOrganizationScope(ctx, record.organizationId);
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
buildAvailabilityPolicyCommandWhere,
|
|
17
|
+
ensureAvailabilityPolicyCommandScope
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=scope.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/availability/commands/scope.ts"],
|
|
4
|
+
"sourcesContent": ["import type { FilterQuery } from '@mikro-orm/core'\nimport type { CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport { buildScopedWhere } from '@open-mercato/shared/lib/api/crud'\nimport { ensureOrganizationScope, ensureTenantScope } from '@open-mercato/shared/lib/commands/scope'\n\ntype AvailabilityPolicyScopedRecord = { organizationId: string; tenantId: string }\n\nexport function buildAvailabilityPolicyCommandWhere<T extends object>(\n ctx: CommandRuntimeContext,\n base: FilterQuery<T>,\n): FilterQuery<T> {\n const organizationId = ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? undefined\n return buildScopedWhere(base as Record<string, unknown>, {\n organizationId,\n organizationIds: ctx.organizationIds ?? undefined,\n tenantId: ctx.auth?.tenantId ?? undefined,\n }) as FilterQuery<T>\n}\n\nexport function ensureAvailabilityPolicyCommandScope(\n ctx: CommandRuntimeContext,\n record: AvailabilityPolicyScopedRecord,\n): void {\n ensureTenantScope(ctx, record.tenantId)\n ensureOrganizationScope(ctx, record.organizationId)\n}\n"],
|
|
5
|
+
"mappings": "AAEA,SAAS,wBAAwB;AACjC,SAAS,yBAAyB,yBAAyB;AAIpD,SAAS,oCACd,KACA,MACgB;AAChB,QAAM,iBAAiB,IAAI,0BAA0B,IAAI,MAAM,SAAS;AACxE,SAAO,iBAAiB,MAAiC;AAAA,IACvD;AAAA,IACA,iBAAiB,IAAI,mBAAmB;AAAA,IACxC,UAAU,IAAI,MAAM,YAAY;AAAA,EAClC,CAAC;AACH;AAEO,SAAS,qCACd,KACA,QACM;AACN,oBAAkB,KAAK,OAAO,QAAQ;AACtC,0BAAwB,KAAK,OAAO,cAAc;AACpD;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
9
|
+
return result;
|
|
10
|
+
};
|
|
11
|
+
import { OptionalProps } from "@mikro-orm/core";
|
|
12
|
+
import { Entity, Index, PrimaryKey, Property } from "@mikro-orm/decorators/legacy";
|
|
13
|
+
OptionalProps;
|
|
14
|
+
let AvailabilityPolicy = class {
|
|
15
|
+
constructor() {
|
|
16
|
+
this.isStockManaged = false;
|
|
17
|
+
this.allowBackorder = false;
|
|
18
|
+
this.hideWhenOutOfStock = false;
|
|
19
|
+
this.isActive = true;
|
|
20
|
+
this.createdAt = /* @__PURE__ */ new Date();
|
|
21
|
+
this.updatedAt = /* @__PURE__ */ new Date();
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
__decorateClass([
|
|
25
|
+
PrimaryKey({ type: "uuid", defaultRaw: "gen_random_uuid()" })
|
|
26
|
+
], AvailabilityPolicy.prototype, "id", 2);
|
|
27
|
+
__decorateClass([
|
|
28
|
+
Property({ name: "organization_id", type: "uuid" })
|
|
29
|
+
], AvailabilityPolicy.prototype, "organizationId", 2);
|
|
30
|
+
__decorateClass([
|
|
31
|
+
Property({ name: "tenant_id", type: "uuid" })
|
|
32
|
+
], AvailabilityPolicy.prototype, "tenantId", 2);
|
|
33
|
+
__decorateClass([
|
|
34
|
+
Property({ name: "store_id", type: "uuid", nullable: true })
|
|
35
|
+
], AvailabilityPolicy.prototype, "storeId", 2);
|
|
36
|
+
__decorateClass([
|
|
37
|
+
Property({ name: "product_id", type: "uuid", nullable: true })
|
|
38
|
+
], AvailabilityPolicy.prototype, "productId", 2);
|
|
39
|
+
__decorateClass([
|
|
40
|
+
Property({ name: "variant_id", type: "uuid", nullable: true })
|
|
41
|
+
], AvailabilityPolicy.prototype, "variantId", 2);
|
|
42
|
+
__decorateClass([
|
|
43
|
+
Property({ name: "is_stock_managed", type: "boolean", default: false })
|
|
44
|
+
], AvailabilityPolicy.prototype, "isStockManaged", 2);
|
|
45
|
+
__decorateClass([
|
|
46
|
+
Property({ name: "allow_backorder", type: "boolean", default: false })
|
|
47
|
+
], AvailabilityPolicy.prototype, "allowBackorder", 2);
|
|
48
|
+
__decorateClass([
|
|
49
|
+
Property({ name: "backorder_lead_time_days", type: "integer", nullable: true })
|
|
50
|
+
], AvailabilityPolicy.prototype, "backorderLeadTimeDays", 2);
|
|
51
|
+
__decorateClass([
|
|
52
|
+
Property({ name: "preorder_release_at", type: Date, nullable: true })
|
|
53
|
+
], AvailabilityPolicy.prototype, "preorderReleaseAt", 2);
|
|
54
|
+
__decorateClass([
|
|
55
|
+
Property({ name: "low_stock_threshold", type: "integer", nullable: true })
|
|
56
|
+
], AvailabilityPolicy.prototype, "lowStockThreshold", 2);
|
|
57
|
+
__decorateClass([
|
|
58
|
+
Property({ name: "min_order_quantity", type: "integer", nullable: true })
|
|
59
|
+
], AvailabilityPolicy.prototype, "minOrderQuantity", 2);
|
|
60
|
+
__decorateClass([
|
|
61
|
+
Property({ name: "max_order_quantity", type: "integer", nullable: true })
|
|
62
|
+
], AvailabilityPolicy.prototype, "maxOrderQuantity", 2);
|
|
63
|
+
__decorateClass([
|
|
64
|
+
Property({ name: "quantity_increment", type: "integer", nullable: true })
|
|
65
|
+
], AvailabilityPolicy.prototype, "quantityIncrement", 2);
|
|
66
|
+
__decorateClass([
|
|
67
|
+
Property({ name: "hide_when_out_of_stock", type: "boolean", default: false })
|
|
68
|
+
], AvailabilityPolicy.prototype, "hideWhenOutOfStock", 2);
|
|
69
|
+
__decorateClass([
|
|
70
|
+
Property({ name: "is_active", type: "boolean", default: true })
|
|
71
|
+
], AvailabilityPolicy.prototype, "isActive", 2);
|
|
72
|
+
__decorateClass([
|
|
73
|
+
Property({ name: "created_at", type: Date, onCreate: () => /* @__PURE__ */ new Date() })
|
|
74
|
+
], AvailabilityPolicy.prototype, "createdAt", 2);
|
|
75
|
+
__decorateClass([
|
|
76
|
+
Property({ name: "updated_at", type: Date, onUpdate: () => /* @__PURE__ */ new Date() })
|
|
77
|
+
], AvailabilityPolicy.prototype, "updatedAt", 2);
|
|
78
|
+
__decorateClass([
|
|
79
|
+
Property({ name: "deleted_at", type: Date, nullable: true })
|
|
80
|
+
], AvailabilityPolicy.prototype, "deletedAt", 2);
|
|
81
|
+
AvailabilityPolicy = __decorateClass([
|
|
82
|
+
Entity({ tableName: "availability_policies" }),
|
|
83
|
+
Index({ name: "availability_policies_scope_idx", properties: ["tenantId", "organizationId"] }),
|
|
84
|
+
Index({
|
|
85
|
+
// Exactly one policy row per (store, product, variant) combination — nullable columns mean
|
|
86
|
+
// "applies to all stores" / "product-level" / "store-level default". Postgres treats NULLs as
|
|
87
|
+
// distinct by default, so the index is declared NULLS NOT DISTINCT (mirrors user_devices).
|
|
88
|
+
name: "availability_policies_scope_target_unique",
|
|
89
|
+
expression: 'create unique index "availability_policies_scope_target_unique" on "availability_policies" ("tenant_id", "organization_id", "store_id", "product_id", "variant_id") nulls not distinct where deleted_at is null'
|
|
90
|
+
})
|
|
91
|
+
], AvailabilityPolicy);
|
|
92
|
+
export {
|
|
93
|
+
AvailabilityPolicy
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=entities.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/availability/data/entities.ts"],
|
|
4
|
+
"sourcesContent": ["import { OptionalProps } from '@mikro-orm/core'\nimport { Entity, Index, PrimaryKey, Property } from '@mikro-orm/decorators/legacy'\n\n@Entity({ tableName: 'availability_policies' })\n@Index({ name: 'availability_policies_scope_idx', properties: ['tenantId', 'organizationId'] })\n@Index({\n // Exactly one policy row per (store, product, variant) combination \u2014 nullable columns mean\n // \"applies to all stores\" / \"product-level\" / \"store-level default\". Postgres treats NULLs as\n // distinct by default, so the index is declared NULLS NOT DISTINCT (mirrors user_devices).\n name: 'availability_policies_scope_target_unique',\n expression:\n 'create unique index \"availability_policies_scope_target_unique\" on \"availability_policies\" (\"tenant_id\", \"organization_id\", \"store_id\", \"product_id\", \"variant_id\") nulls not distinct where deleted_at is null',\n})\nexport class AvailabilityPolicy {\n [OptionalProps]?:\n | 'storeId'\n | 'productId'\n | 'variantId'\n | 'isStockManaged'\n | 'allowBackorder'\n | 'backorderLeadTimeDays'\n | 'preorderReleaseAt'\n | 'lowStockThreshold'\n | 'minOrderQuantity'\n | 'maxOrderQuantity'\n | 'quantityIncrement'\n | 'hideWhenOutOfStock'\n | 'isActive'\n | 'createdAt'\n | 'updatedAt'\n | 'deletedAt'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'organization_id', type: 'uuid' })\n organizationId!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n /** `catalog.EcommerceStore`-shaped id (not yet a real entity in this repo) \u2014 null = all stores. */\n @Property({ name: 'store_id', type: 'uuid', nullable: true })\n storeId?: string | null\n\n /** `catalog.CatalogProduct.id`. */\n @Property({ name: 'product_id', type: 'uuid', nullable: true })\n productId?: string | null\n\n /** `catalog.CatalogProductVariant.id`. Non-null requires `productId` non-null (validated). */\n @Property({ name: 'variant_id', type: 'uuid', nullable: true })\n variantId?: string | null\n\n @Property({ name: 'is_stock_managed', type: 'boolean', default: false })\n isStockManaged: boolean = false\n\n @Property({ name: 'allow_backorder', type: 'boolean', default: false })\n allowBackorder: boolean = false\n\n @Property({ name: 'backorder_lead_time_days', type: 'integer', nullable: true })\n backorderLeadTimeDays?: number | null\n\n @Property({ name: 'preorder_release_at', type: Date, nullable: true })\n preorderReleaseAt?: Date | null\n\n @Property({ name: 'low_stock_threshold', type: 'integer', nullable: true })\n lowStockThreshold?: number | null\n\n @Property({ name: 'min_order_quantity', type: 'integer', nullable: true })\n minOrderQuantity?: number | null\n\n @Property({ name: 'max_order_quantity', type: 'integer', nullable: true })\n maxOrderQuantity?: number | null\n\n @Property({ name: 'quantity_increment', type: 'integer', nullable: true })\n quantityIncrement?: number | null\n\n @Property({ name: 'hide_when_out_of_stock', type: 'boolean', default: false })\n hideWhenOutOfStock: boolean = false\n\n @Property({ name: 'is_active', type: 'boolean', default: true })\n isActive: boolean = true\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;AAAA,SAAS,qBAAqB;AAC9B,SAAS,QAAQ,OAAO,YAAY,gBAAgB;AAajD;AADI,IAAM,qBAAN,MAAyB;AAAA,EAAzB;AAyCL,0BAA0B;AAG1B,0BAA0B;AAqB1B,8BAA8B;AAG9B,oBAAoB;AAGpB,qBAAkB,oBAAI,KAAK;AAG3B,qBAAkB,oBAAI,KAAK;AAAA;AAI7B;AA1DE;AAAA,EADC,WAAW,EAAE,MAAM,QAAQ,YAAY,oBAAoB,CAAC;AAAA,GAnBlD,mBAoBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,mBAAmB,MAAM,OAAO,CAAC;AAAA,GAtBxC,mBAuBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,GAzBlC,mBA0BX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,YAAY,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GA7BjD,mBA8BX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAjCnD,mBAkCX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GArCnD,mBAsCX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,oBAAoB,MAAM,WAAW,SAAS,MAAM,CAAC;AAAA,GAxC5D,mBAyCX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,mBAAmB,MAAM,WAAW,SAAS,MAAM,CAAC;AAAA,GA3C3D,mBA4CX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,4BAA4B,MAAM,WAAW,UAAU,KAAK,CAAC;AAAA,GA9CpE,mBA+CX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,uBAAuB,MAAM,MAAM,UAAU,KAAK,CAAC;AAAA,GAjD1D,mBAkDX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,uBAAuB,MAAM,WAAW,UAAU,KAAK,CAAC;AAAA,GApD/D,mBAqDX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,sBAAsB,MAAM,WAAW,UAAU,KAAK,CAAC;AAAA,GAvD9D,mBAwDX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,sBAAsB,MAAM,WAAW,UAAU,KAAK,CAAC;AAAA,GA1D9D,mBA2DX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,sBAAsB,MAAM,WAAW,UAAU,KAAK,CAAC;AAAA,GA7D9D,mBA8DX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,0BAA0B,MAAM,WAAW,SAAS,MAAM,CAAC;AAAA,GAhElE,mBAiEX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,aAAa,MAAM,WAAW,SAAS,KAAK,CAAC;AAAA,GAnEpD,mBAoEX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GAtE7D,mBAuEX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GAzE7D,mBA0EX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,KAAK,CAAC;AAAA,GA5EjD,mBA6EX;AA7EW,qBAAN;AAAA,EAVN,OAAO,EAAE,WAAW,wBAAwB,CAAC;AAAA,EAC7C,MAAM,EAAE,MAAM,mCAAmC,YAAY,CAAC,YAAY,gBAAgB,EAAE,CAAC;AAAA,EAC7F,MAAM;AAAA;AAAA;AAAA;AAAA,IAIL,MAAM;AAAA,IACN,YACE;AAAA,EACJ,CAAC;AAAA,GACY;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const uuid = () => z.string().uuid();
|
|
3
|
+
const scopedSchema = z.object({
|
|
4
|
+
organizationId: uuid(),
|
|
5
|
+
tenantId: uuid()
|
|
6
|
+
});
|
|
7
|
+
const nonNegativeInt = () => z.number().int().min(0);
|
|
8
|
+
const policyFieldsSchema = z.object({
|
|
9
|
+
storeId: uuid().nullable().optional(),
|
|
10
|
+
productId: uuid().nullable().optional(),
|
|
11
|
+
variantId: uuid().nullable().optional(),
|
|
12
|
+
isStockManaged: z.boolean().optional(),
|
|
13
|
+
allowBackorder: z.boolean().optional(),
|
|
14
|
+
backorderLeadTimeDays: nonNegativeInt().nullable().optional(),
|
|
15
|
+
preorderReleaseAt: z.coerce.date().nullable().optional(),
|
|
16
|
+
lowStockThreshold: nonNegativeInt().nullable().optional(),
|
|
17
|
+
minOrderQuantity: nonNegativeInt().nullable().optional(),
|
|
18
|
+
maxOrderQuantity: nonNegativeInt().nullable().optional(),
|
|
19
|
+
quantityIncrement: nonNegativeInt().nullable().optional(),
|
|
20
|
+
hideWhenOutOfStock: z.boolean().optional(),
|
|
21
|
+
isActive: z.boolean().optional()
|
|
22
|
+
});
|
|
23
|
+
const AVAILABILITY_POLICY_VARIANT_REQUIRES_PRODUCT_MESSAGE_KEY = "availability.policies.errors.variantRequiresProduct";
|
|
24
|
+
const AVAILABILITY_POLICY_BACKORDER_REQUIRES_LEAD_TIME_MESSAGE_KEY = "availability.policies.errors.backorderRequiresLeadTime";
|
|
25
|
+
const AVAILABILITY_POLICY_MAX_BELOW_MIN_MESSAGE_KEY = "availability.policies.errors.maxBelowMin";
|
|
26
|
+
function refinePolicyConstraints(schema) {
|
|
27
|
+
return schema.refine((val) => !(val.variantId && !val.productId), {
|
|
28
|
+
message: AVAILABILITY_POLICY_VARIANT_REQUIRES_PRODUCT_MESSAGE_KEY,
|
|
29
|
+
path: ["variantId"]
|
|
30
|
+
}).refine((val) => !(val.allowBackorder && val.backorderLeadTimeDays == null), {
|
|
31
|
+
message: AVAILABILITY_POLICY_BACKORDER_REQUIRES_LEAD_TIME_MESSAGE_KEY,
|
|
32
|
+
path: ["backorderLeadTimeDays"]
|
|
33
|
+
}).refine(
|
|
34
|
+
(val) => !(val.minOrderQuantity != null && val.maxOrderQuantity != null && val.maxOrderQuantity < val.minOrderQuantity),
|
|
35
|
+
{ message: AVAILABILITY_POLICY_MAX_BELOW_MIN_MESSAGE_KEY, path: ["maxOrderQuantity"] }
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
const availabilityPolicyCreateSchema = refinePolicyConstraints(
|
|
39
|
+
scopedSchema.extend(policyFieldsSchema.shape)
|
|
40
|
+
);
|
|
41
|
+
const availabilityPolicyUpdateSchema = z.object({ id: uuid() }).merge(scopedSchema.extend(policyFieldsSchema.shape).partial());
|
|
42
|
+
const availabilityPolicyDeleteSchema = scopedSchema.extend({ id: uuid() });
|
|
43
|
+
const availabilityPolicyMergedConstraintsSchema = refinePolicyConstraints(policyFieldsSchema);
|
|
44
|
+
export {
|
|
45
|
+
AVAILABILITY_POLICY_BACKORDER_REQUIRES_LEAD_TIME_MESSAGE_KEY,
|
|
46
|
+
AVAILABILITY_POLICY_MAX_BELOW_MIN_MESSAGE_KEY,
|
|
47
|
+
AVAILABILITY_POLICY_VARIANT_REQUIRES_PRODUCT_MESSAGE_KEY,
|
|
48
|
+
availabilityPolicyCreateSchema,
|
|
49
|
+
availabilityPolicyDeleteSchema,
|
|
50
|
+
availabilityPolicyMergedConstraintsSchema,
|
|
51
|
+
availabilityPolicyUpdateSchema
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=validators.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/availability/data/validators.ts"],
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\n\nconst uuid = () => z.string().uuid()\n\nconst scopedSchema = z.object({\n organizationId: uuid(),\n tenantId: uuid(),\n})\n\nconst nonNegativeInt = () => z.number().int().min(0)\n\nconst policyFieldsSchema = z.object({\n storeId: uuid().nullable().optional(),\n productId: uuid().nullable().optional(),\n variantId: uuid().nullable().optional(),\n isStockManaged: z.boolean().optional(),\n allowBackorder: z.boolean().optional(),\n backorderLeadTimeDays: nonNegativeInt().nullable().optional(),\n preorderReleaseAt: z.coerce.date().nullable().optional(),\n lowStockThreshold: nonNegativeInt().nullable().optional(),\n minOrderQuantity: nonNegativeInt().nullable().optional(),\n maxOrderQuantity: nonNegativeInt().nullable().optional(),\n quantityIncrement: nonNegativeInt().nullable().optional(),\n hideWhenOutOfStock: z.boolean().optional(),\n isActive: z.boolean().optional(),\n})\n\nexport const AVAILABILITY_POLICY_VARIANT_REQUIRES_PRODUCT_MESSAGE_KEY =\n 'availability.policies.errors.variantRequiresProduct'\nexport const AVAILABILITY_POLICY_BACKORDER_REQUIRES_LEAD_TIME_MESSAGE_KEY =\n 'availability.policies.errors.backorderRequiresLeadTime'\nexport const AVAILABILITY_POLICY_MAX_BELOW_MIN_MESSAGE_KEY = 'availability.policies.errors.maxBelowMin'\n\nfunction refinePolicyConstraints<T extends z.ZodTypeAny>(schema: T) {\n return schema\n .refine((val: any) => !(val.variantId && !val.productId), {\n message: AVAILABILITY_POLICY_VARIANT_REQUIRES_PRODUCT_MESSAGE_KEY,\n path: ['variantId'],\n })\n .refine((val: any) => !(val.allowBackorder && val.backorderLeadTimeDays == null), {\n message: AVAILABILITY_POLICY_BACKORDER_REQUIRES_LEAD_TIME_MESSAGE_KEY,\n path: ['backorderLeadTimeDays'],\n })\n .refine(\n (val: any) =>\n !(val.minOrderQuantity != null && val.maxOrderQuantity != null && val.maxOrderQuantity < val.minOrderQuantity),\n { message: AVAILABILITY_POLICY_MAX_BELOW_MIN_MESSAGE_KEY, path: ['maxOrderQuantity'] },\n )\n}\n\nexport const availabilityPolicyCreateSchema = refinePolicyConstraints(\n scopedSchema.extend(policyFieldsSchema.shape),\n)\n\n// Cross-field constraints (variant requires product, backorder requires lead time, max >= min)\n// are NOT re-checked here at the zod layer: a partial update payload may touch only one side of\n// a constraint while the other side's value already satisfies it in the stored row. The update\n// command (commands/policies.ts) re-validates the same constraints against the merged\n// (existing-row + patch) record, where the full picture is available.\nexport const availabilityPolicyUpdateSchema = z\n .object({ id: uuid() })\n .merge(scopedSchema.extend(policyFieldsSchema.shape).partial())\n\nexport const availabilityPolicyDeleteSchema = scopedSchema.extend({ id: uuid() })\n\n/** Re-applies the create-time cross-field constraints to a merged (existing + patch) record. Used by the update command. */\nexport const availabilityPolicyMergedConstraintsSchema = refinePolicyConstraints(policyFieldsSchema)\n\nexport type AvailabilityPolicyCreateInput = z.infer<typeof availabilityPolicyCreateSchema>\nexport type AvailabilityPolicyUpdateInput = z.infer<typeof availabilityPolicyUpdateSchema>\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,SAAS;AAElB,MAAM,OAAO,MAAM,EAAE,OAAO,EAAE,KAAK;AAEnC,MAAM,eAAe,EAAE,OAAO;AAAA,EAC5B,gBAAgB,KAAK;AAAA,EACrB,UAAU,KAAK;AACjB,CAAC;AAED,MAAM,iBAAiB,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC;AAEnD,MAAM,qBAAqB,EAAE,OAAO;AAAA,EAClC,SAAS,KAAK,EAAE,SAAS,EAAE,SAAS;AAAA,EACpC,WAAW,KAAK,EAAE,SAAS,EAAE,SAAS;AAAA,EACtC,WAAW,KAAK,EAAE,SAAS,EAAE,SAAS;AAAA,EACtC,gBAAgB,EAAE,QAAQ,EAAE,SAAS;AAAA,EACrC,gBAAgB,EAAE,QAAQ,EAAE,SAAS;AAAA,EACrC,uBAAuB,eAAe,EAAE,SAAS,EAAE,SAAS;AAAA,EAC5D,mBAAmB,EAAE,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS;AAAA,EACvD,mBAAmB,eAAe,EAAE,SAAS,EAAE,SAAS;AAAA,EACxD,kBAAkB,eAAe,EAAE,SAAS,EAAE,SAAS;AAAA,EACvD,kBAAkB,eAAe,EAAE,SAAS,EAAE,SAAS;AAAA,EACvD,mBAAmB,eAAe,EAAE,SAAS,EAAE,SAAS;AAAA,EACxD,oBAAoB,EAAE,QAAQ,EAAE,SAAS;AAAA,EACzC,UAAU,EAAE,QAAQ,EAAE,SAAS;AACjC,CAAC;AAEM,MAAM,2DACX;AACK,MAAM,+DACX;AACK,MAAM,gDAAgD;AAE7D,SAAS,wBAAgD,QAAW;AAClE,SAAO,OACJ,OAAO,CAAC,QAAa,EAAE,IAAI,aAAa,CAAC,IAAI,YAAY;AAAA,IACxD,SAAS;AAAA,IACT,MAAM,CAAC,WAAW;AAAA,EACpB,CAAC,EACA,OAAO,CAAC,QAAa,EAAE,IAAI,kBAAkB,IAAI,yBAAyB,OAAO;AAAA,IAChF,SAAS;AAAA,IACT,MAAM,CAAC,uBAAuB;AAAA,EAChC,CAAC,EACA;AAAA,IACC,CAAC,QACC,EAAE,IAAI,oBAAoB,QAAQ,IAAI,oBAAoB,QAAQ,IAAI,mBAAmB,IAAI;AAAA,IAC/F,EAAE,SAAS,+CAA+C,MAAM,CAAC,kBAAkB,EAAE;AAAA,EACvF;AACJ;AAEO,MAAM,iCAAiC;AAAA,EAC5C,aAAa,OAAO,mBAAmB,KAAK;AAC9C;AAOO,MAAM,iCAAiC,EAC3C,OAAO,EAAE,IAAI,KAAK,EAAE,CAAC,EACrB,MAAM,aAAa,OAAO,mBAAmB,KAAK,EAAE,QAAQ,CAAC;AAEzD,MAAM,iCAAiC,aAAa,OAAO,EAAE,IAAI,KAAK,EAAE,CAAC;AAGzE,MAAM,4CAA4C,wBAAwB,kBAAkB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { asValue } from "awilix";
|
|
2
|
+
import { setCatalogOnlyPolicyLookup, availabilityItemKey } from "@open-mercato/shared/lib/availability";
|
|
3
|
+
import { AvailabilityPolicy } from "./data/entities.js";
|
|
4
|
+
import { createPolicyResolutionService } from "./lib/policyResolution.js";
|
|
5
|
+
function register(container) {
|
|
6
|
+
container.register({
|
|
7
|
+
AvailabilityPolicy: asValue(AvailabilityPolicy),
|
|
8
|
+
policyResolutionService: {
|
|
9
|
+
resolve: (c) => createPolicyResolutionService(c)
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
setCatalogOnlyPolicyLookup(async (query) => {
|
|
13
|
+
const em = container.resolve("em").fork();
|
|
14
|
+
const service = createPolicyResolutionService(container);
|
|
15
|
+
const overrides = {};
|
|
16
|
+
const resolved = await service.resolveMany(
|
|
17
|
+
em,
|
|
18
|
+
query.items.map((item) => ({
|
|
19
|
+
tenantId: query.tenantId,
|
|
20
|
+
organizationId: query.organizationId,
|
|
21
|
+
storeId: query.storeId ?? null,
|
|
22
|
+
productId: item.catalogProductId,
|
|
23
|
+
variantId: item.catalogVariantId ?? null
|
|
24
|
+
}))
|
|
25
|
+
);
|
|
26
|
+
query.items.forEach((item, index) => {
|
|
27
|
+
const policy = resolved[index];
|
|
28
|
+
overrides[availabilityItemKey(item)] = {
|
|
29
|
+
isStockManaged: policy.isStockManaged.value,
|
|
30
|
+
isActive: policy.isActive.value,
|
|
31
|
+
preorderReleaseAt: policy.preorderReleaseAt.value ? policy.preorderReleaseAt.value.toISOString() : null,
|
|
32
|
+
policySourceId: policy.preorderReleaseAt.policySourceId ?? policy.isActive.policySourceId ?? policy.isStockManaged.policySourceId ?? null
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
return overrides;
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
export {
|
|
39
|
+
register
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=di.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/modules/availability/di.ts"],
|
|
4
|
+
"sourcesContent": ["import { asValue } from 'awilix'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport type { AppContainer } from '@open-mercato/shared/lib/di/container'\nimport { setCatalogOnlyPolicyLookup, availabilityItemKey } from '@open-mercato/shared/lib/availability'\nimport type { CatalogOnlyPolicyOverride } from '@open-mercato/shared/lib/availability'\nimport { AvailabilityPolicy } from './data/entities'\nimport { createPolicyResolutionService } from './lib/policyResolution'\n\nexport function register(container: AppContainer) {\n container.register({\n AvailabilityPolicy: asValue(AvailabilityPolicy),\n policyResolutionService: {\n resolve: (c) => createPolicyResolutionService(c),\n },\n })\n\n // Wires the shared catalog-only fallback's optional policy hook (decision 2,\n // PLAN.md \u00A7 Key design decisions) \u2014 closure captures the boot container, the\n // same technique `wms/di.ts` uses for its own provider registration.\n setCatalogOnlyPolicyLookup(async (query) => {\n const em = (container.resolve('em') as EntityManager).fork()\n const service = createPolicyResolutionService(container)\n const overrides: Record<string, CatalogOnlyPolicyOverride | null> = {}\n\n // Batched (R4): one resolveMany() call for the whole item set, not one\n // resolve() per item \u2014 the same discipline wms's provider follows.\n const resolved = await service.resolveMany(\n em,\n query.items.map((item) => ({\n tenantId: query.tenantId,\n organizationId: query.organizationId,\n storeId: query.storeId ?? null,\n productId: item.catalogProductId,\n variantId: item.catalogVariantId ?? null,\n })),\n )\n\n query.items.forEach((item, index) => {\n const policy = resolved[index]\n overrides[availabilityItemKey(item)] = {\n isStockManaged: policy.isStockManaged.value,\n isActive: policy.isActive.value,\n preorderReleaseAt: policy.preorderReleaseAt.value ? policy.preorderReleaseAt.value.toISOString() : null,\n policySourceId:\n policy.preorderReleaseAt.policySourceId\n ?? policy.isActive.policySourceId\n ?? policy.isStockManaged.policySourceId\n ?? null,\n }\n })\n\n return overrides\n })\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,eAAe;AAGxB,SAAS,4BAA4B,2BAA2B;AAEhE,SAAS,0BAA0B;AACnC,SAAS,qCAAqC;AAEvC,SAAS,SAAS,WAAyB;AAChD,YAAU,SAAS;AAAA,IACjB,oBAAoB,QAAQ,kBAAkB;AAAA,IAC9C,yBAAyB;AAAA,MACvB,SAAS,CAAC,MAAM,8BAA8B,CAAC;AAAA,IACjD;AAAA,EACF,CAAC;AAKD,6BAA2B,OAAO,UAAU;AAC1C,UAAM,KAAM,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC3D,UAAM,UAAU,8BAA8B,SAAS;AACvD,UAAM,YAA8D,CAAC;AAIrE,UAAM,WAAW,MAAM,QAAQ;AAAA,MAC7B;AAAA,MACA,MAAM,MAAM,IAAI,CAAC,UAAU;AAAA,QACzB,UAAU,MAAM;AAAA,QAChB,gBAAgB,MAAM;AAAA,QACtB,SAAS,MAAM,WAAW;AAAA,QAC1B,WAAW,KAAK;AAAA,QAChB,WAAW,KAAK,oBAAoB;AAAA,MACtC,EAAE;AAAA,IACJ;AAEA,UAAM,MAAM,QAAQ,CAAC,MAAM,UAAU;AACnC,YAAM,SAAS,SAAS,KAAK;AAC7B,gBAAU,oBAAoB,IAAI,CAAC,IAAI;AAAA,QACrC,gBAAgB,OAAO,eAAe;AAAA,QACtC,UAAU,OAAO,SAAS;AAAA,QAC1B,mBAAmB,OAAO,kBAAkB,QAAQ,OAAO,kBAAkB,MAAM,YAAY,IAAI;AAAA,QACnG,gBACE,OAAO,kBAAkB,kBACtB,OAAO,SAAS,kBAChB,OAAO,eAAe,kBACtB;AAAA,MACP;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT,CAAC;AACH;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|