@open-mercato/checkout 0.6.5-canary.4425.1.75a266b232 → 0.6.5-develop.4393.1.de282b5dfd
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 +1 -1
- package/dist/modules/checkout/commands/links.js +0 -13
- package/dist/modules/checkout/commands/links.js.map +2 -2
- package/dist/modules/checkout/commands/templates.js +0 -13
- package/dist/modules/checkout/commands/templates.js.map +2 -2
- package/dist/modules/checkout/components/LinkTemplateForm.js +7 -26
- package/dist/modules/checkout/components/LinkTemplateForm.js.map +2 -2
- package/package.json +5 -5
- package/src/modules/checkout/commands/links.ts +0 -13
- package/src/modules/checkout/commands/templates.ts +0 -13
- package/src/modules/checkout/components/LinkTemplateForm.tsx +7 -26
- package/dist/modules/checkout/__integration__/TC-CHKT-039-stale-delete-lock.spec.js +0 -66
- package/dist/modules/checkout/__integration__/TC-CHKT-039-stale-delete-lock.spec.js.map +0 -7
- package/src/modules/checkout/__integration__/TC-CHKT-039-stale-delete-lock.spec.ts +0 -98
- package/src/modules/checkout/commands/__tests__/optimistic-lock.test.ts +0 -261
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
[build:checkout] found
|
|
1
|
+
[build:checkout] found 147 entry points
|
|
2
2
|
[build:checkout] built successfully
|
|
@@ -3,7 +3,6 @@ import { buildCustomFieldResetMap, loadCustomFieldSnapshot } from "@open-mercato
|
|
|
3
3
|
import { setCustomFieldsIfAny } from "@open-mercato/shared/lib/commands/helpers";
|
|
4
4
|
import { loadCustomFieldValues } from "@open-mercato/shared/lib/crud/custom-fields";
|
|
5
5
|
import { CrudHttpError } from "@open-mercato/shared/lib/crud/errors";
|
|
6
|
-
import { enforceCommandOptimisticLock } from "@open-mercato/shared/lib/crud/optimistic-lock-command";
|
|
7
6
|
import { findOneWithDecryption } from "@open-mercato/shared/lib/encryption/find";
|
|
8
7
|
import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
|
|
9
8
|
import { CheckoutLink, CheckoutLinkTemplate, CheckoutTransaction } from "../data/entities.js";
|
|
@@ -216,12 +215,6 @@ const updateLinkCommand = {
|
|
|
216
215
|
deletedAt: null
|
|
217
216
|
}, void 0, scope);
|
|
218
217
|
if (!link) throw new CrudHttpError(404, { error: "Link not found" });
|
|
219
|
-
enforceCommandOptimisticLock({
|
|
220
|
-
resourceKind: "checkout.link",
|
|
221
|
-
resourceId: link.id,
|
|
222
|
-
current: link.updatedAt ?? null,
|
|
223
|
-
request: ctx.request ?? null
|
|
224
|
-
});
|
|
225
218
|
if (link.isLocked) {
|
|
226
219
|
throw new CrudHttpError(422, { error: "This link has active transactions and cannot be edited" });
|
|
227
220
|
}
|
|
@@ -365,12 +358,6 @@ const deleteLinkCommand = {
|
|
|
365
358
|
deletedAt: null
|
|
366
359
|
}, void 0, scope);
|
|
367
360
|
if (!link) throw new CrudHttpError(404, { error: "Link not found" });
|
|
368
|
-
enforceCommandOptimisticLock({
|
|
369
|
-
resourceKind: "checkout.link",
|
|
370
|
-
resourceId: link.id,
|
|
371
|
-
current: link.updatedAt ?? null,
|
|
372
|
-
request: ctx.request ?? null
|
|
373
|
-
});
|
|
374
361
|
const activeCount = await em.count(CheckoutTransaction, {
|
|
375
362
|
linkId: link.id,
|
|
376
363
|
organizationId: scope.organizationId,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/checkout/commands/links.ts"],
|
|
4
|
-
"sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport type { CommandHandler } from '@open-mercato/shared/lib/commands'\nimport { registerCommand } from '@open-mercato/shared/lib/commands'\nimport { buildCustomFieldResetMap, loadCustomFieldSnapshot } from '@open-mercato/shared/lib/commands/customFieldSnapshots'\nimport { setCustomFieldsIfAny } from '@open-mercato/shared/lib/commands/helpers'\nimport { loadCustomFieldValues } from '@open-mercato/shared/lib/crud/custom-fields'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { enforceCommandOptimisticLock } from '@open-mercato/shared/lib/crud/optimistic-lock-command'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { CheckoutLink, CheckoutLinkTemplate, CheckoutTransaction } from '../data/entities'\nimport { createLinkSchema, updateLinkSchema } from '../data/validators'\nimport { CHECKOUT_ENTITY_IDS } from '../lib/constants'\nimport {\n ensureGatewayProviderConfigured,\n type PaymentGatewayDescriptorService,\n} from '../lib/gatewayProviderAvailability'\nimport { emitCheckoutEvent } from '../events'\nimport {\n deriveConfiguredCurrencies,\n ensureUniqueSlug,\n hashCheckoutPassword,\n isCheckoutLinkPublic,\n parseCheckoutInput,\n pickExplicitParsedOverrides,\n resolveLoadedCheckoutCustomFields,\n serializeTemplateOrLink,\n toMoneyString,\n toTemplateOrLinkMutationInput,\n validateDescriptorCurrencies,\n} from '../lib/utils'\nimport {\n captureLinkSnapshot,\n createLinkFromSnapshot,\n extractUndoPayload,\n readCommandId,\n resolveCommandScope,\n restoreLinkFromSnapshot,\n toCheckoutAuditSnapshot,\n type CheckoutLinkSnapshot,\n} from './shared'\n\nconst ACTIVE_TRANSACTION_STATUSES = ['pending', 'processing']\n\ntype CheckoutLinkUndoPayload = {\n before?: CheckoutLinkSnapshot | null\n after?: CheckoutLinkSnapshot | null\n}\n\nasync function resolveRestoredLinkSlug(\n em: EntityManager,\n snapshot: CheckoutLinkSnapshot,\n): Promise<string> {\n return ensureUniqueSlug(\n em,\n {\n tenantId: snapshot.tenantId,\n organizationId: snapshot.organizationId,\n },\n snapshot.slug,\n snapshot.title ?? snapshot.name,\n snapshot.id,\n )\n}\n\nconst createLinkCommand: CommandHandler<Record<string, unknown>, { id: string; slug: string }> = {\n id: 'checkout.link.create',\n async execute(rawInput, ctx) {\n const { parsed, customFields } = parseCheckoutInput(rawInput, createLinkSchema.parse)\n const scope = resolveCommandScope(ctx)\n const em = ctx.container.resolve('em') as EntityManager\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n\n let sourceValues = parsed\n let templateCustomFields: Record<string, unknown> = {}\n if (parsed.templateId) {\n const template = await findOneWithDecryption(em, CheckoutLinkTemplate, {\n id: parsed.templateId,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n deletedAt: null,\n }, undefined, scope)\n if (!template) throw new CrudHttpError(404, { error: 'Template not found' })\n sourceValues = toTemplateOrLinkMutationInput(template, {\n ...pickExplicitParsedOverrides(rawInput, parsed),\n templateId: template.id,\n })\n const loaded = await loadCustomFieldValues({\n em,\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordIds: [template.id],\n tenantIdByRecord: { [template.id]: scope.tenantId },\n organizationIdByRecord: { [template.id]: scope.organizationId },\n })\n templateCustomFields = resolveLoadedCheckoutCustomFields(loaded[template.id])\n }\n\n validateDescriptorCurrencies(sourceValues.gatewayProviderKey ?? null, deriveConfiguredCurrencies(sourceValues))\n const descriptorService = ctx.container.resolve('paymentGatewayDescriptorService') as PaymentGatewayDescriptorService\n await ensureGatewayProviderConfigured(sourceValues.gatewayProviderKey ?? null, descriptorService, scope)\n if (isCheckoutLinkPublic(sourceValues.status) && !sourceValues.gatewayProviderKey) {\n throw new CrudHttpError(422, { error: 'A payment gateway must be configured before this link can be published' })\n }\n const slug = await ensureUniqueSlug(\n em,\n scope,\n sourceValues.slug ?? null,\n sourceValues.title ?? sourceValues.name,\n )\n const link = em.create(CheckoutLink, {\n ...sourceValues,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n completionCount: 0,\n activeReservationCount: 0,\n isLocked: false,\n fixedPriceAmount: toMoneyString(sourceValues.fixedPriceAmount),\n fixedPriceOriginalAmount: toMoneyString(sourceValues.fixedPriceOriginalAmount),\n customAmountMin: toMoneyString(sourceValues.customAmountMin),\n customAmountMax: toMoneyString(sourceValues.customAmountMax),\n slug,\n passwordHash: await hashCheckoutPassword(sourceValues.password),\n } as any)\n em.persist(link)\n await em.flush()\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: CHECKOUT_ENTITY_IDS.link,\n recordId: link.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n values: { ...templateCustomFields, ...customFields },\n })\n await emitCheckoutEvent('checkout.link.created', {\n id: link.id,\n slug: link.slug,\n status: link.status,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n }).catch(() => undefined)\n if (link.status === 'active') {\n await emitCheckoutEvent('checkout.link.published', {\n id: link.id,\n slug: link.slug,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n }).catch(() => undefined)\n }\n return { id: link.id, slug: link.slug }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const link = await findOneWithDecryption(em, CheckoutLink, { id: result.id })\n if (!link) return null\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: CHECKOUT_ENTITY_IDS.link,\n recordId: link.id,\n tenantId: link.tenantId,\n organizationId: link.organizationId,\n })\n return captureLinkSnapshot(link, custom)\n },\n buildLog: async ({ result, snapshots }) => {\n const { translate } = await resolveTranslations()\n const after = snapshots.after as CheckoutLinkSnapshot | null | undefined\n return {\n actionLabel: translate('checkout.audit.links.create', 'Create pay link'),\n resourceKind: 'checkout.link',\n resourceId: result.id,\n tenantId: after?.tenantId ?? null,\n organizationId: after?.organizationId ?? null,\n snapshotAfter: after ? toCheckoutAuditSnapshot(after) : null,\n payload: {\n undo: {\n after: after ?? null,\n } satisfies CheckoutLinkUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const after = extractUndoPayload<CheckoutLinkUndoPayload>(logEntry)?.after\n if (!after) return\n const em = ctx.container.resolve('em') as EntityManager\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n const reset = buildCustomFieldResetMap(undefined, after.custom)\n if (Object.keys(reset).length) {\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: CHECKOUT_ENTITY_IDS.link,\n recordId: after.id,\n tenantId: after.tenantId,\n organizationId: after.organizationId,\n values: reset,\n notify: false,\n })\n }\n const link = await em.findOne(CheckoutLink, { id: after.id })\n if (!link) return\n link.deletedAt = new Date()\n await em.flush()\n },\n}\n\nconst updateLinkCommand: CommandHandler<Record<string, unknown>, { ok: true; slug: string }> = {\n id: 'checkout.link.update',\n async prepare(rawInput, ctx) {\n const { parsed } = parseCheckoutInput(rawInput, updateLinkSchema.parse)\n const scope = resolveCommandScope(ctx)\n const em = ctx.container.resolve('em') as EntityManager\n const link = await findOneWithDecryption(em, CheckoutLink, {\n id: parsed.id,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n deletedAt: null,\n }, undefined, scope)\n if (!link) return {}\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: CHECKOUT_ENTITY_IDS.link,\n recordId: link.id,\n tenantId: link.tenantId,\n organizationId: link.organizationId,\n })\n return { before: captureLinkSnapshot(link, custom) }\n },\n async execute(rawInput, ctx) {\n const { parsed, customFields } = parseCheckoutInput(rawInput, updateLinkSchema.parse)\n const scope = resolveCommandScope(ctx)\n const em = ctx.container.resolve('em') as EntityManager\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n const link = await findOneWithDecryption(em, CheckoutLink, {\n id: parsed.id,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n deletedAt: null,\n }, undefined, scope)\n if (!link) throw new CrudHttpError(404, { error: 'Link not found' })\n enforceCommandOptimisticLock({\n resourceKind: 'checkout.link',\n resourceId: link.id,\n current: link.updatedAt ?? null,\n request: ctx.request ?? null,\n })\n if (link.isLocked) {\n throw new CrudHttpError(422, { error: 'This link has active transactions and cannot be edited' })\n }\n const nextValues = toTemplateOrLinkMutationInput(link, parsed)\n validateDescriptorCurrencies(\n parsed.gatewayProviderKey ?? link.gatewayProviderKey ?? null,\n deriveConfiguredCurrencies(nextValues),\n )\n const descriptorService = ctx.container.resolve('paymentGatewayDescriptorService') as PaymentGatewayDescriptorService\n await ensureGatewayProviderConfigured(nextValues.gatewayProviderKey ?? null, descriptorService, scope)\n if (isCheckoutLinkPublic(nextValues.status) && !nextValues.gatewayProviderKey) {\n throw new CrudHttpError(422, { error: 'A payment gateway must be configured before this link can be published' })\n }\n const slug = parsed.slug !== undefined || parsed.name !== undefined || parsed.title !== undefined\n ? await ensureUniqueSlug(em, scope, parsed.slug ?? link.slug, parsed.title ?? parsed.name ?? link.title ?? link.name, link.id)\n : link.slug\n const passwordHash = parsed.password !== undefined ? await hashCheckoutPassword(parsed.password) : link.passwordHash\n const previousStatus = link.status\n Object.assign(link, {\n ...parsed,\n fixedPriceAmount: parsed.fixedPriceAmount !== undefined ? toMoneyString(parsed.fixedPriceAmount) : link.fixedPriceAmount,\n fixedPriceOriginalAmount: parsed.fixedPriceOriginalAmount !== undefined ? toMoneyString(parsed.fixedPriceOriginalAmount) : link.fixedPriceOriginalAmount,\n customAmountMin: parsed.customAmountMin !== undefined ? toMoneyString(parsed.customAmountMin) : link.customAmountMin,\n customAmountMax: parsed.customAmountMax !== undefined ? toMoneyString(parsed.customAmountMax) : link.customAmountMax,\n slug,\n passwordHash,\n })\n await em.flush()\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: CHECKOUT_ENTITY_IDS.link,\n recordId: link.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n values: customFields,\n })\n await emitCheckoutEvent('checkout.link.updated', {\n id: link.id,\n slug: link.slug,\n status: link.status,\n previousStatus,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n }).catch(() => undefined)\n if (previousStatus !== 'active' && link.status === 'active') {\n await emitCheckoutEvent('checkout.link.published', {\n id: link.id,\n slug: link.slug,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n }).catch(() => undefined)\n }\n return { ok: true, slug: link.slug }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const link = await findOneWithDecryption(em, CheckoutLink, { slug: result.slug, deletedAt: null })\n if (!link) return null\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: CHECKOUT_ENTITY_IDS.link,\n recordId: link.id,\n tenantId: link.tenantId,\n organizationId: link.organizationId,\n })\n return captureLinkSnapshot(link, custom)\n },\n buildLog: async ({ snapshots, result }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as CheckoutLinkSnapshot | null | undefined\n const after = snapshots.after as CheckoutLinkSnapshot | null | undefined\n return {\n actionLabel: translate('checkout.audit.links.update', 'Update pay link'),\n resourceKind: 'checkout.link',\n resourceId: after?.id ?? before?.id ?? null,\n tenantId: after?.tenantId ?? before?.tenantId ?? null,\n organizationId: after?.organizationId ?? before?.organizationId ?? null,\n snapshotBefore: before ? toCheckoutAuditSnapshot(before) : null,\n snapshotAfter: after ? toCheckoutAuditSnapshot(after) : null,\n payload: {\n undo: {\n before: before ?? null,\n after: after ?? null,\n } satisfies CheckoutLinkUndoPayload,\n },\n context: result.slug ? { slug: result.slug } : null,\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const undo = extractUndoPayload<CheckoutLinkUndoPayload>(logEntry)\n const before = undo?.before\n const after = undo?.after\n if (!before) return\n const em = ctx.container.resolve('em') as EntityManager\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n const link = await em.findOne(CheckoutLink, { id: before.id, deletedAt: null })\n if (!link) return\n restoreLinkFromSnapshot(link, before)\n link.slug = await resolveRestoredLinkSlug(em, before)\n await em.flush()\n const reset = buildCustomFieldResetMap(before.custom, after?.custom)\n if (Object.keys(reset).length) {\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: CHECKOUT_ENTITY_IDS.link,\n recordId: before.id,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n values: reset,\n notify: false,\n })\n }\n },\n}\n\nconst deleteLinkCommand: CommandHandler<Record<string, unknown>, { ok: true }> = {\n id: 'checkout.link.delete',\n async prepare(rawInput, ctx) {\n const linkId = readCommandId(rawInput, 'Link id is required')\n const scope = resolveCommandScope(ctx)\n const em = ctx.container.resolve('em') as EntityManager\n const link = await findOneWithDecryption(em, CheckoutLink, {\n id: linkId,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n deletedAt: null,\n }, undefined, scope)\n if (!link) return {}\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: CHECKOUT_ENTITY_IDS.link,\n recordId: link.id,\n tenantId: link.tenantId,\n organizationId: link.organizationId,\n })\n return { before: captureLinkSnapshot(link, custom) }\n },\n async execute(rawInput, ctx) {\n const linkId = readCommandId(rawInput, 'Link id is required')\n const scope = resolveCommandScope(ctx)\n const em = ctx.container.resolve('em') as EntityManager\n const link = await findOneWithDecryption(em, CheckoutLink, {\n id: linkId,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n deletedAt: null,\n }, undefined, scope)\n if (!link) throw new CrudHttpError(404, { error: 'Link not found' })\n enforceCommandOptimisticLock({\n resourceKind: 'checkout.link',\n resourceId: link.id,\n current: link.updatedAt ?? null,\n request: ctx.request ?? null,\n })\n const activeCount = await em.count(CheckoutTransaction, {\n linkId: link.id,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n status: { $in: ACTIVE_TRANSACTION_STATUSES as Array<CheckoutTransaction['status']> },\n })\n if (activeCount > 0) {\n throw new CrudHttpError(422, { error: 'This link has active transactions and cannot be deleted' })\n }\n link.deletedAt = new Date()\n await em.flush()\n await emitCheckoutEvent('checkout.link.deleted', {\n id: link.id,\n slug: link.slug,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n }).catch(() => undefined)\n return { ok: true }\n },\n buildLog: async ({ snapshots, input }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as CheckoutLinkSnapshot | null | undefined\n return {\n actionLabel: translate('checkout.audit.links.delete', 'Delete pay link'),\n resourceKind: 'checkout.link',\n resourceId: before?.id ?? readCommandId(input, 'Link id is required'),\n tenantId: before?.tenantId ?? null,\n organizationId: before?.organizationId ?? null,\n snapshotBefore: before ? toCheckoutAuditSnapshot(before) : null,\n payload: {\n undo: {\n before: before ?? null,\n } satisfies CheckoutLinkUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const before = extractUndoPayload<CheckoutLinkUndoPayload>(logEntry)?.before\n if (!before) return\n const em = ctx.container.resolve('em') as EntityManager\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n let link = await em.findOne(CheckoutLink, { id: before.id })\n if (link) {\n restoreLinkFromSnapshot(link, before)\n link.slug = await resolveRestoredLinkSlug(em, before)\n } else {\n link = em.create(CheckoutLink, {\n ...createLinkFromSnapshot(before),\n slug: await resolveRestoredLinkSlug(em, before),\n })\n em.persist(link)\n }\n await em.flush()\n const reset = buildCustomFieldResetMap(before.custom, undefined)\n if (Object.keys(reset).length) {\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: CHECKOUT_ENTITY_IDS.link,\n recordId: before.id,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n values: reset,\n notify: false,\n })\n }\n },\n}\n\nregisterCommand(createLinkCommand)\nregisterCommand(updateLinkCommand)\nregisterCommand(deleteLinkCommand)\n\nexport function serializeLinkRecord(record: CheckoutLink) {\n return serializeTemplateOrLink(record)\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport type { CommandHandler } from '@open-mercato/shared/lib/commands'\nimport { registerCommand } from '@open-mercato/shared/lib/commands'\nimport { buildCustomFieldResetMap, loadCustomFieldSnapshot } from '@open-mercato/shared/lib/commands/customFieldSnapshots'\nimport { setCustomFieldsIfAny } from '@open-mercato/shared/lib/commands/helpers'\nimport { loadCustomFieldValues } from '@open-mercato/shared/lib/crud/custom-fields'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { CheckoutLink, CheckoutLinkTemplate, CheckoutTransaction } from '../data/entities'\nimport { createLinkSchema, updateLinkSchema } from '../data/validators'\nimport { CHECKOUT_ENTITY_IDS } from '../lib/constants'\nimport {\n ensureGatewayProviderConfigured,\n type PaymentGatewayDescriptorService,\n} from '../lib/gatewayProviderAvailability'\nimport { emitCheckoutEvent } from '../events'\nimport {\n deriveConfiguredCurrencies,\n ensureUniqueSlug,\n hashCheckoutPassword,\n isCheckoutLinkPublic,\n parseCheckoutInput,\n pickExplicitParsedOverrides,\n resolveLoadedCheckoutCustomFields,\n serializeTemplateOrLink,\n toMoneyString,\n toTemplateOrLinkMutationInput,\n validateDescriptorCurrencies,\n} from '../lib/utils'\nimport {\n captureLinkSnapshot,\n createLinkFromSnapshot,\n extractUndoPayload,\n readCommandId,\n resolveCommandScope,\n restoreLinkFromSnapshot,\n toCheckoutAuditSnapshot,\n type CheckoutLinkSnapshot,\n} from './shared'\n\nconst ACTIVE_TRANSACTION_STATUSES = ['pending', 'processing']\n\ntype CheckoutLinkUndoPayload = {\n before?: CheckoutLinkSnapshot | null\n after?: CheckoutLinkSnapshot | null\n}\n\nasync function resolveRestoredLinkSlug(\n em: EntityManager,\n snapshot: CheckoutLinkSnapshot,\n): Promise<string> {\n return ensureUniqueSlug(\n em,\n {\n tenantId: snapshot.tenantId,\n organizationId: snapshot.organizationId,\n },\n snapshot.slug,\n snapshot.title ?? snapshot.name,\n snapshot.id,\n )\n}\n\nconst createLinkCommand: CommandHandler<Record<string, unknown>, { id: string; slug: string }> = {\n id: 'checkout.link.create',\n async execute(rawInput, ctx) {\n const { parsed, customFields } = parseCheckoutInput(rawInput, createLinkSchema.parse)\n const scope = resolveCommandScope(ctx)\n const em = ctx.container.resolve('em') as EntityManager\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n\n let sourceValues = parsed\n let templateCustomFields: Record<string, unknown> = {}\n if (parsed.templateId) {\n const template = await findOneWithDecryption(em, CheckoutLinkTemplate, {\n id: parsed.templateId,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n deletedAt: null,\n }, undefined, scope)\n if (!template) throw new CrudHttpError(404, { error: 'Template not found' })\n sourceValues = toTemplateOrLinkMutationInput(template, {\n ...pickExplicitParsedOverrides(rawInput, parsed),\n templateId: template.id,\n })\n const loaded = await loadCustomFieldValues({\n em,\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordIds: [template.id],\n tenantIdByRecord: { [template.id]: scope.tenantId },\n organizationIdByRecord: { [template.id]: scope.organizationId },\n })\n templateCustomFields = resolveLoadedCheckoutCustomFields(loaded[template.id])\n }\n\n validateDescriptorCurrencies(sourceValues.gatewayProviderKey ?? null, deriveConfiguredCurrencies(sourceValues))\n const descriptorService = ctx.container.resolve('paymentGatewayDescriptorService') as PaymentGatewayDescriptorService\n await ensureGatewayProviderConfigured(sourceValues.gatewayProviderKey ?? null, descriptorService, scope)\n if (isCheckoutLinkPublic(sourceValues.status) && !sourceValues.gatewayProviderKey) {\n throw new CrudHttpError(422, { error: 'A payment gateway must be configured before this link can be published' })\n }\n const slug = await ensureUniqueSlug(\n em,\n scope,\n sourceValues.slug ?? null,\n sourceValues.title ?? sourceValues.name,\n )\n const link = em.create(CheckoutLink, {\n ...sourceValues,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n completionCount: 0,\n activeReservationCount: 0,\n isLocked: false,\n fixedPriceAmount: toMoneyString(sourceValues.fixedPriceAmount),\n fixedPriceOriginalAmount: toMoneyString(sourceValues.fixedPriceOriginalAmount),\n customAmountMin: toMoneyString(sourceValues.customAmountMin),\n customAmountMax: toMoneyString(sourceValues.customAmountMax),\n slug,\n passwordHash: await hashCheckoutPassword(sourceValues.password),\n } as any)\n em.persist(link)\n await em.flush()\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: CHECKOUT_ENTITY_IDS.link,\n recordId: link.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n values: { ...templateCustomFields, ...customFields },\n })\n await emitCheckoutEvent('checkout.link.created', {\n id: link.id,\n slug: link.slug,\n status: link.status,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n }).catch(() => undefined)\n if (link.status === 'active') {\n await emitCheckoutEvent('checkout.link.published', {\n id: link.id,\n slug: link.slug,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n }).catch(() => undefined)\n }\n return { id: link.id, slug: link.slug }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const link = await findOneWithDecryption(em, CheckoutLink, { id: result.id })\n if (!link) return null\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: CHECKOUT_ENTITY_IDS.link,\n recordId: link.id,\n tenantId: link.tenantId,\n organizationId: link.organizationId,\n })\n return captureLinkSnapshot(link, custom)\n },\n buildLog: async ({ result, snapshots }) => {\n const { translate } = await resolveTranslations()\n const after = snapshots.after as CheckoutLinkSnapshot | null | undefined\n return {\n actionLabel: translate('checkout.audit.links.create', 'Create pay link'),\n resourceKind: 'checkout.link',\n resourceId: result.id,\n tenantId: after?.tenantId ?? null,\n organizationId: after?.organizationId ?? null,\n snapshotAfter: after ? toCheckoutAuditSnapshot(after) : null,\n payload: {\n undo: {\n after: after ?? null,\n } satisfies CheckoutLinkUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const after = extractUndoPayload<CheckoutLinkUndoPayload>(logEntry)?.after\n if (!after) return\n const em = ctx.container.resolve('em') as EntityManager\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n const reset = buildCustomFieldResetMap(undefined, after.custom)\n if (Object.keys(reset).length) {\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: CHECKOUT_ENTITY_IDS.link,\n recordId: after.id,\n tenantId: after.tenantId,\n organizationId: after.organizationId,\n values: reset,\n notify: false,\n })\n }\n const link = await em.findOne(CheckoutLink, { id: after.id })\n if (!link) return\n link.deletedAt = new Date()\n await em.flush()\n },\n}\n\nconst updateLinkCommand: CommandHandler<Record<string, unknown>, { ok: true; slug: string }> = {\n id: 'checkout.link.update',\n async prepare(rawInput, ctx) {\n const { parsed } = parseCheckoutInput(rawInput, updateLinkSchema.parse)\n const scope = resolveCommandScope(ctx)\n const em = ctx.container.resolve('em') as EntityManager\n const link = await findOneWithDecryption(em, CheckoutLink, {\n id: parsed.id,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n deletedAt: null,\n }, undefined, scope)\n if (!link) return {}\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: CHECKOUT_ENTITY_IDS.link,\n recordId: link.id,\n tenantId: link.tenantId,\n organizationId: link.organizationId,\n })\n return { before: captureLinkSnapshot(link, custom) }\n },\n async execute(rawInput, ctx) {\n const { parsed, customFields } = parseCheckoutInput(rawInput, updateLinkSchema.parse)\n const scope = resolveCommandScope(ctx)\n const em = ctx.container.resolve('em') as EntityManager\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n const link = await findOneWithDecryption(em, CheckoutLink, {\n id: parsed.id,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n deletedAt: null,\n }, undefined, scope)\n if (!link) throw new CrudHttpError(404, { error: 'Link not found' })\n if (link.isLocked) {\n throw new CrudHttpError(422, { error: 'This link has active transactions and cannot be edited' })\n }\n const nextValues = toTemplateOrLinkMutationInput(link, parsed)\n validateDescriptorCurrencies(\n parsed.gatewayProviderKey ?? link.gatewayProviderKey ?? null,\n deriveConfiguredCurrencies(nextValues),\n )\n const descriptorService = ctx.container.resolve('paymentGatewayDescriptorService') as PaymentGatewayDescriptorService\n await ensureGatewayProviderConfigured(nextValues.gatewayProviderKey ?? null, descriptorService, scope)\n if (isCheckoutLinkPublic(nextValues.status) && !nextValues.gatewayProviderKey) {\n throw new CrudHttpError(422, { error: 'A payment gateway must be configured before this link can be published' })\n }\n const slug = parsed.slug !== undefined || parsed.name !== undefined || parsed.title !== undefined\n ? await ensureUniqueSlug(em, scope, parsed.slug ?? link.slug, parsed.title ?? parsed.name ?? link.title ?? link.name, link.id)\n : link.slug\n const passwordHash = parsed.password !== undefined ? await hashCheckoutPassword(parsed.password) : link.passwordHash\n const previousStatus = link.status\n Object.assign(link, {\n ...parsed,\n fixedPriceAmount: parsed.fixedPriceAmount !== undefined ? toMoneyString(parsed.fixedPriceAmount) : link.fixedPriceAmount,\n fixedPriceOriginalAmount: parsed.fixedPriceOriginalAmount !== undefined ? toMoneyString(parsed.fixedPriceOriginalAmount) : link.fixedPriceOriginalAmount,\n customAmountMin: parsed.customAmountMin !== undefined ? toMoneyString(parsed.customAmountMin) : link.customAmountMin,\n customAmountMax: parsed.customAmountMax !== undefined ? toMoneyString(parsed.customAmountMax) : link.customAmountMax,\n slug,\n passwordHash,\n })\n await em.flush()\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: CHECKOUT_ENTITY_IDS.link,\n recordId: link.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n values: customFields,\n })\n await emitCheckoutEvent('checkout.link.updated', {\n id: link.id,\n slug: link.slug,\n status: link.status,\n previousStatus,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n }).catch(() => undefined)\n if (previousStatus !== 'active' && link.status === 'active') {\n await emitCheckoutEvent('checkout.link.published', {\n id: link.id,\n slug: link.slug,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n }).catch(() => undefined)\n }\n return { ok: true, slug: link.slug }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const link = await findOneWithDecryption(em, CheckoutLink, { slug: result.slug, deletedAt: null })\n if (!link) return null\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: CHECKOUT_ENTITY_IDS.link,\n recordId: link.id,\n tenantId: link.tenantId,\n organizationId: link.organizationId,\n })\n return captureLinkSnapshot(link, custom)\n },\n buildLog: async ({ snapshots, result }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as CheckoutLinkSnapshot | null | undefined\n const after = snapshots.after as CheckoutLinkSnapshot | null | undefined\n return {\n actionLabel: translate('checkout.audit.links.update', 'Update pay link'),\n resourceKind: 'checkout.link',\n resourceId: after?.id ?? before?.id ?? null,\n tenantId: after?.tenantId ?? before?.tenantId ?? null,\n organizationId: after?.organizationId ?? before?.organizationId ?? null,\n snapshotBefore: before ? toCheckoutAuditSnapshot(before) : null,\n snapshotAfter: after ? toCheckoutAuditSnapshot(after) : null,\n payload: {\n undo: {\n before: before ?? null,\n after: after ?? null,\n } satisfies CheckoutLinkUndoPayload,\n },\n context: result.slug ? { slug: result.slug } : null,\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const undo = extractUndoPayload<CheckoutLinkUndoPayload>(logEntry)\n const before = undo?.before\n const after = undo?.after\n if (!before) return\n const em = ctx.container.resolve('em') as EntityManager\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n const link = await em.findOne(CheckoutLink, { id: before.id, deletedAt: null })\n if (!link) return\n restoreLinkFromSnapshot(link, before)\n link.slug = await resolveRestoredLinkSlug(em, before)\n await em.flush()\n const reset = buildCustomFieldResetMap(before.custom, after?.custom)\n if (Object.keys(reset).length) {\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: CHECKOUT_ENTITY_IDS.link,\n recordId: before.id,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n values: reset,\n notify: false,\n })\n }\n },\n}\n\nconst deleteLinkCommand: CommandHandler<Record<string, unknown>, { ok: true }> = {\n id: 'checkout.link.delete',\n async prepare(rawInput, ctx) {\n const linkId = readCommandId(rawInput, 'Link id is required')\n const scope = resolveCommandScope(ctx)\n const em = ctx.container.resolve('em') as EntityManager\n const link = await findOneWithDecryption(em, CheckoutLink, {\n id: linkId,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n deletedAt: null,\n }, undefined, scope)\n if (!link) return {}\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: CHECKOUT_ENTITY_IDS.link,\n recordId: link.id,\n tenantId: link.tenantId,\n organizationId: link.organizationId,\n })\n return { before: captureLinkSnapshot(link, custom) }\n },\n async execute(rawInput, ctx) {\n const linkId = readCommandId(rawInput, 'Link id is required')\n const scope = resolveCommandScope(ctx)\n const em = ctx.container.resolve('em') as EntityManager\n const link = await findOneWithDecryption(em, CheckoutLink, {\n id: linkId,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n deletedAt: null,\n }, undefined, scope)\n if (!link) throw new CrudHttpError(404, { error: 'Link not found' })\n const activeCount = await em.count(CheckoutTransaction, {\n linkId: link.id,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n status: { $in: ACTIVE_TRANSACTION_STATUSES as Array<CheckoutTransaction['status']> },\n })\n if (activeCount > 0) {\n throw new CrudHttpError(422, { error: 'This link has active transactions and cannot be deleted' })\n }\n link.deletedAt = new Date()\n await em.flush()\n await emitCheckoutEvent('checkout.link.deleted', {\n id: link.id,\n slug: link.slug,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n }).catch(() => undefined)\n return { ok: true }\n },\n buildLog: async ({ snapshots, input }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as CheckoutLinkSnapshot | null | undefined\n return {\n actionLabel: translate('checkout.audit.links.delete', 'Delete pay link'),\n resourceKind: 'checkout.link',\n resourceId: before?.id ?? readCommandId(input, 'Link id is required'),\n tenantId: before?.tenantId ?? null,\n organizationId: before?.organizationId ?? null,\n snapshotBefore: before ? toCheckoutAuditSnapshot(before) : null,\n payload: {\n undo: {\n before: before ?? null,\n } satisfies CheckoutLinkUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const before = extractUndoPayload<CheckoutLinkUndoPayload>(logEntry)?.before\n if (!before) return\n const em = ctx.container.resolve('em') as EntityManager\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n let link = await em.findOne(CheckoutLink, { id: before.id })\n if (link) {\n restoreLinkFromSnapshot(link, before)\n link.slug = await resolveRestoredLinkSlug(em, before)\n } else {\n link = em.create(CheckoutLink, {\n ...createLinkFromSnapshot(before),\n slug: await resolveRestoredLinkSlug(em, before),\n })\n em.persist(link)\n }\n await em.flush()\n const reset = buildCustomFieldResetMap(before.custom, undefined)\n if (Object.keys(reset).length) {\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: CHECKOUT_ENTITY_IDS.link,\n recordId: before.id,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n values: reset,\n notify: false,\n })\n }\n },\n}\n\nregisterCommand(createLinkCommand)\nregisterCommand(updateLinkCommand)\nregisterCommand(deleteLinkCommand)\n\nexport function serializeLinkRecord(record: CheckoutLink) {\n return serializeTemplateOrLink(record)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -2,7 +2,6 @@ import { registerCommand } from "@open-mercato/shared/lib/commands";
|
|
|
2
2
|
import { buildCustomFieldResetMap, loadCustomFieldSnapshot } from "@open-mercato/shared/lib/commands/customFieldSnapshots";
|
|
3
3
|
import { setCustomFieldsIfAny } from "@open-mercato/shared/lib/commands/helpers";
|
|
4
4
|
import { CrudHttpError } from "@open-mercato/shared/lib/crud/errors";
|
|
5
|
-
import { enforceCommandOptimisticLock } from "@open-mercato/shared/lib/crud/optimistic-lock-command";
|
|
6
5
|
import { findOneWithDecryption, findWithDecryption } from "@open-mercato/shared/lib/encryption/find";
|
|
7
6
|
import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
|
|
8
7
|
import { CheckoutLink, CheckoutLinkTemplate } from "../data/entities.js";
|
|
@@ -203,12 +202,6 @@ const updateTemplateCommand = {
|
|
|
203
202
|
deletedAt: null
|
|
204
203
|
}, void 0, scope);
|
|
205
204
|
if (!template) throw new CrudHttpError(404, { error: "Template not found" });
|
|
206
|
-
enforceCommandOptimisticLock({
|
|
207
|
-
resourceKind: "checkout.template",
|
|
208
|
-
resourceId: template.id,
|
|
209
|
-
current: template.updatedAt ?? null,
|
|
210
|
-
request: ctx.request ?? null
|
|
211
|
-
});
|
|
212
205
|
const beforeCustom = await loadCustomFieldSnapshot(em, {
|
|
213
206
|
entityId: CHECKOUT_ENTITY_IDS.template,
|
|
214
207
|
recordId: template.id,
|
|
@@ -356,12 +349,6 @@ const deleteTemplateCommand = {
|
|
|
356
349
|
deletedAt: null
|
|
357
350
|
}, void 0, scope);
|
|
358
351
|
if (!template) throw new CrudHttpError(404, { error: "Template not found" });
|
|
359
|
-
enforceCommandOptimisticLock({
|
|
360
|
-
resourceKind: "checkout.template",
|
|
361
|
-
resourceId: template.id,
|
|
362
|
-
current: template.updatedAt ?? null,
|
|
363
|
-
request: ctx.request ?? null
|
|
364
|
-
});
|
|
365
352
|
template.deletedAt = /* @__PURE__ */ new Date();
|
|
366
353
|
await em.flush();
|
|
367
354
|
await emitCheckoutEvent("checkout.template.deleted", {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/checkout/commands/templates.ts"],
|
|
4
|
-
"sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport type { CommandHandler } from '@open-mercato/shared/lib/commands'\nimport { registerCommand } from '@open-mercato/shared/lib/commands'\nimport { buildCustomFieldResetMap, loadCustomFieldSnapshot } from '@open-mercato/shared/lib/commands/customFieldSnapshots'\nimport { setCustomFieldsIfAny } from '@open-mercato/shared/lib/commands/helpers'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { enforceCommandOptimisticLock } from '@open-mercato/shared/lib/crud/optimistic-lock-command'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { CheckoutLink, CheckoutLinkTemplate } from '../data/entities'\nimport { createTemplateSchema, updateTemplateSchema } from '../data/validators'\nimport { CHECKOUT_ENTITY_IDS } from '../lib/constants'\nimport {\n ensureGatewayProviderConfigured,\n type PaymentGatewayDescriptorService,\n} from '../lib/gatewayProviderAvailability'\nimport { emitCheckoutEvent } from '../events'\nimport {\n deriveConfiguredCurrencies,\n hashCheckoutPassword,\n parseCheckoutInput,\n serializeTemplateOrLink,\n toMoneyString,\n validateDescriptorCurrencies,\n} from '../lib/utils'\nimport {\n buildSelectiveLinkedCustomFieldUpdates,\n buildSelectiveLinkedLinkSnapshot,\n captureTemplateSnapshot,\n createTemplateFromSnapshot,\n extractUndoPayload,\n captureLinkSnapshot,\n readCommandId,\n resolveCommandScope,\n restoreLinkFromSnapshot,\n restoreTemplateFromSnapshot,\n toCheckoutAuditSnapshot,\n type CheckoutTemplateSnapshot,\n} from './shared'\n\ntype CheckoutTemplateUndoPayload = {\n before?: CheckoutTemplateSnapshot | null\n after?: CheckoutTemplateSnapshot | null\n}\n\nasync function syncLinkedLinksWithTemplateSnapshot(params: {\n em: EntityManager\n dataEngine: DataEngine\n scope: { organizationId: string; tenantId: string }\n templateId: string\n before: CheckoutTemplateSnapshot\n after: CheckoutTemplateSnapshot\n}) {\n const { em, dataEngine, scope, templateId, before, after } = params\n const linkedLinks = await findWithDecryption(\n em,\n CheckoutLink,\n {\n templateId,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n deletedAt: null,\n isLocked: false,\n },\n undefined,\n scope,\n )\n\n let changedLinks = false\n\n for (const link of linkedLinks) {\n const currentLinkSnapshot = captureLinkSnapshot(link)\n const nextLinkSnapshot = buildSelectiveLinkedLinkSnapshot(currentLinkSnapshot, before, after)\n if (nextLinkSnapshot.changed) {\n restoreLinkFromSnapshot(link, nextLinkSnapshot.snapshot)\n changedLinks = true\n }\n\n const currentCustom = await loadCustomFieldSnapshot(em, {\n entityId: CHECKOUT_ENTITY_IDS.link,\n recordId: link.id,\n tenantId: link.tenantId,\n organizationId: link.organizationId,\n })\n const customFieldUpdates = buildSelectiveLinkedCustomFieldUpdates(currentCustom, before.custom, after.custom)\n if (Object.keys(customFieldUpdates).length > 0) {\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: CHECKOUT_ENTITY_IDS.link,\n recordId: link.id,\n tenantId: link.tenantId,\n organizationId: link.organizationId,\n values: customFieldUpdates,\n })\n }\n }\n\n if (changedLinks) {\n await em.flush()\n }\n}\n\nconst createTemplateCommand: CommandHandler<Record<string, unknown>, { id: string }> = {\n id: 'checkout.template.create',\n async execute(rawInput, ctx) {\n const { parsed, customFields } = parseCheckoutInput(rawInput, createTemplateSchema.parse)\n const scope = resolveCommandScope(ctx)\n validateDescriptorCurrencies(parsed.gatewayProviderKey, deriveConfiguredCurrencies(parsed))\n const descriptorService = ctx.container.resolve('paymentGatewayDescriptorService') as PaymentGatewayDescriptorService\n await ensureGatewayProviderConfigured(parsed.gatewayProviderKey, descriptorService, scope)\n const em = ctx.container.resolve('em') as EntityManager\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n const template = em.create(CheckoutLinkTemplate, {\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n ...parsed,\n fixedPriceAmount: toMoneyString(parsed.fixedPriceAmount),\n fixedPriceOriginalAmount: toMoneyString(parsed.fixedPriceOriginalAmount),\n customAmountMin: toMoneyString(parsed.customAmountMin),\n customAmountMax: toMoneyString(parsed.customAmountMax),\n passwordHash: await hashCheckoutPassword(parsed.password),\n } as any)\n em.persist(template)\n await em.flush()\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordId: template.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n values: customFields,\n })\n await emitCheckoutEvent('checkout.template.created', {\n id: template.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n }).catch(() => undefined)\n return { id: template.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const template = await findOneWithDecryption(em, CheckoutLinkTemplate, { id: result.id })\n if (!template) return null\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordId: template.id,\n tenantId: template.tenantId,\n organizationId: template.organizationId,\n })\n return captureTemplateSnapshot(template, custom)\n },\n buildLog: async ({ result, snapshots }) => {\n const { translate } = await resolveTranslations()\n const after = snapshots.after as CheckoutTemplateSnapshot | null | undefined\n return {\n actionLabel: translate('checkout.audit.templates.create', 'Create pay-link template'),\n resourceKind: 'checkout.template',\n resourceId: result.id,\n tenantId: after?.tenantId ?? null,\n organizationId: after?.organizationId ?? null,\n snapshotAfter: after ? toCheckoutAuditSnapshot(after) : null,\n payload: {\n undo: {\n after: after ?? null,\n } satisfies CheckoutTemplateUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const after = extractUndoPayload<CheckoutTemplateUndoPayload>(logEntry)?.after\n if (!after) return\n const em = ctx.container.resolve('em') as EntityManager\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n const reset = buildCustomFieldResetMap(undefined, after.custom)\n if (Object.keys(reset).length) {\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordId: after.id,\n tenantId: after.tenantId,\n organizationId: after.organizationId,\n values: reset,\n notify: false,\n })\n }\n const template = await em.findOne(CheckoutLinkTemplate, { id: after.id })\n if (!template) return\n template.deletedAt = new Date()\n await em.flush()\n },\n}\n\nconst updateTemplateCommand: CommandHandler<Record<string, unknown>, { ok: true }> = {\n id: 'checkout.template.update',\n async prepare(rawInput, ctx) {\n const { parsed } = parseCheckoutInput(rawInput, updateTemplateSchema.parse)\n const scope = resolveCommandScope(ctx)\n const em = ctx.container.resolve('em') as EntityManager\n const template = await findOneWithDecryption(em, CheckoutLinkTemplate, {\n id: parsed.id,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n deletedAt: null,\n }, undefined, scope)\n if (!template) return {}\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordId: template.id,\n tenantId: template.tenantId,\n organizationId: template.organizationId,\n })\n return { before: captureTemplateSnapshot(template, custom) }\n },\n async execute(rawInput, ctx) {\n const { parsed, customFields } = parseCheckoutInput(rawInput, updateTemplateSchema.parse)\n const scope = resolveCommandScope(ctx)\n validateDescriptorCurrencies(parsed.gatewayProviderKey ?? null, deriveConfiguredCurrencies(parsed))\n const descriptorService = ctx.container.resolve('paymentGatewayDescriptorService') as PaymentGatewayDescriptorService\n await ensureGatewayProviderConfigured(parsed.gatewayProviderKey ?? null, descriptorService, scope)\n const em = ctx.container.resolve('em') as EntityManager\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n const template = await findOneWithDecryption(em, CheckoutLinkTemplate, {\n id: parsed.id,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n deletedAt: null,\n }, undefined, scope)\n if (!template) throw new CrudHttpError(404, { error: 'Template not found' })\n enforceCommandOptimisticLock({\n resourceKind: 'checkout.template',\n resourceId: template.id,\n current: template.updatedAt ?? null,\n request: ctx.request ?? null,\n })\n const beforeCustom = await loadCustomFieldSnapshot(em, {\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordId: template.id,\n tenantId: template.tenantId,\n organizationId: template.organizationId,\n })\n const beforeSnapshot = captureTemplateSnapshot(template, beforeCustom)\n const passwordHash = parsed.password !== undefined\n ? await hashCheckoutPassword(parsed.password)\n : template.passwordHash\n Object.assign(template, {\n ...parsed,\n fixedPriceAmount: parsed.fixedPriceAmount !== undefined ? toMoneyString(parsed.fixedPriceAmount) : template.fixedPriceAmount,\n fixedPriceOriginalAmount: parsed.fixedPriceOriginalAmount !== undefined ? toMoneyString(parsed.fixedPriceOriginalAmount) : template.fixedPriceOriginalAmount,\n customAmountMin: parsed.customAmountMin !== undefined ? toMoneyString(parsed.customAmountMin) : template.customAmountMin,\n customAmountMax: parsed.customAmountMax !== undefined ? toMoneyString(parsed.customAmountMax) : template.customAmountMax,\n passwordHash,\n })\n await em.flush()\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordId: template.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n values: customFields,\n })\n const afterCustom = await loadCustomFieldSnapshot(em, {\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordId: template.id,\n tenantId: template.tenantId,\n organizationId: template.organizationId,\n })\n const afterSnapshot = captureTemplateSnapshot(template, afterCustom)\n await syncLinkedLinksWithTemplateSnapshot({\n em,\n dataEngine,\n scope,\n templateId: template.id,\n before: beforeSnapshot,\n after: afterSnapshot,\n })\n await emitCheckoutEvent('checkout.template.updated', {\n id: template.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n }).catch(() => undefined)\n return { ok: true }\n },\n captureAfter: async (input, _result, ctx) => {\n const { parsed } = parseCheckoutInput(input, updateTemplateSchema.parse)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const template = await findOneWithDecryption(em, CheckoutLinkTemplate, { id: parsed.id, deletedAt: null })\n if (!template) return null\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordId: template.id,\n tenantId: template.tenantId,\n organizationId: template.organizationId,\n })\n return captureTemplateSnapshot(template, custom)\n },\n buildLog: async ({ snapshots, input }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as CheckoutTemplateSnapshot | null | undefined\n const after = snapshots.after as CheckoutTemplateSnapshot | null | undefined\n return {\n actionLabel: translate('checkout.audit.templates.update', 'Update pay-link template'),\n resourceKind: 'checkout.template',\n resourceId: after?.id ?? before?.id ?? readCommandId(input, 'Template id is required'),\n tenantId: after?.tenantId ?? before?.tenantId ?? null,\n organizationId: after?.organizationId ?? before?.organizationId ?? null,\n snapshotBefore: before ? toCheckoutAuditSnapshot(before) : null,\n snapshotAfter: after ? toCheckoutAuditSnapshot(after) : null,\n payload: {\n undo: {\n before: before ?? null,\n after: after ?? null,\n } satisfies CheckoutTemplateUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const undo = extractUndoPayload<CheckoutTemplateUndoPayload>(logEntry)\n const before = undo?.before\n const after = undo?.after\n if (!before) return\n const em = ctx.container.resolve('em') as EntityManager\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n const template = await em.findOne(CheckoutLinkTemplate, { id: before.id, deletedAt: null })\n if (!template) return\n restoreTemplateFromSnapshot(template, before)\n await em.flush()\n const reset = buildCustomFieldResetMap(before.custom, after?.custom)\n if (Object.keys(reset).length) {\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordId: before.id,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n values: reset,\n notify: false,\n })\n }\n if (after) {\n await syncLinkedLinksWithTemplateSnapshot({\n em,\n dataEngine,\n scope: { organizationId: before.organizationId, tenantId: before.tenantId },\n templateId: before.id,\n before: after,\n after: before,\n })\n }\n },\n}\n\nconst deleteTemplateCommand: CommandHandler<Record<string, unknown>, { ok: true }> = {\n id: 'checkout.template.delete',\n async prepare(rawInput, ctx) {\n const templateId = readCommandId(rawInput, 'Template id is required')\n const scope = resolveCommandScope(ctx)\n const em = ctx.container.resolve('em') as EntityManager\n const template = await findOneWithDecryption(em, CheckoutLinkTemplate, {\n id: templateId,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n deletedAt: null,\n }, undefined, scope)\n if (!template) return {}\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordId: template.id,\n tenantId: template.tenantId,\n organizationId: template.organizationId,\n })\n return { before: captureTemplateSnapshot(template, custom) }\n },\n async execute(rawInput, ctx) {\n const templateId = readCommandId(rawInput, 'Template id is required')\n const scope = resolveCommandScope(ctx)\n const em = ctx.container.resolve('em') as EntityManager\n const template = await findOneWithDecryption(em, CheckoutLinkTemplate, {\n id: templateId,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n deletedAt: null,\n }, undefined, scope)\n if (!template) throw new CrudHttpError(404, { error: 'Template not found' })\n enforceCommandOptimisticLock({\n resourceKind: 'checkout.template',\n resourceId: template.id,\n current: template.updatedAt ?? null,\n request: ctx.request ?? null,\n })\n template.deletedAt = new Date()\n await em.flush()\n await emitCheckoutEvent('checkout.template.deleted', {\n id: template.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n }).catch(() => undefined)\n return { ok: true }\n },\n buildLog: async ({ snapshots, input }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as CheckoutTemplateSnapshot | null | undefined\n return {\n actionLabel: translate('checkout.audit.templates.delete', 'Delete pay-link template'),\n resourceKind: 'checkout.template',\n resourceId: before?.id ?? readCommandId(input, 'Template id is required'),\n tenantId: before?.tenantId ?? null,\n organizationId: before?.organizationId ?? null,\n snapshotBefore: before ? toCheckoutAuditSnapshot(before) : null,\n payload: {\n undo: {\n before: before ?? null,\n } satisfies CheckoutTemplateUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const before = extractUndoPayload<CheckoutTemplateUndoPayload>(logEntry)?.before\n if (!before) return\n const em = ctx.container.resolve('em') as EntityManager\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n let template = await em.findOne(CheckoutLinkTemplate, { id: before.id })\n if (template) {\n restoreTemplateFromSnapshot(template, before)\n } else {\n template = em.create(CheckoutLinkTemplate, createTemplateFromSnapshot(before))\n em.persist(template)\n }\n await em.flush()\n const reset = buildCustomFieldResetMap(before.custom, undefined)\n if (Object.keys(reset).length) {\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordId: before.id,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n values: reset,\n notify: false,\n })\n }\n },\n}\n\nregisterCommand(createTemplateCommand)\nregisterCommand(updateTemplateCommand)\nregisterCommand(deleteTemplateCommand)\n\nexport function serializeTemplateRecord(record: CheckoutLinkTemplate) {\n return serializeTemplateOrLink(record)\n}\n"],
|
|
5
|
-
"mappings": "AAGA,SAAS,uBAAuB;AAChC,SAAS,0BAA0B,+BAA+B;AAClE,SAAS,4BAA4B;AACrC,SAAS,qBAAqB;AAC9B,SAAS,
|
|
4
|
+
"sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport type { CommandHandler } from '@open-mercato/shared/lib/commands'\nimport { registerCommand } from '@open-mercato/shared/lib/commands'\nimport { buildCustomFieldResetMap, loadCustomFieldSnapshot } from '@open-mercato/shared/lib/commands/customFieldSnapshots'\nimport { setCustomFieldsIfAny } from '@open-mercato/shared/lib/commands/helpers'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { CheckoutLink, CheckoutLinkTemplate } from '../data/entities'\nimport { createTemplateSchema, updateTemplateSchema } from '../data/validators'\nimport { CHECKOUT_ENTITY_IDS } from '../lib/constants'\nimport {\n ensureGatewayProviderConfigured,\n type PaymentGatewayDescriptorService,\n} from '../lib/gatewayProviderAvailability'\nimport { emitCheckoutEvent } from '../events'\nimport {\n deriveConfiguredCurrencies,\n hashCheckoutPassword,\n parseCheckoutInput,\n serializeTemplateOrLink,\n toMoneyString,\n validateDescriptorCurrencies,\n} from '../lib/utils'\nimport {\n buildSelectiveLinkedCustomFieldUpdates,\n buildSelectiveLinkedLinkSnapshot,\n captureTemplateSnapshot,\n createTemplateFromSnapshot,\n extractUndoPayload,\n captureLinkSnapshot,\n readCommandId,\n resolveCommandScope,\n restoreLinkFromSnapshot,\n restoreTemplateFromSnapshot,\n toCheckoutAuditSnapshot,\n type CheckoutTemplateSnapshot,\n} from './shared'\n\ntype CheckoutTemplateUndoPayload = {\n before?: CheckoutTemplateSnapshot | null\n after?: CheckoutTemplateSnapshot | null\n}\n\nasync function syncLinkedLinksWithTemplateSnapshot(params: {\n em: EntityManager\n dataEngine: DataEngine\n scope: { organizationId: string; tenantId: string }\n templateId: string\n before: CheckoutTemplateSnapshot\n after: CheckoutTemplateSnapshot\n}) {\n const { em, dataEngine, scope, templateId, before, after } = params\n const linkedLinks = await findWithDecryption(\n em,\n CheckoutLink,\n {\n templateId,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n deletedAt: null,\n isLocked: false,\n },\n undefined,\n scope,\n )\n\n let changedLinks = false\n\n for (const link of linkedLinks) {\n const currentLinkSnapshot = captureLinkSnapshot(link)\n const nextLinkSnapshot = buildSelectiveLinkedLinkSnapshot(currentLinkSnapshot, before, after)\n if (nextLinkSnapshot.changed) {\n restoreLinkFromSnapshot(link, nextLinkSnapshot.snapshot)\n changedLinks = true\n }\n\n const currentCustom = await loadCustomFieldSnapshot(em, {\n entityId: CHECKOUT_ENTITY_IDS.link,\n recordId: link.id,\n tenantId: link.tenantId,\n organizationId: link.organizationId,\n })\n const customFieldUpdates = buildSelectiveLinkedCustomFieldUpdates(currentCustom, before.custom, after.custom)\n if (Object.keys(customFieldUpdates).length > 0) {\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: CHECKOUT_ENTITY_IDS.link,\n recordId: link.id,\n tenantId: link.tenantId,\n organizationId: link.organizationId,\n values: customFieldUpdates,\n })\n }\n }\n\n if (changedLinks) {\n await em.flush()\n }\n}\n\nconst createTemplateCommand: CommandHandler<Record<string, unknown>, { id: string }> = {\n id: 'checkout.template.create',\n async execute(rawInput, ctx) {\n const { parsed, customFields } = parseCheckoutInput(rawInput, createTemplateSchema.parse)\n const scope = resolveCommandScope(ctx)\n validateDescriptorCurrencies(parsed.gatewayProviderKey, deriveConfiguredCurrencies(parsed))\n const descriptorService = ctx.container.resolve('paymentGatewayDescriptorService') as PaymentGatewayDescriptorService\n await ensureGatewayProviderConfigured(parsed.gatewayProviderKey, descriptorService, scope)\n const em = ctx.container.resolve('em') as EntityManager\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n const template = em.create(CheckoutLinkTemplate, {\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n ...parsed,\n fixedPriceAmount: toMoneyString(parsed.fixedPriceAmount),\n fixedPriceOriginalAmount: toMoneyString(parsed.fixedPriceOriginalAmount),\n customAmountMin: toMoneyString(parsed.customAmountMin),\n customAmountMax: toMoneyString(parsed.customAmountMax),\n passwordHash: await hashCheckoutPassword(parsed.password),\n } as any)\n em.persist(template)\n await em.flush()\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordId: template.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n values: customFields,\n })\n await emitCheckoutEvent('checkout.template.created', {\n id: template.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n }).catch(() => undefined)\n return { id: template.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const template = await findOneWithDecryption(em, CheckoutLinkTemplate, { id: result.id })\n if (!template) return null\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordId: template.id,\n tenantId: template.tenantId,\n organizationId: template.organizationId,\n })\n return captureTemplateSnapshot(template, custom)\n },\n buildLog: async ({ result, snapshots }) => {\n const { translate } = await resolveTranslations()\n const after = snapshots.after as CheckoutTemplateSnapshot | null | undefined\n return {\n actionLabel: translate('checkout.audit.templates.create', 'Create pay-link template'),\n resourceKind: 'checkout.template',\n resourceId: result.id,\n tenantId: after?.tenantId ?? null,\n organizationId: after?.organizationId ?? null,\n snapshotAfter: after ? toCheckoutAuditSnapshot(after) : null,\n payload: {\n undo: {\n after: after ?? null,\n } satisfies CheckoutTemplateUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const after = extractUndoPayload<CheckoutTemplateUndoPayload>(logEntry)?.after\n if (!after) return\n const em = ctx.container.resolve('em') as EntityManager\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n const reset = buildCustomFieldResetMap(undefined, after.custom)\n if (Object.keys(reset).length) {\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordId: after.id,\n tenantId: after.tenantId,\n organizationId: after.organizationId,\n values: reset,\n notify: false,\n })\n }\n const template = await em.findOne(CheckoutLinkTemplate, { id: after.id })\n if (!template) return\n template.deletedAt = new Date()\n await em.flush()\n },\n}\n\nconst updateTemplateCommand: CommandHandler<Record<string, unknown>, { ok: true }> = {\n id: 'checkout.template.update',\n async prepare(rawInput, ctx) {\n const { parsed } = parseCheckoutInput(rawInput, updateTemplateSchema.parse)\n const scope = resolveCommandScope(ctx)\n const em = ctx.container.resolve('em') as EntityManager\n const template = await findOneWithDecryption(em, CheckoutLinkTemplate, {\n id: parsed.id,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n deletedAt: null,\n }, undefined, scope)\n if (!template) return {}\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordId: template.id,\n tenantId: template.tenantId,\n organizationId: template.organizationId,\n })\n return { before: captureTemplateSnapshot(template, custom) }\n },\n async execute(rawInput, ctx) {\n const { parsed, customFields } = parseCheckoutInput(rawInput, updateTemplateSchema.parse)\n const scope = resolveCommandScope(ctx)\n validateDescriptorCurrencies(parsed.gatewayProviderKey ?? null, deriveConfiguredCurrencies(parsed))\n const descriptorService = ctx.container.resolve('paymentGatewayDescriptorService') as PaymentGatewayDescriptorService\n await ensureGatewayProviderConfigured(parsed.gatewayProviderKey ?? null, descriptorService, scope)\n const em = ctx.container.resolve('em') as EntityManager\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n const template = await findOneWithDecryption(em, CheckoutLinkTemplate, {\n id: parsed.id,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n deletedAt: null,\n }, undefined, scope)\n if (!template) throw new CrudHttpError(404, { error: 'Template not found' })\n const beforeCustom = await loadCustomFieldSnapshot(em, {\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordId: template.id,\n tenantId: template.tenantId,\n organizationId: template.organizationId,\n })\n const beforeSnapshot = captureTemplateSnapshot(template, beforeCustom)\n const passwordHash = parsed.password !== undefined\n ? await hashCheckoutPassword(parsed.password)\n : template.passwordHash\n Object.assign(template, {\n ...parsed,\n fixedPriceAmount: parsed.fixedPriceAmount !== undefined ? toMoneyString(parsed.fixedPriceAmount) : template.fixedPriceAmount,\n fixedPriceOriginalAmount: parsed.fixedPriceOriginalAmount !== undefined ? toMoneyString(parsed.fixedPriceOriginalAmount) : template.fixedPriceOriginalAmount,\n customAmountMin: parsed.customAmountMin !== undefined ? toMoneyString(parsed.customAmountMin) : template.customAmountMin,\n customAmountMax: parsed.customAmountMax !== undefined ? toMoneyString(parsed.customAmountMax) : template.customAmountMax,\n passwordHash,\n })\n await em.flush()\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordId: template.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n values: customFields,\n })\n const afterCustom = await loadCustomFieldSnapshot(em, {\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordId: template.id,\n tenantId: template.tenantId,\n organizationId: template.organizationId,\n })\n const afterSnapshot = captureTemplateSnapshot(template, afterCustom)\n await syncLinkedLinksWithTemplateSnapshot({\n em,\n dataEngine,\n scope,\n templateId: template.id,\n before: beforeSnapshot,\n after: afterSnapshot,\n })\n await emitCheckoutEvent('checkout.template.updated', {\n id: template.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n }).catch(() => undefined)\n return { ok: true }\n },\n captureAfter: async (input, _result, ctx) => {\n const { parsed } = parseCheckoutInput(input, updateTemplateSchema.parse)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const template = await findOneWithDecryption(em, CheckoutLinkTemplate, { id: parsed.id, deletedAt: null })\n if (!template) return null\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordId: template.id,\n tenantId: template.tenantId,\n organizationId: template.organizationId,\n })\n return captureTemplateSnapshot(template, custom)\n },\n buildLog: async ({ snapshots, input }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as CheckoutTemplateSnapshot | null | undefined\n const after = snapshots.after as CheckoutTemplateSnapshot | null | undefined\n return {\n actionLabel: translate('checkout.audit.templates.update', 'Update pay-link template'),\n resourceKind: 'checkout.template',\n resourceId: after?.id ?? before?.id ?? readCommandId(input, 'Template id is required'),\n tenantId: after?.tenantId ?? before?.tenantId ?? null,\n organizationId: after?.organizationId ?? before?.organizationId ?? null,\n snapshotBefore: before ? toCheckoutAuditSnapshot(before) : null,\n snapshotAfter: after ? toCheckoutAuditSnapshot(after) : null,\n payload: {\n undo: {\n before: before ?? null,\n after: after ?? null,\n } satisfies CheckoutTemplateUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const undo = extractUndoPayload<CheckoutTemplateUndoPayload>(logEntry)\n const before = undo?.before\n const after = undo?.after\n if (!before) return\n const em = ctx.container.resolve('em') as EntityManager\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n const template = await em.findOne(CheckoutLinkTemplate, { id: before.id, deletedAt: null })\n if (!template) return\n restoreTemplateFromSnapshot(template, before)\n await em.flush()\n const reset = buildCustomFieldResetMap(before.custom, after?.custom)\n if (Object.keys(reset).length) {\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordId: before.id,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n values: reset,\n notify: false,\n })\n }\n if (after) {\n await syncLinkedLinksWithTemplateSnapshot({\n em,\n dataEngine,\n scope: { organizationId: before.organizationId, tenantId: before.tenantId },\n templateId: before.id,\n before: after,\n after: before,\n })\n }\n },\n}\n\nconst deleteTemplateCommand: CommandHandler<Record<string, unknown>, { ok: true }> = {\n id: 'checkout.template.delete',\n async prepare(rawInput, ctx) {\n const templateId = readCommandId(rawInput, 'Template id is required')\n const scope = resolveCommandScope(ctx)\n const em = ctx.container.resolve('em') as EntityManager\n const template = await findOneWithDecryption(em, CheckoutLinkTemplate, {\n id: templateId,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n deletedAt: null,\n }, undefined, scope)\n if (!template) return {}\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordId: template.id,\n tenantId: template.tenantId,\n organizationId: template.organizationId,\n })\n return { before: captureTemplateSnapshot(template, custom) }\n },\n async execute(rawInput, ctx) {\n const templateId = readCommandId(rawInput, 'Template id is required')\n const scope = resolveCommandScope(ctx)\n const em = ctx.container.resolve('em') as EntityManager\n const template = await findOneWithDecryption(em, CheckoutLinkTemplate, {\n id: templateId,\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n deletedAt: null,\n }, undefined, scope)\n if (!template) throw new CrudHttpError(404, { error: 'Template not found' })\n template.deletedAt = new Date()\n await em.flush()\n await emitCheckoutEvent('checkout.template.deleted', {\n id: template.id,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n }).catch(() => undefined)\n return { ok: true }\n },\n buildLog: async ({ snapshots, input }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as CheckoutTemplateSnapshot | null | undefined\n return {\n actionLabel: translate('checkout.audit.templates.delete', 'Delete pay-link template'),\n resourceKind: 'checkout.template',\n resourceId: before?.id ?? readCommandId(input, 'Template id is required'),\n tenantId: before?.tenantId ?? null,\n organizationId: before?.organizationId ?? null,\n snapshotBefore: before ? toCheckoutAuditSnapshot(before) : null,\n payload: {\n undo: {\n before: before ?? null,\n } satisfies CheckoutTemplateUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const before = extractUndoPayload<CheckoutTemplateUndoPayload>(logEntry)?.before\n if (!before) return\n const em = ctx.container.resolve('em') as EntityManager\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n let template = await em.findOne(CheckoutLinkTemplate, { id: before.id })\n if (template) {\n restoreTemplateFromSnapshot(template, before)\n } else {\n template = em.create(CheckoutLinkTemplate, createTemplateFromSnapshot(before))\n em.persist(template)\n }\n await em.flush()\n const reset = buildCustomFieldResetMap(before.custom, undefined)\n if (Object.keys(reset).length) {\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: CHECKOUT_ENTITY_IDS.template,\n recordId: before.id,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n values: reset,\n notify: false,\n })\n }\n },\n}\n\nregisterCommand(createTemplateCommand)\nregisterCommand(updateTemplateCommand)\nregisterCommand(deleteTemplateCommand)\n\nexport function serializeTemplateRecord(record: CheckoutLinkTemplate) {\n return serializeTemplateOrLink(record)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -24,9 +24,7 @@ import { CrudForm } from "@open-mercato/ui/backend/CrudForm";
|
|
|
24
24
|
import { ComboboxInput } from "@open-mercato/ui/backend/inputs";
|
|
25
25
|
import { Page, PageBody } from "@open-mercato/ui/backend/Page";
|
|
26
26
|
import { SwitchableMarkdownInput } from "@open-mercato/ui/backend/inputs";
|
|
27
|
-
import { apiCall, apiCallOrThrow, readApiResultOrThrow
|
|
28
|
-
import { buildOptimisticLockHeader } from "@open-mercato/ui/backend/utils/optimisticLock";
|
|
29
|
-
import { surfaceRecordConflict } from "@open-mercato/ui/backend/conflicts";
|
|
27
|
+
import { apiCall, apiCallOrThrow, readApiResultOrThrow } from "@open-mercato/ui/backend/utils/apiCall";
|
|
30
28
|
import { collectCustomFieldValues } from "@open-mercato/ui/backend/utils/customFieldValues";
|
|
31
29
|
import { Button } from "@open-mercato/ui/primitives/button";
|
|
32
30
|
import { ColorPicker } from "@open-mercato/ui/primitives/color-picker";
|
|
@@ -1421,20 +1419,11 @@ function LinkTemplateForm({ mode, recordId }) {
|
|
|
1421
1419
|
customFields: collectCustomFieldValues(values)
|
|
1422
1420
|
};
|
|
1423
1421
|
const endpoint = `/api/checkout/${mode === "link" ? "links" : "templates"}${recordId ? `/${encodeURIComponent(recordId)}` : ""}`;
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
method: recordId ? "PUT" : "POST",
|
|
1430
|
-
headers: { "Content-Type": "application/json" },
|
|
1431
|
-
body: JSON.stringify(payload)
|
|
1432
|
-
})
|
|
1433
|
-
);
|
|
1434
|
-
} catch (error) {
|
|
1435
|
-
if (surfaceRecordConflict(error, t)) return;
|
|
1436
|
-
throw error;
|
|
1437
|
-
}
|
|
1422
|
+
const response = await readApiResultOrThrow(endpoint, {
|
|
1423
|
+
method: recordId ? "PUT" : "POST",
|
|
1424
|
+
headers: { "Content-Type": "application/json" },
|
|
1425
|
+
body: JSON.stringify(payload)
|
|
1426
|
+
});
|
|
1438
1427
|
const targetId = recordId ?? (typeof response?.id === "string" ? response.id : null);
|
|
1439
1428
|
const logoAttachmentId = readString(values.logoAttachmentId);
|
|
1440
1429
|
if (!recordId && targetId && logoAttachmentId && logoAttachmentId !== initialLogoAttachmentIdRef.current) {
|
|
@@ -1470,15 +1459,7 @@ function LinkTemplateForm({ mode, recordId }) {
|
|
|
1470
1459
|
)}&type=success` : `/backend/checkout/templates?flash=${encodeURIComponent(t("checkout.common.flash.saved"))}&type=success`;
|
|
1471
1460
|
},
|
|
1472
1461
|
onDelete: recordId ? async () => {
|
|
1473
|
-
|
|
1474
|
-
await withScopedApiRequestHeaders(
|
|
1475
|
-
buildOptimisticLockHeader(readString(initialValues?.updatedAt) || null),
|
|
1476
|
-
() => apiCallOrThrow(`/api/checkout/${mode === "link" ? "links" : "templates"}/${encodeURIComponent(recordId)}`, { method: "DELETE" })
|
|
1477
|
-
);
|
|
1478
|
-
} catch (error) {
|
|
1479
|
-
if (surfaceRecordConflict(error, t)) return;
|
|
1480
|
-
throw error;
|
|
1481
|
-
}
|
|
1462
|
+
await apiCallOrThrow(`/api/checkout/${mode === "link" ? "links" : "templates"}/${encodeURIComponent(recordId)}`, { method: "DELETE" });
|
|
1482
1463
|
window.location.href = mode === "link" ? `/backend/checkout/pay-links?flash=${encodeURIComponent(t("checkout.common.flash.deleted"))}&type=success` : `/backend/checkout/templates?flash=${encodeURIComponent(t("checkout.common.flash.deleted"))}&type=success`;
|
|
1483
1464
|
} : void 0
|
|
1484
1465
|
},
|