@open-mercato/core 0.6.7-develop.6788.1.c2a1520a30 → 0.6.7-develop.6795.1.8a3f27921c
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.ids.generated.js +1 -0
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/modules/customers/cli.js +17 -7
- package/dist/modules/customers/cli.js.map +2 -2
- package/dist/modules/customers/search.js +50 -29
- package/dist/modules/customers/search.js.map +2 -2
- package/dist/modules/data_sync/api/mappings/[id]/route.js +22 -9
- package/dist/modules/data_sync/api/mappings/[id]/route.js.map +2 -2
- package/dist/modules/data_sync/api/mappings/route.js +13 -4
- package/dist/modules/data_sync/api/mappings/route.js.map +2 -2
- package/dist/modules/data_sync/api/options.js +7 -2
- package/dist/modules/data_sync/api/options.js.map +2 -2
- package/dist/modules/data_sync/api/run.js +7 -2
- package/dist/modules/data_sync/api/run.js.map +2 -2
- package/dist/modules/data_sync/api/runs/[id]/cancel.js +8 -3
- package/dist/modules/data_sync/api/runs/[id]/cancel.js.map +2 -2
- package/dist/modules/data_sync/api/runs/[id]/retry.js +7 -2
- package/dist/modules/data_sync/api/runs/[id]/retry.js.map +2 -2
- package/dist/modules/data_sync/api/runs/[id]/route.js +8 -3
- package/dist/modules/data_sync/api/runs/[id]/route.js.map +2 -2
- package/dist/modules/data_sync/api/runs.js +7 -2
- package/dist/modules/data_sync/api/runs.js.map +2 -2
- package/dist/modules/data_sync/api/schedules/[id]/route.js +19 -6
- package/dist/modules/data_sync/api/schedules/[id]/route.js.map +2 -2
- package/dist/modules/data_sync/api/schedules/route.js +13 -4
- package/dist/modules/data_sync/api/schedules/route.js.map +2 -2
- package/dist/modules/data_sync/api/validate.js +9 -4
- package/dist/modules/data_sync/api/validate.js.map +2 -2
- package/dist/modules/design_system/acl.js +9 -0
- package/dist/modules/design_system/acl.js.map +7 -0
- package/dist/modules/design_system/backend/design-system/page.js +11 -0
- package/dist/modules/design_system/backend/design-system/page.js.map +7 -0
- package/dist/modules/design_system/backend/design-system/page.meta.js +15 -0
- package/dist/modules/design_system/backend/design-system/page.meta.js.map +7 -0
- package/dist/modules/design_system/gallery/components/CodeSnippet.js +52 -0
- package/dist/modules/design_system/gallery/components/CodeSnippet.js.map +7 -0
- package/dist/modules/design_system/gallery/components/EntryCard.js +63 -0
- package/dist/modules/design_system/gallery/components/EntryCard.js.map +7 -0
- package/dist/modules/design_system/gallery/components/GalleryShell.js +163 -0
- package/dist/modules/design_system/gallery/components/GalleryShell.js.map +7 -0
- package/dist/modules/design_system/gallery/components/VariantPreview.js +9 -0
- package/dist/modules/design_system/gallery/components/VariantPreview.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/banners.js +186 -0
- package/dist/modules/design_system/gallery/entries/banners.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/buttons.js +361 -0
- package/dist/modules/design_system/gallery/entries/buttons.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/charts.js +457 -0
- package/dist/modules/design_system/gallery/entries/charts.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/dates.js +306 -0
- package/dist/modules/design_system/gallery/entries/dates.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/detail.js +358 -0
- package/dist/modules/design_system/gallery/entries/detail.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/display.js +785 -0
- package/dist/modules/design_system/gallery/entries/display.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/feedback.js +658 -0
- package/dist/modules/design_system/gallery/entries/feedback.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/filters.js +505 -0
- package/dist/modules/design_system/gallery/entries/filters.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/foundations.js +453 -0
- package/dist/modules/design_system/gallery/entries/foundations.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/icons.js +140 -0
- package/dist/modules/design_system/gallery/entries/icons.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/inputs.js +1217 -0
- package/dist/modules/design_system/gallery/entries/inputs.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/messages.js +334 -0
- package/dist/modules/design_system/gallery/entries/messages.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/navigation.js +475 -0
- package/dist/modules/design_system/gallery/entries/navigation.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/notifications.js +257 -0
- package/dist/modules/design_system/gallery/entries/notifications.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/overlays.js +576 -0
- package/dist/modules/design_system/gallery/entries/overlays.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/scaffolding.js +378 -0
- package/dist/modules/design_system/gallery/entries/scaffolding.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/schedule.js +297 -0
- package/dist/modules/design_system/gallery/entries/schedule.js.map +7 -0
- package/dist/modules/design_system/gallery/registry.js +139 -0
- package/dist/modules/design_system/gallery/registry.js.map +7 -0
- package/dist/modules/design_system/gallery/types.js +1 -0
- package/dist/modules/design_system/gallery/types.js.map +7 -0
- package/dist/modules/design_system/index.js +9 -0
- package/dist/modules/design_system/index.js.map +7 -0
- package/dist/modules/design_system/setup.js +14 -0
- package/dist/modules/design_system/setup.js.map +7 -0
- package/dist/modules/inbox_ops/search.js +15 -4
- package/dist/modules/inbox_ops/search.js.map +2 -2
- package/dist/modules/integrations/api/[id]/credentials/route.js +11 -5
- package/dist/modules/integrations/api/[id]/credentials/route.js.map +2 -2
- package/dist/modules/integrations/api/[id]/health/route.js +6 -3
- package/dist/modules/integrations/api/[id]/health/route.js.map +2 -2
- package/dist/modules/integrations/api/[id]/route.js +6 -3
- package/dist/modules/integrations/api/[id]/route.js.map +2 -2
- package/dist/modules/integrations/api/[id]/state/route.js +6 -3
- package/dist/modules/integrations/api/[id]/state/route.js.map +2 -2
- package/dist/modules/integrations/api/[id]/version/route.js +6 -3
- package/dist/modules/integrations/api/[id]/version/route.js.map +2 -2
- package/dist/modules/integrations/api/logs/route.js +6 -3
- package/dist/modules/integrations/api/logs/route.js.map +2 -2
- package/dist/modules/integrations/api/route.js +6 -3
- package/dist/modules/integrations/api/route.js.map +2 -2
- package/dist/modules/integrations/api/umes-read.js +2 -2
- package/dist/modules/integrations/api/umes-read.js.map +2 -2
- package/dist/modules/integrations/lib/organization-scope.js +2 -9
- package/dist/modules/integrations/lib/organization-scope.js.map +2 -2
- package/dist/modules/messages/search.js +10 -5
- package/dist/modules/messages/search.js.map +2 -2
- package/dist/modules/query_index/data/entities.js +2 -1
- package/dist/modules/query_index/data/entities.js.map +2 -2
- package/dist/modules/query_index/lib/engine.js +32 -50
- package/dist/modules/query_index/lib/engine.js.map +2 -2
- package/dist/modules/query_index/migrations/Migration20260731105052_query_index.js +17 -0
- package/dist/modules/query_index/migrations/Migration20260731105052_query_index.js.map +7 -0
- package/generated/entities.ids.generated.ts +1 -0
- package/package.json +16 -16
- package/src/modules/customers/cli.ts +17 -7
- package/src/modules/customers/i18n/de.json +17 -0
- package/src/modules/customers/i18n/en.json +17 -0
- package/src/modules/customers/i18n/es.json +17 -0
- package/src/modules/customers/i18n/pl.json +17 -0
- package/src/modules/customers/search.ts +59 -27
- package/src/modules/data_sync/AGENTS.md +1 -0
- package/src/modules/data_sync/api/mappings/[id]/route.ts +22 -9
- package/src/modules/data_sync/api/mappings/route.ts +13 -4
- package/src/modules/data_sync/api/options.ts +7 -2
- package/src/modules/data_sync/api/run.ts +7 -2
- package/src/modules/data_sync/api/runs/[id]/cancel.ts +8 -3
- package/src/modules/data_sync/api/runs/[id]/retry.ts +7 -2
- package/src/modules/data_sync/api/runs/[id]/route.ts +8 -3
- package/src/modules/data_sync/api/runs.ts +7 -2
- package/src/modules/data_sync/api/schedules/[id]/route.ts +19 -6
- package/src/modules/data_sync/api/schedules/route.ts +13 -4
- package/src/modules/data_sync/api/validate.ts +9 -4
- package/src/modules/design_system/AGENTS.md +34 -0
- package/src/modules/design_system/acl.ts +5 -0
- package/src/modules/design_system/backend/design-system/page.meta.ts +11 -0
- package/src/modules/design_system/backend/design-system/page.tsx +14 -0
- package/src/modules/design_system/gallery/components/CodeSnippet.tsx +55 -0
- package/src/modules/design_system/gallery/components/EntryCard.tsx +95 -0
- package/src/modules/design_system/gallery/components/GalleryShell.tsx +206 -0
- package/src/modules/design_system/gallery/components/VariantPreview.tsx +15 -0
- package/src/modules/design_system/gallery/entries/banners.tsx +226 -0
- package/src/modules/design_system/gallery/entries/buttons.tsx +422 -0
- package/src/modules/design_system/gallery/entries/charts.tsx +518 -0
- package/src/modules/design_system/gallery/entries/dates.tsx +325 -0
- package/src/modules/design_system/gallery/entries/detail.tsx +403 -0
- package/src/modules/design_system/gallery/entries/display.tsx +893 -0
- package/src/modules/design_system/gallery/entries/feedback.tsx +746 -0
- package/src/modules/design_system/gallery/entries/filters.tsx +570 -0
- package/src/modules/design_system/gallery/entries/foundations.tsx +529 -0
- package/src/modules/design_system/gallery/entries/icons.tsx +168 -0
- package/src/modules/design_system/gallery/entries/inputs.tsx +1516 -0
- package/src/modules/design_system/gallery/entries/messages.tsx +339 -0
- package/src/modules/design_system/gallery/entries/navigation.tsx +573 -0
- package/src/modules/design_system/gallery/entries/notifications.tsx +285 -0
- package/src/modules/design_system/gallery/entries/overlays.tsx +677 -0
- package/src/modules/design_system/gallery/entries/scaffolding.tsx +430 -0
- package/src/modules/design_system/gallery/entries/schedule.tsx +307 -0
- package/src/modules/design_system/gallery/registry.ts +152 -0
- package/src/modules/design_system/gallery/types.ts +32 -0
- package/src/modules/design_system/i18n/.hardcoded-allowlist.json +71 -0
- package/src/modules/design_system/i18n/de.json +46 -0
- package/src/modules/design_system/i18n/en.json +46 -0
- package/src/modules/design_system/i18n/es.json +46 -0
- package/src/modules/design_system/i18n/pl.json +46 -0
- package/src/modules/design_system/index.ts +7 -0
- package/src/modules/design_system/setup.ts +12 -0
- package/src/modules/inbox_ops/i18n/de.json +3 -0
- package/src/modules/inbox_ops/i18n/en.json +3 -0
- package/src/modules/inbox_ops/i18n/es.json +3 -0
- package/src/modules/inbox_ops/i18n/pl.json +3 -0
- package/src/modules/inbox_ops/search.ts +20 -4
- package/src/modules/integrations/api/[id]/credentials/route.ts +11 -5
- package/src/modules/integrations/api/[id]/health/route.ts +6 -3
- package/src/modules/integrations/api/[id]/route.ts +6 -3
- package/src/modules/integrations/api/[id]/state/route.ts +6 -3
- package/src/modules/integrations/api/[id]/version/route.ts +6 -3
- package/src/modules/integrations/api/logs/route.ts +6 -3
- package/src/modules/integrations/api/route.ts +6 -3
- package/src/modules/integrations/api/umes-read.ts +2 -2
- package/src/modules/integrations/lib/organization-scope.ts +5 -25
- package/src/modules/messages/i18n/de.json +2 -0
- package/src/modules/messages/i18n/en.json +2 -0
- package/src/modules/messages/i18n/es.json +2 -0
- package/src/modules/messages/i18n/pl.json +2 -0
- package/src/modules/messages/search.ts +11 -5
- package/src/modules/query_index/data/entities.ts +7 -0
- package/src/modules/query_index/lib/engine.ts +40 -63
- package/src/modules/query_index/migrations/.snapshot-open-mercato.json +12 -0
- package/src/modules/query_index/migrations/Migration20260731105052_query_index.ts +35 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { z } from 'zod'
|
|
3
3
|
import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
|
|
4
|
+
import { organizationScopeRequiredResponse, resolveActiveOrganizationId } from '@open-mercato/shared/lib/auth/organizationScope'
|
|
4
5
|
import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
|
|
5
6
|
import type { EntityManager } from '@mikro-orm/postgresql'
|
|
6
7
|
import { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'
|
|
@@ -36,9 +37,13 @@ async function resolveParams(ctx: { params?: Promise<{ id?: string }> | { id?: s
|
|
|
36
37
|
|
|
37
38
|
export async function GET(req: Request, ctx: { params?: Promise<{ id?: string }> | { id?: string } }) {
|
|
38
39
|
const auth = await getAuthFromRequest(req)
|
|
39
|
-
if (!auth?.tenantId
|
|
40
|
+
if (!auth?.tenantId) {
|
|
40
41
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
41
42
|
}
|
|
43
|
+
const organizationId = resolveActiveOrganizationId(auth)
|
|
44
|
+
if (!organizationId) {
|
|
45
|
+
return organizationScopeRequiredResponse()
|
|
46
|
+
}
|
|
42
47
|
|
|
43
48
|
const parsedParams = await resolveParams(ctx)
|
|
44
49
|
if (!parsedParams.success) {
|
|
@@ -47,14 +52,14 @@ export async function GET(req: Request, ctx: { params?: Promise<{ id?: string }>
|
|
|
47
52
|
|
|
48
53
|
const container = await createRequestContainer()
|
|
49
54
|
const em = container.resolve('em') as EntityManager
|
|
50
|
-
const scope = { organizationId
|
|
55
|
+
const scope = { organizationId, tenantId: auth.tenantId }
|
|
51
56
|
|
|
52
57
|
const mapping = await findOneWithDecryption(
|
|
53
58
|
em,
|
|
54
59
|
SyncMapping,
|
|
55
60
|
{
|
|
56
61
|
id: parsedParams.data.id,
|
|
57
|
-
organizationId
|
|
62
|
+
organizationId,
|
|
58
63
|
tenantId: auth.tenantId,
|
|
59
64
|
},
|
|
60
65
|
undefined,
|
|
@@ -77,9 +82,13 @@ export async function GET(req: Request, ctx: { params?: Promise<{ id?: string }>
|
|
|
77
82
|
|
|
78
83
|
export async function PUT(req: Request, ctx: { params?: Promise<{ id?: string }> | { id?: string } }) {
|
|
79
84
|
const auth = await getAuthFromRequest(req)
|
|
80
|
-
if (!auth?.tenantId
|
|
85
|
+
if (!auth?.tenantId) {
|
|
81
86
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
82
87
|
}
|
|
88
|
+
const organizationId = resolveActiveOrganizationId(auth)
|
|
89
|
+
if (!organizationId) {
|
|
90
|
+
return organizationScopeRequiredResponse()
|
|
91
|
+
}
|
|
83
92
|
|
|
84
93
|
const parsedParams = await resolveParams(ctx)
|
|
85
94
|
if (!parsedParams.success) {
|
|
@@ -94,14 +103,14 @@ export async function PUT(req: Request, ctx: { params?: Promise<{ id?: string }>
|
|
|
94
103
|
|
|
95
104
|
const container = await createRequestContainer()
|
|
96
105
|
const em = container.resolve('em') as EntityManager
|
|
97
|
-
const scope = { organizationId
|
|
106
|
+
const scope = { organizationId, tenantId: auth.tenantId }
|
|
98
107
|
|
|
99
108
|
const mapping = await findOneWithDecryption(
|
|
100
109
|
em,
|
|
101
110
|
SyncMapping,
|
|
102
111
|
{
|
|
103
112
|
id: parsedParams.data.id,
|
|
104
|
-
organizationId
|
|
113
|
+
organizationId,
|
|
105
114
|
tenantId: auth.tenantId,
|
|
106
115
|
},
|
|
107
116
|
undefined,
|
|
@@ -155,9 +164,13 @@ export async function PUT(req: Request, ctx: { params?: Promise<{ id?: string }>
|
|
|
155
164
|
|
|
156
165
|
export async function DELETE(req: Request, ctx: { params?: Promise<{ id?: string }> | { id?: string } }) {
|
|
157
166
|
const auth = await getAuthFromRequest(req)
|
|
158
|
-
if (!auth?.tenantId
|
|
167
|
+
if (!auth?.tenantId) {
|
|
159
168
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
160
169
|
}
|
|
170
|
+
const organizationId = resolveActiveOrganizationId(auth)
|
|
171
|
+
if (!organizationId) {
|
|
172
|
+
return organizationScopeRequiredResponse()
|
|
173
|
+
}
|
|
161
174
|
|
|
162
175
|
const parsedParams = await resolveParams(ctx)
|
|
163
176
|
if (!parsedParams.success) {
|
|
@@ -166,14 +179,14 @@ export async function DELETE(req: Request, ctx: { params?: Promise<{ id?: string
|
|
|
166
179
|
|
|
167
180
|
const container = await createRequestContainer()
|
|
168
181
|
const em = container.resolve('em') as EntityManager
|
|
169
|
-
const scope = { organizationId
|
|
182
|
+
const scope = { organizationId, tenantId: auth.tenantId }
|
|
170
183
|
|
|
171
184
|
const mapping = await findOneWithDecryption(
|
|
172
185
|
em,
|
|
173
186
|
SyncMapping,
|
|
174
187
|
{
|
|
175
188
|
id: parsedParams.data.id,
|
|
176
|
-
organizationId
|
|
189
|
+
organizationId,
|
|
177
190
|
tenantId: auth.tenantId,
|
|
178
191
|
},
|
|
179
192
|
undefined,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { z } from 'zod'
|
|
3
3
|
import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
|
|
4
|
+
import { organizationScopeRequiredResponse, resolveActiveOrganizationId } from '@open-mercato/shared/lib/auth/organizationScope'
|
|
4
5
|
import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
|
|
5
6
|
import type { EntityManager, FilterQuery } from '@mikro-orm/postgresql'
|
|
6
7
|
import { findAndCountWithDecryption, findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'
|
|
@@ -35,9 +36,13 @@ export const openApi = {
|
|
|
35
36
|
|
|
36
37
|
export async function GET(req: Request) {
|
|
37
38
|
const auth = await getAuthFromRequest(req)
|
|
38
|
-
if (!auth?.tenantId
|
|
39
|
+
if (!auth?.tenantId) {
|
|
39
40
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
40
41
|
}
|
|
42
|
+
const organizationId = resolveActiveOrganizationId(auth)
|
|
43
|
+
if (!organizationId) {
|
|
44
|
+
return organizationScopeRequiredResponse()
|
|
45
|
+
}
|
|
41
46
|
|
|
42
47
|
const url = new URL(req.url)
|
|
43
48
|
const parsed = listMappingsQuerySchema.safeParse({
|
|
@@ -53,7 +58,7 @@ export async function GET(req: Request) {
|
|
|
53
58
|
|
|
54
59
|
const container = await createRequestContainer()
|
|
55
60
|
const em = container.resolve('em') as EntityManager
|
|
56
|
-
const scope = { organizationId
|
|
61
|
+
const scope = { organizationId, tenantId: auth.tenantId }
|
|
57
62
|
|
|
58
63
|
const where: FilterQuery<SyncMapping> = {
|
|
59
64
|
organizationId: scope.organizationId,
|
|
@@ -92,9 +97,13 @@ export async function GET(req: Request) {
|
|
|
92
97
|
|
|
93
98
|
export async function POST(req: Request) {
|
|
94
99
|
const auth = await getAuthFromRequest(req)
|
|
95
|
-
if (!auth?.tenantId
|
|
100
|
+
if (!auth?.tenantId) {
|
|
96
101
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
97
102
|
}
|
|
103
|
+
const organizationId = resolveActiveOrganizationId(auth)
|
|
104
|
+
if (!organizationId) {
|
|
105
|
+
return organizationScopeRequiredResponse()
|
|
106
|
+
}
|
|
98
107
|
|
|
99
108
|
const payload = await req.json().catch(() => null)
|
|
100
109
|
const parsed = createMappingSchema.safeParse(payload)
|
|
@@ -104,7 +113,7 @@ export async function POST(req: Request) {
|
|
|
104
113
|
|
|
105
114
|
const container = await createRequestContainer()
|
|
106
115
|
const em = container.resolve('em') as EntityManager
|
|
107
|
-
const scope = { organizationId
|
|
116
|
+
const scope = { organizationId, tenantId: auth.tenantId }
|
|
108
117
|
|
|
109
118
|
const existing = await findOneWithDecryption(
|
|
110
119
|
em,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
|
|
3
|
+
import { organizationScopeRequiredResponse, resolveActiveOrganizationId } from '@open-mercato/shared/lib/auth/organizationScope'
|
|
3
4
|
import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
|
|
4
5
|
import { getAllIntegrations } from '@open-mercato/shared/modules/integrations/types'
|
|
5
6
|
import type { CredentialsService } from '../../integrations/lib/credentials-service'
|
|
@@ -17,14 +18,18 @@ export const openApi = {
|
|
|
17
18
|
|
|
18
19
|
export async function GET(req: Request) {
|
|
19
20
|
const auth = await getAuthFromRequest(req)
|
|
20
|
-
if (!auth?.tenantId
|
|
21
|
+
if (!auth?.tenantId) {
|
|
21
22
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
22
23
|
}
|
|
24
|
+
const organizationId = resolveActiveOrganizationId(auth)
|
|
25
|
+
if (!organizationId) {
|
|
26
|
+
return organizationScopeRequiredResponse()
|
|
27
|
+
}
|
|
23
28
|
|
|
24
29
|
const container = await createRequestContainer()
|
|
25
30
|
const credentialsService = container.resolve('integrationCredentialsService') as CredentialsService
|
|
26
31
|
const stateService = container.resolve('integrationStateService') as IntegrationStateService
|
|
27
|
-
const scope = { organizationId
|
|
32
|
+
const scope = { organizationId, tenantId: auth.tenantId }
|
|
28
33
|
|
|
29
34
|
const items = await Promise.all(
|
|
30
35
|
getAllIntegrations()
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
|
|
3
|
+
import { organizationScopeRequiredResponse, resolveActiveOrganizationId } from '@open-mercato/shared/lib/auth/organizationScope'
|
|
3
4
|
import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
|
|
4
5
|
import { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'
|
|
5
6
|
import { getIntegration } from '@open-mercato/shared/modules/integrations/types'
|
|
@@ -29,9 +30,13 @@ export const openApi = {
|
|
|
29
30
|
export async function POST(req: Request) {
|
|
30
31
|
try {
|
|
31
32
|
const auth = await getAuthFromRequest(req)
|
|
32
|
-
if (!auth?.tenantId
|
|
33
|
+
if (!auth?.tenantId) {
|
|
33
34
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
34
35
|
}
|
|
36
|
+
const organizationId = resolveActiveOrganizationId(auth)
|
|
37
|
+
if (!organizationId) {
|
|
38
|
+
return organizationScopeRequiredResponse()
|
|
39
|
+
}
|
|
35
40
|
|
|
36
41
|
const payload = await readJsonSafe(req)
|
|
37
42
|
const parsed = runSyncSchema.safeParse(payload)
|
|
@@ -45,7 +50,7 @@ export async function POST(req: Request) {
|
|
|
45
50
|
const integrationStateService = container.resolve('integrationStateService') as IntegrationStateService
|
|
46
51
|
|
|
47
52
|
const scope = {
|
|
48
|
-
organizationId
|
|
53
|
+
organizationId,
|
|
49
54
|
tenantId: auth.tenantId,
|
|
50
55
|
}
|
|
51
56
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { z } from 'zod'
|
|
3
3
|
import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
|
|
4
|
+
import { organizationScopeRequiredResponse, resolveActiveOrganizationId } from '@open-mercato/shared/lib/auth/organizationScope'
|
|
4
5
|
import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
|
|
5
6
|
import type { IntegrationLogService } from '../../../../integrations/lib/log-service'
|
|
6
7
|
import type { IntegrationStateService } from '../../../../integrations/lib/state-service'
|
|
@@ -24,9 +25,13 @@ export const openApi = {
|
|
|
24
25
|
|
|
25
26
|
export async function POST(req: Request, ctx: { params?: Promise<{ id?: string }> | { id?: string } }) {
|
|
26
27
|
const auth = await getAuthFromRequest(req)
|
|
27
|
-
if (!auth?.tenantId
|
|
28
|
+
if (!auth?.tenantId) {
|
|
28
29
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
29
30
|
}
|
|
31
|
+
const organizationId = resolveActiveOrganizationId(auth)
|
|
32
|
+
if (!organizationId) {
|
|
33
|
+
return organizationScopeRequiredResponse()
|
|
34
|
+
}
|
|
30
35
|
|
|
31
36
|
const rawParams = (ctx.params && typeof (ctx.params as Promise<unknown>).then === 'function')
|
|
32
37
|
? await (ctx.params as Promise<{ id?: string }>)
|
|
@@ -42,7 +47,7 @@ export async function POST(req: Request, ctx: { params?: Promise<{ id?: string }
|
|
|
42
47
|
const progressService = container.resolve('progressService') as ProgressService
|
|
43
48
|
const integrationLogService = container.resolve('integrationLogService') as IntegrationLogService
|
|
44
49
|
const integrationStateService = container.resolve('integrationStateService') as IntegrationStateService
|
|
45
|
-
const scope = { organizationId
|
|
50
|
+
const scope = { organizationId, tenantId: auth.tenantId }
|
|
46
51
|
|
|
47
52
|
const run = await syncRunService.getRun(parsed.data.id, scope)
|
|
48
53
|
if (!run) {
|
|
@@ -69,7 +74,7 @@ export async function POST(req: Request, ctx: { params?: Promise<{ id?: string }
|
|
|
69
74
|
|
|
70
75
|
const progressCtx = {
|
|
71
76
|
tenantId: auth.tenantId,
|
|
72
|
-
organizationId
|
|
77
|
+
organizationId,
|
|
73
78
|
userId: auth.sub,
|
|
74
79
|
}
|
|
75
80
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { z } from 'zod'
|
|
3
3
|
import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
|
|
4
|
+
import { organizationScopeRequiredResponse, resolveActiveOrganizationId } from '@open-mercato/shared/lib/auth/organizationScope'
|
|
4
5
|
import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
|
|
5
6
|
import { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'
|
|
6
7
|
import type { ProgressService } from '../../../../progress/lib/progressService'
|
|
@@ -25,9 +26,13 @@ export const openApi = {
|
|
|
25
26
|
|
|
26
27
|
export async function POST(req: Request, ctx: { params?: Promise<{ id?: string }> | { id?: string } }) {
|
|
27
28
|
const auth = await getAuthFromRequest(req)
|
|
28
|
-
if (!auth?.tenantId
|
|
29
|
+
if (!auth?.tenantId) {
|
|
29
30
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
30
31
|
}
|
|
32
|
+
const organizationId = resolveActiveOrganizationId(auth)
|
|
33
|
+
if (!organizationId) {
|
|
34
|
+
return organizationScopeRequiredResponse()
|
|
35
|
+
}
|
|
31
36
|
|
|
32
37
|
const rawParams = (ctx.params && typeof (ctx.params as Promise<unknown>).then === 'function')
|
|
33
38
|
? await (ctx.params as Promise<{ id?: string }>)
|
|
@@ -47,7 +52,7 @@ export async function POST(req: Request, ctx: { params?: Promise<{ id?: string }
|
|
|
47
52
|
const container = await createRequestContainer()
|
|
48
53
|
const syncRunService = container.resolve('dataSyncRunService') as SyncRunService
|
|
49
54
|
const progressService = container.resolve('progressService') as ProgressService
|
|
50
|
-
const scope = { organizationId
|
|
55
|
+
const scope = { organizationId, tenantId: auth.tenantId }
|
|
51
56
|
|
|
52
57
|
const previous = await syncRunService.getRun(parsedParams.data.id, scope)
|
|
53
58
|
if (!previous) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { z } from 'zod'
|
|
3
3
|
import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
|
|
4
|
+
import { organizationScopeRequiredResponse, resolveActiveOrganizationId } from '@open-mercato/shared/lib/auth/organizationScope'
|
|
4
5
|
import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
|
|
5
6
|
import type { ProgressService } from '../../../../progress/lib/progressService'
|
|
6
7
|
import type { SyncRunService } from '../../../lib/sync-run-service'
|
|
@@ -18,9 +19,13 @@ export const openApi = {
|
|
|
18
19
|
|
|
19
20
|
export async function GET(req: Request, ctx: { params?: Promise<{ id?: string }> | { id?: string } }) {
|
|
20
21
|
const auth = await getAuthFromRequest(req)
|
|
21
|
-
if (!auth?.tenantId
|
|
22
|
+
if (!auth?.tenantId) {
|
|
22
23
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
23
24
|
}
|
|
25
|
+
const organizationId = resolveActiveOrganizationId(auth)
|
|
26
|
+
if (!organizationId) {
|
|
27
|
+
return organizationScopeRequiredResponse()
|
|
28
|
+
}
|
|
24
29
|
|
|
25
30
|
const rawParams = (ctx.params && typeof (ctx.params as Promise<unknown>).then === 'function')
|
|
26
31
|
? await (ctx.params as Promise<{ id?: string }>)
|
|
@@ -34,7 +39,7 @@ export async function GET(req: Request, ctx: { params?: Promise<{ id?: string }>
|
|
|
34
39
|
const container = await createRequestContainer()
|
|
35
40
|
const syncRunService = container.resolve('dataSyncRunService') as SyncRunService
|
|
36
41
|
const progressService = container.resolve('progressService') as ProgressService
|
|
37
|
-
const scope = { organizationId
|
|
42
|
+
const scope = { organizationId, tenantId: auth.tenantId }
|
|
38
43
|
|
|
39
44
|
const run = await syncRunService.getRun(parsed.data.id, scope)
|
|
40
45
|
if (!run) {
|
|
@@ -44,7 +49,7 @@ export async function GET(req: Request, ctx: { params?: Promise<{ id?: string }>
|
|
|
44
49
|
const progressJob = run.progressJobId
|
|
45
50
|
? await progressService.getJob(run.progressJobId, {
|
|
46
51
|
tenantId: auth.tenantId,
|
|
47
|
-
organizationId
|
|
52
|
+
organizationId,
|
|
48
53
|
userId: auth.sub,
|
|
49
54
|
})
|
|
50
55
|
: null
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
|
|
3
|
+
import { organizationScopeRequiredResponse, resolveActiveOrganizationId } from '@open-mercato/shared/lib/auth/organizationScope'
|
|
3
4
|
import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
|
|
4
5
|
import { listSyncRunsQuerySchema } from '../data/validators'
|
|
5
6
|
import type { SyncRunService } from '../lib/sync-run-service'
|
|
@@ -15,9 +16,13 @@ export const openApi = {
|
|
|
15
16
|
|
|
16
17
|
export async function GET(req: Request) {
|
|
17
18
|
const auth = await getAuthFromRequest(req)
|
|
18
|
-
if (!auth?.tenantId
|
|
19
|
+
if (!auth?.tenantId) {
|
|
19
20
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
20
21
|
}
|
|
22
|
+
const organizationId = resolveActiveOrganizationId(auth)
|
|
23
|
+
if (!organizationId) {
|
|
24
|
+
return organizationScopeRequiredResponse()
|
|
25
|
+
}
|
|
21
26
|
|
|
22
27
|
const url = new URL(req.url)
|
|
23
28
|
const parsed = listSyncRunsQuerySchema.safeParse({
|
|
@@ -38,7 +43,7 @@ export async function GET(req: Request) {
|
|
|
38
43
|
const syncRunService = container.resolve('dataSyncRunService') as SyncRunService
|
|
39
44
|
|
|
40
45
|
const { items, total } = await syncRunService.listRuns(parsed.data, {
|
|
41
|
-
organizationId
|
|
46
|
+
organizationId,
|
|
42
47
|
tenantId: auth.tenantId,
|
|
43
48
|
})
|
|
44
49
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { z } from 'zod'
|
|
3
3
|
import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
|
|
4
|
+
import { organizationScopeRequiredResponse, resolveActiveOrganizationId } from '@open-mercato/shared/lib/auth/organizationScope'
|
|
4
5
|
import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
|
|
5
6
|
import { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'
|
|
6
7
|
import { readOptimisticLockExpected } from '@open-mercato/shared/lib/crud/optimistic-lock-command'
|
|
@@ -30,9 +31,13 @@ export const openApi = {
|
|
|
30
31
|
|
|
31
32
|
export async function GET(req: Request, ctx: { params?: Promise<{ id?: string }> | { id?: string } }) {
|
|
32
33
|
const auth = await getAuthFromRequest(req)
|
|
33
|
-
if (!auth?.tenantId
|
|
34
|
+
if (!auth?.tenantId) {
|
|
34
35
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
35
36
|
}
|
|
37
|
+
const organizationId = resolveActiveOrganizationId(auth)
|
|
38
|
+
if (!organizationId) {
|
|
39
|
+
return organizationScopeRequiredResponse()
|
|
40
|
+
}
|
|
36
41
|
|
|
37
42
|
const rawParams = (ctx.params && typeof (ctx.params as Promise<unknown>).then === 'function')
|
|
38
43
|
? await (ctx.params as Promise<{ id?: string }>)
|
|
@@ -46,7 +51,7 @@ export async function GET(req: Request, ctx: { params?: Promise<{ id?: string }>
|
|
|
46
51
|
const container = await createRequestContainer()
|
|
47
52
|
const scheduleService = container.resolve('dataSyncScheduleService') as SyncScheduleService
|
|
48
53
|
const schedule = await scheduleService.getById(parsedParams.data.id, {
|
|
49
|
-
organizationId
|
|
54
|
+
organizationId,
|
|
50
55
|
tenantId: auth.tenantId,
|
|
51
56
|
})
|
|
52
57
|
|
|
@@ -59,9 +64,13 @@ export async function GET(req: Request, ctx: { params?: Promise<{ id?: string }>
|
|
|
59
64
|
|
|
60
65
|
export async function PUT(req: Request, ctx: { params?: Promise<{ id?: string }> | { id?: string } }) {
|
|
61
66
|
const auth = await getAuthFromRequest(req)
|
|
62
|
-
if (!auth?.tenantId
|
|
67
|
+
if (!auth?.tenantId) {
|
|
63
68
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
64
69
|
}
|
|
70
|
+
const organizationId = resolveActiveOrganizationId(auth)
|
|
71
|
+
if (!organizationId) {
|
|
72
|
+
return organizationScopeRequiredResponse()
|
|
73
|
+
}
|
|
65
74
|
|
|
66
75
|
const rawParams = (ctx.params && typeof (ctx.params as Promise<unknown>).then === 'function')
|
|
67
76
|
? await (ctx.params as Promise<{ id?: string }>)
|
|
@@ -80,7 +89,7 @@ export async function PUT(req: Request, ctx: { params?: Promise<{ id?: string }>
|
|
|
80
89
|
|
|
81
90
|
const container = await createRequestContainer()
|
|
82
91
|
const scheduleService = container.resolve('dataSyncScheduleService') as SyncScheduleService
|
|
83
|
-
const scope = { organizationId
|
|
92
|
+
const scope = { organizationId, tenantId: auth.tenantId }
|
|
84
93
|
const current = await scheduleService.getById(parsedParams.data.id, scope)
|
|
85
94
|
|
|
86
95
|
if (!current) {
|
|
@@ -141,9 +150,13 @@ export async function PUT(req: Request, ctx: { params?: Promise<{ id?: string }>
|
|
|
141
150
|
|
|
142
151
|
export async function DELETE(req: Request, ctx: { params?: Promise<{ id?: string }> | { id?: string } }) {
|
|
143
152
|
const auth = await getAuthFromRequest(req)
|
|
144
|
-
if (!auth?.tenantId
|
|
153
|
+
if (!auth?.tenantId) {
|
|
145
154
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
146
155
|
}
|
|
156
|
+
const organizationId = resolveActiveOrganizationId(auth)
|
|
157
|
+
if (!organizationId) {
|
|
158
|
+
return organizationScopeRequiredResponse()
|
|
159
|
+
}
|
|
147
160
|
|
|
148
161
|
const rawParams = (ctx.params && typeof (ctx.params as Promise<unknown>).then === 'function')
|
|
149
162
|
? await (ctx.params as Promise<{ id?: string }>)
|
|
@@ -156,7 +169,7 @@ export async function DELETE(req: Request, ctx: { params?: Promise<{ id?: string
|
|
|
156
169
|
|
|
157
170
|
const container = await createRequestContainer()
|
|
158
171
|
const scheduleService = container.resolve('dataSyncScheduleService') as SyncScheduleService
|
|
159
|
-
const scope = { organizationId
|
|
172
|
+
const scope = { organizationId, tenantId: auth.tenantId }
|
|
160
173
|
|
|
161
174
|
const guardResult = await validateCrudMutationGuard(container, {
|
|
162
175
|
tenantId: auth.tenantId,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
|
|
3
|
+
import { organizationScopeRequiredResponse, resolveActiveOrganizationId } from '@open-mercato/shared/lib/auth/organizationScope'
|
|
3
4
|
import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
|
|
4
5
|
import { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'
|
|
5
6
|
import { createSyncScheduleSchema, listSyncSchedulesQuerySchema } from '../../data/validators'
|
|
@@ -24,9 +25,13 @@ export const openApi = {
|
|
|
24
25
|
|
|
25
26
|
export async function GET(req: Request) {
|
|
26
27
|
const auth = await getAuthFromRequest(req)
|
|
27
|
-
if (!auth?.tenantId
|
|
28
|
+
if (!auth?.tenantId) {
|
|
28
29
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
29
30
|
}
|
|
31
|
+
const organizationId = resolveActiveOrganizationId(auth)
|
|
32
|
+
if (!organizationId) {
|
|
33
|
+
return organizationScopeRequiredResponse()
|
|
34
|
+
}
|
|
30
35
|
|
|
31
36
|
const url = new URL(req.url)
|
|
32
37
|
const parsed = listSyncSchedulesQuerySchema.safeParse({
|
|
@@ -43,7 +48,7 @@ export async function GET(req: Request) {
|
|
|
43
48
|
|
|
44
49
|
const container = await createRequestContainer()
|
|
45
50
|
const scheduleService = container.resolve('dataSyncScheduleService') as SyncScheduleService
|
|
46
|
-
const scope = { organizationId
|
|
51
|
+
const scope = { organizationId, tenantId: auth.tenantId }
|
|
47
52
|
const { items, total } = await scheduleService.listSchedules(parsed.data, scope)
|
|
48
53
|
|
|
49
54
|
return NextResponse.json({
|
|
@@ -57,9 +62,13 @@ export async function GET(req: Request) {
|
|
|
57
62
|
|
|
58
63
|
export async function POST(req: Request) {
|
|
59
64
|
const auth = await getAuthFromRequest(req)
|
|
60
|
-
if (!auth?.tenantId
|
|
65
|
+
if (!auth?.tenantId) {
|
|
61
66
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
62
67
|
}
|
|
68
|
+
const organizationId = resolveActiveOrganizationId(auth)
|
|
69
|
+
if (!organizationId) {
|
|
70
|
+
return organizationScopeRequiredResponse()
|
|
71
|
+
}
|
|
63
72
|
|
|
64
73
|
const payload = await readJsonSafe(req)
|
|
65
74
|
const parsed = createSyncScheduleSchema.safeParse(payload)
|
|
@@ -69,7 +78,7 @@ export async function POST(req: Request) {
|
|
|
69
78
|
|
|
70
79
|
const container = await createRequestContainer()
|
|
71
80
|
const scheduleService = container.resolve('dataSyncScheduleService') as SyncScheduleService
|
|
72
|
-
const scope = { organizationId
|
|
81
|
+
const scope = { organizationId, tenantId: auth.tenantId }
|
|
73
82
|
|
|
74
83
|
const guardResult = await validateCrudMutationGuard(container, {
|
|
75
84
|
tenantId: auth.tenantId,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server'
|
|
2
2
|
import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
|
|
3
|
+
import { organizationScopeRequiredResponse, resolveActiveOrganizationId } from '@open-mercato/shared/lib/auth/organizationScope'
|
|
3
4
|
import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
|
|
4
5
|
import { getIntegration } from '@open-mercato/shared/modules/integrations/types'
|
|
5
6
|
import type { CredentialsService } from '../../integrations/lib/credentials-service'
|
|
@@ -17,9 +18,13 @@ export const openApi = {
|
|
|
17
18
|
|
|
18
19
|
export async function POST(req: Request) {
|
|
19
20
|
const auth = await getAuthFromRequest(req)
|
|
20
|
-
if (!auth?.tenantId
|
|
21
|
+
if (!auth?.tenantId) {
|
|
21
22
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
22
23
|
}
|
|
24
|
+
const organizationId = resolveActiveOrganizationId(auth)
|
|
25
|
+
if (!organizationId) {
|
|
26
|
+
return organizationScopeRequiredResponse()
|
|
27
|
+
}
|
|
23
28
|
|
|
24
29
|
const parsed = validateConnectionSchema.safeParse(await req.json())
|
|
25
30
|
if (!parsed.success) {
|
|
@@ -39,7 +44,7 @@ export async function POST(req: Request) {
|
|
|
39
44
|
const container = await createRequestContainer()
|
|
40
45
|
const credentialsService = container.resolve('integrationCredentialsService') as CredentialsService
|
|
41
46
|
const credentials = await credentialsService.resolve(integration.id, {
|
|
42
|
-
organizationId
|
|
47
|
+
organizationId,
|
|
43
48
|
tenantId: auth.tenantId,
|
|
44
49
|
})
|
|
45
50
|
|
|
@@ -50,7 +55,7 @@ export async function POST(req: Request) {
|
|
|
50
55
|
const mapping = await adapter.getMapping({
|
|
51
56
|
entityType: parsed.data.entityType,
|
|
52
57
|
scope: {
|
|
53
|
-
organizationId
|
|
58
|
+
organizationId,
|
|
54
59
|
tenantId: auth.tenantId,
|
|
55
60
|
},
|
|
56
61
|
})
|
|
@@ -64,7 +69,7 @@ export async function POST(req: Request) {
|
|
|
64
69
|
credentials,
|
|
65
70
|
mapping,
|
|
66
71
|
scope: {
|
|
67
|
-
organizationId
|
|
72
|
+
organizationId,
|
|
68
73
|
tenantId: auth.tenantId,
|
|
69
74
|
},
|
|
70
75
|
})
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Design System Module — Agent Guidelines
|
|
2
|
+
|
|
3
|
+
Live component gallery at `/backend/design-system`, gated by `design_system.view`. Entries are plain data (`gallery/entries/<family>.tsx`) listed in the family manifest (`gallery/registry.ts`) and lazy-loaded per family. The gallery is a DS consumer: it must showcase the DS without ever violating it.
|
|
4
|
+
|
|
5
|
+
## Registry Contract
|
|
6
|
+
|
|
7
|
+
- `gallery/types.ts` defines `GalleryVariant` / `GalleryEntry` / `GalleryFamily` — do not extend them casually; the shapes are the spec contract (`.ai/specs/2026-07-05-ds-live-component-gallery.md`).
|
|
8
|
+
- A family = one manifest row in `galleryFamilies` + one `entries/<id>.tsx` exporting `entries: GalleryEntry[]`.
|
|
9
|
+
- Every variant keeps `render` and `code` side by side in one object literal; review them together — colocation is the drift defense.
|
|
10
|
+
|
|
11
|
+
## Always
|
|
12
|
+
|
|
13
|
+
1. **MUST keep every variant `code` snippet containing the entry's `importPath`** — enforced by `gallery/__tests__/registry-integrity.test.ts`.
|
|
14
|
+
2. **MUST update the coverage allowlist honestly** — when adding a primitive entry, delete its row from `PENDING_FAMILIES` in `gallery/__tests__/gallery-coverage.test.ts`; when a new primitive lands without an entry, add it there with a one-line reason. `PENDING_FAMILIES` must only shrink as families land.
|
|
15
|
+
3. **MUST use semantic tokens only** in gallery chrome (`border-border`, `bg-background`, `bg-muted`, `text-muted-foreground`) and lucide icons only.
|
|
16
|
+
4. **MUST route all gallery chrome strings through `i18n/` in all four locales** (en, pl, es, de) via `useT()`. Component titles and variant names (`Button`, `destructive-soft`) are proper nouns and stay untranslated.
|
|
17
|
+
5. **MUST render entries with inline mock props only** — the gallery never calls tenant APIs and never renders tenant data.
|
|
18
|
+
6. **MUST keep `figmaNodeId` in `<page>:<node>` format** pointing into `DS_FIGMA_FILE`; omit it when unknown — never guess node ids.
|
|
19
|
+
|
|
20
|
+
## Never
|
|
21
|
+
|
|
22
|
+
- Never add gallery-specific props or code to `packages/ui` — the gallery consumes primitives exactly as any other module does.
|
|
23
|
+
- Never hardcode colors, arbitrary sizes, or full-pill chips in gallery chrome.
|
|
24
|
+
- Never add API routes, entities, DI registrations, or tenant-scoped anything to this module.
|
|
25
|
+
- Never remove a file from the primitives coverage enumeration by loosening the test — only entries or allowlist rows with reasons.
|
|
26
|
+
|
|
27
|
+
## Validation Commands
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
yarn generate
|
|
31
|
+
yarn workspace @open-mercato/core test --testPathPattern design_system
|
|
32
|
+
yarn workspace @open-mercato/core typecheck
|
|
33
|
+
yarn i18n:check-hardcoded
|
|
34
|
+
```
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const metadata = {
|
|
2
|
+
requireAuth: true,
|
|
3
|
+
requireFeatures: ['design_system.view'],
|
|
4
|
+
pageTitle: 'Design system',
|
|
5
|
+
pageTitleKey: 'design_system.nav.title',
|
|
6
|
+
pageGroup: 'Developer',
|
|
7
|
+
pageGroupKey: 'design_system.nav.group',
|
|
8
|
+
pageOrder: 900,
|
|
9
|
+
icon: 'shapes',
|
|
10
|
+
breadcrumb: [{ label: 'Design system', labelKey: 'design_system.nav.title' }],
|
|
11
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { Page, PageBody } from '@open-mercato/ui/backend/Page'
|
|
4
|
+
import { GalleryShell } from '../../gallery/components/GalleryShell'
|
|
5
|
+
|
|
6
|
+
export default function DesignSystemGalleryPage() {
|
|
7
|
+
return (
|
|
8
|
+
<Page>
|
|
9
|
+
<PageBody>
|
|
10
|
+
<GalleryShell />
|
|
11
|
+
</PageBody>
|
|
12
|
+
</Page>
|
|
13
|
+
)
|
|
14
|
+
}
|