@open-mercato/core 0.9.1-develop.7519.1.38f51f8dbb → 0.9.1-develop.7536.1.f9a5776a07

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/modules/auth/api/logout.js +14 -6
  3. package/dist/modules/auth/api/logout.js.map +2 -2
  4. package/dist/modules/auth/api/session/refresh.js +6 -1
  5. package/dist/modules/auth/api/session/refresh.js.map +2 -2
  6. package/dist/modules/catalog/ai-tools/mutation-pack.js +10 -5
  7. package/dist/modules/catalog/ai-tools/mutation-pack.js.map +2 -2
  8. package/dist/modules/catalog/ai-tools/types.js.map +2 -2
  9. package/dist/modules/currencies/backend/currencies/[id]/page.js +5 -2
  10. package/dist/modules/currencies/backend/currencies/[id]/page.js.map +2 -2
  11. package/dist/modules/currencies/commands/currencies.js +399 -137
  12. package/dist/modules/currencies/commands/currencies.js.map +2 -2
  13. package/dist/modules/currencies/lib/seeds.js +2 -0
  14. package/dist/modules/currencies/lib/seeds.js.map +2 -2
  15. package/dist/modules/customer_accounts/api/login.js +14 -7
  16. package/dist/modules/customer_accounts/api/login.js.map +2 -2
  17. package/dist/modules/customer_accounts/services/customerUserService.js +10 -10
  18. package/dist/modules/customer_accounts/services/customerUserService.js.map +2 -2
  19. package/dist/modules/customers/commands/companies.js +10 -3
  20. package/dist/modules/customers/commands/companies.js.map +2 -2
  21. package/dist/modules/customers/commands/interactionRestoreDetails.js +75 -0
  22. package/dist/modules/customers/commands/interactionRestoreDetails.js.map +7 -0
  23. package/dist/modules/customers/commands/people.js +10 -3
  24. package/dist/modules/customers/commands/people.js.map +2 -2
  25. package/dist/modules/forms/api/distributions/[distributionId]/invitations/[invitationId]/route.js +1 -1
  26. package/dist/modules/forms/api/distributions/[distributionId]/invitations/[invitationId]/route.js.map +1 -1
  27. package/dist/modules/forms/api/form-submissions/[id]/submit/route.js +12 -2
  28. package/dist/modules/forms/api/form-submissions/[id]/submit/route.js.map +2 -2
  29. package/dist/modules/forms/api/form-submissions/route.js +16 -1
  30. package/dist/modules/forms/api/form-submissions/route.js.map +2 -2
  31. package/dist/modules/forms/api/public/submissions/[id]/submit/route.js +6 -1
  32. package/dist/modules/forms/api/public/submissions/[id]/submit/route.js.map +2 -2
  33. package/dist/modules/forms/api/runtime-helpers.js +16 -0
  34. package/dist/modules/forms/api/runtime-helpers.js.map +2 -2
  35. package/dist/modules/forms/data/validators.js.map +2 -2
  36. package/dist/modules/forms/lib/portal-subject-policy.js +17 -0
  37. package/dist/modules/forms/lib/portal-subject-policy.js.map +7 -0
  38. package/dist/modules/forms/lib/runtime-principal.js +27 -10
  39. package/dist/modules/forms/lib/runtime-principal.js.map +2 -2
  40. package/dist/modules/forms/services/distribution-service.js +35 -13
  41. package/dist/modules/forms/services/distribution-service.js.map +2 -2
  42. package/dist/modules/forms/services/submission-service.js +4 -0
  43. package/dist/modules/forms/services/submission-service.js.map +2 -2
  44. package/dist/modules/staff/commands/leave-requests.js +54 -24
  45. package/dist/modules/staff/commands/leave-requests.js.map +2 -2
  46. package/dist/modules/warranty_claims/api/portal/attachments/route.js +19 -7
  47. package/dist/modules/warranty_claims/api/portal/attachments/route.js.map +2 -2
  48. package/dist/modules/warranty_claims/commands/claims.js +1 -1
  49. package/dist/modules/warranty_claims/commands/claims.js.map +2 -2
  50. package/dist/modules/warranty_claims/subscribers/return-shipment-tracking.js +6 -6
  51. package/dist/modules/warranty_claims/subscribers/return-shipment-tracking.js.map +2 -2
  52. package/dist/modules/wms/commands/inventory-actions.js +19 -3
  53. package/dist/modules/wms/commands/inventory-actions.js.map +2 -2
  54. package/dist/modules/workflows/lib/async-activity-wait.js +43 -0
  55. package/dist/modules/workflows/lib/async-activity-wait.js.map +7 -0
  56. package/dist/modules/workflows/lib/parallel-handler.js +20 -14
  57. package/dist/modules/workflows/lib/parallel-handler.js.map +2 -2
  58. package/dist/modules/workflows/lib/workflow-executor.js +21 -23
  59. package/dist/modules/workflows/lib/workflow-executor.js.map +2 -2
  60. package/package.json +7 -7
  61. package/src/modules/auth/api/logout.ts +15 -6
  62. package/src/modules/auth/api/session/refresh.ts +6 -1
  63. package/src/modules/catalog/ai-tools/mutation-pack.ts +14 -5
  64. package/src/modules/catalog/ai-tools/types.ts +1 -0
  65. package/src/modules/currencies/backend/currencies/[id]/page.tsx +5 -1
  66. package/src/modules/currencies/commands/currencies.ts +475 -168
  67. package/src/modules/currencies/i18n/de.json +4 -0
  68. package/src/modules/currencies/i18n/en.json +4 -0
  69. package/src/modules/currencies/i18n/es.json +4 -0
  70. package/src/modules/currencies/i18n/ko.json +4 -0
  71. package/src/modules/currencies/i18n/pl.json +4 -0
  72. package/src/modules/currencies/lib/seeds.ts +2 -0
  73. package/src/modules/customer_accounts/api/login.ts +15 -7
  74. package/src/modules/customer_accounts/services/customerUserService.ts +34 -10
  75. package/src/modules/customers/commands/companies.ts +16 -4
  76. package/src/modules/customers/commands/interactionRestoreDetails.ts +110 -0
  77. package/src/modules/customers/commands/people.ts +16 -4
  78. package/src/modules/forms/api/distributions/[distributionId]/invitations/[invitationId]/route.ts +1 -1
  79. package/src/modules/forms/api/form-submissions/[id]/submit/route.ts +16 -3
  80. package/src/modules/forms/api/form-submissions/route.ts +21 -2
  81. package/src/modules/forms/api/public/submissions/[id]/submit/route.ts +7 -0
  82. package/src/modules/forms/api/runtime-helpers.ts +16 -0
  83. package/src/modules/forms/data/validators.ts +2 -1
  84. package/src/modules/forms/i18n/de.json +1 -0
  85. package/src/modules/forms/i18n/en.json +1 -0
  86. package/src/modules/forms/i18n/es.json +1 -0
  87. package/src/modules/forms/i18n/ko.json +1 -0
  88. package/src/modules/forms/i18n/pl.json +1 -0
  89. package/src/modules/forms/lib/portal-subject-policy.ts +42 -0
  90. package/src/modules/forms/lib/runtime-principal.ts +35 -11
  91. package/src/modules/forms/services/distribution-service.ts +35 -13
  92. package/src/modules/forms/services/submission-service.ts +12 -0
  93. package/src/modules/staff/commands/leave-requests.ts +54 -23
  94. package/src/modules/staff/i18n/de.json +2 -0
  95. package/src/modules/staff/i18n/en.json +2 -0
  96. package/src/modules/staff/i18n/es.json +2 -0
  97. package/src/modules/staff/i18n/ko.json +2 -0
  98. package/src/modules/staff/i18n/pl.json +2 -0
  99. package/src/modules/warranty_claims/api/portal/attachments/route.ts +20 -8
  100. package/src/modules/warranty_claims/commands/claims.ts +1 -1
  101. package/src/modules/warranty_claims/subscribers/return-shipment-tracking.ts +5 -5
  102. package/src/modules/wms/commands/inventory-actions.ts +30 -10
  103. package/src/modules/workflows/lib/async-activity-wait.ts +71 -0
  104. package/src/modules/workflows/lib/parallel-handler.ts +24 -15
  105. package/src/modules/workflows/lib/workflow-executor.ts +24 -27
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Async-activity wait resolution, PURE.
3
+ *
4
+ * A transition that queues async activities parks its token (instance or
5
+ * branch) and records the queue job ids it is waiting for in
6
+ * `_pendingAsyncActivities`. The worker logs one `ACTIVITY_COMPLETED` /
7
+ * `ACTIVITY_FAILED` event per delivery attempt, keyed by `jobId`, and the event
8
+ * log keeps every earlier wait's events. The wait is therefore decided by the
9
+ * outcome of exactly the jobs it queued — one outcome per job — and never by
10
+ * events of an earlier wait, an earlier attempt of the run, or a duplicate
11
+ * delivery. A job with a completed attempt counts as completed; otherwise any
12
+ * logged failed attempt counts as its failure, whether or not the queue retries
13
+ * it later. `events` must be in log order: the last event per job and outcome
14
+ * is the one used.
15
+ */
16
+
17
+ export const ASYNC_ACTIVITY_OUTCOME_EVENT_TYPES = ['ACTIVITY_COMPLETED', 'ACTIVITY_FAILED'] as const
18
+
19
+ export type AsyncActivityOutcomeEvent = {
20
+ eventType: string
21
+ eventData: Record<string, unknown> | null | undefined
22
+ }
23
+
24
+ export type AsyncActivityWaitResolution<TEvent extends AsyncActivityOutcomeEvent> = {
25
+ settled: boolean
26
+ completed: TEvent[]
27
+ failed: TEvent[]
28
+ }
29
+
30
+ export function readPendingAsyncJobIds(pending: unknown): string[] {
31
+ if (!Array.isArray(pending)) return []
32
+ const jobIds: string[] = []
33
+ for (const entry of pending) {
34
+ const jobId = entry && typeof entry === 'object' ? (entry as { jobId?: unknown }).jobId : undefined
35
+ if (typeof jobId === 'string' && jobId.length > 0 && !jobIds.includes(jobId)) jobIds.push(jobId)
36
+ }
37
+ return jobIds
38
+ }
39
+
40
+ export function resolveAsyncActivityWait<TEvent extends AsyncActivityOutcomeEvent>(
41
+ pendingJobIds: readonly string[],
42
+ events: readonly TEvent[],
43
+ ): AsyncActivityWaitResolution<TEvent> {
44
+ const completedByJob = new Map<string, TEvent>()
45
+ const failedByJob = new Map<string, TEvent>()
46
+ for (const event of events) {
47
+ const jobId = event.eventData?.jobId
48
+ if (typeof jobId !== 'string') continue
49
+ if (event.eventType === 'ACTIVITY_COMPLETED') completedByJob.set(jobId, event)
50
+ else if (event.eventType === 'ACTIVITY_FAILED') failedByJob.set(jobId, event)
51
+ }
52
+
53
+ const completed: TEvent[] = []
54
+ const failed: TEvent[] = []
55
+ let settled = true
56
+ for (const jobId of pendingJobIds) {
57
+ const completion = completedByJob.get(jobId)
58
+ if (completion) {
59
+ completed.push(completion)
60
+ continue
61
+ }
62
+ const failure = failedByJob.get(jobId)
63
+ if (failure) {
64
+ failed.push(failure)
65
+ continue
66
+ }
67
+ settled = false
68
+ }
69
+
70
+ return { settled, completed, failed }
71
+ }
@@ -30,6 +30,11 @@ import {
30
30
  WorkflowEvent,
31
31
  } from '../data/entities'
