@open-mercato/core 0.10.1-develop.7761.1.9dfaf470ed → 0.10.1-develop.7763.1.caea616ebf
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/profile/route.js +16 -2
- package/dist/modules/auth/api/profile/route.js.map +2 -2
- package/dist/modules/auth/lib/userDataSubject.js +26 -0
- package/dist/modules/auth/lib/userDataSubject.js.map +7 -0
- package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js +1 -0
- package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js.map +2 -2
- package/dist/modules/customers/api/companies/[id]/route.js +3 -2
- package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/deals/[id]/route.js +11 -12
- package/dist/modules/customers/api/deals/[id]/route.js.map +2 -2
- package/dist/modules/customers/api/people/[id]/route.js +3 -2
- package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies/create/page.js +6 -0
- package/dist/modules/customers/backend/customers/companies/create/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +25 -25
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealInjectedTabs.js +8 -27
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealInjectedTabs.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js +175 -171
- package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/pipeline/components/QuickDealDialog.js +25 -24
- package/dist/modules/customers/backend/customers/deals/pipeline/components/QuickDealDialog.js.map +2 -2
- package/dist/modules/customers/backend/customers/people/create/page.js +9 -0
- package/dist/modules/customers/backend/customers/people/create/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +140 -144
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/components/detail/CompanyDetailHeader.js +2 -0
- package/dist/modules/customers/components/detail/CompanyDetailHeader.js.map +2 -2
- package/dist/modules/customers/components/detail/CompanyDetailTabs.js +13 -4
- package/dist/modules/customers/components/detail/CompanyDetailTabs.js.map +2 -2
- package/dist/modules/customers/components/detail/CreatePersonDialog.js +13 -3
- package/dist/modules/customers/components/detail/CreatePersonDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/CustomerDetailSidebar.js +29 -0
- package/dist/modules/customers/components/detail/CustomerDetailSidebar.js.map +7 -0
- package/dist/modules/customers/components/detail/DealDetailHeader.js +4 -2
- package/dist/modules/customers/components/detail/DealDetailHeader.js.map +2 -2
- package/dist/modules/customers/components/detail/DealDetailTabs.js +9 -1
- package/dist/modules/customers/components/detail/DealDetailTabs.js.map +2 -2
- package/dist/modules/customers/components/detail/DealForm.js +5 -0
- package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
- package/dist/modules/customers/components/detail/PersonDetailHeader.js +2 -0
- package/dist/modules/customers/components/detail/PersonDetailHeader.js.map +2 -2
- package/dist/modules/customers/components/detail/PersonDetailTabs.js +9 -1
- package/dist/modules/customers/components/detail/PersonDetailTabs.js.map +2 -2
- package/dist/modules/customers/components/detail/create/CreateDealForm.js +160 -176
- package/dist/modules/customers/components/detail/create/CreateDealForm.js.map +2 -2
- package/dist/modules/customers/components/detail/useCustomerInjectedTabs.js +47 -0
- package/dist/modules/customers/components/detail/useCustomerInjectedTabs.js.map +7 -0
- package/dist/modules/customers/components/formConfig.js +3 -0
- package/dist/modules/customers/components/formConfig.js.map +2 -2
- package/dist/modules/customers/extension-points.js +14 -4
- package/dist/modules/customers/extension-points.js.map +2 -2
- package/dist/modules/customers/lib/detailResponseEnrichment.js +38 -0
- package/dist/modules/customers/lib/detailResponseEnrichment.js.map +7 -0
- package/dist/modules/dashboards/api/layout/[itemId]/route.js +11 -4
- package/dist/modules/dashboards/api/layout/[itemId]/route.js.map +2 -2
- package/dist/modules/dashboards/api/layout/route.js +25 -13
- package/dist/modules/dashboards/api/layout/route.js.map +2 -2
- package/dist/modules/integrations/widgets/injection/external-ids/widget.client.js +4 -4
- package/dist/modules/integrations/widgets/injection/external-ids/widget.client.js.map +2 -2
- package/package.json +7 -7
- package/src/modules/auth/api/profile/route.ts +15 -1
- package/src/modules/auth/lib/userDataSubject.ts +30 -0
- package/src/modules/customer_accounts/widgets/injection/account-status/widget.client.tsx +2 -0
- package/src/modules/customers/api/companies/[id]/route.ts +3 -2
- package/src/modules/customers/api/deals/[id]/route.ts +12 -12
- package/src/modules/customers/api/people/[id]/route.ts +3 -2
- package/src/modules/customers/backend/customers/companies/create/page.tsx +6 -0
- package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +27 -30
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealInjectedTabs.tsx +9 -44
- package/src/modules/customers/backend/customers/deals/[id]/page.tsx +7 -3
- package/src/modules/customers/backend/customers/deals/pipeline/components/QuickDealDialog.tsx +25 -27
- package/src/modules/customers/backend/customers/people/create/page.tsx +9 -0
- package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +21 -33
- package/src/modules/customers/components/detail/CompanyDetailHeader.tsx +3 -0
- package/src/modules/customers/components/detail/CompanyDetailTabs.tsx +15 -4
- package/src/modules/customers/components/detail/CreatePersonDialog.tsx +15 -4
- package/src/modules/customers/components/detail/CustomerDetailSidebar.tsx +41 -0
- package/src/modules/customers/components/detail/DealDetailHeader.tsx +4 -1
- package/src/modules/customers/components/detail/DealDetailTabs.tsx +11 -1
- package/src/modules/customers/components/detail/DealForm.tsx +5 -0
- package/src/modules/customers/components/detail/PersonDetailHeader.tsx +3 -0
- package/src/modules/customers/components/detail/PersonDetailTabs.tsx +11 -1
- package/src/modules/customers/components/detail/create/CreateDealForm.tsx +126 -209
- package/src/modules/customers/components/detail/useCustomerInjectedTabs.tsx +64 -0
- package/src/modules/customers/components/formConfig.tsx +3 -0
- package/src/modules/customers/extension-points.ts +14 -4
- package/src/modules/customers/lib/detailResponseEnrichment.ts +53 -0
- package/src/modules/dashboards/api/layout/[itemId]/route.ts +12 -4
- package/src/modules/dashboards/api/layout/route.ts +25 -12
- package/src/modules/integrations/widgets/injection/external-ids/widget.client.tsx +4 -4
|
@@ -9,6 +9,8 @@ import { resolveAllowedWidgetIds } from '@open-mercato/core/modules/dashboards/l
|
|
|
9
9
|
import { authorizeFeatures } from '@open-mercato/shared/security/featurePolicy'
|
|
10
10
|
import { User } from '@open-mercato/core/modules/auth/data/entities'
|
|
11
11
|
import { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'
|
|
12
|
+
import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
|
|
13
|
+
import { resolveUserDataSubject } from '@open-mercato/core/modules/auth/lib/userDataSubject'
|
|
12
14
|
import {
|
|
13
15
|
runCrudMutationGuardAfterSuccess,
|
|
14
16
|
validateCrudMutationGuard,
|
|
@@ -80,15 +82,19 @@ export async function GET(req: Request) {
|
|
|
80
82
|
// Use a fresh fork to avoid carrying over pending entities from other operations
|
|
81
83
|
const em = (container.resolve('em') as any).fork({ clear: true, freshEventManager: true, useContext: true })
|
|
82
84
|
const rbac = container.resolve('rbacService') as any
|
|
83
|
-
const
|
|
85
|
+
const userId = await resolveUserDataSubject(em, auth)
|
|
86
|
+
if (!userId) {
|
|
87
|
+
const { translate } = await resolveTranslations()
|
|
88
|
+
return NextResponse.json({ error: translate('api.errors.forbidden', 'Forbidden') }, { status: 403 })
|
|
89
|
+
}
|
|
84
90
|
|
|
85
91
|
const scope: LayoutScope = {
|
|
86
|
-
userId
|
|
92
|
+
userId,
|
|
87
93
|
tenantId: auth.tenantId ?? null,
|
|
88
94
|
organizationId: auth.orgId ?? null,
|
|
89
95
|
}
|
|
90
96
|
|
|
91
|
-
const effectiveFeatures = await rbac.getEffectiveFeatures(
|
|
97
|
+
const effectiveFeatures = await rbac.getEffectiveFeatures(auth.sub, {
|
|
92
98
|
tenantId: scope.tenantId,
|
|
93
99
|
organizationId: scope.organizationId,
|
|
94
100
|
})
|
|
@@ -128,7 +134,7 @@ export async function GET(req: Request) {
|
|
|
128
134
|
size: widget.metadata.defaultSize ?? DEFAULT_SIZE,
|
|
129
135
|
settings: widget.metadata.defaultSettings ?? undefined,
|
|
130
136
|
}))
|
|
131
|
-
if (hasRegisteredWidgets) {
|
|
137
|
+
if (hasRegisteredWidgets && !auth.isApiKey) {
|
|
132
138
|
layout = em.create(DashboardLayout, {
|
|
133
139
|
userId: scope.userId,
|
|
134
140
|
tenantId: scope.tenantId,
|
|
@@ -138,7 +144,7 @@ export async function GET(req: Request) {
|
|
|
138
144
|
em.persist(layout)
|
|
139
145
|
hasChanged = true
|
|
140
146
|
}
|
|
141
|
-
} else if (hasRegisteredWidgets) {
|
|
147
|
+
} else if (hasRegisteredWidgets || auth.isApiKey) {
|
|
142
148
|
const existingLayout = layout
|
|
143
149
|
const filtered = items.filter((item) => allowedIds.includes(item.widgetId))
|
|
144
150
|
if (filtered.length !== items.length) {
|
|
@@ -152,11 +158,11 @@ export async function GET(req: Request) {
|
|
|
152
158
|
) {
|
|
153
159
|
hasChanged = true
|
|
154
160
|
}
|
|
155
|
-
existingLayout.layoutJson = items
|
|
161
|
+
if (!auth.isApiKey) existingLayout.layoutJson = items
|
|
156
162
|
layout = existingLayout
|
|
157
163
|
}
|
|
158
164
|
|
|
159
|
-
if (hasChanged) {
|
|
165
|
+
if (hasChanged && !auth.isApiKey) {
|
|
160
166
|
await em.flush()
|
|
161
167
|
}
|
|
162
168
|
|
|
@@ -231,14 +237,20 @@ export async function PUT(req: Request) {
|
|
|
231
237
|
const em = (resolve('em') as any).fork({ clear: true, freshEventManager: true, useContext: true })
|
|
232
238
|
const rbac = resolve('rbacService') as any
|
|
233
239
|
|
|
240
|
+
const userId = await resolveUserDataSubject(em, auth)
|
|
241
|
+
if (!userId) {
|
|
242
|
+
const { translate } = await resolveTranslations()
|
|
243
|
+
return NextResponse.json({ error: translate('api.errors.forbidden', 'Forbidden') }, { status: 403 })
|
|
244
|
+
}
|
|
245
|
+
|
|
234
246
|
const scope: LayoutScope = {
|
|
235
|
-
userId
|
|
247
|
+
userId,
|
|
236
248
|
tenantId: auth.tenantId ?? null,
|
|
237
249
|
organizationId: auth.orgId ?? null,
|
|
238
250
|
}
|
|
239
251
|
|
|
240
252
|
const canConfigure = await rbac.userHasAllFeatures(
|
|
241
|
-
|
|
253
|
+
auth.sub,
|
|
242
254
|
['dashboards.configure'],
|
|
243
255
|
{ tenantId: scope.tenantId, organizationId: scope.organizationId },
|
|
244
256
|
)
|
|
@@ -249,7 +261,7 @@ export async function PUT(req: Request) {
|
|
|
249
261
|
const guardResult = await validateCrudMutationGuard(container, {
|
|
250
262
|
tenantId: scope.tenantId ?? '',
|
|
251
263
|
organizationId: scope.organizationId,
|
|
252
|
-
userId:
|
|
264
|
+
userId: auth.sub,
|
|
253
265
|
resourceKind: RESOURCE_KIND,
|
|
254
266
|
resourceId: scope.userId,
|
|
255
267
|
operation: 'update',
|
|
@@ -271,7 +283,7 @@ export async function PUT(req: Request) {
|
|
|
271
283
|
if (widgets.length === 0) {
|
|
272
284
|
return NextResponse.json({ error: 'Widget registry unavailable' }, { status: 503 })
|
|
273
285
|
}
|
|
274
|
-
const effectiveFeatures = await rbac.getEffectiveFeatures(
|
|
286
|
+
const effectiveFeatures = await rbac.getEffectiveFeatures(auth.sub, {
|
|
275
287
|
tenantId: scope.tenantId,
|
|
276
288
|
organizationId: scope.organizationId,
|
|
277
289
|
})
|
|
@@ -323,7 +335,7 @@ export async function PUT(req: Request) {
|
|
|
323
335
|
await runCrudMutationGuardAfterSuccess(container, {
|
|
324
336
|
tenantId: scope.tenantId ?? '',
|
|
325
337
|
organizationId: scope.organizationId,
|
|
326
|
-
userId:
|
|
338
|
+
userId: auth.sub,
|
|
327
339
|
resourceKind: RESOURCE_KIND,
|
|
328
340
|
resourceId: scope.userId,
|
|
329
341
|
operation: 'update',
|
|
@@ -349,6 +361,7 @@ const layoutGetDoc: OpenApiMethodDoc = {
|
|
|
349
361
|
],
|
|
350
362
|
errors: [
|
|
351
363
|
{ status: 401, description: 'Authentication required', schema: dashboardsErrorSchema },
|
|
364
|
+
{ status: 403, description: 'No user binding in the authenticated scope', schema: dashboardsErrorSchema },
|
|
352
365
|
],
|
|
353
366
|
}
|
|
354
367
|
|
|
@@ -22,7 +22,7 @@ function SyncStatusBadge({ status, lastSynced }: { status: ExternalIdMapping['sy
|
|
|
22
22
|
const label = t(config.label, status)
|
|
23
23
|
|
|
24
24
|
return (
|
|
25
|
-
<span className="inline-flex items-center gap-1 text-xs text-muted-foreground">
|
|
25
|
+
<span className="inline-flex shrink-0 items-center gap-1 text-xs text-muted-foreground">
|
|
26
26
|
<span className={cn('inline-block size-1.5 rounded-full', config.dot)} aria-hidden="true" />
|
|
27
27
|
<span>{label}</span>
|
|
28
28
|
{lastSynced && (
|
|
@@ -60,11 +60,11 @@ export default function ExternalIdsWidget({ data }: InjectionWidgetComponentProp
|
|
|
60
60
|
key={integrationId}
|
|
61
61
|
className="flex items-center justify-between gap-2 rounded-md bg-muted/50 px-3 py-2"
|
|
62
62
|
>
|
|
63
|
-
<div className="flex items-center gap-2
|
|
63
|
+
<div className="flex min-w-0 flex-1 flex-wrap items-center gap-2">
|
|
64
64
|
<span className="text-sm font-medium truncate">
|
|
65
65
|
{getIntegrationTitle(integrationId)}
|
|
66
66
|
</span>
|
|
67
|
-
<code className="rounded bg-muted px-1.5 py-0.5 text-xs font-mono text-muted-foreground">
|
|
67
|
+
<code className="min-w-0 max-w-full break-all rounded bg-muted px-1.5 py-0.5 text-xs font-mono text-muted-foreground">
|
|
68
68
|
{mapping.externalId}
|
|
69
69
|
</code>
|
|
70
70
|
{mapping.externalUrl && (
|
|
@@ -72,7 +72,7 @@ export default function ExternalIdsWidget({ data }: InjectionWidgetComponentProp
|
|
|
72
72
|
href={mapping.externalUrl}
|
|
73
73
|
target="_blank"
|
|
74
74
|
rel="noopener noreferrer"
|
|
75
|
-
className="text-muted-foreground hover:text-foreground transition-colors"
|
|
75
|
+
className="shrink-0 text-muted-foreground hover:text-foreground transition-colors"
|
|
76
76
|
aria-label={t('integrations.externalIds.openExternal', 'Open in external system')}
|
|
77
77
|
>
|
|
78
78
|
<ExternalLinkIcon />
|