@open-mercato/core 0.10.1-develop.7741.1.61a2652671 → 0.10.1-develop.7749.1.ea3edf75e3
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/generated/entities/attachment_partition/index.js +2 -0
- package/dist/generated/entities/attachment_partition/index.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +1 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/helpers/integration/attachmentAccessFixtures.js +144 -0
- package/dist/helpers/integration/attachmentAccessFixtures.js.map +7 -0
- package/dist/modules/attachments/api/file/[id]/route.js +16 -10
- package/dist/modules/attachments/api/file/[id]/route.js.map +2 -2
- package/dist/modules/attachments/api/image/[id]/[[...slug]]/route.js +15 -9
- package/dist/modules/attachments/api/image/[id]/[[...slug]]/route.js.map +2 -2
- package/dist/modules/attachments/api/library/[id]/route.js +100 -56
- package/dist/modules/attachments/api/library/[id]/route.js.map +3 -3
- package/dist/modules/attachments/api/library/route.js +56 -17
- package/dist/modules/attachments/api/library/route.js.map +2 -2
- package/dist/modules/attachments/api/partitions/route.js +2 -0
- package/dist/modules/attachments/api/partitions/route.js.map +2 -2
- package/dist/modules/attachments/api/route.js +74 -34
- package/dist/modules/attachments/api/route.js.map +3 -3
- package/dist/modules/attachments/api/transfer/route.js +63 -37
- package/dist/modules/attachments/api/transfer/route.js.map +2 -2
- package/dist/modules/attachments/data/entities.js +3 -0
- package/dist/modules/attachments/data/entities.js.map +2 -2
- package/dist/modules/attachments/data/validators.js +41 -0
- package/dist/modules/attachments/data/validators.js.map +7 -0
- package/dist/modules/attachments/di.js +5 -2
- package/dist/modules/attachments/di.js.map +2 -2
- package/dist/modules/attachments/generators.js +29 -0
- package/dist/modules/attachments/generators.js.map +7 -0
- package/dist/modules/attachments/index.js +8 -1
- package/dist/modules/attachments/index.js.map +2 -2
- package/dist/modules/attachments/lib/access-errors.js +35 -0
- package/dist/modules/attachments/lib/access-errors.js.map +7 -0
- package/dist/modules/attachments/lib/access-mutation.js +23 -0
- package/dist/modules/attachments/lib/access-mutation.js.map +7 -0
- package/dist/modules/attachments/lib/access-protection.js +73 -0
- package/dist/modules/attachments/lib/access-protection.js.map +7 -0
- package/dist/modules/attachments/lib/access-query.js +74 -0
- package/dist/modules/attachments/lib/access-query.js.map +7 -0
- package/dist/modules/attachments/lib/access-registry.js +87 -0
- package/dist/modules/attachments/lib/access-registry.js.map +7 -0
- package/dist/modules/attachments/lib/access-runner.js +161 -0
- package/dist/modules/attachments/lib/access-runner.js.map +7 -0
- package/dist/modules/attachments/lib/access-types.js +1 -0
- package/dist/modules/attachments/lib/access-types.js.map +7 -0
- package/dist/modules/attachments/lib/attachment-service.js +14 -6
- package/dist/modules/attachments/lib/attachment-service.js.map +2 -2
- package/dist/modules/attachments/lib/createFromBuffer.js +2 -0
- package/dist/modules/attachments/lib/createFromBuffer.js.map +2 -2
- package/dist/modules/attachments/lib/partitions.js +3 -2
- package/dist/modules/attachments/lib/partitions.js.map +2 -2
- package/dist/modules/attachments/lib/scoped-upload-service.js +2 -0
- package/dist/modules/attachments/lib/scoped-upload-service.js.map +2 -2
- package/dist/modules/attachments/lib/target-access-service.js +12 -3
- package/dist/modules/attachments/lib/target-access-service.js.map +2 -2
- package/dist/modules/attachments/migrations/Migration20261001120000_attachments.js +38 -0
- package/dist/modules/attachments/migrations/Migration20261001120000_attachments.js.map +7 -0
- package/dist/modules/attachments/setup.js +10 -0
- package/dist/modules/attachments/setup.js.map +2 -2
- package/dist/modules/notifications/api/[id]/action/route.js +8 -0
- package/dist/modules/notifications/api/[id]/action/route.js.map +2 -2
- package/dist/modules/notifications/api/route.js +17 -0
- package/dist/modules/notifications/api/route.js.map +2 -2
- package/dist/modules/notifications/data/validators.js +1 -1
- package/dist/modules/notifications/data/validators.js.map +2 -2
- package/dist/modules/notifications/lib/notificationService.js +45 -3
- package/dist/modules/notifications/lib/notificationService.js.map +2 -2
- package/dist/modules/notifications/lib/routeHelpers.js +27 -0
- package/dist/modules/notifications/lib/routeHelpers.js.map +2 -2
- package/dist/modules/payment_gateways/lib/gateway-service.js +50 -34
- package/dist/modules/payment_gateways/lib/gateway-service.js.map +2 -2
- package/dist/modules/payment_gateways/lib/status-machine.js +10 -1
- package/dist/modules/payment_gateways/lib/status-machine.js.map +2 -2
- package/dist/modules/payment_gateways/lib/webhook-processor.js +1 -1
- package/dist/modules/payment_gateways/lib/webhook-processor.js.map +2 -2
- package/dist/modules/staff/notifications.js +4 -2
- package/dist/modules/staff/notifications.js.map +2 -2
- package/dist/modules/workflows/data/entities.js.map +2 -2
- package/dist/modules/workflows/lib/activity-executor.js +18 -4
- package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
- package/dist/modules/workflows/lib/activity-types.js +2 -2
- package/dist/modules/workflows/lib/activity-types.js.map +2 -2
- package/dist/modules/workflows/lib/condition-handler.js +7 -1
- package/dist/modules/workflows/lib/condition-handler.js.map +2 -2
- package/dist/modules/workflows/lib/duration.js +13 -0
- package/dist/modules/workflows/lib/duration.js.map +2 -2
- package/dist/modules/workflows/lib/step-handler.js +9 -2
- package/dist/modules/workflows/lib/step-handler.js.map +2 -2
- package/dist/modules/workflows/lib/task-quick-action.js +13 -10
- package/dist/modules/workflows/lib/task-quick-action.js.map +2 -2
- package/dist/modules/workflows/lib/transition-handler.js +2 -1
- package/dist/modules/workflows/lib/transition-handler.js.map +2 -2
- package/dist/modules/workflows/notifications.js +4 -0
- package/dist/modules/workflows/notifications.js.map +2 -2
- package/generated/entities/attachment_partition/index.ts +1 -0
- package/generated/entity-fields-registry.ts +1 -0
- package/package.json +7 -7
- package/src/helpers/integration/attachmentAccessFixtures.ts +141 -0
- package/src/modules/attachments/api/file/[id]/route.ts +12 -9
- package/src/modules/attachments/api/image/[id]/[[...slug]]/route.ts +10 -8
- package/src/modules/attachments/api/library/[id]/route.ts +87 -58
- package/src/modules/attachments/api/library/route.ts +40 -11
- package/src/modules/attachments/api/partitions/route.ts +2 -0
- package/src/modules/attachments/api/route.ts +68 -35
- package/src/modules/attachments/api/transfer/route.ts +65 -42
- package/src/modules/attachments/data/entities.ts +4 -0
- package/src/modules/attachments/data/validators.ts +36 -0
- package/src/modules/attachments/di.ts +4 -1
- package/src/modules/attachments/generators.ts +27 -0
- package/src/modules/attachments/i18n/de.json +4 -0
- package/src/modules/attachments/i18n/en.json +4 -0
- package/src/modules/attachments/i18n/es.json +4 -0
- package/src/modules/attachments/i18n/ko.json +4 -0
- package/src/modules/attachments/i18n/pl.json +4 -0
- package/src/modules/attachments/index.ts +18 -0
- package/src/modules/attachments/lib/access-errors.ts +32 -0
- package/src/modules/attachments/lib/access-mutation.ts +26 -0
- package/src/modules/attachments/lib/access-protection.ts +83 -0
- package/src/modules/attachments/lib/access-query.ts +86 -0
- package/src/modules/attachments/lib/access-registry.ts +117 -0
- package/src/modules/attachments/lib/access-runner.ts +183 -0
- package/src/modules/attachments/lib/access-types.ts +78 -0
- package/src/modules/attachments/lib/attachment-service.ts +8 -4
- package/src/modules/attachments/lib/createFromBuffer.ts +3 -0
- package/src/modules/attachments/lib/partitions.ts +3 -2
- package/src/modules/attachments/lib/scoped-upload-service.ts +2 -0
- package/src/modules/attachments/lib/target-access-service.ts +10 -3
- package/src/modules/attachments/migrations/.snapshot-open-mercato.json +17 -0
- package/src/modules/attachments/migrations/Migration20261001120000_attachments.ts +35 -0
- package/src/modules/attachments/setup.ts +10 -0
- package/src/modules/auth/i18n/de.json +3 -0
- package/src/modules/auth/i18n/en.json +3 -0
- package/src/modules/auth/i18n/es.json +3 -0
- package/src/modules/auth/i18n/ko.json +3 -0
- package/src/modules/auth/i18n/pl.json +3 -0
- package/src/modules/notifications/api/[id]/action/route.ts +8 -0
- package/src/modules/notifications/api/route.ts +17 -0
- package/src/modules/notifications/data/validators.ts +1 -1
- package/src/modules/notifications/i18n/de.json +2 -0
- package/src/modules/notifications/i18n/en.json +2 -0
- package/src/modules/notifications/i18n/es.json +2 -0
- package/src/modules/notifications/i18n/ko.json +2 -0
- package/src/modules/notifications/i18n/pl.json +2 -0
- package/src/modules/notifications/lib/notificationService.ts +67 -1
- package/src/modules/notifications/lib/routeHelpers.ts +38 -0
- package/src/modules/payment_gateways/lib/gateway-service.ts +50 -33
- package/src/modules/payment_gateways/lib/status-machine.ts +19 -0
- package/src/modules/payment_gateways/lib/webhook-processor.ts +1 -1
- package/src/modules/staff/notifications.ts +2 -0
- package/src/modules/workflows/AGENTS.md +2 -2
- package/src/modules/workflows/data/entities.ts +6 -0
- package/src/modules/workflows/lib/activity-executor.ts +36 -4
- package/src/modules/workflows/lib/activity-types.ts +2 -2
- package/src/modules/workflows/lib/condition-handler.ts +16 -1
- package/src/modules/workflows/lib/duration.ts +25 -0
- package/src/modules/workflows/lib/step-handler.ts +16 -1
- package/src/modules/workflows/lib/task-quick-action.ts +19 -10
- package/src/modules/workflows/lib/transition-handler.ts +2 -1
- package/src/modules/workflows/notifications.ts +4 -0
|
@@ -106,6 +106,21 @@ export function resolveMaxConditionAttempts(): number {
|
|
|
106
106
|
return parsed
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
/**
|
|
110
|
+
* The attempt cap one waiter actually gets: the configured floor, raised to the
|
|
111
|
+
* number of polls its own timeout needs (`timeoutMs / pollIntervalMs`, plus
|
|
112
|
+
* the entry poll). A fixed 1000 would force a 90-day wait polled hourly to
|
|
113
|
+
* time out after ~42 days. The deadline still ends the wait first; this only
|
|
114
|
+
* bounds a loop whose deadline arithmetic went wrong.
|
|
115
|
+
*/
|
|
116
|
+
export function resolveConditionAttemptCap(
|
|
117
|
+
config: Pick<WaitForConditionConfig, 'timeoutMs' | 'pollIntervalMs'>
|
|
118
|
+
): number {
|
|
119
|
+
const floor = resolveMaxConditionAttempts()
|
|
120
|
+
if (!(config.timeoutMs > 0) || !(config.pollIntervalMs > 0)) return floor
|
|
121
|
+
return Math.max(floor, Math.ceil(config.timeoutMs / config.pollIntervalMs) + 1)
|
|
122
|
+
}
|
|
123
|
+
|
|
109
124
|
/**
|
|
110
125
|
* Read and normalise a WAIT_FOR_CONDITION step's config. Fails closed: the
|
|
111
126
|
* predicate and the timeout are both mandatory, and the poll interval is
|
|
@@ -499,7 +514,7 @@ export async function evaluateWaitCondition(
|
|
|
499
514
|
|
|
500
515
|
const deadlineMs = Date.parse(options.deadlineAt)
|
|
501
516
|
const deadlinePassed = Number.isFinite(deadlineMs) ? nowMs >= deadlineMs : true
|
|
502
|
-
const attemptCapReached = attempts >=
|
|
517
|
+
const attemptCapReached = attempts >= resolveConditionAttemptCap(waiter.config)
|
|
503
518
|
|
|
504
519
|
if (deadlinePassed || attemptCapReached) {
|
|
505
520
|
const eventLogger = container.resolve<typeof eventLoggerModule>('eventLogger')
|
|
@@ -147,6 +147,31 @@ export function calculateDueDate(duration: string, from: Date = new Date()): Dat
|
|
|
147
147
|
return new Date(from.getTime() + parseDuration(duration))
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
+
/**
|
|
151
|
+
* Largest delay Node's `setTimeout` honours (a signed 32-bit millisecond count,
|
|
152
|
+
* ~24.86 days). A longer delay is not rejected — it fires after 1 ms with only a
|
|
153
|
+
* `TimeoutOverflowWarning` — so an in-process wait must refuse it explicitly.
|
|
154
|
+
*/
|
|
155
|
+
export const MAX_TIMER_DELAY_MS = 2_147_483_647
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* A WAIT longer than this is not slept inside the executing request: when it is
|
|
159
|
+
* the last activity of its transition it is handed to the activity queue (the
|
|
160
|
+
* path an `async: true` WAIT already takes). One minute keeps the short pauses
|
|
161
|
+
* people use for pacing inline while anything that would hold a request or a
|
|
162
|
+
* worker slot open for minutes becomes durable.
|
|
163
|
+
*/
|
|
164
|
+
export const MAX_INLINE_WAIT_MS = 60_000
|
|
165
|
+
|
|
166
|
+
export function assertInProcessWaitDelay(delayMs: number): number {
|
|
167
|
+
if (delayMs > MAX_TIMER_DELAY_MS) {
|
|
168
|
+
throw new Error(
|
|
169
|
+
`WAIT activity: a ${delayMs}ms delay cannot be slept in-process (limit ${MAX_TIMER_DELAY_MS}ms); make it the last activity of its transition, mark it async, or use a WAIT_FOR_TIMER step`
|
|
170
|
+
)
|
|
171
|
+
}
|
|
172
|
+
return delayMs
|
|
173
|
+
}
|
|
174
|
+
|
|
150
175
|
export function calculateWaitDelayMs(config: { duration?: string; until?: string }): number {
|
|
151
176
|
if (config.until) {
|
|
152
177
|
const targetDate = new Date(config.until)
|
|
@@ -222,6 +222,21 @@ async function emitStepMilestone(em: EntityManager, stepInstance: StepInstance):
|
|
|
222
222
|
}
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
+
/**
|
|
226
|
+
* `step_instances.execution_time_ms` is a Postgres `integer`, so a step that
|
|
227
|
+
* lasted 2^31 ms (~24.86 days) or longer cannot be stored there — the flush
|
|
228
|
+
* that completes the step would throw after its task already committed,
|
|
229
|
+
* stranding the run. Such a duration persists as `null` (every reader already
|
|
230
|
+
* falls back to `exitedAt - enteredAt`); the exact value still travels on the
|
|
231
|
+
* `STEP_EXITED` event, whose payload is jsonb.
|
|
232
|
+
*/
|
|
233
|
+
export const MAX_PERSISTED_EXECUTION_TIME_MS = 2_147_483_647
|
|
234
|
+
|
|
235
|
+
export function toPersistableExecutionTimeMs(executionTimeMs: number | null): number | null {
|
|
236
|
+
if (executionTimeMs === null || !Number.isFinite(executionTimeMs)) return null
|
|
237
|
+
return Math.abs(executionTimeMs) > MAX_PERSISTED_EXECUTION_TIME_MS ? null : executionTimeMs
|
|
238
|
+
}
|
|
239
|
+
|
|
225
240
|
export async function exitStep(
|
|
226
241
|
em: EntityManager,
|
|
227
242
|
stepInstance: StepInstance,
|
|
@@ -239,7 +254,7 @@ export async function exitStep(
|
|
|
239
254
|
stepInstance.status = 'COMPLETED'
|
|
240
255
|
stepInstance.outputData = outputData || null
|
|
241
256
|
stepInstance.exitedAt = now
|
|
242
|
-
stepInstance.executionTimeMs = executionTimeMs
|
|
257
|
+
stepInstance.executionTimeMs = toPersistableExecutionTimeMs(executionTimeMs)
|
|
243
258
|
stepInstance.updatedAt = now
|
|
244
259
|
|
|
245
260
|
await em.flush()
|
|
@@ -43,6 +43,24 @@ export const TASK_QUICK_ACTION_VIEW_ID = 'view'
|
|
|
43
43
|
|
|
44
44
|
export const TASK_DEEP_LINK_HREF = '/backend/tasks/{sourceEntityId}'
|
|
45
45
|
|
|
46
|
+
/** Feature the clicking user must hold to complete a task from its notification. */
|
|
47
|
+
export const TASK_COMPLETE_REQUIRED_FEATURE = 'workflows.tasks.complete'
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The one-click completion button. Shared by {@link buildTaskQuickActions} and the
|
|
51
|
+
* `workflows.task.assigned` type declaration, so the stored action id and command id always
|
|
52
|
+
* match what the notifications module allows to dispatch.
|
|
53
|
+
*/
|
|
54
|
+
export function buildTaskQuickCompleteAction(): NotificationTypeAction {
|
|
55
|
+
return {
|
|
56
|
+
id: TASK_QUICK_ACTION_COMPLETE_ID,
|
|
57
|
+
labelKey: 'workflows.notifications.task.actions.complete',
|
|
58
|
+
variant: 'default',
|
|
59
|
+
icon: 'check',
|
|
60
|
+
commandId: TASK_COMPLETE_COMMAND_ID,
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
46
64
|
export interface TaskQuickActionInput {
|
|
47
65
|
/** Decision buttons resolved for this task. */
|
|
48
66
|
decisions?: { id: string }[] | null
|
|
@@ -90,16 +108,7 @@ export function buildTaskQuickActions(input: TaskQuickActionInput): Notification
|
|
|
90
108
|
|
|
91
109
|
if (!isOneClickTask(input)) return [viewAction]
|
|
92
110
|
|
|
93
|
-
return [
|
|
94
|
-
viewAction,
|
|
95
|
-
{
|
|
96
|
-
id: TASK_QUICK_ACTION_COMPLETE_ID,
|
|
97
|
-
labelKey: 'workflows.notifications.task.actions.complete',
|
|
98
|
-
variant: 'default',
|
|
99
|
-
icon: 'check',
|
|
100
|
-
commandId: TASK_COMPLETE_COMMAND_ID,
|
|
101
|
-
},
|
|
102
|
-
]
|
|
111
|
+
return [viewAction, buildTaskQuickCompleteAction()]
|
|
103
112
|
}
|
|
104
113
|
|
|
105
114
|
/**
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { NotificationTypeDefinition } from '@open-mercato/shared/modules/notifications/types'
|
|
2
|
+
import { buildTaskQuickCompleteAction, TASK_COMPLETE_REQUIRED_FEATURE } from './lib/task-quick-action'
|
|
2
3
|
|
|
3
4
|
const taskDeepLink = '/backend/tasks/{sourceEntityId}'
|
|
4
5
|
|
|
@@ -21,6 +22,9 @@ export const notificationTypes: NotificationTypeDefinition[] = [
|
|
|
21
22
|
icon: 'clipboard-list',
|
|
22
23
|
severity: 'info',
|
|
23
24
|
actions: [viewTaskAction],
|
|
25
|
+
optionalActions: [
|
|
26
|
+
{ ...buildTaskQuickCompleteAction(), requiredFeatures: [TASK_COMPLETE_REQUIRED_FEATURE] },
|
|
27
|
+
],
|
|
24
28
|
linkHref: taskDeepLink,
|
|
25
29
|
expiresAfterHours: 168, // 7 days
|
|
26
30
|
},
|