@rpcbase/server 0.474.0 → 0.476.0

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.
Files changed (33) hide show
  1. package/dist/email-DEw8keax.js +8041 -0
  2. package/dist/handler-BITFtEr_.js +396 -0
  3. package/dist/{handler-D6oN38vE.js → handler-BYVnU9H-.js} +1 -1
  4. package/dist/{handler-ybYk2VTq.js → handler-CHuOXAtH.js} +5 -5
  5. package/dist/{handler-CGko2pJM.js → handler-DEEir2xV.js} +2 -2
  6. package/dist/{index-dlSIqvl2.js → index-Ckx0UHs6.js} +3 -3
  7. package/dist/index.js +70 -8107
  8. package/dist/notifications/api/notifications/handler.d.ts +4 -0
  9. package/dist/notifications/api/notifications/handler.d.ts.map +1 -0
  10. package/dist/notifications/api/notifications/index.d.ts +168 -0
  11. package/dist/notifications/api/notifications/index.d.ts.map +1 -0
  12. package/dist/notifications/api/notifications/shared.d.ts +6 -0
  13. package/dist/notifications/api/notifications/shared.d.ts.map +1 -0
  14. package/dist/notifications/createNotification.d.ts +13 -0
  15. package/dist/notifications/createNotification.d.ts.map +1 -0
  16. package/dist/notifications/digest.d.ts +13 -0
  17. package/dist/notifications/digest.d.ts.map +1 -0
  18. package/dist/notifications/routes.d.ts +2 -0
  19. package/dist/notifications/routes.d.ts.map +1 -0
  20. package/dist/notifications.d.ts +4 -0
  21. package/dist/notifications.d.ts.map +1 -0
  22. package/dist/notifications.js +126 -0
  23. package/dist/rts/api/changes/handler.d.ts +2 -2
  24. package/dist/rts/api/changes/handler.d.ts.map +1 -1
  25. package/dist/rts.js +2 -2
  26. package/dist/{schemas-CyxqObur.js → schemas-DI7ewltq.js} +112 -1
  27. package/dist/{shared-8XhCreJo.js → shared-Chfrv8o6.js} +2 -2
  28. package/dist/types/index.d.ts +2 -2
  29. package/dist/types/index.d.ts.map +1 -1
  30. package/dist/uploads/api/file-uploads/shared.d.ts +1 -1
  31. package/dist/uploads/api/file-uploads/shared.d.ts.map +1 -1
  32. package/dist/uploads.js +1 -1
  33. package/package.json +6 -1
