@open-mercato/core 0.9.0 → 0.9.1-develop.7459.1.99e3accd30
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/customer_dictionary_entry/index.js +2 -0
- package/dist/generated/entities/customer_dictionary_entry/index.js.map +2 -2
- package/dist/generated/entities/customer_interaction/index.js +2 -0
- package/dist/generated/entities/customer_interaction/index.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +2 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/modules/catalog/commands/categories.js +1 -1
- package/dist/modules/catalog/commands/categories.js.map +2 -2
- package/dist/modules/catalog/commands/productDeleteChildren.js +389 -0
- package/dist/modules/catalog/commands/productDeleteChildren.js.map +7 -0
- package/dist/modules/catalog/commands/products.js +52 -17
- package/dist/modules/catalog/commands/products.js.map +2 -2
- package/dist/modules/communication_channels/api/post/channels/connect/credentials/route.js +4 -6
- package/dist/modules/communication_channels/api/post/channels/connect/credentials/route.js.map +2 -2
- package/dist/modules/communication_channels/api/post/channels/connect/tenant-credentials/route.js +4 -6
- package/dist/modules/communication_channels/api/post/channels/connect/tenant-credentials/route.js.map +2 -2
- package/dist/modules/communication_channels/api/post/oauth/[provider]/initiate/route.js +47 -11
- package/dist/modules/communication_channels/api/post/oauth/[provider]/initiate/route.js.map +3 -3
- package/dist/modules/communication_channels/commands/deliver-outbound-message.js +5 -1
- package/dist/modules/communication_channels/commands/deliver-outbound-message.js.map +2 -2
- package/dist/modules/communication_channels/lib/inbound-message-origin.js +1 -1
- package/dist/modules/communication_channels/lib/inbound-message-origin.js.map +2 -2
- package/dist/modules/communication_channels/lib/oauth-state.js +4 -1
- package/dist/modules/communication_channels/lib/oauth-state.js.map +2 -2
- package/dist/modules/communication_channels/lib/use-connect-channel.js +10 -0
- package/dist/modules/communication_channels/lib/use-connect-channel.js.map +2 -2
- package/dist/modules/customers/api/activity-types/route.js +151 -0
- package/dist/modules/customers/api/activity-types/route.js.map +7 -0
- package/dist/modules/customers/api/deals/[id]/people/route.js +58 -5
- package/dist/modules/customers/api/deals/[id]/people/route.js.map +2 -2
- package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js +13 -5
- package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/dictionaries/[kind]/route.js +20 -5
- package/dist/modules/customers/api/dictionaries/[kind]/route.js.map +2 -2
- package/dist/modules/customers/api/interactions/route.js +3 -0
- package/dist/modules/customers/api/interactions/route.js.map +2 -2
- package/dist/modules/customers/api/interactions/tasks/route.js +1 -0
- package/dist/modules/customers/api/interactions/tasks/route.js.map +2 -2
- package/dist/modules/customers/backend/config/customers/pipeline-stages/page.meta.js +18 -0
- package/dist/modules/customers/backend/config/customers/pipeline-stages/page.meta.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.js +0 -23
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js +15 -17
- package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
- package/dist/modules/customers/calendar-event-types.js +548 -0
- package/dist/modules/customers/calendar-event-types.js.map +7 -0
- package/dist/modules/customers/commands/dictionaries.js +70 -10
- package/dist/modules/customers/commands/dictionaries.js.map +2 -2
- package/dist/modules/customers/commands/interactions.js +187 -22
- package/dist/modules/customers/commands/interactions.js.map +3 -3
- package/dist/modules/customers/components/ActivityTypeEditor.js +288 -0
- package/dist/modules/customers/components/ActivityTypeEditor.js.map +7 -0
- package/dist/modules/customers/components/DictionarySettings.js +3 -1
- package/dist/modules/customers/components/DictionarySettings.js.map +2 -2
- package/dist/modules/customers/components/calendar/CalendarEventEditor.js +391 -297
- package/dist/modules/customers/components/calendar/CalendarEventEditor.js.map +3 -3
- package/dist/modules/customers/components/calendar/CalendarSettingsModal.js +9 -74
- package/dist/modules/customers/components/calendar/CalendarSettingsModal.js.map +2 -2
- package/dist/modules/customers/components/calendar/TimeGrid.js +20 -16
- package/dist/modules/customers/components/calendar/TimeGrid.js.map +2 -2
- package/dist/modules/customers/components/calendar/editor/EventTypePanel.js +218 -0
- package/dist/modules/customers/components/calendar/editor/EventTypePanel.js.map +7 -0
- package/dist/modules/customers/components/calendar/editor/LocationField.js +7 -3
- package/dist/modules/customers/components/calendar/editor/LocationField.js.map +2 -2
- package/dist/modules/customers/components/calendar/editor/PeopleField.js +5 -2
- package/dist/modules/customers/components/calendar/editor/PeopleField.js.map +2 -2
- package/dist/modules/customers/components/calendar/editor/PriorityField.js +3 -1
- package/dist/modules/customers/components/calendar/editor/PriorityField.js.map +2 -2
- package/dist/modules/customers/components/calendar/editor/RepeatField.js +9 -1
- package/dist/modules/customers/components/calendar/editor/RepeatField.js.map +2 -2
- package/dist/modules/customers/components/calendar/editor/ResourcesField.js +4 -1
- package/dist/modules/customers/components/calendar/editor/ResourcesField.js.map +2 -2
- package/dist/modules/customers/components/calendar/editor/ScheduleSection.js +15 -7
- package/dist/modules/customers/components/calendar/editor/ScheduleSection.js.map +2 -2
- package/dist/modules/customers/components/calendar/editor/SegmentGroup.js +3 -1
- package/dist/modules/customers/components/calendar/editor/SegmentGroup.js.map +2 -2
- package/dist/modules/customers/components/calendar/editor/hooks.js +28 -13
- package/dist/modules/customers/components/calendar/editor/hooks.js.map +3 -3
- package/dist/modules/customers/components/calendar/editor/inputs.js +14 -6
- package/dist/modules/customers/components/calendar/editor/inputs.js.map +2 -2
- package/dist/modules/customers/components/calendar/editor/useCalendarCustomFields.js +54 -0
- package/dist/modules/customers/components/calendar/editor/useCalendarCustomFields.js.map +7 -0
- package/dist/modules/customers/components/calendar/editor/useEventTypeCatalog.js +82 -0
- package/dist/modules/customers/components/calendar/editor/useEventTypeCatalog.js.map +7 -0
- package/dist/modules/customers/components/calendar/types.js +1 -0
- package/dist/modules/customers/components/calendar/types.js.map +2 -2
- package/dist/modules/customers/components/detail/CompanyPeopleSection.js +78 -343
- package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
- package/dist/modules/customers/components/detail/CreatePersonDialog.js +12 -11
- package/dist/modules/customers/components/detail/CreatePersonDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/DealForm.js +7 -3
- package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
- package/dist/modules/customers/components/detail/DealPeopleSection.js +206 -0
- package/dist/modules/customers/components/detail/DealPeopleSection.js.map +7 -0
- package/dist/modules/customers/components/detail/LinkedPeopleSection.js +342 -0
- package/dist/modules/customers/components/detail/LinkedPeopleSection.js.map +7 -0
- package/dist/modules/customers/components/detail/PersonCard.js +5 -2
- package/dist/modules/customers/components/detail/PersonCard.js.map +2 -2
- package/dist/modules/customers/components/linking/adapters/personAdapter.js +3 -0
- package/dist/modules/customers/components/linking/adapters/personAdapter.js.map +2 -2
- package/dist/modules/customers/data/entities.js +6 -0
- package/dist/modules/customers/data/entities.js.map +2 -2
- package/dist/modules/customers/data/validators.js +39 -10
- package/dist/modules/customers/data/validators.js.map +2 -2
- package/dist/modules/customers/di.js +20 -1
- package/dist/modules/customers/di.js.map +2 -2
- package/dist/modules/customers/extension-points.js +13 -0
- package/dist/modules/customers/extension-points.js.map +2 -2
- package/dist/modules/customers/lib/calendar/conflicts.js +59 -16
- package/dist/modules/customers/lib/calendar/conflicts.js.map +2 -2
- package/dist/modules/customers/lib/calendar/editorPayload.js +34 -16
- package/dist/modules/customers/lib/calendar/editorPayload.js.map +2 -2
- package/dist/modules/customers/lib/calendar/eventTypeResolver.js +197 -0
- package/dist/modules/customers/lib/calendar/eventTypeResolver.js.map +7 -0
- package/dist/modules/customers/lib/calendar/interactionApplicability.js +67 -0
- package/dist/modules/customers/lib/calendar/interactionApplicability.js.map +7 -0
- package/dist/modules/customers/lib/calendar/mapItem.js +5 -2
- package/dist/modules/customers/lib/calendar/mapItem.js.map +2 -2
- package/dist/modules/customers/lib/calendar/recurrence.js +62 -1
- package/dist/modules/customers/lib/calendar/recurrence.js.map +2 -2
- package/dist/modules/customers/lib/calendar/timezone.js +111 -0
- package/dist/modules/customers/lib/calendar/timezone.js.map +7 -0
- package/dist/modules/customers/lib/interactionReadModel.js +1 -0
- package/dist/modules/customers/lib/interactionReadModel.js.map +2 -2
- package/dist/modules/customers/lib/todoCompatibility.js +1 -0
- package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
- package/dist/modules/customers/migrations/Migration20260928175058_customers.js +17 -0
- package/dist/modules/customers/migrations/Migration20260928175058_customers.js.map +7 -0
- package/dist/modules/customers/migrations/Migration20260930110235_customers.js +17 -0
- package/dist/modules/customers/migrations/Migration20260930110235_customers.js.map +7 -0
- package/dist/modules/dictionaries/components/DictionaryTable.js +60 -51
- package/dist/modules/dictionaries/components/DictionaryTable.js.map +2 -2
- package/dist/modules/messages/subscribers/message-notification.js +13 -1
- package/dist/modules/messages/subscribers/message-notification.js.map +2 -2
- package/dist/modules/payment_gateways/api/webhook/[provider]/route.js +201 -53
- package/dist/modules/payment_gateways/api/webhook/[provider]/route.js.map +2 -2
- package/dist/modules/payment_gateways/lib/gateway-service.js +37 -11
- package/dist/modules/payment_gateways/lib/gateway-service.js.map +2 -2
- package/dist/modules/planner/lib/availabilityMerge.js +101 -38
- package/dist/modules/planner/lib/availabilityMerge.js.map +3 -3
- package/dist/modules/planner/services/plannerAvailabilityService.js.map +2 -2
- package/dist/modules/sales/components/documents/LineItemDialog.js +159 -81
- package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/lineItemUtils.js +7 -0
- package/dist/modules/sales/components/documents/lineItemUtils.js.map +2 -2
- package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.js +12 -7
- package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.js.map +2 -2
- package/dist/modules/sync_excel/lib/adapters/customers.js +28 -25
- package/dist/modules/sync_excel/lib/adapters/customers.js.map +2 -2
- package/generated/entities/customer_dictionary_entry/index.ts +1 -0
- package/generated/entities/customer_interaction/index.ts +1 -0
- package/generated/entity-fields-registry.ts +2 -0
- package/package.json +9 -8
- 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/catalog/commands/categories.ts +1 -1
- package/src/modules/catalog/commands/productDeleteChildren.ts +557 -0
- package/src/modules/catalog/commands/products.ts +58 -17
- package/src/modules/communication_channels/api/post/channels/connect/credentials/route.ts +4 -6
- package/src/modules/communication_channels/api/post/channels/connect/tenant-credentials/route.ts +4 -6
- package/src/modules/communication_channels/api/post/oauth/[provider]/initiate/route.ts +46 -10
- package/src/modules/communication_channels/commands/deliver-outbound-message.ts +6 -1
- package/src/modules/communication_channels/i18n/de.json +4 -0
- package/src/modules/communication_channels/i18n/en.json +4 -0
- package/src/modules/communication_channels/i18n/es.json +4 -0
- package/src/modules/communication_channels/i18n/ko.json +4 -0
- package/src/modules/communication_channels/i18n/pl.json +4 -0
- package/src/modules/communication_channels/lib/inbound-message-origin.ts +2 -6
- package/src/modules/communication_channels/lib/oauth-state.ts +4 -1
- package/src/modules/communication_channels/lib/use-connect-channel.ts +10 -0
- package/src/modules/customers/api/activity-types/route.ts +154 -0
- package/src/modules/customers/api/deals/[id]/people/route.ts +82 -3
- package/src/modules/customers/api/dictionaries/[kind]/[id]/route.ts +9 -1
- package/src/modules/customers/api/dictionaries/[kind]/route.ts +18 -2
- package/src/modules/customers/api/interactions/route.ts +4 -0
- package/src/modules/customers/api/interactions/tasks/route.ts +1 -0
- package/src/modules/customers/backend/config/customers/pipeline-stages/page.meta.ts +20 -0
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.ts +0 -29
- package/src/modules/customers/backend/customers/deals/[id]/page.tsx +15 -17
- package/src/modules/customers/calendar-event-types.ts +674 -0
- package/src/modules/customers/commands/dictionaries.ts +84 -8
- package/src/modules/customers/commands/interactions.ts +244 -21
- package/src/modules/customers/components/ActivityTypeEditor.tsx +239 -0
- package/src/modules/customers/components/DictionarySettings.tsx +5 -3
- package/src/modules/customers/components/calendar/CalendarEventEditor.tsx +347 -218
- package/src/modules/customers/components/calendar/CalendarSettingsModal.tsx +18 -96
- package/src/modules/customers/components/calendar/TimeGrid.tsx +20 -18
- package/src/modules/customers/components/calendar/editor/EventTypePanel.tsx +230 -0
- package/src/modules/customers/components/calendar/editor/LocationField.tsx +7 -1
- package/src/modules/customers/components/calendar/editor/PeopleField.tsx +4 -0
- package/src/modules/customers/components/calendar/editor/PriorityField.tsx +3 -0
- package/src/modules/customers/components/calendar/editor/RepeatField.tsx +10 -0
- package/src/modules/customers/components/calendar/editor/ResourcesField.tsx +4 -0
- package/src/modules/customers/components/calendar/editor/ScheduleSection.tsx +16 -4
- package/src/modules/customers/components/calendar/editor/SegmentGroup.tsx +3 -0
- package/src/modules/customers/components/calendar/editor/hooks.ts +29 -13
- package/src/modules/customers/components/calendar/editor/inputs.tsx +17 -5
- package/src/modules/customers/components/calendar/editor/useCalendarCustomFields.ts +49 -0
- package/src/modules/customers/components/calendar/editor/useEventTypeCatalog.ts +100 -0
- package/src/modules/customers/components/calendar/types.ts +1 -0
- package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +94 -388
- package/src/modules/customers/components/detail/CreatePersonDialog.tsx +39 -19
- package/src/modules/customers/components/detail/DealForm.tsx +7 -3
- package/src/modules/customers/components/detail/DealPeopleSection.tsx +256 -0
- package/src/modules/customers/components/detail/LinkedPeopleSection.tsx +474 -0
- package/src/modules/customers/components/detail/PersonCard.tsx +12 -4
- package/src/modules/customers/components/detail/types.ts +1 -0
- package/src/modules/customers/components/linking/adapters/personAdapter.tsx +4 -0
- package/src/modules/customers/data/entities.ts +8 -1
- package/src/modules/customers/data/validators.ts +42 -7
- package/src/modules/customers/di.ts +21 -0
- package/src/modules/customers/extension-points.ts +13 -0
- package/src/modules/customers/i18n/de.json +104 -8
- package/src/modules/customers/i18n/en.json +104 -8
- package/src/modules/customers/i18n/es.json +104 -8
- package/src/modules/customers/i18n/ko.json +104 -8
- package/src/modules/customers/i18n/pl.json +104 -8
- package/src/modules/customers/lib/calendar/conflicts.ts +106 -27
- package/src/modules/customers/lib/calendar/editorPayload.ts +39 -19
- package/src/modules/customers/lib/calendar/eventTypeResolver.ts +258 -0
- package/src/modules/customers/lib/calendar/interactionApplicability.ts +99 -0
- package/src/modules/customers/lib/calendar/mapItem.ts +6 -2
- package/src/modules/customers/lib/calendar/recurrence.ts +65 -1
- package/src/modules/customers/lib/calendar/timezone.ts +117 -0
- package/src/modules/customers/lib/interactionReadModel.ts +1 -0
- package/src/modules/customers/lib/todoCompatibility.ts +2 -0
- package/src/modules/customers/migrations/.snapshot-open-mercato.json +34 -0
- package/src/modules/customers/migrations/Migration20260928175058_customers.ts +15 -0
- package/src/modules/customers/migrations/Migration20260930110235_customers.ts +15 -0
- package/src/modules/dictionaries/components/DictionaryTable.tsx +63 -56
- package/src/modules/messages/subscribers/message-notification.ts +13 -3
- package/src/modules/payment_gateways/api/webhook/[provider]/route.ts +243 -62
- package/src/modules/payment_gateways/lib/gateway-service.ts +39 -12
- package/src/modules/planner/lib/availabilityMerge.ts +106 -41
- package/src/modules/planner/services/plannerAvailabilityService.ts +4 -0
- package/src/modules/sales/components/documents/LineItemDialog.tsx +194 -111
- package/src/modules/sales/components/documents/lineItemUtils.ts +18 -0
- package/src/modules/staff/backend/staff/time-tracking/projects/[id]/page.tsx +25 -13
- package/src/modules/sync_excel/lib/adapters/customers.ts +33 -27
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isDeepStrictEqual } from 'node:util'
|
|
1
2
|
import { registerCommand, type CommandHandler } from '@open-mercato/shared/lib/commands'
|
|
2
3
|
import type { CommandRuntimeContext } from '@open-mercato/shared/lib/commands'
|
|
3
4
|
import { buildChanges } from '@open-mercato/shared/lib/commands/helpers'
|
|
@@ -26,6 +27,8 @@ import {
|
|
|
26
27
|
} from './shared'
|
|
27
28
|
import { resolveRedoSnapshot } from '@open-mercato/shared/lib/commands/redo'
|
|
28
29
|
import { createLogger } from '@open-mercato/shared/lib/logger'
|
|
30
|
+
import { enforceCommandOptimisticLockWithGuards } from '@open-mercato/shared/lib/crud/optimistic-lock-command'
|
|
31
|
+
import { calendarEventTypeBehaviorSchema, type CalendarEventTypeBehavior } from '../calendar-event-types'
|
|
29
32
|
|
|
30
33
|
const logger = createLogger('customers')
|
|
31
34
|
|
|
@@ -39,6 +42,7 @@ type CustomerDictionaryEntrySnapshot = {
|
|
|
39
42
|
label: string
|
|
40
43
|
color: string | null
|
|
41
44
|
icon: string | null
|
|
45
|
+
behavior: CalendarEventTypeBehavior | null
|
|
42
46
|
}
|
|
43
47
|
|
|
44
48
|
type CustomerDictionaryEntryUndoPayload = {
|
|
@@ -46,6 +50,18 @@ type CustomerDictionaryEntryUndoPayload = {
|
|
|
46
50
|
after?: CustomerDictionaryEntrySnapshot | null
|
|
47
51
|
}
|
|
48
52
|
|
|
53
|
+
const nullableCalendarEventTypeBehaviorSchema = calendarEventTypeBehaviorSchema.nullable()
|
|
54
|
+
|
|
55
|
+
function calendarEventTypeBehaviorsEqual(
|
|
56
|
+
left: CalendarEventTypeBehavior | null,
|
|
57
|
+
right: CalendarEventTypeBehavior | null,
|
|
58
|
+
): boolean {
|
|
59
|
+
const parsedLeft = nullableCalendarEventTypeBehaviorSchema.safeParse(left)
|
|
60
|
+
const parsedRight = nullableCalendarEventTypeBehaviorSchema.safeParse(right)
|
|
61
|
+
if (parsedLeft.success && parsedRight.success) return isDeepStrictEqual(parsedLeft.data, parsedRight.data)
|
|
62
|
+
return isDeepStrictEqual(left, right)
|
|
63
|
+
}
|
|
64
|
+
|
|
49
65
|
function buildRoleTypeInUseError(usageCount: number, ownerAssignments: number, relationshipAssignments: number) {
|
|
50
66
|
return new CrudHttpError(409, {
|
|
51
67
|
code: 'role_type_in_use',
|
|
@@ -87,9 +103,27 @@ function toSnapshot(entry: CustomerDictionaryEntry): CustomerDictionaryEntrySnap
|
|
|
87
103
|
label: entry.label,
|
|
88
104
|
color: entry.color ?? null,
|
|
89
105
|
icon: entry.icon ?? null,
|
|
106
|
+
behavior: entry.activityTypeBehavior ?? null,
|
|
90
107
|
}
|
|
91
108
|
}
|
|
92
109
|
|
|
110
|
+
function buildDictionaryChanges(
|
|
111
|
+
before: CustomerDictionaryEntrySnapshot,
|
|
112
|
+
after: CustomerDictionaryEntrySnapshot,
|
|
113
|
+
keys: readonly (keyof CustomerDictionaryEntrySnapshot)[],
|
|
114
|
+
): Record<string, { from: unknown; to: unknown }> {
|
|
115
|
+
const scalarKeys = keys.filter((key) => key !== 'behavior')
|
|
116
|
+
const changes = buildChanges(
|
|
117
|
+
before as unknown as Record<string, unknown>,
|
|
118
|
+
after as unknown as Record<string, unknown>,
|
|
119
|
+
scalarKeys,
|
|
120
|
+
)
|
|
121
|
+
if (keys.includes('behavior') && !calendarEventTypeBehaviorsEqual(before.behavior, after.behavior)) {
|
|
122
|
+
changes.behavior = { from: before.behavior, to: after.behavior }
|
|
123
|
+
}
|
|
124
|
+
return changes
|
|
125
|
+
}
|
|
126
|
+
|
|
93
127
|
async function loadSnapshot(
|
|
94
128
|
em: EntityManager,
|
|
95
129
|
id: string,
|
|
@@ -108,6 +142,7 @@ function applySnapshot(entry: CustomerDictionaryEntry, snapshot: CustomerDiction
|
|
|
108
142
|
entry.label = snapshot.label
|
|
109
143
|
entry.color = snapshot.color
|
|
110
144
|
entry.icon = snapshot.icon
|
|
145
|
+
entry.activityTypeBehavior = snapshot.behavior
|
|
111
146
|
}
|
|
112
147
|
|
|
113
148
|
async function invalidateCache(
|
|
@@ -150,6 +185,7 @@ const createDictionaryEntryCommand: CommandHandler<CustomerDictionaryEntryCreate
|
|
|
150
185
|
const label = parsed.label?.trim() || value.value
|
|
151
186
|
const color = sanitizeColor(parsed.color)
|
|
152
187
|
const icon = sanitizeIcon(parsed.icon)
|
|
188
|
+
const behavior = parsed.behavior
|
|
153
189
|
|
|
154
190
|
const existing = await findOneWithDecryption(
|
|
155
191
|
em,
|
|
@@ -168,6 +204,12 @@ const createDictionaryEntryCommand: CommandHandler<CustomerDictionaryEntryCreate
|
|
|
168
204
|
)
|
|
169
205
|
|
|
170
206
|
if (existing) {
|
|
207
|
+
await enforceCommandOptimisticLockWithGuards(ctx.container, {
|
|
208
|
+
resourceKind: 'customers.dictionary_entry',
|
|
209
|
+
resourceId: existing.id,
|
|
210
|
+
current: existing.updatedAt,
|
|
211
|
+
request: ctx.request ?? null,
|
|
212
|
+
})
|
|
171
213
|
const before = toSnapshot(existing)
|
|
172
214
|
let changed = false
|
|
173
215
|
|
|
@@ -183,10 +225,15 @@ const createDictionaryEntryCommand: CommandHandler<CustomerDictionaryEntryCreate
|
|
|
183
225
|
existing.icon = icon ?? null
|
|
184
226
|
changed = true
|
|
185
227
|
}
|
|
228
|
+
if (behavior !== undefined && !isDeepStrictEqual(existing.activityTypeBehavior ?? null, behavior)) {
|
|
229
|
+
existing.activityTypeBehavior = behavior
|
|
230
|
+
changed = true
|
|
231
|
+
}
|
|
186
232
|
|
|
187
233
|
if (changed) {
|
|
188
234
|
existing.updatedAt = new Date()
|
|
189
235
|
await em.flush()
|
|
236
|
+
await invalidateCache(ctx, toSnapshot(existing))
|
|
190
237
|
return {
|
|
191
238
|
entryId: existing.id,
|
|
192
239
|
tenantId: parsed.tenantId,
|
|
@@ -214,9 +261,11 @@ const createDictionaryEntryCommand: CommandHandler<CustomerDictionaryEntryCreate
|
|
|
214
261
|
label,
|
|
215
262
|
color: color ?? null,
|
|
216
263
|
icon: icon ?? null,
|
|
264
|
+
activityTypeBehavior: behavior ?? null,
|
|
217
265
|
})
|
|
218
266
|
em.persist(entry)
|
|
219
267
|
await em.flush()
|
|
268
|
+
await invalidateCache(ctx, toSnapshot(entry))
|
|
220
269
|
|
|
221
270
|
return {
|
|
222
271
|
entryId: entry.id,
|
|
@@ -254,10 +303,10 @@ const createDictionaryEntryCommand: CommandHandler<CustomerDictionaryEntryCreate
|
|
|
254
303
|
if (result.mode === 'updated') {
|
|
255
304
|
const before = result.before ?? null
|
|
256
305
|
if (!before) return null
|
|
257
|
-
const changes =
|
|
258
|
-
before
|
|
259
|
-
after
|
|
260
|
-
['label', 'color', 'icon']
|
|
306
|
+
const changes = buildDictionaryChanges(
|
|
307
|
+
before,
|
|
308
|
+
after,
|
|
309
|
+
['label', 'color', 'icon', 'behavior']
|
|
261
310
|
)
|
|
262
311
|
if (!changes || Object.keys(changes).length === 0) return null
|
|
263
312
|
return {
|
|
@@ -333,6 +382,7 @@ const createDictionaryEntryCommand: CommandHandler<CustomerDictionaryEntryCreate
|
|
|
333
382
|
label: before.label,
|
|
334
383
|
color: before.color,
|
|
335
384
|
icon: before.icon,
|
|
385
|
+
activityTypeBehavior: before.behavior,
|
|
336
386
|
})
|
|
337
387
|
em.persist(entry)
|
|
338
388
|
} else {
|
|
@@ -369,6 +419,7 @@ const createDictionaryEntryCommand: CommandHandler<CustomerDictionaryEntryCreate
|
|
|
369
419
|
label: after.label,
|
|
370
420
|
color: after.color,
|
|
371
421
|
icon: after.icon,
|
|
422
|
+
activityTypeBehavior: after.behavior,
|
|
372
423
|
})
|
|
373
424
|
em.persist(entry)
|
|
374
425
|
} else {
|
|
@@ -428,6 +479,13 @@ const updateDictionaryEntryCommand: CommandHandler<CustomerDictionaryEntryUpdate
|
|
|
428
479
|
throw notFound('Dictionary entry not found')
|
|
429
480
|
}
|
|
430
481
|
|
|
482
|
+
await enforceCommandOptimisticLockWithGuards(ctx.container, {
|
|
483
|
+
resourceKind: 'customers.dictionary_entry',
|
|
484
|
+
resourceId: entry.id,
|
|
485
|
+
current: entry.updatedAt,
|
|
486
|
+
request: ctx.request ?? null,
|
|
487
|
+
})
|
|
488
|
+
|
|
431
489
|
let changed = false
|
|
432
490
|
|
|
433
491
|
if (parsed.value !== undefined) {
|
|
@@ -499,9 +557,18 @@ const updateDictionaryEntryCommand: CommandHandler<CustomerDictionaryEntryUpdate
|
|
|
499
557
|
}
|
|
500
558
|
}
|
|
501
559
|
|
|
560
|
+
if (
|
|
561
|
+
parsed.behavior !== undefined &&
|
|
562
|
+
!isDeepStrictEqual(entry.activityTypeBehavior ?? null, parsed.behavior)
|
|
563
|
+
) {
|
|
564
|
+
entry.activityTypeBehavior = parsed.behavior
|
|
565
|
+
changed = true
|
|
566
|
+
}
|
|
567
|
+
|
|
502
568
|
if (changed) {
|
|
503
569
|
entry.updatedAt = new Date()
|
|
504
570
|
await em.flush()
|
|
571
|
+
await invalidateCache(ctx, toSnapshot(entry))
|
|
505
572
|
}
|
|
506
573
|
|
|
507
574
|
return {
|
|
@@ -522,10 +589,10 @@ const updateDictionaryEntryCommand: CommandHandler<CustomerDictionaryEntryUpdate
|
|
|
522
589
|
const before = snapshots.before as CustomerDictionaryEntrySnapshot | undefined
|
|
523
590
|
const after = snapshots.after as CustomerDictionaryEntrySnapshot | undefined
|
|
524
591
|
if (!before || !after || !result.changed) return null
|
|
525
|
-
const changes =
|
|
526
|
-
before
|
|
527
|
-
after
|
|
528
|
-
['value', 'label', 'color', 'icon']
|
|
592
|
+
const changes = buildDictionaryChanges(
|
|
593
|
+
before,
|
|
594
|
+
after,
|
|
595
|
+
['value', 'label', 'color', 'icon', 'behavior']
|
|
529
596
|
)
|
|
530
597
|
if (!changes || Object.keys(changes).length === 0) return null
|
|
531
598
|
const { translate } = await resolveTranslations()
|
|
@@ -571,6 +638,7 @@ const updateDictionaryEntryCommand: CommandHandler<CustomerDictionaryEntryUpdate
|
|
|
571
638
|
label: before.label,
|
|
572
639
|
color: before.color,
|
|
573
640
|
icon: before.icon,
|
|
641
|
+
activityTypeBehavior: before.behavior,
|
|
574
642
|
})
|
|
575
643
|
em.persist(entry)
|
|
576
644
|
} else {
|
|
@@ -613,6 +681,12 @@ const deleteDictionaryEntryCommand: CommandHandler<CustomerDictionaryEntryDelete
|
|
|
613
681
|
if (!entry || entry.organizationId !== parsed.organizationId || entry.tenantId !== parsed.tenantId || entry.kind !== parsed.kind) {
|
|
614
682
|
throw notFound('Dictionary entry not found')
|
|
615
683
|
}
|
|
684
|
+
await enforceCommandOptimisticLockWithGuards(ctx.container, {
|
|
685
|
+
resourceKind: 'customers.dictionary_entry',
|
|
686
|
+
resourceId: entry.id,
|
|
687
|
+
current: entry.updatedAt,
|
|
688
|
+
request: ctx.request ?? null,
|
|
689
|
+
})
|
|
616
690
|
if (entry.kind === 'person_company_role') {
|
|
617
691
|
const usage = await loadRoleTypeUsage(em, {
|
|
618
692
|
tenantId: entry.tenantId,
|
|
@@ -629,6 +703,7 @@ const deleteDictionaryEntryCommand: CommandHandler<CustomerDictionaryEntryDelete
|
|
|
629
703
|
}
|
|
630
704
|
em.remove(entry)
|
|
631
705
|
await em.flush()
|
|
706
|
+
await invalidateCache(ctx, toSnapshot(entry))
|
|
632
707
|
return { entryId: entry.id }
|
|
633
708
|
},
|
|
634
709
|
buildLog: async ({ snapshots }) => {
|
|
@@ -675,6 +750,7 @@ const deleteDictionaryEntryCommand: CommandHandler<CustomerDictionaryEntryDelete
|
|
|
675
750
|
label: before.label,
|
|
676
751
|
color: before.color,
|
|
677
752
|
icon: before.icon,
|
|
753
|
+
activityTypeBehavior: before.behavior,
|
|
678
754
|
})
|
|
679
755
|
em.persist(entry)
|
|
680
756
|
} else {
|