32
32
  import { logWorkflowEvent } from './event-logger'
33
+ import {
34
+ ASYNC_ACTIVITY_OUTCOME_EVENT_TYPES,
35
+ readPendingAsyncJobIds,
36
+ resolveAsyncActivityWait,
37
+ } from './async-activity-wait'
33
38
  import * as stepHandler from './step-handler'
34
39
  import { branchToken, mergeTokenContext, type ExecutionToken } from './execution-token'
35
40
  import { WORKFLOW_ERROR_CONTEXT_KEY, buildErrorContextEntry } from './error-routing'
@@ -202,26 +207,30 @@ export async function resumeBranchAfterActivities(
202
207
  }
203
208
 
204
209
  const namespace = branch.contextNamespace || {}
205
- const pendingJobIds = (namespace._pendingAsyncActivities as any[]) || []
206
-
207
- const completedEvents = await em.find(WorkflowEvent, {
208
- workflowInstanceId: instanceId,
209
- branchInstanceId,
210
- eventType: 'ACTIVITY_COMPLETED',
211
- eventData: { async: true },
212
- })
213
- const failedCount = await em.count(WorkflowEvent, {
214
- workflowInstanceId: instanceId,
215
- branchInstanceId,
216
- eventType: 'ACTIVITY_FAILED',
217
- eventData: { async: true },
218
- })
210
+ const pendingJobIds = readPendingAsyncJobIds(namespace._pendingAsyncActivities)
211
+
212
+ const outcomeEvents = pendingJobIds.length === 0
213
+ ? []
214
+ : await em.find(
215
+ WorkflowEvent,
216
+ {
217
+ workflowInstanceId: instanceId,
218
+ branchInstanceId,
219
+ eventType: { $in: [...ASYNC_ACTIVITY_OUTCOME_EVENT_TYPES] },
220
+ eventData: { async: true, jobId: { $in: pendingJobIds } },
221
+ },
222
+ { orderBy: { occurredAt: 'asc', id: 'asc' } },
223
+ )
224
+ const wait = resolveAsyncActivityWait(pendingJobIds, outcomeEvents)
219
225
 
