@open-mercato/core 0.7.1-develop.7131.1.20abf9e885 → 0.7.1-develop.7136.1.0f76137a1d
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/helpers/integration/communicationChannelsFixtures.js.map +2 -2
- package/dist/modules/communication_channels/api/post/test-seed/route.js +40 -2
- package/dist/modules/communication_channels/api/post/test-seed/route.js.map +2 -2
- package/dist/modules/communication_channels/lib/access-control.js +6 -1
- package/dist/modules/communication_channels/lib/access-control.js.map +2 -2
- package/dist/modules/communication_channels/lib/system-user.js +8 -3
- package/dist/modules/communication_channels/lib/system-user.js.map +2 -2
- package/dist/modules/warranty_claims/api/ai/assess/route.js +20 -18
- package/dist/modules/warranty_claims/api/ai/assess/route.js.map +2 -2
- package/dist/modules/warranty_claims/api/credit-memo/route.js +11 -12
- package/dist/modules/warranty_claims/api/credit-memo/route.js.map +2 -2
- package/dist/modules/warranty_claims/api/events/route.js +1 -1
- package/dist/modules/warranty_claims/api/events/route.js.map +2 -2
- package/dist/modules/warranty_claims/api/portal/attachments/route.js +24 -27
- package/dist/modules/warranty_claims/api/portal/attachments/route.js.map +2 -2
- package/dist/modules/warranty_claims/api/portal/claims/[id]/route.js +8 -10
- package/dist/modules/warranty_claims/api/portal/claims/[id]/route.js.map +2 -2
- package/dist/modules/warranty_claims/api/portal/claims/[id]/shared.js +4 -9
- package/dist/modules/warranty_claims/api/portal/claims/[id]/shared.js.map +2 -2
- package/dist/modules/warranty_claims/api/portal/claims/[id]/submit/route.js +3 -3
- package/dist/modules/warranty_claims/api/portal/claims/[id]/submit/route.js.map +2 -2
- package/dist/modules/warranty_claims/api/portal/claims/[id]/withdraw/route.js +3 -3
- package/dist/modules/warranty_claims/api/portal/claims/[id]/withdraw/route.js.map +2 -2
- package/dist/modules/warranty_claims/api/portal/claims/route.js +4 -9
- package/dist/modules/warranty_claims/api/portal/claims/route.js.map +2 -2
- package/dist/modules/warranty_claims/api/portal/events/route.js +12 -13
- package/dist/modules/warranty_claims/api/portal/events/route.js.map +2 -2
- package/dist/modules/warranty_claims/api/receiving/route.js +14 -15
- package/dist/modules/warranty_claims/api/receiving/route.js.map +2 -2
- package/dist/modules/warranty_claims/api/registrations/route.js +9 -4
- package/dist/modules/warranty_claims/api/registrations/route.js.map +2 -2
- package/dist/modules/warranty_claims/api/replacement-order/route.js +11 -12
- package/dist/modules/warranty_claims/api/replacement-order/route.js.map +2 -2
- package/dist/modules/warranty_claims/api/return-label/route.js +20 -19
- package/dist/modules/warranty_claims/api/return-label/route.js.map +2 -2
- package/dist/modules/warranty_claims/api/risk/route.js +2 -1
- package/dist/modules/warranty_claims/api/risk/route.js.map +2 -2
- package/dist/modules/warranty_claims/api/sales-return/route.js +11 -12
- package/dist/modules/warranty_claims/api/sales-return/route.js.map +2 -2
- package/dist/modules/warranty_claims/api/troubleshooting-guides/route.js +22 -1
- package/dist/modules/warranty_claims/api/troubleshooting-guides/route.js.map +2 -2
- package/dist/modules/warranty_claims/api/vendor-recovery-suggestions/route.js +2 -1
- package/dist/modules/warranty_claims/api/vendor-recovery-suggestions/route.js.map +2 -2
- package/dist/modules/warranty_claims/commands/shared.js +2 -2
- package/dist/modules/warranty_claims/commands/shared.js.map +2 -2
- package/dist/modules/warranty_claims/lib/portalAuthGuard.js +31 -0
- package/dist/modules/warranty_claims/lib/portalAuthGuard.js.map +7 -0
- package/package.json +7 -7
- package/src/helpers/integration/communicationChannelsFixtures.ts +13 -0
- package/src/modules/communication_channels/api/post/test-seed/route.ts +47 -2
- package/src/modules/communication_channels/lib/access-control.ts +28 -0
- package/src/modules/communication_channels/lib/system-user.ts +40 -22
- package/src/modules/warranty_claims/api/ai/assess/route.ts +23 -17
- package/src/modules/warranty_claims/api/credit-memo/route.ts +14 -13
- package/src/modules/warranty_claims/api/events/route.ts +1 -1
- package/src/modules/warranty_claims/api/portal/attachments/route.ts +29 -27
- package/src/modules/warranty_claims/api/portal/claims/[id]/route.ts +9 -10
- package/src/modules/warranty_claims/api/portal/claims/[id]/shared.ts +5 -9
- package/src/modules/warranty_claims/api/portal/claims/[id]/submit/route.ts +3 -3
- package/src/modules/warranty_claims/api/portal/claims/[id]/withdraw/route.ts +3 -3
- package/src/modules/warranty_claims/api/portal/claims/route.ts +5 -9
- package/src/modules/warranty_claims/api/portal/events/route.ts +13 -13
- package/src/modules/warranty_claims/api/receiving/route.ts +17 -15
- package/src/modules/warranty_claims/api/registrations/route.ts +9 -3
- package/src/modules/warranty_claims/api/replacement-order/route.ts +14 -13
- package/src/modules/warranty_claims/api/return-label/route.ts +21 -17
- package/src/modules/warranty_claims/api/risk/route.ts +3 -1
- package/src/modules/warranty_claims/api/sales-return/route.ts +14 -13
- package/src/modules/warranty_claims/api/troubleshooting-guides/route.ts +23 -1
- package/src/modules/warranty_claims/api/vendor-recovery-suggestions/route.ts +3 -1
- package/src/modules/warranty_claims/commands/shared.ts +7 -1
- package/src/modules/warranty_claims/lib/portalAuthGuard.ts +30 -0
|
@@ -2,6 +2,7 @@ import { z } from 'zod'
|
|
|
2
2
|
import type { CrudCtx } from '@open-mercato/shared/lib/crud/factory'
|
|
3
3
|
import { makeCrudRoute } from '@open-mercato/shared/lib/crud/factory'
|
|
4
4
|
import { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'
|
|
5
|
+
import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
|
|
5
6
|
import { parseBooleanFromUnknown } from '@open-mercato/shared/lib/boolean'
|
|
6
7
|
import { buildIlikeTerm } from '@open-mercato/shared/lib/db/buildIlikeTerm'
|
|
7
8
|
import { applyIdsFilter } from '../../lib/apiIdsFilter'
|
|
@@ -122,11 +123,24 @@ function toEntitySteps(value: unknown): Record<string, unknown> | null {
|
|
|
122
123
|
if (value === undefined || value === null) return null
|
|
123
124
|
const parsed = parseGuideSteps(value)
|
|
124
125
|
if (!parsed) {
|
|
125
|
-
throw new CrudHttpError(400, { error: '
|
|
126
|
+
throw new CrudHttpError(400, { error: '[internal] troubleshooting steps reached the entity mapper unvalidated' })
|
|
126
127
|
}
|
|
127
128
|
return { prompt: parsed.prompt, options: parsed.options }
|
|
128
129
|
}
|
|
129
130
|
|
|
131
|
+
async function assertParsableGuideSteps(input: object): Promise<void> {
|
|
132
|
+
if (!hasOwn(input, 'steps')) return
|
|
133
|
+
const value = (input as { steps?: unknown }).steps
|
|
134
|
+
if (value === undefined || value === null || parseGuideSteps(value)) return
|
|
135
|
+
const { translate } = await resolveTranslations()
|
|
136
|
+
throw new CrudHttpError(400, {
|
|
137
|
+
error: translate(
|
|
138
|
+
'warranty_claims.errors.invalidTroubleshootingSteps',
|
|
139
|
+
'Troubleshooting steps must include a prompt and valid option branches.',
|
|
140
|
+
),
|
|
141
|
+
})
|
|
142
|
+
}
|
|
143
|
+
|
|
130
144
|
function toTroubleshootingGuideEntityData(input: TroubleshootingGuideCreateInput): Record<string, unknown> {
|
|
131
145
|
return {
|
|
132
146
|
claimType: input.claimType ?? null,
|
|
@@ -238,6 +252,14 @@ const crud = makeCrudRoute<RawTroubleshootingGuideInput, RawTroubleshootingGuide
|
|
|
238
252
|
schema: rawBodySchema,
|
|
239
253
|
mapToEntity: (input, ctx) => toTroubleshootingGuideEntityData(parseCreateInput(input, ctx)),
|
|
240
254
|
},
|
|
255
|
+
hooks: {
|
|
256
|
+
beforeCreate: async (input) => {
|
|
257
|
+
await assertParsableGuideSteps(input)
|
|
258
|
+
},
|
|
259
|
+
beforeUpdate: async (input) => {
|
|
260
|
+
await assertParsableGuideSteps(input)
|
|
261
|
+
},
|
|
262
|
+
},
|
|
241
263
|
update: {
|
|
242
264
|
schema: rawBodySchema,
|
|
243
265
|
getId: (input) => {
|
|
@@ -43,6 +43,7 @@ type SuggestionsRouteContext = {
|
|
|
43
43
|
tenantId: string
|
|
44
44
|
organizationId: string
|
|
45
45
|
scope: WarrantyClaimScope
|
|
46
|
+
translate: (key: string, fallback?: string) => string
|
|
46
47
|
em: EntityManager
|
|
47
48
|
}
|
|
48
49
|
|
|
@@ -79,6 +80,7 @@ async function resolveSuggestionsContext(req: Request): Promise<SuggestionsRoute
|
|
|
79
80
|
tenantId: auth.tenantId,
|
|
80
81
|
organizationId,
|
|
81
82
|
scope: { tenantId: auth.tenantId, organizationId },
|
|
83
|
+
translate,
|
|
82
84
|
em,
|
|
83
85
|
}
|
|
84
86
|
}
|
|
@@ -88,7 +90,7 @@ export async function GET(req: Request) {
|
|
|
88
90
|
const context = await resolveSuggestionsContext(req)
|
|
89
91
|
const url = new URL(req.url)
|
|
90
92
|
const query = querySchema.parse(Object.fromEntries(url.searchParams))
|
|
91
|
-
const claim = await requireScopedClaim(context.em, query.claimId, context.scope)
|
|
93
|
+
const claim = await requireScopedClaim(context.em, query.claimId, context.scope, {}, context.translate('warranty_claims.errors.notFound', 'Claim not found.'))
|
|
92
94
|
if (claim.claimType !== 'warranty' || (claim.status !== 'resolved' && claim.status !== 'closed')) {
|
|
93
95
|
return NextResponse.json({ ok: true, result: { claimId: claim.id, suggestions: [] } })
|
|
94
96
|
}
|
|
@@ -80,14 +80,20 @@ export async function loadScopedClaim(
|
|
|
80
80
|
)
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
/**
|
|
84
|
+
* `notFoundMessage` is passed to `assertFound` verbatim, so request-scoped callers
|
|
85
|
+
* must hand in an already-translated sentence; the key default only suits the
|
|
86
|
+
* command surface, which runs without a request locale.
|
|
87
|
+
*/
|
|
83
88
|
export async function requireScopedClaim(
|
|
84
89
|
em: EntityManager,
|
|
85
90
|
id: string,
|
|
86
91
|
scope: WarrantyClaimScope,
|
|
87
92
|
options: FindOneOptions<WarrantyClaim> = {},
|
|
93
|
+
notFoundMessage = 'warranty_claims.errors.notFound',
|
|
88
94
|
): Promise<WarrantyClaim> {
|
|
89
95
|
const claim = await loadScopedClaim(em, id, scope, options)
|
|
90
|
-
return assertFound(claim,
|
|
96
|
+
return assertFound(claim, notFoundMessage)
|
|
91
97
|
}
|
|
92
98
|
|
|
93
99
|
export function appendClaimEvent(
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { NextResponse } from 'next/server'
|
|
2
|
+
import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
|
|
3
|
+
import { getCustomerAuthFromRequest, type CustomerAuthContext } from '@open-mercato/core/modules/customer_accounts/lib/customerAuth'
|
|
4
|
+
|
|
5
|
+
export type LinkedCustomerAuthContext = CustomerAuthContext & { customerEntityId: string }
|
|
6
|
+
|
|
7
|
+
export async function resolveLinkedCustomerAuth(req: Request): Promise<LinkedCustomerAuthContext | Response> {
|
|
8
|
+
const auth = await getCustomerAuthFromRequest(req)
|
|
9
|
+
if (!auth) {
|
|
10
|
+
const { translate } = await resolveTranslations()
|
|
11
|
+
return NextResponse.json(
|
|
12
|
+
{ ok: false, error: translate('warranty_claims.errors.unauthorized', 'Unauthorized') },
|
|
13
|
+
{ status: 401 },
|
|
14
|
+
)
|
|
15
|
+
}
|
|
16
|
+
if (!auth.customerEntityId) {
|
|
17
|
+
const { translate } = await resolveTranslations()
|
|
18
|
+
return NextResponse.json(
|
|
19
|
+
{
|
|
20
|
+
ok: false,
|
|
21
|
+
error: translate(
|
|
22
|
+
'warranty_claims.errors.customerAccountNotLinked',
|
|
23
|
+
'Customer account is not linked to a customer record',
|
|
24
|
+
),
|
|
25
|
+
},
|
|
26
|
+
{ status: 403 },
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
return auth as LinkedCustomerAuthContext
|
|
30
|
+
}
|