@@ -0,0 +1,396 @@
1
+ import { loadModel } from "@rpcbase/db";
2
+ import { createNotification, sendNotificationsDigestForUser } from "./notifications.js";
3
+ import { o as object, b as boolean, n as number, a as array, s as string, r as record, u as unknown, _ as _enum } from "./schemas-DI7ewltq.js";
4
+ const getSessionUser = (ctx) => {
5
+ const rawSessionUser = ctx.req.session?.user;
6
+ const userId = typeof rawSessionUser?.id === "string" ? rawSessionUser.id.trim() : "";
7
+ const tenantId = typeof rawSessionUser?.currentTenantId === "string" ? rawSessionUser.currentTenantId.trim() : "";
8
+ if (!userId) {
9
+ ctx.res.status(401);
10
+ return null;
11
+ }
12
+ if (!tenantId) {
13
+ ctx.res.status(400);
14
+ return null;
15
+ }
16
+ return { userId, tenantId };
17
+ };
18
+ const ListRoute = "/api/rb/notifications";
19
+ const CreateRoute = "/api/rb/notifications/create";
20
+ const MarkReadRoute = "/api/rb/notifications/:notificationId/read";
21
+ const ArchiveRoute = "/api/rb/notifications/:notificationId/archive";
22
+ const MarkAllReadRoute = "/api/rb/notifications/mark-all-read";
23
+ const SettingsRoute = "/api/rb/notifications/settings";
24
+ const DigestRunRoute = "/api/rb/notifications/digest/run";
25
+ const listRequestSchema = object({
26
+ includeArchived: boolean().optional(),
27
+ unreadOnly: boolean().optional(),
28
+ limit: number().int().min(1).max(200).optional(),
29
+ markSeen: boolean().optional()
30
+ });
31
+ const createRequestSchema = object({
32
+ topic: string().trim().min(1).optional(),
33
+ title: string().trim().min(1),
34
+ body: string().trim().optional(),
35
+ url: string().trim().optional(),
36
+ metadata: record(string(), unknown()).optional()
37
+ });
38
+ const notificationSchema = object({
39
+ id: string(),
40
+ topic: string().optional(),
41
+ title: string(),
42
+ body: string().optional(),
43
+ url: string().optional(),
44
+ createdAt: string(),
45
+ seenAt: string().optional(),
46
+ readAt: string().optional(),
47
+ archivedAt: string().optional(),
48
+ metadata: record(string(), unknown()).optional()
49
+ });
50
+ const listResponseSchema = object({
51
+ ok: boolean(),
52
+ error: string().optional(),
53
+ notifications: array(notificationSchema).optional(),
54
+ unreadCount: number().int().min(0).optional(),
55
+ unseenCount: number().int().min(0).optional()
56
+ });
57
+ const createResponseSchema = object({
58
+ ok: boolean(),
59
+ error: string().optional(),
60
+ id: string().optional()
61
+ });
62
+ object({
63
+ ok: boolean(),
64
+ error: string().optional()
65
+ });
66
+ object({
67
+ ok: boolean(),
68
+ error: string().optional()
69
+ });
70
+ object({
71
+ ok: boolean(),
72
+ error: string().optional()
73
+ });
74
+ const digestFrequencySchema = _enum(["off", "daily", "weekly"]);
75
+ const topicPreferenceSchema = object({
76
+ topic: string(),
77
+ inApp: boolean(),
78
+ emailDigest: boolean(),
79
+ push: boolean()
80
+ });
81
+ const settingsSchema = object({
82
+ digestFrequency: digestFrequencySchema,
83
+ topicPreferences: array(topicPreferenceSchema),
84
+ lastDigestSentAt: string().optional()
85
+ });
86
+ const settingsResponseSchema = object({
87
+ ok: boolean(),
88
+ error: string().optional(),
89
+ settings: settingsSchema.optional()
90
+ });
91
+ const updateSettingsRequestSchema = object({
92
+ digestFrequency: digestFrequencySchema.optional(),
93
+ topicPreferences: array(topicPreferenceSchema).optional()
94
+ });
95
+ const updateSettingsResponseSchema = object({
96
+ ok: boolean(),
97
+ error: string().optional(),
98
+ settings: settingsSchema.optional()
99
+ });
100
+ const digestRunRequestSchema = object({
101
+ force: boolean().optional()
102
+ });
103
+ object({
104
+ ok: boolean(),
105
+ error: string().optional(),
106
+ sent: boolean().optional(),
107
+ skippedReason: string().optional()
108
+ });
109
+ const toIso = (value) => value instanceof Date ? value.toISOString() : void 0;
110
+ const buildDisabledTopics = (settings, key) => {
111
+ const raw = settings?.topicPreferences;
112
+ if (!Array.isArray(raw) || raw.length === 0) return [];
113
+ return raw.map((pref) => {
114
+ if (!pref || typeof pref !== "object") return null;
115
+ const topic = typeof pref.topic === "string" ? pref.topic.trim() : "";
116
+ if (!topic) return null;
117
+ const enabled = pref[key] === true;
118
+ return enabled ? null : topic;
119
+ }).filter((topic) => Boolean(topic));
120
+ };
121
+ const listNotifications = async (payload, ctx) => {
122
+ const session = getSessionUser(ctx);
123
+ if (!session) {
124
+ return { ok: false, error: "unauthorized" };
125
+ }
126
+ const parsed = listRequestSchema.safeParse(payload);
127
+ if (!parsed.success) {
128
+ ctx.res.status(400);
129
+ return { ok: false, error: "invalid_payload" };
130
+ }
131
+ const { userId } = session;
132
+ const includeArchived = parsed.data.includeArchived === true;
133
+ const unreadOnly = parsed.data.unreadOnly === true;
134
+ const limit = parsed.data.limit ?? 50;
135
+ const markSeen = parsed.data.markSeen === true;
136
+ const SettingsModel = await loadModel("RBNotificationSettings", ctx);
137
+ const settings = await SettingsModel.findOne({ userId }).lean();
138
+ const disabledTopics = buildDisabledTopics(settings, "inApp");
139
+ const NotificationModel = await loadModel("RBNotification", ctx);
140
+ const query = { userId };
141
+ if (!includeArchived) {
142
+ query.archivedAt = { $exists: false };
143
+ }
144
+ if (unreadOnly) {
145
+ query.readAt = { $exists: false };
146
+ }
147
+ if (disabledTopics.length > 0) {
148
+ query.topic = { $nin: disabledTopics };
149
+ }
150
+ const notifications = await NotificationModel.find(query).sort({ createdAt: -1 }).limit(limit).lean();
151
+ const unseenQuery = {
152
+ userId,
153
+ archivedAt: { $exists: false },
154
+ seenAt: { $exists: false }
155
+ };
156
+ if (disabledTopics.length > 0) {
157
+ unseenQuery.topic = { $nin: disabledTopics };
158
+ }
159
+ const unreadQuery = {
160
+ userId,
161
+ archivedAt: { $exists: false },
162
+ readAt: { $exists: false }
163
+ };
164
+ if (disabledTopics.length > 0) {
165
+ unreadQuery.topic = { $nin: disabledTopics };
166
+ }
167
+ const [unreadCount, unseenCount] = await Promise.all([
168
+ NotificationModel.countDocuments(unreadQuery),
169
+ NotificationModel.countDocuments(unseenQuery)
170
+ ]);
171
+ const now = markSeen ? /* @__PURE__ */ new Date() : null;
172
+ if (now && unseenCount > 0) {
173
+ await NotificationModel.updateMany(unseenQuery, { $set: { seenAt: now } });
174
+ }
175
+ return listResponseSchema.parse({
176
+ ok: true,
177
+ notifications: notifications.map((n) => ({
178
+ id: String(n._id),
179
+ topic: typeof n.topic === "string" ? n.topic : void 0,
180
+ title: typeof n.title === "string" ? n.title : "",
181
+ body: typeof n.body === "string" ? n.body : void 0,
182
+ url: typeof n.url === "string" ? n.url : void 0,
183
+ createdAt: toIso(n.createdAt) ?? (/* @__PURE__ */ new Date()).toISOString(),
184
+ seenAt: toIso(n.seenAt) ?? (now && !n.archivedAt && !n.seenAt ? now.toISOString() : void 0),
185
+ readAt: toIso(n.readAt),
186
+ archivedAt: toIso(n.archivedAt),
187
+ metadata: typeof n.metadata === "object" && n.metadata !== null ? n.metadata : void 0
188
+ })),
189
+ unreadCount,
190
+ unseenCount: now ? 0 : unseenCount
191
+ });
192
+ };
193
+ const createNotificationForCurrentUser = async (payload, ctx) => {
194
+ const session = getSessionUser(ctx);
195
+ if (!session) {
196
+ return { ok: false, error: "unauthorized" };
197
+ }
198
+ const parsed = createRequestSchema.safeParse(payload);
199
+ if (!parsed.success) {
200
+ ctx.res.status(400);
201
+ return { ok: false, error: "invalid_payload" };
202
+ }
203
+ const created = await createNotification(ctx, {
204
+ userId: session.userId,
205
+ topic: parsed.data.topic,
206
+ title: parsed.data.title,
207
+ body: parsed.data.body,
208
+ url: parsed.data.url,
209
+ metadata: parsed.data.metadata
210
+ });
211
+ return createResponseSchema.parse({ ok: true, id: created.id });
212
+ };
213
+ const markRead = async (_payload, ctx) => {
214
+ const session = getSessionUser(ctx);
215
+ if (!session) {
216
+ return { ok: false, error: "unauthorized" };
217
+ }
218
+ const notificationId = typeof ctx.req.params.notificationId === "string" ? ctx.req.params.notificationId.trim() : "";
219
+ if (!notificationId) {
220
+ ctx.res.status(400);
221
+ return { ok: false, error: "missing_notification_id" };
222
+ }
223
+ const NotificationModel = await loadModel("RBNotification", ctx);
224
+ const now = /* @__PURE__ */ new Date();
225
+ try {
226
+ await NotificationModel.updateOne(
227
+ { _id: notificationId, userId: session.userId, archivedAt: { $exists: false } },
228
+ { $set: { readAt: now, seenAt: now } }
229
+ );
230
+ } catch {
231
+ ctx.res.status(400);
232
+ return { ok: false, error: "invalid_notification_id" };
233
+ }
234
+ return { ok: true };
235
+ };
236
+ const markAllRead = async (_payload, ctx) => {
237
+ const session = getSessionUser(ctx);
238
+ if (!session) {
239
+ return { ok: false, error: "unauthorized" };
240
+ }
241
+ const SettingsModel = await loadModel("RBNotificationSettings", ctx);
242
+ const settings = await SettingsModel.findOne({ userId: session.userId }).lean();
243
+ const disabledTopics = buildDisabledTopics(settings, "inApp");
244
+ const NotificationModel = await loadModel("RBNotification", ctx);
245
+ const query = {
246
+ userId: session.userId,
247
+ archivedAt: { $exists: false },
248
+ readAt: { $exists: false }
249
+ };
250
+ if (disabledTopics.length > 0) {
251
+ query.topic = { $nin: disabledTopics };
252
+ }
253
+ const now = /* @__PURE__ */ new Date();
254
+ await NotificationModel.updateMany(query, { $set: { readAt: now, seenAt: now } });
255
+ return { ok: true };
256
+ };
257
+ const archiveNotification = async (_payload, ctx) => {
258
+ const session = getSessionUser(ctx);
259
+ if (!session) {
260
+ return { ok: false, error: "unauthorized" };
261
+ }
262
+ const notificationId = typeof ctx.req.params.notificationId === "string" ? ctx.req.params.notificationId.trim() : "";
263
+ if (!notificationId) {
264
+ ctx.res.status(400);
265
+ return { ok: false, error: "missing_notification_id" };
266
+ }
267
+ const NotificationModel = await loadModel("RBNotification", ctx);
268
+ try {
269
+ await NotificationModel.updateOne(
270
+ { _id: notificationId, userId: session.userId, archivedAt: { $exists: false } },
271
+ { $set: { archivedAt: /* @__PURE__ */ new Date() } }
272
+ );
273
+ } catch {
274
+ ctx.res.status(400);
275
+ return { ok: false, error: "invalid_notification_id" };
276
+ }
277
+ return { ok: true };
278
+ };
279
+ const getSettings = async (_payload, ctx) => {
280
+ const session = getSessionUser(ctx);
281
+ if (!session) {
282
+ return { ok: false, error: "unauthorized" };
283
+ }
284
+ const SettingsModel = await loadModel("RBNotificationSettings", ctx);
285
+ const settings = await SettingsModel.findOne({ userId: session.userId }).lean();
286
+ const digestFrequencyRaw = typeof settings?.digestFrequency === "string" ? settings.digestFrequency : "weekly";
287
+ const digestFrequency = digestFrequencyRaw === "off" || digestFrequencyRaw === "daily" || digestFrequencyRaw === "weekly" ? digestFrequencyRaw : "weekly";
288
+ const topicPreferences = Array.isArray(settings?.topicPreferences) ? settings.topicPreferences.map((pref) => ({
289
+ topic: typeof pref.topic === "string" ? pref.topic : "",
290
+ inApp: pref.inApp === true,
291
+ emailDigest: pref.emailDigest === true,
292
+ push: pref.push === true
293
+ })).filter((pref) => pref.topic.length > 0) : [];
294
+ return settingsResponseSchema.parse({
295
+ ok: true,
296
+ settings: {
297
+ digestFrequency,
298
+ topicPreferences,
299
+ lastDigestSentAt: toIso(settings?.lastDigestSentAt)
300
+ }
301
+ });
302
+ };
303
+ const updateSettings = async (payload, ctx) => {
304
+ const session = getSessionUser(ctx);
305
+ if (!session) {
306
+ return { ok: false, error: "unauthorized" };
307
+ }
308
+ const parsed = updateSettingsRequestSchema.safeParse(payload);
309
+ if (!parsed.success) {
310
+ ctx.res.status(400);
311
+ return { ok: false, error: "invalid_payload" };
312
+ }
313
+ const SettingsModel = await loadModel("RBNotificationSettings", ctx);
314
+ const nextValues = {};
315
+ if (parsed.data.digestFrequency) {
316
+ nextValues.digestFrequency = parsed.data.digestFrequency;
317
+ }
318
+ if (parsed.data.topicPreferences) {
319
+ const seen = /* @__PURE__ */ new Set();
320
+ const next = parsed.data.topicPreferences.map((pref) => ({
321
+ topic: pref.topic.trim(),
322
+ inApp: pref.inApp,
323
+ emailDigest: pref.emailDigest,
324
+ push: pref.push
325
+ })).filter((pref) => pref.topic.length > 0).filter((pref) => {
326
+ if (seen.has(pref.topic)) return false;
327
+ seen.add(pref.topic);
328
+ return true;
329
+ });
330
+ nextValues.topicPreferences = next;
331
+ }
332
+ const ops = {
333
+ $setOnInsert: { userId: session.userId }
334
+ };
335
+ if (Object.keys(nextValues).length > 0) {
336
+ ops.$set = nextValues;
337
+ }
338
+ const settings = await SettingsModel.findOneAndUpdate(
339
+ { userId: session.userId },
340
+ ops,
341
+ { upsert: true, new: true, setDefaultsOnInsert: true }
342
+ ).lean();
343
+ const digestFrequencyRaw = typeof settings?.digestFrequency === "string" ? settings.digestFrequency : "weekly";
344
+ const digestFrequency = digestFrequencyRaw === "off" || digestFrequencyRaw === "daily" || digestFrequencyRaw === "weekly" ? digestFrequencyRaw : "weekly";
345
+ const topicPreferences = Array.isArray(settings?.topicPreferences) ? settings.topicPreferences.map((pref) => ({
346
+ topic: typeof pref.topic === "string" ? pref.topic : "",
347
+ inApp: pref.inApp === true,
348
+ emailDigest: pref.emailDigest === true,
349
+ push: pref.push === true
350
+ })).filter((pref) => pref.topic.length > 0) : [];
351
+ return updateSettingsResponseSchema.parse({
352
+ ok: true,
353
+ settings: {
354
+ digestFrequency,
355
+ topicPreferences,
356
+ lastDigestSentAt: toIso(settings?.lastDigestSentAt)
357
+ }
358
+ });
359
+ };
360
+ const runDigest = async (payload, ctx) => {
361
+ const session = getSessionUser(ctx);
362
+ if (!session) {
363
+ return { ok: false, error: "unauthorized" };
364
+ }
365
+ const parsed = digestRunRequestSchema.safeParse(payload);
366
+ if (!parsed.success) {
367
+ ctx.res.status(400);
368
+ return { ok: false, error: "invalid_payload" };
369
+ }
370
+ const result = await sendNotificationsDigestForUser(ctx, {
371
+ userId: session.userId,
372
+ force: parsed.data.force === true
373
+ });
374
+ if (!result.ok) {
375
+ ctx.res.status(500);
376
+ return { ok: false, error: result.error };
377
+ }
378
+ return {
379
+ ok: true,
380
+ sent: result.sent,
381
+ ...result.skippedReason ? { skippedReason: result.skippedReason } : {}
382
+ };
383
+ };
384
+ const handler = (api) => {
385
+ api.post(ListRoute, listNotifications);
386
+ api.post(CreateRoute, createNotificationForCurrentUser);
387
+ api.post(MarkReadRoute, markRead);
388
+ api.post(MarkAllReadRoute, markAllRead);
389
+ api.post(ArchiveRoute, archiveNotification);
390
+ api.get(SettingsRoute, getSettings);
391
+ api.put(SettingsRoute, updateSettings);
392
+ api.post(DigestRunRoute, runDigest);
393
+ };
394
+ export {
395
+ handler as default
396
+ };
@@ -1,6 +1,6 @@
1
1
  import { getTenantFilesystemDb } from "@rpcbase/db";
