@open-mercato/core 0.5.1-develop.2975.ccbadc8198 → 0.5.1-develop.2996.ce62fd491c
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 +2 -2
- package/dist/generated/entities/sidebar_variant/index.js +25 -0
- package/dist/generated/entities/sidebar_variant/index.js.map +7 -0
- package/dist/generated/entities.ids.generated.js +1 -0
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +13 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/helpers/integration/authUi.js +1 -1
- package/dist/helpers/integration/authUi.js.map +2 -2
- package/dist/modules/audit_logs/services/actionLogService.js +4 -5
- package/dist/modules/audit_logs/services/actionLogService.js.map +2 -2
- package/dist/modules/auth/api/sidebar/preferences/route.js +224 -35
- package/dist/modules/auth/api/sidebar/preferences/route.js.map +3 -3
- package/dist/modules/auth/api/sidebar/variants/[id]/route.js +161 -0
- package/dist/modules/auth/api/sidebar/variants/[id]/route.js.map +7 -0
- package/dist/modules/auth/api/sidebar/variants/route.js +142 -0
- package/dist/modules/auth/api/sidebar/variants/route.js.map +7 -0
- package/dist/modules/auth/backend/sidebar-customization/page.js +16 -0
- package/dist/modules/auth/backend/sidebar-customization/page.js.map +7 -0
- package/dist/modules/auth/backend/sidebar-customization/page.meta.js +28 -0
- package/dist/modules/auth/backend/sidebar-customization/page.meta.js.map +7 -0
- package/dist/modules/auth/data/entities.js +45 -4
- package/dist/modules/auth/data/entities.js.map +2 -2
- package/dist/modules/auth/data/validators.js +63 -1
- package/dist/modules/auth/data/validators.js.map +2 -2
- package/dist/modules/auth/migrations/Migration20260427081815.js +15 -0
- package/dist/modules/auth/migrations/Migration20260427081815.js.map +7 -0
- package/dist/modules/auth/migrations/Migration20260427124900.js +15 -0
- package/dist/modules/auth/migrations/Migration20260427124900.js.map +7 -0
- package/dist/modules/auth/migrations/Migration20260427143311.js +72 -0
- package/dist/modules/auth/migrations/Migration20260427143311.js.map +7 -0
- package/dist/modules/auth/services/sidebarPreferencesService.js +176 -16
- package/dist/modules/auth/services/sidebarPreferencesService.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies/[id]/page.js +3 -1
- package/dist/modules/customers/backend/customers/companies/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +4 -2
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +8 -3
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/components/detail/CompanyPeopleSection.js +3 -2
- package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
- package/dist/modules/customers/components/formConfig.js +3 -3
- package/dist/modules/customers/components/formConfig.js.map +2 -2
- package/dist/modules/customers/lib/displayName.js +12 -0
- package/dist/modules/customers/lib/displayName.js.map +2 -2
- package/dist/modules/entities/cli.js +5 -6
- package/dist/modules/entities/cli.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.js +124 -0
- package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.js.map +7 -0
- package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.meta.js +11 -0
- package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.meta.js.map +7 -0
- package/generated/entities/sidebar_variant/index.ts +11 -0
- package/generated/entities.ids.generated.ts +1 -0
- package/generated/entity-fields-registry.ts +13 -0
- package/package.json +6 -6
- package/src/helpers/integration/authUi.ts +1 -1
- package/src/modules/audit_logs/services/actionLogService.ts +5 -6
- package/src/modules/auth/api/sidebar/preferences/route.ts +266 -34
- package/src/modules/auth/api/sidebar/variants/[id]/route.ts +183 -0
- package/src/modules/auth/api/sidebar/variants/route.ts +157 -0
- package/src/modules/auth/backend/sidebar-customization/page.meta.ts +34 -0
- package/src/modules/auth/backend/sidebar-customization/page.tsx +17 -0
- package/src/modules/auth/data/entities.ts +48 -2
- package/src/modules/auth/data/validators.ts +70 -0
- package/src/modules/auth/migrations/.snapshot-open-mercato.json +790 -71
- package/src/modules/auth/migrations/Migration20260427081815.ts +16 -0
- package/src/modules/auth/migrations/Migration20260427124900.ts +19 -0
- package/src/modules/auth/migrations/Migration20260427143311.ts +83 -0
- package/src/modules/auth/services/sidebarPreferencesService.ts +243 -18
- package/src/modules/customers/backend/customers/companies/[id]/page.tsx +5 -4
- package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +6 -5
- package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +13 -9
- package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +3 -2
- package/src/modules/customers/components/formConfig.tsx +3 -3
- package/src/modules/customers/lib/displayName.ts +21 -0
- package/src/modules/entities/cli.ts +5 -6
- package/src/modules/portal/frontend/[orgSlug]/portal/reset-password/page.meta.ts +9 -0
- package/src/modules/portal/frontend/[orgSlug]/portal/reset-password/page.tsx +168 -0
- package/src/modules/portal/i18n/de.json +20 -0
- package/src/modules/portal/i18n/en.json +20 -0
- package/src/modules/portal/i18n/es.json +20 -0
- package/src/modules/portal/i18n/pl.json +20 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
|
|
4
|
+
import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
|
|
5
|
+
import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
|
|
6
|
+
import { SIDEBAR_PREFERENCES_VERSION } from "@open-mercato/shared/modules/navigation/sidebarPreferences";
|
|
7
|
+
import {
|
|
8
|
+
deleteSidebarVariant,
|
|
9
|
+
loadSidebarVariant,
|
|
10
|
+
updateSidebarVariant
|
|
11
|
+
} from "../../../../services/sidebarPreferencesService.js";
|
|
12
|
+
import {
|
|
13
|
+
sidebarVariantRecordSchema,
|
|
14
|
+
updateSidebarVariantInputSchema
|
|
15
|
+
} from "../../../../data/validators.js";
|
|
16
|
+
const metadata = {
|
|
17
|
+
GET: { requireAuth: true },
|
|
18
|
+
PUT: { requireAuth: true },
|
|
19
|
+
DELETE: { requireAuth: true }
|
|
20
|
+
};
|
|
21
|
+
const variantResponseSchema = z.object({
|
|
22
|
+
locale: z.string(),
|
|
23
|
+
variant: sidebarVariantRecordSchema
|
|
24
|
+
});
|
|
25
|
+
const deleteResponseSchema = z.object({ ok: z.literal(true) });
|
|
26
|
+
const errorSchema = z.object({ error: z.string() });
|
|
27
|
+
function serializeVariant(record) {
|
|
28
|
+
return {
|
|
29
|
+
id: record.id,
|
|
30
|
+
name: record.name,
|
|
31
|
+
isActive: record.isActive,
|
|
32
|
+
settings: {
|
|
33
|
+
version: record.settings.version ?? SIDEBAR_PREFERENCES_VERSION,
|
|
34
|
+
groupOrder: record.settings.groupOrder ?? [],
|
|
35
|
+
groupLabels: record.settings.groupLabels ?? {},
|
|
36
|
+
itemLabels: record.settings.itemLabels ?? {},
|
|
37
|
+
hiddenItems: record.settings.hiddenItems ?? [],
|
|
38
|
+
itemOrder: record.settings.itemOrder ?? {}
|
|
39
|
+
},
|
|
40
|
+
createdAt: record.createdAt.toISOString(),
|
|
41
|
+
updatedAt: record.updatedAt ? record.updatedAt.toISOString() : null
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function extractIdFromUrl(req) {
|
|
45
|
+
const url = new URL(req.url);
|
|
46
|
+
const segments = url.pathname.split("/").filter(Boolean);
|
|
47
|
+
return segments[segments.length - 1] || null;
|
|
48
|
+
}
|
|
49
|
+
async function GET(req) {
|
|
50
|
+
const auth = await getAuthFromRequest(req);
|
|
51
|
+
if (!auth) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
52
|
+
const effectiveUserId = auth.isApiKey ? auth.userId : auth.sub;
|
|
53
|
+
if (!effectiveUserId) return NextResponse.json({ error: "No user context" }, { status: 403 });
|
|
54
|
+
const id = extractIdFromUrl(req);
|
|
55
|
+
if (!id) return NextResponse.json({ error: "Invalid id" }, { status: 400 });
|
|
56
|
+
const { locale } = await resolveTranslations();
|
|
57
|
+
const { resolve } = await createRequestContainer();
|
|
58
|
+
const em = resolve("em");
|
|
59
|
+
const variant = await loadSidebarVariant(em, {
|
|
60
|
+
userId: effectiveUserId,
|
|
61
|
+
tenantId: auth.tenantId ?? null,
|
|
62
|
+
organizationId: auth.orgId ?? null,
|
|
63
|
+
locale
|
|
64
|
+
}, id);
|
|
65
|
+
if (!variant) return NextResponse.json({ error: "Variant not found" }, { status: 404 });
|
|
66
|
+
return NextResponse.json({ locale, variant: serializeVariant(variant) });
|
|
67
|
+
}
|
|
68
|
+
async function PUT(req) {
|
|
69
|
+
const auth = await getAuthFromRequest(req);
|
|
70
|
+
if (!auth) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
71
|
+
const effectiveUserId = auth.isApiKey ? auth.userId : auth.sub;
|
|
72
|
+
if (!effectiveUserId) return NextResponse.json({ error: "No user context" }, { status: 403 });
|
|
73
|
+
const id = extractIdFromUrl(req);
|
|
74
|
+
if (!id) return NextResponse.json({ error: "Invalid id" }, { status: 400 });
|
|
75
|
+
let parsedBody;
|
|
76
|
+
try {
|
|
77
|
+
parsedBody = await req.json();
|
|
78
|
+
} catch {
|
|
79
|
+
return NextResponse.json({ error: "Invalid JSON" }, { status: 400 });
|
|
80
|
+
}
|
|
81
|
+
const parsed = updateSidebarVariantInputSchema.safeParse(parsedBody);
|
|
82
|
+
if (!parsed.success) {
|
|
83
|
+
return NextResponse.json({ error: "Invalid payload", details: parsed.error.flatten() }, { status: 400 });
|
|
84
|
+
}
|
|
85
|
+
const { locale } = await resolveTranslations();
|
|
86
|
+
const { resolve } = await createRequestContainer();
|
|
87
|
+
const em = resolve("em");
|
|
88
|
+
const variant = await updateSidebarVariant(em, {
|
|
89
|
+
userId: effectiveUserId,
|
|
90
|
+
tenantId: auth.tenantId ?? null,
|
|
91
|
+
organizationId: auth.orgId ?? null,
|
|
92
|
+
locale
|
|
93
|
+
}, id, {
|
|
94
|
+
name: parsed.data.name,
|
|
95
|
+
settings: parsed.data.settings ?? null,
|
|
96
|
+
isActive: parsed.data.isActive
|
|
97
|
+
});
|
|
98
|
+
if (!variant) return NextResponse.json({ error: "Variant not found" }, { status: 404 });
|
|
99
|
+
return NextResponse.json({ locale, variant: serializeVariant(variant) });
|
|
100
|
+
}
|
|
101
|
+
async function DELETE(req) {
|
|
102
|
+
const auth = await getAuthFromRequest(req);
|
|
103
|
+
if (!auth) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
104
|
+
const effectiveUserId = auth.isApiKey ? auth.userId : auth.sub;
|
|
105
|
+
if (!effectiveUserId) return NextResponse.json({ error: "No user context" }, { status: 403 });
|
|
106
|
+
const id = extractIdFromUrl(req);
|
|
107
|
+
if (!id) return NextResponse.json({ error: "Invalid id" }, { status: 400 });
|
|
108
|
+
const { locale } = await resolveTranslations();
|
|
109
|
+
const { resolve } = await createRequestContainer();
|
|
110
|
+
const em = resolve("em");
|
|
111
|
+
const ok = await deleteSidebarVariant(em, {
|
|
112
|
+
userId: effectiveUserId,
|
|
113
|
+
tenantId: auth.tenantId ?? null,
|
|
114
|
+
organizationId: auth.orgId ?? null,
|
|
115
|
+
locale
|
|
116
|
+
}, id);
|
|
117
|
+
if (!ok) return NextResponse.json({ error: "Variant not found" }, { status: 404 });
|
|
118
|
+
return NextResponse.json({ ok: true });
|
|
119
|
+
}
|
|
120
|
+
const openApi = {
|
|
121
|
+
tag: "Authentication & Accounts",
|
|
122
|
+
summary: "Sidebar variant",
|
|
123
|
+
methods: {
|
|
124
|
+
GET: {
|
|
125
|
+
summary: "Get a sidebar variant",
|
|
126
|
+
responses: [
|
|
127
|
+
{ status: 200, description: "Variant", schema: variantResponseSchema },
|
|
128
|
+
{ status: 401, description: "Unauthorized", schema: errorSchema },
|
|
129
|
+
{ status: 404, description: "Variant not found", schema: errorSchema }
|
|
130
|
+
]
|
|
131
|
+
},
|
|
132
|
+
PUT: {
|
|
133
|
+
summary: "Update a sidebar variant",
|
|
134
|
+
description: "Updates the variant's name, settings, and/or isActive flag. Setting `isActive: true` deactivates other variants in the same scope (only one active per user/tenant/locale).",
|
|
135
|
+
requestBody: { contentType: "application/json", schema: updateSidebarVariantInputSchema },
|
|
136
|
+
responses: [
|
|
137
|
+
{ status: 200, description: "Variant updated", schema: variantResponseSchema },
|
|
138
|
+
{ status: 400, description: "Invalid payload", schema: errorSchema },
|
|
139
|
+
{ status: 401, description: "Unauthorized", schema: errorSchema },
|
|
140
|
+
{ status: 404, description: "Variant not found", schema: errorSchema }
|
|
141
|
+
]
|
|
142
|
+
},
|
|
143
|
+
DELETE: {
|
|
144
|
+
summary: "Delete a sidebar variant",
|
|
145
|
+
description: "Soft-deletes the variant (sets deleted_at).",
|
|
146
|
+
responses: [
|
|
147
|
+
{ status: 200, description: "Variant deleted", schema: deleteResponseSchema },
|
|
148
|
+
{ status: 401, description: "Unauthorized", schema: errorSchema },
|
|
149
|
+
{ status: 404, description: "Variant not found", schema: errorSchema }
|
|
150
|
+
]
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
export {
|
|
155
|
+
DELETE,
|
|
156
|
+
GET,
|
|
157
|
+
PUT,
|
|
158
|
+
metadata,
|
|
159
|
+
openApi
|
|
160
|
+
};
|
|
161
|
+
//# sourceMappingURL=route.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../../src/modules/auth/api/sidebar/variants/%5Bid%5D/route.ts"],
|
|
4
|
+
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { SIDEBAR_PREFERENCES_VERSION } from '@open-mercato/shared/modules/navigation/sidebarPreferences'\nimport {\n deleteSidebarVariant,\n loadSidebarVariant,\n updateSidebarVariant,\n type SidebarVariantRecord,\n} from '../../../../services/sidebarPreferencesService'\nimport {\n sidebarVariantRecordSchema,\n updateSidebarVariantInputSchema,\n} from '../../../../data/validators'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\n\nexport const metadata = {\n GET: { requireAuth: true },\n PUT: { requireAuth: true },\n DELETE: { requireAuth: true },\n}\n\nconst variantResponseSchema = z.object({\n locale: z.string(),\n variant: sidebarVariantRecordSchema,\n})\n\nconst deleteResponseSchema = z.object({ ok: z.literal(true) })\nconst errorSchema = z.object({ error: z.string() })\n\nfunction serializeVariant(record: SidebarVariantRecord) {\n return {\n id: record.id,\n name: record.name,\n isActive: record.isActive,\n settings: {\n version: record.settings.version ?? SIDEBAR_PREFERENCES_VERSION,\n groupOrder: record.settings.groupOrder ?? [],\n groupLabels: record.settings.groupLabels ?? {},\n itemLabels: record.settings.itemLabels ?? {},\n hiddenItems: record.settings.hiddenItems ?? [],\n itemOrder: record.settings.itemOrder ?? {},\n },\n createdAt: record.createdAt.toISOString(),\n updatedAt: record.updatedAt ? record.updatedAt.toISOString() : null,\n }\n}\n\nfunction extractIdFromUrl(req: Request): string | null {\n const url = new URL(req.url)\n const segments = url.pathname.split('/').filter(Boolean)\n // .../api/auth/sidebar/variants/<id>\n return segments[segments.length - 1] || null\n}\n\nexport async function GET(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n const effectiveUserId = auth.isApiKey ? auth.userId : auth.sub\n if (!effectiveUserId) return NextResponse.json({ error: 'No user context' }, { status: 403 })\n\n const id = extractIdFromUrl(req)\n if (!id) return NextResponse.json({ error: 'Invalid id' }, { status: 400 })\n\n const { locale } = await resolveTranslations()\n const { resolve } = await createRequestContainer()\n const em = resolve('em') as EntityManager\n\n const variant = await loadSidebarVariant(em, {\n userId: effectiveUserId,\n tenantId: auth.tenantId ?? null,\n organizationId: auth.orgId ?? null,\n locale,\n }, id)\n\n if (!variant) return NextResponse.json({ error: 'Variant not found' }, { status: 404 })\n\n return NextResponse.json({ locale, variant: serializeVariant(variant) })\n}\n\nexport async function PUT(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n const effectiveUserId = auth.isApiKey ? auth.userId : auth.sub\n if (!effectiveUserId) return NextResponse.json({ error: 'No user context' }, { status: 403 })\n\n const id = extractIdFromUrl(req)\n if (!id) return NextResponse.json({ error: 'Invalid id' }, { status: 400 })\n\n let parsedBody: unknown\n try {\n parsedBody = await req.json()\n } catch {\n return NextResponse.json({ error: 'Invalid JSON' }, { status: 400 })\n }\n\n const parsed = updateSidebarVariantInputSchema.safeParse(parsedBody)\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid payload', details: parsed.error.flatten() }, { status: 400 })\n }\n\n const { locale } = await resolveTranslations()\n const { resolve } = await createRequestContainer()\n const em = resolve('em') as EntityManager\n\n const variant = await updateSidebarVariant(em, {\n userId: effectiveUserId,\n tenantId: auth.tenantId ?? null,\n organizationId: auth.orgId ?? null,\n locale,\n }, id, {\n name: parsed.data.name,\n settings: parsed.data.settings ?? null,\n isActive: parsed.data.isActive,\n })\n\n if (!variant) return NextResponse.json({ error: 'Variant not found' }, { status: 404 })\n\n return NextResponse.json({ locale, variant: serializeVariant(variant) })\n}\n\nexport async function DELETE(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n const effectiveUserId = auth.isApiKey ? auth.userId : auth.sub\n if (!effectiveUserId) return NextResponse.json({ error: 'No user context' }, { status: 403 })\n\n const id = extractIdFromUrl(req)\n if (!id) return NextResponse.json({ error: 'Invalid id' }, { status: 400 })\n\n const { locale } = await resolveTranslations()\n const { resolve } = await createRequestContainer()\n const em = resolve('em') as EntityManager\n\n const ok = await deleteSidebarVariant(em, {\n userId: effectiveUserId,\n tenantId: auth.tenantId ?? null,\n organizationId: auth.orgId ?? null,\n locale,\n }, id)\n\n if (!ok) return NextResponse.json({ error: 'Variant not found' }, { status: 404 })\n\n return NextResponse.json({ ok: true })\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Authentication & Accounts',\n summary: 'Sidebar variant',\n methods: {\n GET: {\n summary: 'Get a sidebar variant',\n responses: [\n { status: 200, description: 'Variant', schema: variantResponseSchema },\n { status: 401, description: 'Unauthorized', schema: errorSchema },\n { status: 404, description: 'Variant not found', schema: errorSchema },\n ],\n },\n PUT: {\n summary: 'Update a sidebar variant',\n description: 'Updates the variant\\'s name, settings, and/or isActive flag. Setting `isActive: true` deactivates other variants in the same scope (only one active per user/tenant/locale).',\n requestBody: { contentType: 'application/json', schema: updateSidebarVariantInputSchema },\n responses: [\n { status: 200, description: 'Variant updated', schema: variantResponseSchema },\n { status: 400, description: 'Invalid payload', schema: errorSchema },\n { status: 401, description: 'Unauthorized', schema: errorSchema },\n { status: 404, description: 'Variant not found', schema: errorSchema },\n ],\n },\n DELETE: {\n summary: 'Delete a sidebar variant',\n description: 'Soft-deletes the variant (sets deleted_at).',\n responses: [\n { status: 200, description: 'Variant deleted', schema: deleteResponseSchema },\n { status: 401, description: 'Unauthorized', schema: errorSchema },\n { status: 404, description: 'Variant not found', schema: errorSchema },\n ],\n },\n },\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
|
|
4
|
+
import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
|
|
5
|
+
import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
|
|
6
|
+
import { SIDEBAR_PREFERENCES_VERSION } from "@open-mercato/shared/modules/navigation/sidebarPreferences";
|
|
7
|
+
import {
|
|
8
|
+
createSidebarVariant,
|
|
9
|
+
listSidebarVariants
|
|
10
|
+
} from "../../../services/sidebarPreferencesService.js";
|
|
11
|
+
import {
|
|
12
|
+
createSidebarVariantInputSchema,
|
|
13
|
+
sidebarVariantRecordSchema
|
|
14
|
+
} from "../../../data/validators.js";
|
|
15
|
+
const metadata = {
|
|
16
|
+
GET: { requireAuth: true },
|
|
17
|
+
POST: { requireAuth: true }
|
|
18
|
+
};
|
|
19
|
+
const variantListResponseSchema = z.object({
|
|
20
|
+
locale: z.string(),
|
|
21
|
+
variants: z.array(sidebarVariantRecordSchema)
|
|
22
|
+
});
|
|
23
|
+
const variantCreateResponseSchema = z.object({
|
|
24
|
+
locale: z.string(),
|
|
25
|
+
variant: sidebarVariantRecordSchema
|
|
26
|
+
});
|
|
27
|
+
const errorSchema = z.object({ error: z.string() });
|
|
28
|
+
function serializeVariant(record) {
|
|
29
|
+
return {
|
|
30
|
+
id: record.id,
|
|
31
|
+
name: record.name,
|
|
32
|
+
isActive: record.isActive,
|
|
33
|
+
settings: {
|
|
34
|
+
version: record.settings.version ?? SIDEBAR_PREFERENCES_VERSION,
|
|
35
|
+
groupOrder: record.settings.groupOrder ?? [],
|
|
36
|
+
groupLabels: record.settings.groupLabels ?? {},
|
|
37
|
+
itemLabels: record.settings.itemLabels ?? {},
|
|
38
|
+
hiddenItems: record.settings.hiddenItems ?? [],
|
|
39
|
+
itemOrder: record.settings.itemOrder ?? {}
|
|
40
|
+
},
|
|
41
|
+
createdAt: record.createdAt.toISOString(),
|
|
42
|
+
updatedAt: record.updatedAt ? record.updatedAt.toISOString() : null
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
async function GET(req) {
|
|
46
|
+
const auth = await getAuthFromRequest(req);
|
|
47
|
+
if (!auth) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
48
|
+
const effectiveUserId = auth.isApiKey ? auth.userId : auth.sub;
|
|
49
|
+
if (!effectiveUserId) return NextResponse.json({ error: "No user context" }, { status: 403 });
|
|
50
|
+
const { locale } = await resolveTranslations();
|
|
51
|
+
const { resolve } = await createRequestContainer();
|
|
52
|
+
const em = resolve("em");
|
|
53
|
+
const variants = await listSidebarVariants(em, {
|
|
54
|
+
userId: effectiveUserId,
|
|
55
|
+
tenantId: auth.tenantId ?? null,
|
|
56
|
+
organizationId: auth.orgId ?? null,
|
|
57
|
+
locale
|
|
58
|
+
});
|
|
59
|
+
return NextResponse.json(
|
|
60
|
+
{
|
|
61
|
+
locale,
|
|
62
|
+
variants: variants.map(serializeVariant)
|
|
63
|
+
},
|
|
64
|
+
{ headers: { "cache-control": "no-store, no-cache, must-revalidate" } }
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
async function POST(req) {
|
|
68
|
+
const auth = await getAuthFromRequest(req);
|
|
69
|
+
if (!auth) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
70
|
+
const effectiveUserId = auth.isApiKey ? auth.userId : auth.sub;
|
|
71
|
+
if (!effectiveUserId) return NextResponse.json({ error: "No user context" }, { status: 403 });
|
|
72
|
+
let parsedBody;
|
|
73
|
+
try {
|
|
74
|
+
parsedBody = await req.json();
|
|
75
|
+
} catch {
|
|
76
|
+
parsedBody = {};
|
|
77
|
+
}
|
|
78
|
+
const parsed = createSidebarVariantInputSchema.safeParse(parsedBody);
|
|
79
|
+
if (!parsed.success) {
|
|
80
|
+
return NextResponse.json({ error: "Invalid payload", details: parsed.error.flatten() }, { status: 400 });
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
const { locale } = await resolveTranslations();
|
|
84
|
+
const { resolve } = await createRequestContainer();
|
|
85
|
+
const em = resolve("em");
|
|
86
|
+
const variant = await createSidebarVariant(em, {
|
|
87
|
+
userId: effectiveUserId,
|
|
88
|
+
tenantId: auth.tenantId ?? null,
|
|
89
|
+
organizationId: auth.orgId ?? null,
|
|
90
|
+
locale
|
|
91
|
+
}, {
|
|
92
|
+
name: parsed.data.name ?? null,
|
|
93
|
+
settings: parsed.data.settings ?? null,
|
|
94
|
+
isActive: parsed.data.isActive
|
|
95
|
+
});
|
|
96
|
+
return NextResponse.json({
|
|
97
|
+
locale,
|
|
98
|
+
variant: serializeVariant(variant)
|
|
99
|
+
});
|
|
100
|
+
} catch (err) {
|
|
101
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
102
|
+
if (err instanceof Error && err.constructor?.name === "UniqueConstraintViolationException") {
|
|
103
|
+
return NextResponse.json(
|
|
104
|
+
{ error: "A variant with this name already exists. Choose a different name.", code: "duplicate_name" },
|
|
105
|
+
{ status: 409 }
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
console.error("[sidebar-variants POST] failed", err);
|
|
109
|
+
return NextResponse.json({ error: message }, { status: 500 });
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const openApi = {
|
|
113
|
+
tag: "Authentication & Accounts",
|
|
114
|
+
summary: "Sidebar variants",
|
|
115
|
+
methods: {
|
|
116
|
+
GET: {
|
|
117
|
+
summary: "List sidebar variants",
|
|
118
|
+
description: "Returns the named sidebar variants saved by the current user for the current tenant + locale.",
|
|
119
|
+
responses: [
|
|
120
|
+
{ status: 200, description: "Variant list", schema: variantListResponseSchema },
|
|
121
|
+
{ status: 401, description: "Unauthorized", schema: errorSchema }
|
|
122
|
+
]
|
|
123
|
+
},
|
|
124
|
+
POST: {
|
|
125
|
+
summary: "Create a sidebar variant",
|
|
126
|
+
description: 'Creates a new variant. If `name` is omitted or blank, an auto-name like "My preferences", "My preferences 2", \u2026 is assigned.',
|
|
127
|
+
requestBody: { contentType: "application/json", schema: createSidebarVariantInputSchema },
|
|
128
|
+
responses: [
|
|
129
|
+
{ status: 200, description: "Variant created", schema: variantCreateResponseSchema },
|
|
130
|
+
{ status: 400, description: "Invalid payload", schema: errorSchema },
|
|
131
|
+
{ status: 401, description: "Unauthorized", schema: errorSchema }
|
|
132
|
+
]
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
export {
|
|
137
|
+
GET,
|
|
138
|
+
POST,
|
|
139
|
+
metadata,
|
|
140
|
+
openApi
|
|
141
|
+
};
|
|
142
|
+
//# sourceMappingURL=route.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../src/modules/auth/api/sidebar/variants/route.ts"],
|
|
4
|
+
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { SIDEBAR_PREFERENCES_VERSION } from '@open-mercato/shared/modules/navigation/sidebarPreferences'\nimport {\n createSidebarVariant,\n listSidebarVariants,\n type SidebarVariantRecord,\n} from '../../../services/sidebarPreferencesService'\nimport {\n createSidebarVariantInputSchema,\n sidebarVariantRecordSchema,\n} from '../../../data/validators'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\n\nexport const metadata = {\n GET: { requireAuth: true },\n POST: { requireAuth: true },\n}\n\nconst variantListResponseSchema = z.object({\n locale: z.string(),\n variants: z.array(sidebarVariantRecordSchema),\n})\n\nconst variantCreateResponseSchema = z.object({\n locale: z.string(),\n variant: sidebarVariantRecordSchema,\n})\n\nconst errorSchema = z.object({ error: z.string() })\n\nfunction serializeVariant(record: SidebarVariantRecord) {\n return {\n id: record.id,\n name: record.name,\n isActive: record.isActive,\n settings: {\n version: record.settings.version ?? SIDEBAR_PREFERENCES_VERSION,\n groupOrder: record.settings.groupOrder ?? [],\n groupLabels: record.settings.groupLabels ?? {},\n itemLabels: record.settings.itemLabels ?? {},\n hiddenItems: record.settings.hiddenItems ?? [],\n itemOrder: record.settings.itemOrder ?? {},\n },\n createdAt: record.createdAt.toISOString(),\n updatedAt: record.updatedAt ? record.updatedAt.toISOString() : null,\n }\n}\n\nexport async function GET(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n const effectiveUserId = auth.isApiKey ? auth.userId : auth.sub\n if (!effectiveUserId) return NextResponse.json({ error: 'No user context' }, { status: 403 })\n\n const { locale } = await resolveTranslations()\n const { resolve } = await createRequestContainer()\n const em = resolve('em') as EntityManager\n\n const variants = await listSidebarVariants(em, {\n userId: effectiveUserId,\n tenantId: auth.tenantId ?? null,\n organizationId: auth.orgId ?? null,\n locale,\n })\n\n return NextResponse.json(\n {\n locale,\n variants: variants.map(serializeVariant),\n },\n { headers: { 'cache-control': 'no-store, no-cache, must-revalidate' } },\n )\n}\n\nexport async function POST(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n const effectiveUserId = auth.isApiKey ? auth.userId : auth.sub\n if (!effectiveUserId) return NextResponse.json({ error: 'No user context' }, { status: 403 })\n\n let parsedBody: unknown\n try {\n parsedBody = await req.json()\n } catch {\n parsedBody = {}\n }\n\n const parsed = createSidebarVariantInputSchema.safeParse(parsedBody)\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid payload', details: parsed.error.flatten() }, { status: 400 })\n }\n\n try {\n const { locale } = await resolveTranslations()\n const { resolve } = await createRequestContainer()\n const em = resolve('em') as EntityManager\n\n const variant = await createSidebarVariant(em, {\n userId: effectiveUserId,\n tenantId: auth.tenantId ?? null,\n organizationId: auth.orgId ?? null,\n locale,\n }, {\n name: parsed.data.name ?? null,\n settings: parsed.data.settings ?? null,\n isActive: parsed.data.isActive,\n })\n\n return NextResponse.json({\n locale,\n variant: serializeVariant(variant),\n })\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n // MikroORM throws UniqueConstraintViolationException for unique conflicts.\n // The constraint name embeds the columns: (user_id, tenant_id, locale, name).\n if (err instanceof Error && err.constructor?.name === 'UniqueConstraintViolationException') {\n return NextResponse.json(\n { error: 'A variant with this name already exists. Choose a different name.', code: 'duplicate_name' },\n { status: 409 },\n )\n }\n // eslint-disable-next-line no-console\n console.error('[sidebar-variants POST] failed', err)\n return NextResponse.json({ error: message }, { status: 500 })\n }\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Authentication & Accounts',\n summary: 'Sidebar variants',\n methods: {\n GET: {\n summary: 'List sidebar variants',\n description: 'Returns the named sidebar variants saved by the current user for the current tenant + locale.',\n responses: [\n { status: 200, description: 'Variant list', schema: variantListResponseSchema },\n { status: 401, description: 'Unauthorized', schema: errorSchema },\n ],\n },\n POST: {\n summary: 'Create a sidebar variant',\n description: 'Creates a new variant. If `name` is omitted or blank, an auto-name like \"My preferences\", \"My preferences 2\", \u2026 is assigned.',\n requestBody: { contentType: 'application/json', schema: createSidebarVariantInputSchema },\n responses: [\n { status: 200, description: 'Variant created', schema: variantCreateResponseSchema },\n { status: 400, description: 'Invalid payload', schema: errorSchema },\n { status: 401, description: 'Unauthorized', schema: errorSchema },\n ],\n },\n },\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { useRouter } from "next/navigation";
|
|
5
|
+
import { SidebarCustomizationEditor } from "@open-mercato/ui/backend/sidebar/SidebarCustomizationEditor";
|
|
6
|
+
function SidebarCustomizationPage() {
|
|
7
|
+
const router = useRouter();
|
|
8
|
+
const goBack = React.useCallback(() => {
|
|
9
|
+
router.push("/backend/settings");
|
|
10
|
+
}, [router]);
|
|
11
|
+
return /* @__PURE__ */ jsx("div", { className: "space-y-4", children: /* @__PURE__ */ jsx(SidebarCustomizationEditor, { onCanceled: goBack }) });
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
SidebarCustomizationPage as default
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=page.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/modules/auth/backend/sidebar-customization/page.tsx"],
|
|
4
|
+
"sourcesContent": ["'use client'\nimport * as React from 'react'\nimport { useRouter } from 'next/navigation'\nimport { SidebarCustomizationEditor } from '@open-mercato/ui/backend/sidebar/SidebarCustomizationEditor'\n\nexport default function SidebarCustomizationPage() {\n const router = useRouter()\n const goBack = React.useCallback(() => {\n router.push('/backend/settings')\n }, [router])\n\n return (\n <div className=\"space-y-4\">\n <SidebarCustomizationEditor onCanceled={goBack} />\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": ";AAaM;AAZN,YAAY,WAAW;AACvB,SAAS,iBAAiB;AAC1B,SAAS,kCAAkC;AAE5B,SAAR,2BAA4C;AACjD,QAAM,SAAS,UAAU;AACzB,QAAM,SAAS,MAAM,YAAY,MAAM;AACrC,WAAO,KAAK,mBAAmB;AAAA,EACjC,GAAG,CAAC,MAAM,CAAC;AAEX,SACE,oBAAC,SAAI,WAAU,aACb,8BAAC,8BAA2B,YAAY,QAAQ,GAClD;AAEJ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
const sidebarCustomizeIcon = React.createElement(
|
|
3
|
+
"svg",
|
|
4
|
+
{ width: 16, height: 16, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" },
|
|
5
|
+
React.createElement("rect", { x: 3, y: 3, width: 7, height: 18, rx: 1 }),
|
|
6
|
+
React.createElement("rect", { x: 14, y: 3, width: 7, height: 11, rx: 1 }),
|
|
7
|
+
React.createElement("path", { d: "M14 17h7" }),
|
|
8
|
+
React.createElement("path", { d: "M17.5 14v7" })
|
|
9
|
+
);
|
|
10
|
+
const metadata = {
|
|
11
|
+
requireAuth: true,
|
|
12
|
+
pageTitle: "Customize sidebar",
|
|
13
|
+
pageTitleKey: "appShell.customizeSidebar",
|
|
14
|
+
pageGroup: "Customization",
|
|
15
|
+
pageGroupKey: "appShell.sidebarCustomizationGroup",
|
|
16
|
+
pageOrder: 1,
|
|
17
|
+
icon: sidebarCustomizeIcon,
|
|
18
|
+
pageContext: "settings",
|
|
19
|
+
breadcrumb: [
|
|
20
|
+
{ label: "Customize sidebar", labelKey: "appShell.customizeSidebar" }
|
|
21
|
+
]
|
|
22
|
+
};
|
|
23
|
+
var page_meta_default = metadata;
|
|
24
|
+
export {
|
|
25
|
+
page_meta_default as default,
|
|
26
|
+
metadata
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=page.meta.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/modules/auth/backend/sidebar-customization/page.meta.ts"],
|
|
4
|
+
"sourcesContent": ["import React from 'react'\n\nconst sidebarCustomizeIcon = React.createElement(\n 'svg',\n { width: 16, height: 16, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 2, strokeLinecap: 'round', strokeLinejoin: 'round' },\n React.createElement('rect', { x: 3, y: 3, width: 7, height: 18, rx: 1 }),\n React.createElement('rect', { x: 14, y: 3, width: 7, height: 11, rx: 1 }),\n React.createElement('path', { d: 'M14 17h7' }),\n React.createElement('path', { d: 'M17.5 14v7' }),\n)\n\n// Page is reachable by any authenticated user \u2014 every staff user has\n// always been able to customize their PERSONAL sidebar (the variants /\n// preferences APIs gate only role-application via `auth.sidebar.manage`).\n// Inside the editor, the \"Apply to roles\" card and role variants picker are\n// already conditionally hidden via `canApplyToRoles` (server-checked against\n// `auth.sidebar.manage`), so non-admins see only the personal-scope flow,\n// matching the pre-PR inline-editor behavior. Restricting the whole page\n// to `auth.sidebar.manage` would be a stealth regression for non-admins.\nexport const metadata = {\n requireAuth: true,\n pageTitle: 'Customize sidebar',\n pageTitleKey: 'appShell.customizeSidebar',\n pageGroup: 'Customization',\n pageGroupKey: 'appShell.sidebarCustomizationGroup',\n pageOrder: 1,\n icon: sidebarCustomizeIcon,\n pageContext: 'settings' as const,\n breadcrumb: [\n { label: 'Customize sidebar', labelKey: 'appShell.customizeSidebar' },\n ],\n}\n\nexport default metadata\n"],
|
|
5
|
+
"mappings": "AAAA,OAAO,WAAW;AAElB,MAAM,uBAAuB,MAAM;AAAA,EACjC;AAAA,EACA,EAAE,OAAO,IAAI,QAAQ,IAAI,SAAS,aAAa,MAAM,QAAQ,QAAQ,gBAAgB,aAAa,GAAG,eAAe,SAAS,gBAAgB,QAAQ;AAAA,EACrJ,MAAM,cAAc,QAAQ,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,GAAG,QAAQ,IAAI,IAAI,EAAE,CAAC;AAAA,EACvE,MAAM,cAAc,QAAQ,EAAE,GAAG,IAAI,GAAG,GAAG,OAAO,GAAG,QAAQ,IAAI,IAAI,EAAE,CAAC;AAAA,EACxE,MAAM,cAAc,QAAQ,EAAE,GAAG,WAAW,CAAC;AAAA,EAC7C,MAAM,cAAc,QAAQ,EAAE,GAAG,aAAa,CAAC;AACjD;AAUO,MAAM,WAAW;AAAA,EACtB,aAAa;AAAA,EACb,WAAW;AAAA,EACX,cAAc;AAAA,EACd,WAAW;AAAA,EACX,cAAc;AAAA,EACd,WAAW;AAAA,EACX,MAAM;AAAA,EACN,aAAa;AAAA,EACb,YAAY;AAAA,IACV,EAAE,OAAO,qBAAqB,UAAU,4BAA4B;AAAA,EACtE;AACF;AAEA,IAAO,oBAAQ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -109,8 +109,7 @@ __decorateClass([
|
|
|
109
109
|
Property({ name: "deleted_at", type: Date, nullable: true })
|
|
110
110
|
], UserSidebarPreference.prototype, "deletedAt", 2);
|
|
111
111
|
UserSidebarPreference = __decorateClass([
|
|
112
|
-
Entity({ tableName: "user_sidebar_preferences" })
|
|
113
|
-
Unique({ properties: ["user", "tenantId", "organizationId", "locale"] })
|
|
112
|
+
Entity({ tableName: "user_sidebar_preferences" })
|
|
114
113
|
], UserSidebarPreference);
|
|
115
114
|
let RoleSidebarPreference = class {
|
|
116
115
|
constructor() {
|
|
@@ -142,9 +141,50 @@ __decorateClass([
|
|
|
142
141
|
Property({ name: "deleted_at", type: Date, nullable: true })
|
|
143
142
|
], RoleSidebarPreference.prototype, "deletedAt", 2);
|
|
144
143
|
RoleSidebarPreference = __decorateClass([
|
|
145
|
-
Entity({ tableName: "role_sidebar_preferences" })
|
|
146
|
-
Unique({ properties: ["role", "tenantId", "locale"] })
|
|
144
|
+
Entity({ tableName: "role_sidebar_preferences" })
|
|
147
145
|
], RoleSidebarPreference);
|
|
146
|
+
let SidebarVariant = class {
|
|
147
|
+
constructor() {
|
|
148
|
+
this.isActive = false;
|
|
149
|
+
this.createdAt = /* @__PURE__ */ new Date();
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
__decorateClass([
|
|
153
|
+
PrimaryKey({ type: "uuid", defaultRaw: "gen_random_uuid()" })
|
|
154
|
+
], SidebarVariant.prototype, "id", 2);
|
|
155
|
+
__decorateClass([
|
|
156
|
+
ManyToOne(() => User)
|
|
157
|
+
], SidebarVariant.prototype, "user", 2);
|
|
158
|
+
__decorateClass([
|
|
159
|
+
Property({ name: "tenant_id", type: "uuid", nullable: true })
|
|
160
|
+
], SidebarVariant.prototype, "tenantId", 2);
|
|
161
|
+
__decorateClass([
|
|
162
|
+
Property({ name: "organization_id", type: "uuid", nullable: true })
|
|
163
|
+
], SidebarVariant.prototype, "organizationId", 2);
|
|
164
|
+
__decorateClass([
|
|
165
|
+
Property({ type: "text" })
|
|
166
|
+
], SidebarVariant.prototype, "locale", 2);
|
|
167
|
+
__decorateClass([
|
|
168
|
+
Property({ type: "text" })
|
|
169
|
+
], SidebarVariant.prototype, "name", 2);
|
|
170
|
+
__decorateClass([
|
|
171
|
+
Property({ name: "settings_json", type: "json", nullable: true })
|
|
172
|
+
], SidebarVariant.prototype, "settingsJson", 2);
|
|
173
|
+
__decorateClass([
|
|
174
|
+
Property({ name: "is_active", type: "boolean", default: false })
|
|
175
|
+
], SidebarVariant.prototype, "isActive", 2);
|
|
176
|
+
__decorateClass([
|
|
177
|
+
Property({ name: "created_at", type: Date, onCreate: () => /* @__PURE__ */ new Date() })
|
|
178
|
+
], SidebarVariant.prototype, "createdAt", 2);
|
|
179
|
+
__decorateClass([
|
|
180
|
+
Property({ name: "updated_at", type: Date, onUpdate: () => /* @__PURE__ */ new Date(), nullable: true })
|
|
181
|
+
], SidebarVariant.prototype, "updatedAt", 2);
|
|
182
|
+
__decorateClass([
|
|
183
|
+
Property({ name: "deleted_at", type: Date, nullable: true })
|
|
184
|
+
], SidebarVariant.prototype, "deletedAt", 2);
|
|
185
|
+
SidebarVariant = __decorateClass([
|
|
186
|
+
Entity({ tableName: "sidebar_variants" })
|
|
187
|
+
], SidebarVariant);
|
|
148
188
|
let UserRole = class {
|
|
149
189
|
constructor() {
|
|
150
190
|
this.createdAt = /* @__PURE__ */ new Date();
|
|
@@ -356,6 +396,7 @@ export {
|
|
|
356
396
|
RoleAcl,
|
|
357
397
|
RoleSidebarPreference,
|
|
358
398
|
Session,
|
|
399
|
+
SidebarVariant,
|
|
359
400
|
User,
|
|
360
401
|
UserAcl,
|
|
361
402
|
UserConsent,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/auth/data/entities.ts"],
|
|
4
|
-
"sourcesContent": ["import { Entity, Index, ManyToOne, PrimaryKey, Property, Unique } from '@mikro-orm/decorators/legacy'\n\n@Entity({ tableName: 'users' })\nexport class User {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'tenant_id', type: 'uuid', nullable: true })\n tenantId?: string | null\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ type: 'text', unique: true })\n email!: string\n\n @Property({ name: 'email_hash', type: 'text', nullable: true })\n @Index({ name: 'users_email_hash_idx' })\n emailHash?: string | null\n\n @Property({ type: 'text', nullable: true })\n name?: string\n\n @Property({ name: 'password_hash', type: 'text', nullable: true })\n passwordHash?: string | null\n\n @Property({ name: 'is_confirmed', type: 'boolean', default: true })\n isConfirmed: boolean = true\n\n @Property({ name: 'last_login_at', type: Date, nullable: true })\n lastLoginAt?: Date\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n@Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'roles' })\n@Unique({ properties: ['tenantId', 'name'] })\nexport class Role {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ type: 'text' })\n name!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'user_sidebar_preferences' })\n@Unique({ properties: ['user', 'tenantId', 'organizationId', 'locale'] })\nexport class UserSidebarPreference {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => User)\n user!: User\n\n @Property({ name: 'tenant_id', type: 'uuid', nullable: true })\n tenantId?: string | null\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ type: 'text' })\n locale!: string\n\n @Property({ name: 'settings_json', type: 'json', nullable: true })\n settingsJson?: unknown\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date(), nullable: true })\n updatedAt?: Date\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'role_sidebar_preferences' })\n@Unique({ properties: ['role', 'tenantId', 'locale'] })\nexport class RoleSidebarPreference {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => Role)\n role!: Role\n\n @Property({ name: 'tenant_id', type: 'uuid', nullable: true })\n tenantId?: string | null\n\n @Property({ type: 'text' })\n locale!: string\n\n @Property({ name: 'settings_json', type: 'json', nullable: true })\n settingsJson?: unknown\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date(), nullable: true })\n updatedAt?: Date\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'user_roles' })\nexport class UserRole {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => User)\n user!: User\n\n @ManyToOne(() => Role)\n role!: Role\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'sessions' })\nexport class Session {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => User)\n user!: User\n\n @Property({ type: 'text', unique: true })\n token!: string\n\n @Property({ name: 'expires_at', type: Date })\n expiresAt!: Date\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'last_used_at', type: Date, nullable: true })\n lastUsedAt?: Date\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'password_resets' })\nexport class PasswordReset {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => User)\n user!: User\n\n @Property({ type: 'text', unique: true })\n token!: string\n\n @Property({ name: 'expires_at', type: Date })\n expiresAt!: Date\n\n @Property({ name: 'used_at', type: Date, nullable: true })\n usedAt?: Date\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n// RBAC: Role-level ACL\n@Entity({ tableName: 'role_acls' })\nexport class RoleAcl {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => Role)\n role!: Role\n\n // Tenant scope is mandatory for ACL evaluation\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n // Feature list (string-based). Use JSON array to preserve order and allow wildcards like \"example.*\".\n @Property({ name: 'features_json', type: 'json', nullable: true })\n featuresJson?: string[] | null\n\n // If true, user with this role can do everything regardless of features\n @Property({ name: 'is_super_admin', type: 'boolean', default: false })\n isSuperAdmin: boolean = false\n\n // Visible organizations within the tenant; null/empty means all organizations\n @Property({ name: 'organizations_json', type: 'json', nullable: true })\n organizationsJson?: string[] | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date(), nullable: true })\n updatedAt?: Date\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n// RBAC: Per-user ACL override\n@Entity({ tableName: 'user_acls' })\nexport class UserAcl {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => User)\n user!: User\n\n // Tenant scope is mandatory for ACL evaluation\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n // Feature list (string-based). Use JSON array to preserve order and allow wildcards like \"example.*\".\n @Property({ name: 'features_json', type: 'json', nullable: true })\n featuresJson?: string[] | null\n\n // If true, this user can do everything regardless of features\n @Property({ name: 'is_super_admin', type: 'boolean', default: false })\n isSuperAdmin: boolean = false\n\n // Visible organizations within the tenant; null/empty means all organizations\n @Property({ name: 'organizations_json', type: 'json', nullable: true })\n organizationsJson?: string[] | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date(), nullable: true })\n updatedAt?: Date\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'user_consents' })\n@Unique({ properties: ['userId', 'tenantId', 'consentType'] })\nexport class UserConsent {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'user_id', type: 'uuid' })\n userId!: string\n\n @Property({ name: 'tenant_id', type: 'uuid', nullable: true })\n tenantId?: string | null\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ name: 'consent_type', type: 'text' })\n consentType!: string\n\n @Property({ name: 'is_granted', type: 'boolean', default: false })\n isGranted: boolean = false\n\n @Property({ name: 'granted_at', type: Date, nullable: true })\n grantedAt?: Date | null\n\n @Property({ name: 'withdrawn_at', type: Date, nullable: true })\n withdrawnAt?: Date | null\n\n @Property({ type: 'text', nullable: true })\n source?: string | null\n\n @Property({ name: 'ip_address', type: 'text', nullable: true })\n ipAddress?: string | null\n\n @Property({ name: 'integrity_hash', type: 'text', nullable: true })\n integrityHash?: string | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date(), nullable: true })\n updatedAt?: Date\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;AAAA,SAAS,QAAQ,OAAO,WAAW,YAAY,UAAU,cAAc;AAGhE,IAAM,OAAN,MAAW;AAAA,EAAX;AAwBL,uBAAuB;AAMvB,qBAAkB,oBAAI,KAAK;AAAA;AAI7B;AAhCE;AAAA,EADC,WAAW,EAAE,MAAM,QAAQ,YAAY,oBAAoB,CAAC;AAAA,GADlD,KAEX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,aAAa,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAJlD,KAKX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,mBAAmB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAPxD,KAQX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,QAAQ,KAAK,CAAC;AAAA,GAV7B,KAWX;AAIA;AAAA,EAFC,SAAS,EAAE,MAAM,cAAc,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,EAC7D,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAAA,GAd5B,KAeX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAjB/B,KAkBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,iBAAiB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GApBtD,KAqBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,gBAAgB,MAAM,WAAW,SAAS,KAAK,CAAC;AAAA,GAvBvD,KAwBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,iBAAiB,MAAM,MAAM,UAAU,KAAK,CAAC;AAAA,GA1BpD,KA2BX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GA7B7D,KA8BX;AAGA;AAAA,EADD,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,KAAK,CAAC;AAAA,GAhC/C,KAiCX;AAjCW,OAAN;AAAA,EADN,OAAO,EAAE,WAAW,QAAQ,CAAC;AAAA,GACjB;AAsCN,IAAM,OAAN,MAAW;AAAA,EAAX;AAWL,qBAAkB,oBAAI,KAAK;AAAA;AAI7B;AAbE;AAAA,EADC,WAAW,EAAE,MAAM,QAAQ,YAAY,oBAAoB,CAAC;AAAA,GADlD,KAEX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAJf,KAKX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,GAPlC,KAQX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GAV7D,KAWX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,KAAK,CAAC;AAAA,GAbjD,KAcX;AAdW,OAAN;AAAA,EAFN,OAAO,EAAE,WAAW,QAAQ,CAAC;AAAA,EAC7B,OAAO,EAAE,YAAY,CAAC,YAAY,MAAM,EAAE,CAAC;AAAA,GAC/B;
|
|
4
|
+
"sourcesContent": ["import { Entity, Index, ManyToOne, PrimaryKey, Property, Unique } from '@mikro-orm/decorators/legacy'\n\n@Entity({ tableName: 'users' })\nexport class User {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'tenant_id', type: 'uuid', nullable: true })\n tenantId?: string | null\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ type: 'text', unique: true })\n email!: string\n\n @Property({ name: 'email_hash', type: 'text', nullable: true })\n @Index({ name: 'users_email_hash_idx' })\n emailHash?: string | null\n\n @Property({ type: 'text', nullable: true })\n name?: string\n\n @Property({ name: 'password_hash', type: 'text', nullable: true })\n passwordHash?: string | null\n\n @Property({ name: 'is_confirmed', type: 'boolean', default: true })\n isConfirmed: boolean = true\n\n @Property({ name: 'last_login_at', type: Date, nullable: true })\n lastLoginAt?: Date\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n@Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'roles' })\n@Unique({ properties: ['tenantId', 'name'] })\nexport class Role {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ type: 'text' })\n name!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'user_sidebar_preferences' })\n// Uniqueness is enforced by a partial unique index (`user_sidebar_preferences_active_unique_idx`)\n// scoped to live rows (`WHERE deleted_at IS NULL`) and owned by raw SQL in\n// Migration20260427143311. A `@Unique` decorator can't express a partial index,\n// so the entity intentionally omits it \u2014 the migration is the source of truth.\nexport class UserSidebarPreference {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => User)\n user!: User\n\n @Property({ name: 'tenant_id', type: 'uuid', nullable: true })\n tenantId?: string | null\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ type: 'text' })\n locale!: string\n\n @Property({ name: 'settings_json', type: 'json', nullable: true })\n settingsJson?: unknown\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date(), nullable: true })\n updatedAt?: Date\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'role_sidebar_preferences' })\n// Uniqueness is enforced by a partial unique index (`role_sidebar_preferences_active_unique_idx`)\n// scoped to live rows (`WHERE deleted_at IS NULL`) and owned by raw SQL in\n// Migration20260427143311. A `@Unique` decorator can't express a partial index,\n// so the entity intentionally omits it \u2014 the migration is the source of truth.\nexport class RoleSidebarPreference {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => Role)\n role!: Role\n\n @Property({ name: 'tenant_id', type: 'uuid', nullable: true })\n tenantId?: string | null\n\n @Property({ type: 'text' })\n locale!: string\n\n @Property({ name: 'settings_json', type: 'json', nullable: true })\n settingsJson?: unknown\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date(), nullable: true })\n updatedAt?: Date\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'sidebar_variants' })\n// Uniqueness is enforced by a partial unique index (`sidebar_variants_active_name_unique_idx`)\n// scoped to live rows (`WHERE deleted_at IS NULL`) and owned by raw SQL in\n// Migration20260427143311. A `@Unique` decorator can't express a partial index,\n// so the entity intentionally omits it \u2014 the migration is the source of truth.\nexport class SidebarVariant {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => User)\n user!: User\n\n @Property({ name: 'tenant_id', type: 'uuid', nullable: true })\n tenantId?: string | null\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ type: 'text' })\n locale!: string\n\n @Property({ type: 'text' })\n name!: string\n\n @Property({ name: 'settings_json', type: 'json', nullable: true })\n settingsJson?: unknown\n\n @Property({ name: 'is_active', type: 'boolean', default: false })\n isActive: boolean = false\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date(), nullable: true })\n updatedAt?: Date\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'user_roles' })\nexport class UserRole {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => User)\n user!: User\n\n @ManyToOne(() => Role)\n role!: Role\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'sessions' })\nexport class Session {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => User)\n user!: User\n\n @Property({ type: 'text', unique: true })\n token!: string\n\n @Property({ name: 'expires_at', type: Date })\n expiresAt!: Date\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'last_used_at', type: Date, nullable: true })\n lastUsedAt?: Date\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'password_resets' })\nexport class PasswordReset {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => User)\n user!: User\n\n @Property({ type: 'text', unique: true })\n token!: string\n\n @Property({ name: 'expires_at', type: Date })\n expiresAt!: Date\n\n @Property({ name: 'used_at', type: Date, nullable: true })\n usedAt?: Date\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n// RBAC: Role-level ACL\n@Entity({ tableName: 'role_acls' })\nexport class RoleAcl {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => Role)\n role!: Role\n\n // Tenant scope is mandatory for ACL evaluation\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n // Feature list (string-based). Use JSON array to preserve order and allow wildcards like \"example.*\".\n @Property({ name: 'features_json', type: 'json', nullable: true })\n featuresJson?: string[] | null\n\n // If true, user with this role can do everything regardless of features\n @Property({ name: 'is_super_admin', type: 'boolean', default: false })\n isSuperAdmin: boolean = false\n\n // Visible organizations within the tenant; null/empty means all organizations\n @Property({ name: 'organizations_json', type: 'json', nullable: true })\n organizationsJson?: string[] | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date(), nullable: true })\n updatedAt?: Date\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n// RBAC: Per-user ACL override\n@Entity({ tableName: 'user_acls' })\nexport class UserAcl {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => User)\n user!: User\n\n // Tenant scope is mandatory for ACL evaluation\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n // Feature list (string-based). Use JSON array to preserve order and allow wildcards like \"example.*\".\n @Property({ name: 'features_json', type: 'json', nullable: true })\n featuresJson?: string[] | null\n\n // If true, this user can do everything regardless of features\n @Property({ name: 'is_super_admin', type: 'boolean', default: false })\n isSuperAdmin: boolean = false\n\n // Visible organizations within the tenant; null/empty means all organizations\n @Property({ name: 'organizations_json', type: 'json', nullable: true })\n organizationsJson?: string[] | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date(), nullable: true })\n updatedAt?: Date\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'user_consents' })\n@Unique({ properties: ['userId', 'tenantId', 'consentType'] })\nexport class UserConsent {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'user_id', type: 'uuid' })\n userId!: string\n\n @Property({ name: 'tenant_id', type: 'uuid', nullable: true })\n tenantId?: string | null\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ name: 'consent_type', type: 'text' })\n consentType!: string\n\n @Property({ name: 'is_granted', type: 'boolean', default: false })\n isGranted: boolean = false\n\n @Property({ name: 'granted_at', type: Date, nullable: true })\n grantedAt?: Date | null\n\n @Property({ name: 'withdrawn_at', type: Date, nullable: true })\n withdrawnAt?: Date | null\n\n @Property({ type: 'text', nullable: true })\n source?: string | null\n\n @Property({ name: 'ip_address', type: 'text', nullable: true })\n ipAddress?: string | null\n\n @Property({ name: 'integrity_hash', type: 'text', nullable: true })\n integrityHash?: string | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date(), nullable: true })\n updatedAt?: Date\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|