220
- if (completedEvents.length + failedCount < pendingJobIds.length) {
226
+ if (!wait.settled) {
221
227
  // Still waiting on other branch activities.
222
228
  return { continueExecution: false }
223
229
  }
224
230
 
231
+ const completedEvents = wait.completed
232
+ const failedCount = wait.failed.length
233
+
225
234
  const now = new Date()
226
235
  if (failedCount > 0) {
227
236
  branch.status = 'FAILED'
@@ -22,6 +22,11 @@ import {
22
22
  type WorkflowInstanceErrorHandlerMetadata,
23
23
  } from '../data/entities'
24
24
  import { compensateWorkflow } from './compensation-handler'
25
+ import {
26
+ ASYNC_ACTIVITY_OUTCOME_EVENT_TYPES,
27
+ readPendingAsyncJobIds,
28
+ resolveAsyncActivityWait,
29
+ } from './async-activity-wait'
25
30
  import { WORKFLOW_ENGINE_VERSION, isEngineVersionSupported } from './engine-version'
26
31
  import {
27
32
  WORKFLOW_ERROR_CONTEXT_KEY,
@@ -1635,33 +1640,31 @@ export async function resumeWorkflowAfterActivities(
1635
1640
  throw new Error('Workflow instance not waiting for activities')
1636
1641
  }
1637
1642
 
1638
- const pendingJobIds = (instance.context._pendingAsyncActivities as any[]) || []
1643
+ const pendingJobIds = readPendingAsyncJobIds(instance.context._pendingAsyncActivities)
1639
1644
 
1640
- const completedActivities = await trx.count(WorkflowEvent, {
1641
- workflowInstanceId: instanceId,
1642
- eventType: 'ACTIVITY_COMPLETED',
1643
- eventData: { async: true },
1644
- })
1645
-
1646
- const failedActivities = await trx.count(WorkflowEvent, {
1647
- workflowInstanceId: instanceId,
1648
- eventType: 'ACTIVITY_FAILED',
1649
- eventData: { async: true },
1650
- })
1651
-
1652
- const totalProcessed = completedActivities + failedActivities
1645
+ const outcomeEvents = pendingJobIds.length === 0
1646
+ ? []
1647
+ : await trx.find(
1648
+ WorkflowEvent,
1649
+ {
1650
+ workflowInstanceId: instanceId,
1651
+ eventType: { $in: [...ASYNC_ACTIVITY_OUTCOME_EVENT_TYPES] },
1652
+ eventData: { async: true, jobId: { $in: pendingJobIds } },
1653
+ },
1654
+ { orderBy: { occurredAt: 'asc', id: 'asc' } },
1655
+ )
1656
+ const wait = resolveAsyncActivityWait(pendingJobIds, outcomeEvents)
1653
1657
 
1654
- if (totalProcessed < pendingJobIds.length) {
1658
+ if (!wait.settled) {
1655
1659
  throw new Error('Activities still pending')
1656
1660
  }
1657
1661
 
1658
- if (failedActivities > 0) {
1659
- const failedEvents = await trx.find(WorkflowEvent, {
1660
- workflowInstanceId: instanceId,
1661
- eventType: 'ACTIVITY_FAILED',
1662
- eventData: { async: true },
1663
- })
1662
+ const completedEvents = wait.completed
1663
+ const failedEvents = wait.failed
1664
+ const completedActivities = completedEvents.length
1665
+ const failedActivities = failedEvents.length
1664
1666
 
1667
+ if (failedActivities > 0) {
1665
1668
  instance.status = 'FAILED'
1666
1669
  instance.errorMessage = `${failedActivities} async activities failed`
1667
1670
  instance.errorDetails = {
@@ -1688,12 +1691,6 @@ export async function resumeWorkflowAfterActivities(
1688
1691
  return { continueExecution: false }
1689
1692
  }
1690
1693
 
1691
- const completedEvents = await trx.find(WorkflowEvent, {
1692
- workflowInstanceId: instanceId,
1693
- eventType: 'ACTIVITY_COMPLETED',
1694
- eventData: { async: true },
1695
- })
1696
-
1697
1694
  for (const event of completedEvents) {
1698
1695
  if (event.eventData.output) {
1699
1696
  instance.context = {