2
2
  import { ObjectId, GridFSBucket } from "mongodb";
3
- import { g as getTenantId, c as getBucketName } from "./shared-8XhCreJo.js";
3
+ import { g as getTenantId, c as getBucketName } from "./shared-Chfrv8o6.js";
4
4
  const deleteFile = async (_payload, ctx) => {
5
5
  const tenantId = getTenantId(ctx);
6
6
  if (!tenantId) {
@@ -1,5 +1,5 @@
1
1
  import { loadModel, ZRBRtsChangeOp } from "@rpcbase/db";
2
- import { o as object, a as array, s as string, n as number, b as boolean, _ as _enum } from "./schemas-CyxqObur.js";
2
+ import { o as object, a as array, s as string, n as number, b as boolean, _ as _enum } from "./schemas-DI7ewltq.js";
3
3
  const Route = "/api/rb/rts/changes";
4
4
  const requestSchema = object({
5
5
  sinceSeq: number().int().min(0).default(0),
@@ -22,15 +22,15 @@ const getTenantId = (ctx) => {
22
22
  const raw = ctx.req.query?.["rb-tenant-id"];
23
23
  const queryTenantId = Array.isArray(raw) ? raw[0] : raw;
24
24
  if (typeof queryTenantId === "string" && queryTenantId.trim()) return queryTenantId.trim();
25
- const sessionTenantId = ctx.req.session?.user?.current_tenant_id;
25
+ const sessionTenantId = ctx.req.session?.user?.currentTenantId;
26
26
  if (typeof sessionTenantId === "string" && sessionTenantId.trim()) return sessionTenantId.trim();
27
27
  return null;
28
28
  };
29
29
  const ensureAuthorized = (ctx, tenantId) => {
30
30
  const userId = ctx.req.session?.user?.id;
31
31
  if (!userId) return null;
32
- const signedInTenants = ctx.req.session?.user?.signed_in_tenants;
33
- const currentTenantId = ctx.req.session?.user?.current_tenant_id;
32
+ const signedInTenants = ctx.req.session?.user?.signedInTenants;
33
+ const currentTenantId = ctx.req.session?.user?.currentTenantId;
34
34
  const hasTenantAccessFromList = Array.isArray(signedInTenants) && signedInTenants.includes(tenantId);
35
35
  const normalizedCurrentTenantId = typeof currentTenantId === "string" ? currentTenantId.trim() : "";
36
36
  const hasTenantAccessFromCurrent = Boolean(normalizedCurrentTenantId) && normalizedCurrentTenantId === tenantId;
@@ -41,7 +41,7 @@ const getModelCtx = (_ctx, tenantId) => ({
41
41
  req: {
42
42
  session: {
43
43
  user: {
44
- current_tenant_id: tenantId
44
+ currentTenantId: tenantId
45
45
  }
46
46
  }
47
47
  }
@@ -1,8 +1,8 @@
1
1
  import { loadModel, getTenantFilesystemDb } from "@rpcbase/db";
2
2
  import { GridFSBucket, ObjectId } from "mongodb";
3
- import { g as getTenantId, a as getModelCtx, b as getOwnershipSelector, e as ensureUploadIndexes, c as getBucketName, d as getUserId, f as getChunkSizeBytes, h as getSessionTtlMs, i as computeSha256Hex, t as toBufferPayload, n as normalizeSha256Hex, j as getMaxClientUploadBytesPerSecond, k as getRawBodyLimitBytes } from "./shared-8XhCreJo.js";
3
+ import { g as getTenantId, a as getModelCtx, b as getOwnershipSelector, e as ensureUploadIndexes, c as getBucketName, d as getUserId, f as getChunkSizeBytes, h as getSessionTtlMs, i as computeSha256Hex, t as toBufferPayload, n as normalizeSha256Hex, j as getMaxClientUploadBytesPerSecond, k as getRawBodyLimitBytes } from "./shared-Chfrv8o6.js";
4
4
  import { randomBytes } from "node:crypto";
5
- import { o as object, n as number, s as string, b as boolean, a as array, _ as _enum } from "./schemas-CyxqObur.js";
5
+ import { o as object, n as number, s as string, b as boolean, a as array, _ as _enum } from "./schemas-DI7ewltq.js";
6
6
  const waitForStreamFinished = async (stream) => new Promise((resolve, reject) => {
7
7
  stream.once("finish", resolve);
8
8
  stream.once("error", reject);
@@ -137,8 +137,8 @@ const parseUpgradeMeta = async ({
137
137
  if (!sessionUserId) {
138
138
  throw new Error("Not signed in (missing session.user.id)");
139
139
  }
140
- const signedInTenants = sessionUser?.signed_in_tenants;
141
- const currentTenantId = sessionUser?.current_tenant_id;
140
+ const signedInTenants = sessionUser?.signedInTenants;
141
+ const currentTenantId = sessionUser?.currentTenantId;
142
142
  if (Array.isArray(signedInTenants) && signedInTenants.length > 0) {
143
143
  if (!signedInTenants.includes(tenantId)) {
144
144
  throw new Error("Tenant not authorized for this session");
@@ -164,7 +164,7 @@ const getTenantModel = async (tenantId, modelName) => {
164
164
  req: {
165
165
  session: {
166
166
  user: {
167
- current_tenant_id: tenantId
167
+ currentTenantId: tenantId
168
168
  }
169
169
  }
170
170
  }