@open-mercato/core 0.10.1-develop.7954.1.48da4a7d13 → 0.10.1-develop.7972.1.03f813eaaf
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/auth/api/logout.js +3 -3
- package/dist/modules/auth/api/logout.js.map +2 -2
- package/dist/modules/auth/commands/roles.js +42 -31
- package/dist/modules/auth/commands/roles.js.map +2 -2
- package/dist/modules/communication_channels/setup.js +49 -45
- package/dist/modules/communication_channels/setup.js.map +2 -2
- package/dist/modules/customer_accounts/services/domainMappingService.js +55 -29
- package/dist/modules/customer_accounts/services/domainMappingService.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivitiesSection.js +8 -3
- package/dist/modules/customers/components/detail/ActivitiesSection.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivityCard.js +3 -3
- package/dist/modules/customers/components/detail/ActivityCard.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivityHistorySection.js +19 -7
- package/dist/modules/customers/components/detail/ActivityHistorySection.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivityTimeline.js +5 -5
- package/dist/modules/customers/components/detail/ActivityTimeline.js.map +2 -2
- package/dist/modules/directory/subscribers/seedOrganizationDefaults.js +67 -0
- package/dist/modules/directory/subscribers/seedOrganizationDefaults.js.map +7 -0
- package/dist/modules/ecommerce/api/storefront/categories/[slug]/route.js +1 -1
- package/dist/modules/ecommerce/api/storefront/categories/[slug]/route.js.map +2 -2
- package/dist/modules/ecommerce/api/storefront/categories/route.js +1 -1
- package/dist/modules/ecommerce/api/storefront/categories/route.js.map +2 -2
- package/dist/modules/ecommerce/api/storefront/context/route.js +1 -1
- package/dist/modules/ecommerce/api/storefront/context/route.js.map +2 -2
- package/dist/modules/ecommerce/api/storefront/products/[idOrHandle]/route.js +1 -1
- package/dist/modules/ecommerce/api/storefront/products/[idOrHandle]/route.js.map +2 -2
- package/dist/modules/ecommerce/api/storefront/products/route.js +1 -1
- package/dist/modules/ecommerce/api/storefront/products/route.js.map +2 -2
- package/dist/modules/ecommerce/api/storefront/search/suggest/route.js +1 -1
- package/dist/modules/ecommerce/api/storefront/search/suggest/route.js.map +2 -2
- package/dist/modules/ecommerce/lib/cacheInvalidation.js +3 -0
- package/dist/modules/ecommerce/lib/cacheInvalidation.js.map +2 -2
- package/dist/modules/ecommerce/lib/cacheKeys.js +4 -0
- package/dist/modules/ecommerce/lib/cacheKeys.js.map +2 -2
- package/dist/modules/ecommerce/lib/storeContext.js +36 -12
- package/dist/modules/ecommerce/lib/storeContext.js.map +2 -2
- package/dist/modules/ecommerce/subscribers/sales-channel-cache-invalidation.js +14 -0
- package/dist/modules/ecommerce/subscribers/sales-channel-cache-invalidation.js.map +7 -0
- package/dist/modules/integrations/setup.js +34 -24
- package/dist/modules/integrations/setup.js.map +2 -2
- package/dist/modules/messages/components/MessagesInboxPageClient.js +1 -1
- package/dist/modules/messages/components/MessagesInboxPageClient.js.map +2 -2
- package/dist/modules/messages/components/message-detail/panels/MainMessageHeader.js +3 -3
- package/dist/modules/messages/components/message-detail/panels/MainMessageHeader.js.map +2 -2
- package/dist/modules/messages/components/message-detail/panels/body-panel.js +2 -2
- package/dist/modules/messages/components/message-detail/panels/body-panel.js.map +2 -2
- package/dist/modules/payment_gateways/setup.js +3 -0
- package/dist/modules/payment_gateways/setup.js.map +2 -2
- package/dist/modules/warranty_claims/backend/warranty_claims/[id]/page.js +30 -11
- package/dist/modules/warranty_claims/backend/warranty_claims/[id]/page.js.map +3 -3
- package/dist/modules/warranty_claims/setup.js +34 -30
- package/dist/modules/warranty_claims/setup.js.map +2 -2
- package/dist/modules/workflows/setup.js +7 -0
- package/dist/modules/workflows/setup.js.map +2 -2
- package/package.json +7 -7
- package/src/modules/auth/api/logout.ts +3 -3
- package/src/modules/auth/commands/roles.ts +43 -32
- package/src/modules/communication_channels/setup.ts +59 -53
- package/src/modules/customer_accounts/services/domainMappingService.ts +57 -29
- package/src/modules/customers/components/detail/ActivitiesSection.tsx +8 -3
- package/src/modules/customers/components/detail/ActivityCard.tsx +3 -3
- package/src/modules/customers/components/detail/ActivityHistorySection.tsx +20 -8
- package/src/modules/customers/components/detail/ActivityTimeline.tsx +7 -7
- package/src/modules/customers/i18n/de.json +1 -0
- package/src/modules/customers/i18n/en.json +1 -0
- package/src/modules/customers/i18n/es.json +1 -0
- package/src/modules/customers/i18n/ko.json +1 -0
- package/src/modules/customers/i18n/pl.json +1 -0
- package/src/modules/directory/subscribers/seedOrganizationDefaults.ts +84 -0
- package/src/modules/ecommerce/api/storefront/categories/[slug]/route.ts +1 -1
- package/src/modules/ecommerce/api/storefront/categories/route.ts +1 -1
- package/src/modules/ecommerce/api/storefront/context/route.ts +1 -1
- package/src/modules/ecommerce/api/storefront/products/[idOrHandle]/route.ts +1 -1
- package/src/modules/ecommerce/api/storefront/products/route.ts +1 -1
- package/src/modules/ecommerce/api/storefront/search/suggest/route.ts +1 -1
- package/src/modules/ecommerce/lib/cacheInvalidation.ts +4 -0
- package/src/modules/ecommerce/lib/cacheKeys.ts +4 -0
- package/src/modules/ecommerce/lib/storeContext.ts +56 -10
- package/src/modules/ecommerce/subscribers/sales-channel-cache-invalidation.ts +12 -0
- package/src/modules/integrations/setup.ts +41 -24
- package/src/modules/messages/components/MessagesInboxPageClient.tsx +1 -1
- package/src/modules/messages/components/message-detail/panels/MainMessageHeader.tsx +3 -3
- package/src/modules/messages/components/message-detail/panels/body-panel.tsx +2 -2
- package/src/modules/payment_gateways/setup.ts +4 -0
- package/src/modules/warranty_claims/backend/warranty_claims/[id]/page.tsx +55 -28
- package/src/modules/warranty_claims/setup.ts +40 -30
- package/src/modules/workflows/setup.ts +8 -0
|
@@ -6,6 +6,7 @@ import { useRouter } from 'next/navigation'
|
|
|
6
6
|
import type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'
|
|
7
7
|
import { Copy, Hash, Info, MessageSquare, Pencil, RefreshCw, Trash2, UserRound } from 'lucide-react'
|
|
8
8
|
import { hasFeature } from '@open-mercato/shared/security/features'
|
|
9
|
+
import { getTelemetryRuntime } from '@open-mercato/shared/lib/telemetry/runtime'
|
|
9
10
|
import { parseBooleanFromUnknown } from '@open-mercato/shared/lib/boolean'
|
|
10
11
|
import type { TranslateFn, TranslateParams } from '@open-mercato/shared/lib/i18n/context'
|
|
11
12
|
import { useLocale, useT } from '@open-mercato/shared/lib/i18n/context'
|
|
@@ -783,6 +784,7 @@ export default function WarrantyClaimDetailPage({ params }: { params?: { id?: st
|
|
|
783
784
|
const [lineDialog, setLineDialog] = React.useState<{ mode: 'create' } | { mode: 'edit'; line: ClaimLine } | null>(null)
|
|
784
785
|
const [defaultWarrantyMonths, setDefaultWarrantyMonths] = React.useState<number | null>(null)
|
|
785
786
|
const [featureAccess, setFeatureAccess] = React.useState({
|
|
787
|
+
attachmentsView: false,
|
|
786
788
|
claimManage: false,
|
|
787
789
|
claimDelete: false,
|
|
788
790
|
receivingManage: false,
|
|
@@ -814,6 +816,7 @@ export default function WarrantyClaimDetailPage({ params }: { params?: { id?: st
|
|
|
814
816
|
headers: { 'content-type': 'application/json' },
|
|
815
817
|
body: JSON.stringify({
|
|
816
818
|
features: [
|
|
819
|
+
'attachments.view',
|
|
817
820
|
'warranty_claims.claim.manage',
|
|
818
821
|
'warranty_claims.claim.delete',
|
|
819
822
|
'warranty_claims.receiving.manage',
|
|
@@ -830,6 +833,7 @@ export default function WarrantyClaimDetailPage({ params }: { params?: { id?: st
|
|
|
830
833
|
const granted = Array.isArray(call.result?.granted) ? call.result.granted : []
|
|
831
834
|
const allGranted = call.result?.ok === true
|
|
832
835
|
setFeatureAccess({
|
|
836
|
+
attachmentsView: allGranted || hasFeature(granted, 'attachments.view'),
|
|
833
837
|
claimManage: allGranted || hasFeature(granted, 'warranty_claims.claim.manage'),
|
|
834
838
|
claimDelete: allGranted || hasFeature(granted, 'warranty_claims.claim.delete'),
|
|
835
839
|
receivingManage: allGranted || hasFeature(granted, 'warranty_claims.receiving.manage'),
|
|
@@ -841,6 +845,7 @@ export default function WarrantyClaimDetailPage({ params }: { params?: { id?: st
|
|
|
841
845
|
.catch(() => {
|
|
842
846
|
if (!cancelled) {
|
|
843
847
|
setFeatureAccess({
|
|
848
|
+
attachmentsView: false,
|
|
844
849
|
claimManage: false,
|
|
845
850
|
claimDelete: false,
|
|
846
851
|
receivingManage: false,
|
|
@@ -925,7 +930,7 @@ export default function WarrantyClaimDetailPage({ params }: { params?: { id?: st
|
|
|
925
930
|
setError(null)
|
|
926
931
|
setNotFound(false)
|
|
927
932
|
try {
|
|
928
|
-
const [claimPayload, linesPayload, eventsPayload, riskPayload, statsPayload
|
|
933
|
+
const [claimPayload, linesPayload, eventsPayload, riskPayload, statsPayload] = await Promise.all([
|
|
929
934
|
readApiResultOrThrow<{ items?: unknown[] }>(
|
|
930
935
|
`/api/warranty_claims?ids=${encodeURIComponent(id)}&page=1&pageSize=1`,
|
|
931
936
|
undefined,
|
|
@@ -950,11 +955,6 @@ export default function WarrantyClaimDetailPage({ params }: { params?: { id?: st
|
|
|
950
955
|
undefined,
|
|
951
956
|
{ fallback: { ok: true, result: {} } },
|
|
952
957
|
),
|
|
953
|
-
readApiResultOrThrow<{ items?: unknown[] }>(
|
|
954
|
-
`/api/attachments?entityId=${encodeURIComponent('warranty_claims:warranty_claim')}&recordId=${encodeURIComponent(id)}`,
|
|
955
|
-
undefined,
|
|
956
|
-
{ fallback: { items: [] } },
|
|
957
|
-
),
|
|
958
958
|
])
|
|
959
959
|
const nextClaim = (claimPayload.items ?? []).map(normalizeClaim).find((item): item is ClaimRecord => item !== null) ?? null
|
|
960
960
|
if (!nextClaim) {
|
|
@@ -969,7 +969,6 @@ export default function WarrantyClaimDetailPage({ params }: { params?: { id?: st
|
|
|
969
969
|
setClaim(nextClaim)
|
|
970
970
|
setLines((linesPayload.items ?? []).map(normalizeLine).filter((item): item is ClaimLine => item !== null))
|
|
971
971
|
setEvents((eventsPayload.items ?? []).map(normalizeEvent).filter((item): item is ClaimEvent => item !== null))
|
|
972
|
-
setAttachmentCount(Array.isArray(attachmentsPayload.items) ? attachmentsPayload.items.length : 0)
|
|
973
972
|
setRiskAssessment(normalizeRiskResponse(riskPayload))
|
|
974
973
|
const nextThreshold = statsPayload?.result?.slaAtRiskThresholdPct
|
|
975
974
|
setSlaAtRiskThresholdPct(typeof nextThreshold === 'number' ? nextThreshold : undefined)
|
|
@@ -984,6 +983,30 @@ export default function WarrantyClaimDetailPage({ params }: { params?: { id?: st
|
|
|
984
983
|
void loadData()
|
|
985
984
|
}, [loadData])
|
|
986
985
|
|
|
986
|
+
React.useEffect(() => {
|
|
987
|
+
let cancelled = false
|
|
988
|
+
setAttachmentCount(0)
|
|
989
|
+
if (!claim || claim.id !== id || !featureAccess.attachmentsView) return
|
|
990
|
+
void apiCall<{ items?: unknown[] }>(
|
|
991
|
+
`/api/attachments?entityId=${encodeURIComponent('warranty_claims:warranty_claim')}&recordId=${encodeURIComponent(claim.id)}`,
|
|
992
|
+
{ headers: { 'x-om-forbidden-redirect': '0' } },
|
|
993
|
+
{ fallback: { items: [] } },
|
|
994
|
+
)
|
|
995
|
+
.then((call) => {
|
|
996
|
+
if (cancelled || !call.ok) return
|
|
997
|
+
setAttachmentCount(Array.isArray(call.result?.items) ? call.result.items.length : 0)
|
|
998
|
+
})
|
|
999
|
+
.catch((error) => {
|
|
1000
|
+
getTelemetryRuntime()?.reportError(error, {
|
|
1001
|
+
module: 'warranty_claims',
|
|
1002
|
+
code: 'warranty_claims.attachment_count_failed',
|
|
1003
|
+
})
|
|
1004
|
+
})
|
|
1005
|
+
return () => {
|
|
1006
|
+
cancelled = true
|
|
1007
|
+
}
|
|
1008
|
+
}, [claim, featureAccess.attachmentsView, id, scopeVersion])
|
|
1009
|
+
|
|
987
1010
|
useAppEvent('warranty_claims.claim.*', (event) => {
|
|
988
1011
|
const eventClaimId = toStringOrNull(event.payload.claimId)
|
|
989
1012
|
if (eventClaimId === id) void loadData()
|
|
@@ -1908,7 +1931,9 @@ export default function WarrantyClaimDetailPage({ params }: { params?: { id?: st
|
|
|
1908
1931
|
const tabs: Array<{ id: TabId; label: string; count?: number }> = [
|
|
1909
1932
|
{ id: 'lines', label: t('warranty_claims.detail.tabs.lines'), count: lines.length },
|
|
1910
1933
|
{ id: 'timeline', label: t('warranty_claims.detail.tabs.timeline'), count: events.length },
|
|
1911
|
-
|
|
1934
|
+
...(featureAccess.attachmentsView
|
|
1935
|
+
? [{ id: 'attachments' as const, label: t('warranty_claims.detail.tabs.attachments'), count: attachmentCount }]
|
|
1936
|
+
: []),
|
|
1912
1937
|
{ id: 'ai', label: t('warranty_claims.detail.tabs.ai') },
|
|
1913
1938
|
]
|
|
1914
1939
|
const approvedLineCount = lines.filter((line) => line.lineStatus === 'approved').length
|
|
@@ -2046,7 +2071,7 @@ export default function WarrantyClaimDetailPage({ params }: { params?: { id?: st
|
|
|
2046
2071
|
</div>
|
|
2047
2072
|
<ClaimStageProgress status={claim.status} />
|
|
2048
2073
|
<Tabs
|
|
2049
|
-
value={activeTab}
|
|
2074
|
+
value={activeTab === 'attachments' && !featureAccess.attachmentsView ? 'lines' : activeTab}
|
|
2050
2075
|
onValueChange={(value) => setActiveTab(value as TabId)}
|
|
2051
2076
|
variant="underline"
|
|
2052
2077
|
>
|
|
@@ -2249,25 +2274,27 @@ export default function WarrantyClaimDetailPage({ params }: { params?: { id?: st
|
|
|
2249
2274
|
</div>
|
|
2250
2275
|
</TabsContent>
|
|
2251
2276
|
|
|
2252
|
-
|
|
2253
|
-
<
|
|
2254
|
-
<
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2277
|
+
{featureAccess.attachmentsView ? (
|
|
2278
|
+
<TabsContent value="attachments" className="mt-0">
|
|
2279
|
+
<div className="px-8 pb-8 pt-6">
|
|
2280
|
+
<AttachmentInput
|
|
2281
|
+
entityId="warranty_claims:warranty_claim"
|
|
2282
|
+
recordId={claim.id}
|
|
2283
|
+
allowDelete={featureAccess.claimManage}
|
|
2284
|
+
allowReplace={featureAccess.claimManage}
|
|
2285
|
+
disabled={!featureAccess.claimManage}
|
|
2286
|
+
onCountChange={setAttachmentCount}
|
|
2287
|
+
renderItemMeta={(item) => (
|
|
2288
|
+
isCustomerVisibleAttachment(item.tags) ? (
|
|
2289
|
+
<StatusBadge variant="info">
|
|
2290
|
+
{t('warranty_claims.detail.attachments.customerVisible', 'Visible to customer')}
|
|
2291
|
+
</StatusBadge>
|
|
2292
|
+
) : null
|
|
2293
|
+
)}
|
|
2294
|
+
/>
|
|
2295
|
+
</div>
|
|
2296
|
+
</TabsContent>
|
|
2297
|
+
) : null}
|
|
2271
2298
|
|
|
2272
2299
|
<TabsContent value="ai" className="mt-0">
|
|
2273
2300
|
<div className="grid gap-4 px-8 pb-8 pt-6 xl:grid-cols-2">
|
|
@@ -76,6 +76,42 @@ function stableSlaSweepScheduleId(organizationId: string): string {
|
|
|
76
76
|
return stableScheduleUuid(`warranty_claims:sla-sweep:${organizationId}`)
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
async function ensureSlaSweepSchedule(ctx: {
|
|
80
|
+
container: import('awilix').AwilixContainer
|
|
81
|
+
tenantId: string
|
|
82
|
+
organizationId: string
|
|
83
|
+
}): Promise<void> {
|
|
84
|
+
const cradle = ctx.container as { hasRegistration?: (name: string) => boolean }
|
|
85
|
+
if (typeof cradle.hasRegistration !== 'function' || !cradle.hasRegistration('schedulerService')) return
|
|
86
|
+
|
|
87
|
+
const schedulerService = ctx.container.resolve('schedulerService') as SchedulerServiceLike
|
|
88
|
+
try {
|
|
89
|
+
await schedulerService.register({
|
|
90
|
+
id: stableSlaSweepScheduleId(ctx.organizationId),
|
|
91
|
+
name: 'Warranty claims SLA sweep',
|
|
92
|
+
description: 'Enqueues tenant-scoped warranty claim SLA escalation sweeps every 900 seconds.',
|
|
93
|
+
scopeType: 'organization',
|
|
94
|
+
organizationId: ctx.organizationId,
|
|
95
|
+
tenantId: ctx.tenantId,
|
|
96
|
+
scheduleType: 'interval',
|
|
97
|
+
scheduleValue: '900s',
|
|
98
|
+
timezone: 'UTC',
|
|
99
|
+
targetType: 'queue',
|
|
100
|
+
targetQueue: 'warranty_claims.sla_sweep',
|
|
101
|
+
targetPayload: {
|
|
102
|
+
scope: { tenantId: ctx.tenantId, organizationId: ctx.organizationId },
|
|
103
|
+
},
|
|
104
|
+
sourceType: 'module',
|
|
105
|
+
sourceModule: 'warranty_claims',
|
|
106
|
+
isEnabled: true,
|
|
107
|
+
})
|
|
108
|
+
} catch (error) {
|
|
109
|
+
logger.warn('[warranty_claims] Failed to register SLA sweep schedule', {
|
|
110
|
+
error: error instanceof Error ? error.message : error,
|
|
111
|
+
})
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
79
115
|
export const setup: ModuleSetupConfig = {
|
|
80
116
|
defaultRoleFeatures: {
|
|
81
117
|
admin: adminFeatures,
|
|
@@ -117,37 +153,11 @@ export const setup: ModuleSetupConfig = {
|
|
|
117
153
|
|
|
118
154
|
async seedDefaults({ em, tenantId, organizationId, container }) {
|
|
119
155
|
await seedWarrantyClaimDictionaries(em, { tenantId, organizationId })
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
return
|
|
123
|
-
}
|
|
156
|
+
await ensureSlaSweepSchedule({ container, tenantId, organizationId })
|
|
157
|
+
},
|
|
124
158
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
await schedulerService.register({
|
|
128
|
-
id: stableSlaSweepScheduleId(organizationId),
|
|
129
|
-
name: 'Warranty claims SLA sweep',
|
|
130
|
-
description: 'Enqueues tenant-scoped warranty claim SLA escalation sweeps every 900 seconds.',
|
|
131
|
-
scopeType: 'organization',
|
|
132
|
-
organizationId,
|
|
133
|
-
tenantId,
|
|
134
|
-
scheduleType: 'interval',
|
|
135
|
-
scheduleValue: '900s',
|
|
136
|
-
timezone: 'UTC',
|
|
137
|
-
targetType: 'queue',
|
|
138
|
-
targetQueue: 'warranty_claims.sla_sweep',
|
|
139
|
-
targetPayload: {
|
|
140
|
-
scope: { tenantId, organizationId },
|
|
141
|
-
},
|
|
142
|
-
sourceType: 'module',
|
|
143
|
-
sourceModule: 'warranty_claims',
|
|
144
|
-
isEnabled: true,
|
|
145
|
-
})
|
|
146
|
-
} catch (error) {
|
|
147
|
-
logger.warn('[warranty_claims] Failed to register SLA sweep schedule', {
|
|
148
|
-
error: error instanceof Error ? error.message : error,
|
|
149
|
-
})
|
|
150
|
-
}
|
|
159
|
+
async onOrganizationCreated({ container, tenantId, organizationId }) {
|
|
160
|
+
await ensureSlaSweepSchedule({ container, tenantId, organizationId })
|
|
151
161
|
},
|
|
152
162
|
}
|
|
153
163
|
|
|
@@ -95,6 +95,14 @@ export const setup: ModuleSetupConfig = {
|
|
|
95
95
|
})
|
|
96
96
|
},
|
|
97
97
|
|
|
98
|
+
onOrganizationCreated: async (ctx) => {
|
|
99
|
+
await ensureMetricRollupSchedule({
|
|
100
|
+
container: ctx.container as never,
|
|
101
|
+
tenantId: ctx.tenantId,
|
|
102
|
+
organizationId: ctx.organizationId,
|
|
103
|
+
})
|
|
104
|
+
},
|
|
105
|
+
|
|
98
106
|
/**
|
|
99
107
|
* Portal grants for the §6.4 portal task surface.
|
|
100
108
|
*
|