@vritti/api-sdk 0.2.3 → 0.2.5

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/dist/index.cjs CHANGED
@@ -18,6 +18,7 @@ var __copyProps = (to, from, except, desc2) => {
18
18
  }
19
19
  return to;
20
20
  };
21
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
21
22
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
23
  // If the importer is in node compatibility mode or this is not an ESM
23
24
  // file that has been converted to a CommonJS file using a Babel-
@@ -41,7 +42,14 @@ __export(index_exports, {
41
42
  ConflictException: () => ConflictException,
42
43
  CookieDomain: () => CookieDomain,
43
44
  CorrelationIdMiddleware: () => CorrelationIdMiddleware,
45
+ CreateDataTableViewDto: () => CreateDataTableViewDto,
46
+ CreateResponseDto: () => CreateResponseDto,
47
+ DATA_TABLE_VIEWS_TABLE: () => DATA_TABLE_VIEWS_TABLE,
44
48
  DEFAULT_CORRELATION_HEADER: () => DEFAULT_CORRELATION_HEADER,
49
+ DataTableModule: () => DataTableModule,
50
+ DataTableStateService: () => DataTableStateService,
51
+ DataTableViewDto: () => DataTableViewDto,
52
+ DataTableViewsService: () => DataTableViewsService,
45
53
  DatabaseModule: () => DatabaseModule,
46
54
  EmailModule: () => EmailModule,
47
55
  EmailService: () => EmailService,
@@ -51,6 +59,8 @@ __export(index_exports, {
51
59
  HttpExceptionFilter: () => HttpExceptionFilter,
52
60
  HttpLoggerInterceptor: () => HttpLoggerInterceptor,
53
61
  HttpProblemException: () => HttpProblemException,
62
+ ImportResponseDto: () => ImportResponseDto,
63
+ ImportSummaryDto: () => ImportSummaryDto,
54
64
  InternalServerErrorException: () => InternalServerErrorException,
55
65
  JwtAuthService: () => JwtAuthService,
56
66
  LOGGER_MODULE_OPTIONS: () => LOGGER_MODULE_OPTIONS,
@@ -60,40 +70,44 @@ __export(index_exports, {
60
70
  NotAcceptableException: () => NotAcceptableException,
61
71
  NotFoundException: () => NotFoundException,
62
72
  NotImplementedException: () => NotImplementedException,
63
- Onboarding: () => Onboarding,
64
73
  PayloadTooLargeException: () => PayloadTooLargeException,
65
74
  PrimaryBaseRepository: () => PrimaryBaseRepository,
66
75
  PrimaryDatabaseService: () => PrimaryDatabaseService,
67
76
  Public: () => Public,
68
- RESET_KEY: () => RESET_KEY,
77
+ REQUIRE_SESSION_KEY: () => REQUIRE_SESSION_KEY,
69
78
  RedisCacheProvider: () => RedisCacheProvider,
70
79
  RefreshCookieOptions: () => RefreshCookieOptions,
71
80
  RefreshTokenCookie: () => RefreshTokenCookie,
81
+ RenameDataTableViewDto: () => RenameDataTableViewDto,
72
82
  RequestTimeoutException: () => RequestTimeoutException,
73
- Reset: () => Reset,
83
+ RequireSession: () => RequireSession,
74
84
  RootModule: () => RootModule,
75
85
  SKIP_CSRF_KEY: () => SKIP_CSRF_KEY,
76
86
  SelectOptionsQueryDto: () => SelectOptionsQueryDto,
77
87
  ServiceUnavailableException: () => ServiceUnavailableException,
78
88
  SessionData: () => SessionData,
79
89
  SkipCsrf: () => SkipCsrf,
90
+ Subdomain: () => Subdomain,
80
91
  SuccessResponseDto: () => SuccessResponseDto,
81
92
  TableResponseDto: () => TableResponseDto,
82
- Tenant: () => Tenant,
83
- TenantBaseRepository: () => TenantBaseRepository,
84
- TenantContextService: () => TenantContextService,
85
- TenantDatabaseService: () => TenantDatabaseService,
93
+ ToggleShareDataTableViewDto: () => ToggleShareDataTableViewDto,
86
94
  TokenType: () => TokenType,
87
95
  TooManyRequestsException: () => TooManyRequestsException,
88
96
  UnauthorizedException: () => UnauthorizedException,
89
97
  UnprocessableEntityException: () => UnprocessableEntityException,
90
98
  UnsupportedMediaTypeException: () => UnsupportedMediaTypeException,
99
+ UpdateDataTableViewDto: () => UpdateDataTableViewDto,
100
+ UploadedFile: () => UploadedFile,
101
+ UpsertDataTableStateDto: () => UpsertDataTableStateDto,
91
102
  UserId: () => UserId,
103
+ ValidatedRowDto: () => ValidatedRowDto,
92
104
  ValidationException: () => ValidationException,
93
105
  VrittiAuthGuard: () => VrittiAuthGuard,
94
106
  addCorrelationIdToResponse: () => addCorrelationIdToResponse,
95
107
  configureApiSdk: () => configureApiSdk,
96
108
  correlationStorage: () => correlationStorage,
109
+ dataTableViewsColumns: () => dataTableViewsColumns,
110
+ dataTableViewsIndexes: () => dataTableViewsIndexes,
97
111
  defineConfig: () => defineConfig,
98
112
  extractCountryFromPhone: () => extractCountryFromPhone,
99
113
  generateCorrelationId: () => generateCorrelationId,
@@ -117,7 +131,7 @@ module.exports = __toCommonJS(index_exports);
117
131
 
118
132
  // src/auth/auth-config.module.ts
119
133
  var import_common26 = require("@nestjs/common");
120
- var import_config4 = require("@nestjs/config");
134
+ var import_config5 = require("@nestjs/config");
121
135
  var import_core3 = require("@nestjs/core");
122
136
  var import_jwt4 = require("@nestjs/jwt");
123
137
 
@@ -365,7 +379,10 @@ var defaultConfig = {
365
379
  guard: {
366
380
  tenantHeaderName: "x-tenant-id",
367
381
  authHeaderName: "authorization",
368
- tokenPrefix: "Bearer"
382
+ tokenPrefix: "Bearer",
383
+ defaultSessionTypes: [
384
+ "CLOUD"
385
+ ]
369
386
  }
370
387
  };
371
388
  var currentConfig = {
@@ -553,10 +570,10 @@ var import_config2 = require("@nestjs/config");
553
570
  var import_core2 = require("@nestjs/core");
554
571
  var import_jwt = require("@nestjs/jwt");
555
572
 
556
- // src/auth/decorators/reset.decorator.ts
573
+ // src/auth/decorators/require-session.decorator.ts
557
574
  var import_common22 = require("@nestjs/common");
558
- var RESET_KEY = "isReset";
559
- var Reset = /* @__PURE__ */ __name(() => (0, import_common22.SetMetadata)(RESET_KEY, true), "Reset");
575
+ var REQUIRE_SESSION_KEY = "requiredSessionTypes";
576
+ var RequireSession = /* @__PURE__ */ __name((...types) => (0, import_common22.SetMetadata)(REQUIRE_SESSION_KEY, types), "RequireSession");
560
577
 
561
578
  // src/auth/decorators/skip-csrf.decorator.ts
562
579
  var import_common23 = require("@nestjs/common");
@@ -620,17 +637,13 @@ var VrittiAuthGuard = class _VrittiAuthGuard {
620
637
  if (isPublic) {
621
638
  return true;
622
639
  }
623
- const isOnboarding = this.reflector.getAllAndOverride("isOnboarding", [
624
- context.getHandler(),
625
- context.getClass()
626
- ]);
627
- const isReset = this.reflector.getAllAndOverride(RESET_KEY, [
640
+ const requiredSessionTypes = this.reflector.getAllAndOverride(REQUIRE_SESSION_KEY, [
628
641
  context.getHandler(),
629
642
  context.getClass()
630
643
  ]);
631
644
  const isSseEndpoint = this.reflector.get(import_constants.SSE_METADATA, context.getHandler());
632
645
  if (isSseEndpoint) {
633
- return this.handleSseAuth(request, isOnboarding);
646
+ return this.handleSseAuth(request, requiredSessionTypes);
634
647
  }
635
648
  try {
636
649
  const accessToken = this.requestService.getAccessToken();
@@ -642,14 +655,10 @@ var VrittiAuthGuard = class _VrittiAuthGuard {
642
655
  throw new import_common24.UnauthorizedException("Invalid token type");
643
656
  }
644
657
  this.validateRefreshTokenBinding(decodedAccessToken);
645
- if (isOnboarding && decodedAccessToken.sessionType !== "ONBOARDING") {
646
- throw new import_common24.UnauthorizedException("This endpoint requires an onboarding session");
647
- }
648
- if (isReset && decodedAccessToken.sessionType !== "RESET") {
649
- throw new import_common24.UnauthorizedException("This endpoint requires a reset session");
650
- }
651
- if (!isOnboarding && !isReset && (decodedAccessToken.sessionType === "ONBOARDING" || decodedAccessToken.sessionType === "RESET")) {
652
- throw new import_common24.UnauthorizedException(`${decodedAccessToken.sessionType} sessions cannot access this endpoint`);
658
+ const sessionType = decodedAccessToken.sessionType;
659
+ const allowed = requiredSessionTypes ?? getConfig().guard.defaultSessionTypes;
660
+ if (!allowed.includes(sessionType)) {
661
+ throw new import_common24.UnauthorizedException(`${sessionType} sessions cannot access this endpoint`);
653
662
  }
654
663
  request.sessionInfo = {
655
664
  userId: decodedAccessToken.userId,
@@ -698,7 +707,7 @@ var VrittiAuthGuard = class _VrittiAuthGuard {
698
707
  }
699
708
  }
700
709
  // Authenticates SSE connections using the refresh token httpOnly cookie
701
- handleSseAuth(request, isOnboarding) {
710
+ handleSseAuth(request, requiredSessionTypes) {
702
711
  const refreshToken = this.requestService.getRefreshToken();
703
712
  if (!refreshToken) {
704
713
  throw new import_common24.UnauthorizedException("Authentication required");
@@ -712,8 +721,9 @@ var VrittiAuthGuard = class _VrittiAuthGuard {
712
721
  if (decoded.tokenType !== "refresh") {
713
722
  throw new import_common24.UnauthorizedException("Invalid token type");
714
723
  }
715
- if (isOnboarding && decoded.sessionType !== "ONBOARDING") {
716
- throw new import_common24.UnauthorizedException("This endpoint requires an onboarding session");
724
+ const allowed = requiredSessionTypes ?? getConfig().guard.defaultSessionTypes;
725
+ if (!allowed.includes(decoded.sessionType)) {
726
+ throw new import_common24.UnauthorizedException(`${decoded.sessionType} sessions cannot access this endpoint`);
717
727
  }
718
728
  request.sessionInfo = {
719
729
  userId: decoded.userId,
@@ -777,7 +787,7 @@ VrittiAuthGuard = _ts_decorate3([
777
787
 
778
788
  // src/auth/services/jwt-auth.service.ts
779
789
  var import_common25 = require("@nestjs/common");
780
- var import_config3 = require("@nestjs/config");
790
+ var import_config4 = require("@nestjs/config");
781
791
  var import_jwt2 = require("@nestjs/jwt");
782
792
 
783
793
  // src/utils/time.utils.ts
@@ -893,7 +903,7 @@ JwtAuthService = _ts_decorate4([
893
903
  _ts_metadata3("design:type", Function),
894
904
  _ts_metadata3("design:paramtypes", [
895
905
  typeof import_jwt2.JwtService === "undefined" ? Object : import_jwt2.JwtService,
896
- typeof import_config3.ConfigService === "undefined" ? Object : import_config3.ConfigService
906
+ typeof import_config4.ConfigService === "undefined" ? Object : import_config4.ConfigService
897
907
  ])
898
908
  ], JwtAuthService);
899
909
 
@@ -914,14 +924,14 @@ var AuthConfigModule = class _AuthConfigModule {
914
924
  return {
915
925
  module: _AuthConfigModule,
916
926
  imports: [
917
- import_config4.ConfigModule,
927
+ import_config5.ConfigModule,
918
928
  RequestModule,
919
929
  import_jwt4.JwtModule.registerAsync({
920
930
  imports: [
921
- import_config4.ConfigModule
931
+ import_config5.ConfigModule
922
932
  ],
923
933
  inject: [
924
- import_config4.ConfigService
934
+ import_config5.ConfigService
925
935
  ],
926
936
  useFactory: /* @__PURE__ */ __name((config) => ({
927
937
  secret: config.get("JWT_SECRET"),
@@ -975,17 +985,13 @@ var CookieDomain = (0, import_common28.createParamDecorator)((_data, ctx) => {
975
985
  return domain.endsWith(`.${baseDomain}`) ? domain : baseDomain;
976
986
  });
977
987
 
978
- // src/auth/decorators/onboarding.decorator.ts
979
- var import_common29 = require("@nestjs/common");
980
- var Onboarding = /* @__PURE__ */ __name(() => (0, import_common29.SetMetadata)("isOnboarding", true), "Onboarding");
981
-
982
988
  // src/auth/decorators/public.decorator.ts
983
- var import_common30 = require("@nestjs/common");
984
- var Public = /* @__PURE__ */ __name(() => (0, import_common30.SetMetadata)("isPublic", true), "Public");
989
+ var import_common29 = require("@nestjs/common");
990
+ var Public = /* @__PURE__ */ __name(() => (0, import_common29.SetMetadata)("isPublic", true), "Public");
985
991
 
986
992
  // src/auth/decorators/refresh-cookie-options.decorator.ts
987
- var import_common31 = require("@nestjs/common");
988
- var RefreshCookieOptions = (0, import_common31.createParamDecorator)((_data, ctx) => {
993
+ var import_common30 = require("@nestjs/common");
994
+ var RefreshCookieOptions = (0, import_common30.createParamDecorator)((_data, ctx) => {
989
995
  const request = ctx.switchToHttp().getRequest();
990
996
  const forwarded = request.headers["x-forwarded-host"];
991
997
  const raw = Array.isArray(forwarded) ? forwarded[0] : forwarded;
@@ -995,14 +1001,32 @@ var RefreshCookieOptions = (0, import_common31.createParamDecorator)((_data, ctx
995
1001
  });
996
1002
 
997
1003
  // src/auth/decorators/refresh-token-cookie.decorator.ts
998
- var import_common32 = require("@nestjs/common");
999
- var RefreshTokenCookie = (0, import_common32.createParamDecorator)((_data, ctx) => {
1004
+ var import_common31 = require("@nestjs/common");
1005
+ var RefreshTokenCookie = (0, import_common31.createParamDecorator)((_data, ctx) => {
1000
1006
  const request = ctx.switchToHttp().getRequest();
1001
1007
  const cookies = request.cookies ?? {};
1002
1008
  const config = getConfig();
1003
1009
  return cookies[config.cookie.refreshCookieName];
1004
1010
  });
1005
1011
 
1012
+ // src/auth/decorators/subdomain.decorator.ts
1013
+ var import_common32 = require("@nestjs/common");
1014
+ var Subdomain = (0, import_common32.createParamDecorator)((_data, ctx) => {
1015
+ const request = ctx.switchToHttp().getRequest();
1016
+ const origin = request.headers.origin;
1017
+ if (origin) {
1018
+ try {
1019
+ const url = new URL(origin);
1020
+ return url.hostname.split(".")[0];
1021
+ } catch {
1022
+ }
1023
+ }
1024
+ const forwarded = request.headers["x-forwarded-host"];
1025
+ const host = Array.isArray(forwarded) ? forwarded[0] : forwarded;
1026
+ if (host) return host.split(".")[0];
1027
+ return void 0;
1028
+ });
1029
+
1006
1030
  // src/auth/decorators/session-data.decorator.ts
1007
1031
  var import_common33 = require("@nestjs/common");
1008
1032
  var SessionData = (0, import_common33.createParamDecorator)((_data, ctx) => {
@@ -1031,7 +1055,7 @@ var UserId = (0, import_common34.createParamDecorator)((_data, ctx) => {
1031
1055
 
1032
1056
  // src/cache/cache.module.ts
1033
1057
  var import_common37 = require("@nestjs/common");
1034
- var import_config9 = require("@nestjs/config");
1058
+ var import_config10 = require("@nestjs/config");
1035
1059
 
1036
1060
  // src/cache/cache.service.ts
1037
1061
  var import_common35 = require("@nestjs/common");
@@ -1121,7 +1145,7 @@ CacheService = _ts_decorate6([
1121
1145
 
1122
1146
  // src/cache/providers/redis.provider.ts
1123
1147
  var import_common36 = require("@nestjs/common");
1124
- var import_config8 = require("@nestjs/config");
1148
+ var import_config9 = require("@nestjs/config");
1125
1149
  var import_ioredis = __toESM(require("ioredis"), 1);
1126
1150
  function _ts_decorate7(decorators, target, key, desc2) {
1127
1151
  var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
@@ -1196,7 +1220,7 @@ RedisCacheProvider = _ts_decorate7([
1196
1220
  (0, import_common36.Injectable)(),
1197
1221
  _ts_metadata5("design:type", Function),
1198
1222
  _ts_metadata5("design:paramtypes", [
1199
- typeof import_config8.ConfigService === "undefined" ? Object : import_config8.ConfigService
1223
+ typeof import_config9.ConfigService === "undefined" ? Object : import_config9.ConfigService
1200
1224
  ])
1201
1225
  ], RedisCacheProvider);
1202
1226
 
@@ -1216,7 +1240,7 @@ var CacheModule = class {
1216
1240
  CacheModule = _ts_decorate8([
1217
1241
  (0, import_common37.Module)({
1218
1242
  imports: [
1219
- import_config9.ConfigModule
1243
+ import_config10.ConfigModule
1220
1244
  ],
1221
1245
  providers: [
1222
1246
  RedisCacheProvider,
@@ -1235,7 +1259,7 @@ CacheModule = _ts_decorate8([
1235
1259
  ], CacheModule);
1236
1260
 
1237
1261
  // src/database/database.module.ts
1238
- var import_common41 = require("@nestjs/common");
1262
+ var import_common39 = require("@nestjs/common");
1239
1263
  var import_core4 = require("@nestjs/core");
1240
1264
 
1241
1265
  // src/database/constants.ts
@@ -1243,7 +1267,6 @@ var DATABASE_MODULE_OPTIONS = Symbol("DATABASE_MODULE_OPTIONS");
1243
1267
 
1244
1268
  // src/database/services/primary-database.service.ts
1245
1269
  var import_common38 = require("@nestjs/common");
1246
- var import_drizzle_orm = require("drizzle-orm");
1247
1270
  var import_node_postgres = require("drizzle-orm/node-postgres");
1248
1271
  var import_pg = require("pg");
1249
1272
  function _ts_decorate9(decorators, target, key, desc2) {
@@ -1271,11 +1294,8 @@ var PrimaryDatabaseService = class _PrimaryDatabaseService {
1271
1294
  logger = new import_common38.Logger(_PrimaryDatabaseService.name);
1272
1295
  pool = null;
1273
1296
  db = null;
1274
- tenantConfigCache = /* @__PURE__ */ new Map();
1275
- cacheTTL;
1276
1297
  constructor(options) {
1277
1298
  this.options = options;
1278
- this.cacheTTL = options.connectionCacheTTL || 3e5;
1279
1299
  }
1280
1300
  async onModuleInit() {
1281
1301
  if (this.options.primaryDb) {
@@ -1285,10 +1305,20 @@ var PrimaryDatabaseService = class _PrimaryDatabaseService {
1285
1305
  // Initializes connection to primary database using Drizzle
1286
1306
  async initializeDrizzleClient() {
1287
1307
  try {
1288
- const databaseUrl = this.buildPrimaryDbUrl();
1308
+ const { host, port = 5432, username, password, database, schema, sslMode = "require" } = this.options.primaryDb;
1289
1309
  this.pool = new import_pg.Pool({
1290
- connectionString: databaseUrl,
1291
- max: this.options.maxConnections || 10
1310
+ host,
1311
+ port,
1312
+ user: username,
1313
+ password,
1314
+ database,
1315
+ max: this.options.maxConnections || 10,
1316
+ ssl: sslMode === "disable" ? false : {
1317
+ rejectUnauthorized: sslMode !== "no-verify"
1318
+ },
1319
+ ...schema && {
1320
+ options: `-csearch_path=${schema}`
1321
+ }
1292
1322
  });
1293
1323
  this.logger.debug(`Schema keys passed to drizzle: [${Object.keys(this.options.drizzleSchema || {}).join(", ")}]`);
1294
1324
  this.logger.debug(`Relations keys passed to drizzle: [${Object.keys(this.options.drizzleRelations || {}).join(", ")}]`);
@@ -1299,110 +1329,13 @@ var PrimaryDatabaseService = class _PrimaryDatabaseService {
1299
1329
  });
1300
1330
  this.logger.debug(`Drizzle query keys after init: [${Object.keys(this.db.query || {}).join(", ")}]`);
1301
1331
  await this.pool.query("SELECT 1");
1302
- this.logger.log("Connected to primary database (tenant registry)");
1332
+ this.logger.log(`Connected to primary database (schema: ${schema ?? "public"})`);
1303
1333
  } catch (error) {
1304
1334
  this.logger.error("Failed to connect to primary database", error);
1305
- throw new import_common38.InternalServerErrorException("Failed to initialize tenant registry");
1306
- }
1307
- }
1308
- // Builds the PostgreSQL connection URL from primary database config properties
1309
- buildPrimaryDbUrl() {
1310
- if (!this.options.primaryDb) {
1311
- throw new Error("Primary database configuration not provided");
1312
- }
1313
- const { host, port = 5432, username, password, database, schema = "public", sslMode = "require" } = this.options.primaryDb;
1314
- let url = `postgresql://${username}:${encodeURIComponent(password)}@${host}:${port}/${database}`;
1315
- const params = new URLSearchParams();
1316
- if (schema) {
1317
- params.set("schema", schema);
1318
- }
1319
- params.set("sslmode", sslMode);
1320
- const queryString = params.toString();
1321
- if (queryString) {
1322
- url += `?${queryString}`;
1323
- }
1324
- this.logger.debug(`Primary DB connection URL: ${this.maskPassword(url)}`);
1325
- return url;
1326
- }
1327
- // Masks password in connection URL for safe logging
1328
- maskPassword(url) {
1329
- return url.replace(/:([^@]+)@/, ":****@");
1330
- }
1331
- // Retrieves tenant configuration by ID or subdomain, with in-memory caching
1332
- async getTenantInfo(tenantIdentifier) {
1333
- const cached = this.tenantConfigCache.get(tenantIdentifier);
1334
- if (cached) {
1335
- this.logger.debug(`Cache hit for tenant: ${tenantIdentifier}`);
1336
- return cached;
1337
- }
1338
- try {
1339
- if (!this.db) {
1340
- throw new Error("Primary database client not initialized");
1341
- }
1342
- this.logger.debug(`Querying primary database for tenant: ${tenantIdentifier}`);
1343
- const schema = this.options.drizzleSchema;
1344
- const { tenants, tenantDatabaseConfigs } = schema;
1345
- const result = await this.db.select().from(tenants).leftJoin(tenantDatabaseConfigs, (0, import_drizzle_orm.eq)(tenants.id, tenantDatabaseConfigs.tenantId)).where((0, import_drizzle_orm.or)((0, import_drizzle_orm.eq)(tenants.id, tenantIdentifier), (0, import_drizzle_orm.eq)(tenants.subdomain, tenantIdentifier))).limit(1);
1346
- if (!result.length) {
1347
- this.logger.warn(`Tenant not found: ${tenantIdentifier}`);
1348
- return null;
1349
- }
1350
- const row = result[0];
1351
- const tenant = row.tenants;
1352
- const config = row.tenant_database_configs;
1353
- if (tenant.status !== "ACTIVE") {
1354
- this.logger.warn(`Tenant not active: ${tenantIdentifier}`);
1355
- return null;
1356
- }
1357
- const info = {
1358
- id: tenant.id,
1359
- subdomain: tenant.subdomain,
1360
- type: tenant.dbType,
1361
- status: tenant.status,
1362
- // For SHARED tenants: schema name
1363
- schemaName: config?.dbSchema || void 0,
1364
- // For DEDICATED tenants: database configuration from TenantDatabaseConfig table
1365
- databaseName: config?.dbName || void 0,
1366
- databaseHost: config?.dbHost || void 0,
1367
- databasePort: config?.dbPort || void 0,
1368
- databaseUsername: config?.dbUsername ? this.decrypt(config.dbUsername) : void 0,
1369
- databasePassword: config?.dbPassword ? this.decrypt(config.dbPassword) : void 0,
1370
- databaseSslMode: config?.dbSslMode || void 0,
1371
- connectionPoolSize: config?.connectionPoolSize || void 0
1372
- };
1373
- this.cacheInfo(info);
1374
- return info;
1375
- } catch (error) {
1376
- this.logger.error(`Failed to fetch tenant info: ${tenantIdentifier}`, error);
1377
- throw new import_common38.InternalServerErrorException("Failed to resolve tenant");
1378
- }
1379
- }
1380
- // Caches tenant info by both ID and subdomain with TTL expiration
1381
- cacheInfo(info) {
1382
- this.tenantConfigCache.set(info.id, info);
1383
- this.tenantConfigCache.set(info.subdomain, info);
1384
- setTimeout(() => {
1385
- this.tenantConfigCache.delete(info.id);
1386
- this.tenantConfigCache.delete(info.subdomain);
1387
- this.logger.debug(`Cache expired for tenant: ${info.subdomain}`);
1388
- }, this.cacheTTL);
1389
- }
1390
- // Clears cached tenant info for the given ID or subdomain
1391
- clearTenantCache(tenantIdentifier) {
1392
- const config = this.tenantConfigCache.get(tenantIdentifier);
1393
- if (config) {
1394
- this.tenantConfigCache.delete(config.id);
1395
- this.tenantConfigCache.delete(config.subdomain);
1396
- this.logger.log(`Cleared cache for tenant: ${tenantIdentifier}`);
1335
+ throw new import_common38.InternalServerErrorException("Failed to initialize database connection");
1397
1336
  }
1398
1337
  }
1399
- // Clears all cached tenant configurations
1400
- clearAllCaches() {
1401
- const size = this.tenantConfigCache.size;
1402
- this.tenantConfigCache.clear();
1403
- this.logger.log(`Cleared ${size} cached tenant configs`);
1404
- }
1405
- // Returns the initialized Drizzle client, throwing if not yet initialized
1338
+ // Returns the initialized Drizzle client
1406
1339
  get drizzleClient() {
1407
1340
  if (!this.db) {
1408
1341
  throw new Error("Primary database client not initialized");
@@ -1413,10 +1346,6 @@ var PrimaryDatabaseService = class _PrimaryDatabaseService {
1413
1346
  get schema() {
1414
1347
  return this.options.drizzleSchema;
1415
1348
  }
1416
- // Decrypts a database credential value (placeholder for actual decryption)
1417
- decrypt(encrypted) {
1418
- return encrypted;
1419
- }
1420
1349
  async onModuleDestroy() {
1421
1350
  if (this.pool) {
1422
1351
  await this.pool.end();
@@ -1433,8 +1362,7 @@ PrimaryDatabaseService = _ts_decorate9([
1433
1362
  ])
1434
1363
  ], PrimaryDatabaseService);
1435
1364
 
1436
- // src/database/services/tenant-context.service.ts
1437
- var import_common39 = require("@nestjs/common");
1365
+ // src/database/database.module.ts
1438
1366
  function _ts_decorate10(decorators, target, key, desc2) {
1439
1367
  var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
1440
1368
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
@@ -1442,52 +1370,63 @@ function _ts_decorate10(decorators, target, key, desc2) {
1442
1370
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1443
1371
  }
1444
1372
  __name(_ts_decorate10, "_ts_decorate");
1445
- var TenantContextService = class {
1373
+ var DatabaseModule = class _DatabaseModule {
1446
1374
  static {
1447
- __name(this, "TenantContextService");
1448
- }
1449
- tenantInfo = null;
1450
- // Sets tenant info for this request, throwing if already set to prevent overwrites
1451
- setTenant(tenantInfo) {
1452
- if (this.tenantInfo) {
1453
- throw new Error("Tenant context already set for this request");
1454
- }
1455
- this.tenantInfo = tenantInfo;
1456
- }
1457
- // Returns the tenant info for this request, throwing if context is not set
1458
- getTenant() {
1459
- if (!this.tenantInfo) {
1460
- throw new import_common39.UnauthorizedException("Tenant context not set");
1461
- }
1462
- return this.tenantInfo;
1463
- }
1464
- // Returns true if tenant context has been set for this request
1465
- hasTenant() {
1466
- return this.tenantInfo !== null;
1467
- }
1468
- // Clears the tenant context (useful for RabbitMQ message handler cleanup)
1469
- clearTenant() {
1470
- this.tenantInfo = null;
1471
- }
1472
- // Returns the tenant ID or null if context is not set
1473
- getTenantIdSafe() {
1474
- return this.tenantInfo?.id ?? null;
1375
+ __name(this, "DatabaseModule");
1475
1376
  }
1476
- // Returns the tenant subdomain or null if context is not set
1477
- getTenantSubdomainSafe() {
1478
- return this.tenantInfo?.subdomain ?? null;
1377
+ // Configures the database module with a single primary connection
1378
+ static forServer(options) {
1379
+ const asyncProvider = {
1380
+ provide: DATABASE_MODULE_OPTIONS,
1381
+ useFactory: options.useFactory,
1382
+ inject: options.inject || []
1383
+ };
1384
+ return {
1385
+ module: _DatabaseModule,
1386
+ imports: [
1387
+ RequestModule
1388
+ ],
1389
+ providers: [
1390
+ {
1391
+ provide: import_core4.Reflector,
1392
+ useClass: import_core4.Reflector
1393
+ },
1394
+ asyncProvider,
1395
+ PrimaryDatabaseService
1396
+ ],
1397
+ exports: [
1398
+ PrimaryDatabaseService,
1399
+ asyncProvider
1400
+ ]
1401
+ };
1479
1402
  }
1480
1403
  };
1481
- TenantContextService = _ts_decorate10([
1482
- (0, import_common39.Injectable)({
1483
- scope: import_common39.Scope.REQUEST
1484
- })
1485
- ], TenantContextService);
1404
+ DatabaseModule = _ts_decorate10([
1405
+ (0, import_common39.Global)(),
1406
+ (0, import_common39.Module)({})
1407
+ ], DatabaseModule);
1486
1408
 
1487
- // src/database/services/tenant-database.service.ts
1409
+ // src/decorators/uploaded-file.decorator.ts
1488
1410
  var import_common40 = require("@nestjs/common");
1489
- var import_node_postgres2 = require("drizzle-orm/node-postgres");
1490
- var import_pg2 = require("pg");
1411
+ var UploadedFile = (0, import_common40.createParamDecorator)(async (_data, ctx) => {
1412
+ const request = ctx.switchToHttp().getRequest();
1413
+ const file = await request.file();
1414
+ if (!file) {
1415
+ throw new BadRequestException({
1416
+ label: "File Required",
1417
+ detail: "Please attach a file to your request."
1418
+ });
1419
+ }
1420
+ const buffer = await file.toBuffer();
1421
+ return {
1422
+ buffer,
1423
+ filename: file.filename,
1424
+ mimetype: file.mimetype
1425
+ };
1426
+ });
1427
+
1428
+ // src/database/dto/create-response.dto.ts
1429
+ var import_swagger = require("@nestjs/swagger");
1491
1430
  function _ts_decorate11(decorators, target, key, desc2) {
1492
1431
  var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
1493
1432
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
@@ -1499,161 +1438,33 @@ function _ts_metadata7(k, v) {
1499
1438
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1500
1439
  }
1501
1440
  __name(_ts_metadata7, "_ts_metadata");
1502
- function _ts_param4(paramIndex, decorator) {
1503
- return function(target, key) {
1504
- decorator(target, key, paramIndex);
1505
- };
1506
- }
1507
- __name(_ts_param4, "_ts_param");
1508
- var TenantDatabaseService = class _TenantDatabaseService {
1441
+ var CreateResponseDto = class {
1509
1442
  static {
1510
- __name(this, "TenantDatabaseService");
1511
- }
1512
- options;
1513
- tenantContext;
1514
- logger = new import_common40.Logger(_TenantDatabaseService.name);
1515
- clients = /* @__PURE__ */ new Map();
1516
- clientLastUsed = /* @__PURE__ */ new Map();
1517
- cleanupInterval;
1518
- constructor(options, tenantContext) {
1519
- this.options = options;
1520
- this.tenantContext = tenantContext;
1521
- this.startConnectionCleaner();
1522
- }
1523
- // Returns the Drizzle client scoped to the current tenant's database
1524
- get drizzleClient() {
1525
- return this.getDbClient();
1526
- }
1527
- // Returns the Drizzle schema passed in module options
1528
- get schema() {
1529
- return this.options.drizzleSchema;
1530
- }
1531
- // Returns a cached or new Drizzle client for the current tenant context
1532
- getDbClient() {
1533
- const tenant = this.tenantContext.getTenant();
1534
- const cacheKey = this.buildCacheKey(tenant);
1535
- const existing = this.clients.get(cacheKey);
1536
- if (existing) {
1537
- this.clientLastUsed.set(cacheKey, Date.now());
1538
- this.logger.debug(`Reusing cached connection: ${cacheKey}`);
1539
- return existing.db;
1540
- }
1541
- this.logger.log(`Creating new database connection: ${cacheKey}`);
1542
- const connection = this.createDbClientSync(tenant);
1543
- this.clients.set(cacheKey, connection);
1544
- this.clientLastUsed.set(cacheKey, Date.now());
1545
- return connection.db;
1546
- }
1547
- // Creates a new pool and Drizzle client for the given tenant
1548
- createDbClientSync(tenant) {
1549
- try {
1550
- const databaseUrl = this.buildTenantDbUrl(tenant);
1551
- const pool = new import_pg2.Pool({
1552
- connectionString: databaseUrl,
1553
- max: tenant.connectionPoolSize || this.options.maxConnections || 10
1554
- });
1555
- const db = (0, import_node_postgres2.drizzle)({
1556
- client: pool,
1557
- schema: this.options.drizzleSchema
1558
- });
1559
- this.logger.log(`Connected to database for tenant: ${tenant.subdomain}`);
1560
- return {
1561
- pool,
1562
- db
1563
- };
1564
- } catch (error) {
1565
- this.logger.error(`Failed to create database connection for tenant: ${tenant.subdomain}`, error);
1566
- throw new import_common40.InternalServerErrorException("Failed to connect to tenant database");
1567
- }
1568
- }
1569
- // Builds the PostgreSQL connection URL for a dedicated tenant database
1570
- buildTenantDbUrl(tenant) {
1571
- const { databaseHost, databasePort, databaseName, databaseUsername, databasePassword, databaseSslMode } = tenant;
1572
- if (!databaseHost || !databaseName || !databaseUsername) {
1573
- throw new Error(`Tenant ${tenant.subdomain} missing database configuration`);
1574
- }
1575
- const port = databasePort || 5432;
1576
- const sslMode = databaseSslMode || "require";
1577
- const connectionUrl = `postgresql://${databaseUsername}:${encodeURIComponent(databasePassword || "")}@${databaseHost}:${port}/${databaseName}?sslmode=${sslMode}`;
1578
- this.logger.debug(`Tenant connection URL: ${this.maskPassword(connectionUrl)}`);
1579
- return connectionUrl;
1580
- }
1581
- // Builds a cache key for connection pooling from tenant database coordinates
1582
- buildCacheKey(tenant) {
1583
- return `${tenant.type}:${tenant.databaseName}@${tenant.databaseHost}`;
1584
- }
1585
- // Starts a periodic interval to close idle database connections
1586
- startConnectionCleaner() {
1587
- const interval = this.options.connectionCacheTTL || 3e5;
1588
- this.cleanupInterval = setInterval(() => {
1589
- this.cleanupIdleConnections();
1590
- }, interval);
1591
- this.logger.log(`Connection cleanup scheduled every ${interval / 1e3} seconds`);
1592
- }
1593
- // Closes and removes connections that have been idle beyond the TTL
1594
- async cleanupIdleConnections() {
1595
- const now = Date.now();
1596
- const maxIdle = this.options.connectionCacheTTL || 3e5;
1597
- let cleaned = 0;
1598
- for (const [key, lastUsed] of this.clientLastUsed.entries()) {
1599
- if (now - lastUsed > maxIdle) {
1600
- const connection = this.clients.get(key);
1601
- if (connection) {
1602
- try {
1603
- await connection.pool.end();
1604
- this.logger.debug(`Cleaned up idle connection: ${key}`);
1605
- } catch (error) {
1606
- this.logger.error(`Error disconnecting idle client: ${key}`, error);
1607
- }
1608
- this.clients.delete(key);
1609
- this.clientLastUsed.delete(key);
1610
- cleaned++;
1611
- }
1612
- }
1613
- }
1614
- if (cleaned > 0) {
1615
- this.logger.log(`Cleaned up ${cleaned} idle connections`);
1616
- }
1617
- }
1618
- // Returns the current number of active pooled connections and their tenant keys
1619
- getPoolStats() {
1620
- return {
1621
- activeConnections: this.clients.size,
1622
- tenants: Array.from(this.clients.keys())
1623
- };
1624
- }
1625
- // Masks password in connection URL for safe logging
1626
- maskPassword(url) {
1627
- return url.replace(/:([^@]+)@/, ":****@");
1628
- }
1629
- async onModuleDestroy() {
1630
- if (this.cleanupInterval) {
1631
- clearInterval(this.cleanupInterval);
1632
- }
1633
- this.logger.log(`Disconnecting ${this.clients.size} database connections`);
1634
- const disconnectPromises = Array.from(this.clients.entries()).map(async ([key, connection]) => {
1635
- try {
1636
- await connection.pool.end();
1637
- this.logger.debug(`Disconnected: ${key}`);
1638
- } catch (error) {
1639
- this.logger.error(`Error disconnecting client: ${key}`, error);
1640
- }
1641
- });
1642
- await Promise.all(disconnectPromises);
1643
- this.logger.log("All database connections closed");
1443
+ __name(this, "CreateResponseDto");
1644
1444
  }
1445
+ success;
1446
+ message;
1447
+ data;
1645
1448
  };
1646
- TenantDatabaseService = _ts_decorate11([
1647
- (0, import_common40.Injectable)(),
1648
- _ts_param4(0, (0, import_common40.Inject)(DATABASE_MODULE_OPTIONS)),
1649
- _ts_metadata7("design:type", Function),
1650
- _ts_metadata7("design:paramtypes", [
1651
- typeof DatabaseModuleOptions === "undefined" ? Object : DatabaseModuleOptions,
1652
- typeof TenantContextService === "undefined" ? Object : TenantContextService
1653
- ])
1654
- ], TenantDatabaseService);
1449
+ _ts_decorate11([
1450
+ (0, import_swagger.ApiProperty)({
1451
+ example: true
1452
+ }),
1453
+ _ts_metadata7("design:type", Boolean)
1454
+ ], CreateResponseDto.prototype, "success", void 0);
1455
+ _ts_decorate11([
1456
+ (0, import_swagger.ApiProperty)({
1457
+ example: "Resource created successfully"
1458
+ }),
1459
+ _ts_metadata7("design:type", String)
1460
+ ], CreateResponseDto.prototype, "message", void 0);
1461
+ _ts_decorate11([
1462
+ (0, import_swagger.ApiProperty)(),
1463
+ _ts_metadata7("design:type", typeof T === "undefined" ? Object : T)
1464
+ ], CreateResponseDto.prototype, "data", void 0);
1655
1465
 
1656
- // src/database/database.module.ts
1466
+ // src/database/dto/import-response.dto.ts
1467
+ var import_swagger2 = require("@nestjs/swagger");
1657
1468
  function _ts_decorate12(decorators, target, key, desc2) {
1658
1469
  var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
1659
1470
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
@@ -1661,69 +1472,133 @@ function _ts_decorate12(decorators, target, key, desc2) {
1661
1472
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1662
1473
  }
1663
1474
  __name(_ts_decorate12, "_ts_decorate");
1664
- var DatabaseModule = class _DatabaseModule {
1475
+ function _ts_metadata8(k, v) {
1476
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1477
+ }
1478
+ __name(_ts_metadata8, "_ts_metadata");
1479
+ var ValidatedRowDto = class {
1665
1480
  static {
1666
- __name(this, "DatabaseModule");
1667
- }
1668
- // Configures the module for gateway/HTTP mode with TenantContextInterceptor
1669
- static forServer(options) {
1670
- return _DatabaseModule.createDynamicModule(options, "server");
1481
+ __name(this, "ValidatedRowDto");
1671
1482
  }
1672
- // Configures the module for microservice mode with MessageTenantContextInterceptor
1673
- static forMicroservice(options) {
1674
- return _DatabaseModule.createDynamicModule(options, "microservice");
1675
- }
1676
- // Creates the dynamic module configuration with the appropriate interceptor for the given mode
1677
- static createDynamicModule(options, mode) {
1678
- const asyncProvider = {
1679
- provide: DATABASE_MODULE_OPTIONS,
1680
- useFactory: options.useFactory,
1681
- inject: options.inject || []
1682
- };
1683
- const providers = [
1684
- // Required for external packages - NestJS global Reflector not available
1685
- {
1686
- provide: import_core4.Reflector,
1687
- useClass: import_core4.Reflector
1688
- },
1689
- asyncProvider,
1690
- TenantContextService,
1691
- PrimaryDatabaseService,
1692
- TenantDatabaseService
1693
- ];
1694
- return {
1695
- module: _DatabaseModule,
1696
- imports: [
1697
- RequestModule
1698
- ],
1699
- providers,
1700
- exports: [
1701
- TenantDatabaseService,
1702
- TenantContextService,
1703
- PrimaryDatabaseService,
1704
- asyncProvider
1705
- ]
1706
- };
1483
+ index;
1484
+ data;
1485
+ valid;
1486
+ errors;
1487
+ };
1488
+ _ts_decorate12([
1489
+ (0, import_swagger2.ApiProperty)({
1490
+ example: 1
1491
+ }),
1492
+ _ts_metadata8("design:type", Number)
1493
+ ], ValidatedRowDto.prototype, "index", void 0);
1494
+ _ts_decorate12([
1495
+ (0, import_swagger2.ApiProperty)({
1496
+ example: {
1497
+ code: "products",
1498
+ name: "Products"
1499
+ }
1500
+ }),
1501
+ _ts_metadata8("design:type", typeof Record === "undefined" ? Object : Record)
1502
+ ], ValidatedRowDto.prototype, "data", void 0);
1503
+ _ts_decorate12([
1504
+ (0, import_swagger2.ApiProperty)({
1505
+ example: true
1506
+ }),
1507
+ _ts_metadata8("design:type", Boolean)
1508
+ ], ValidatedRowDto.prototype, "valid", void 0);
1509
+ _ts_decorate12([
1510
+ (0, import_swagger2.ApiProperty)({
1511
+ example: [
1512
+ "Code already exists"
1513
+ ]
1514
+ }),
1515
+ _ts_metadata8("design:type", Array)
1516
+ ], ValidatedRowDto.prototype, "errors", void 0);
1517
+ var ImportSummaryDto = class {
1518
+ static {
1519
+ __name(this, "ImportSummaryDto");
1707
1520
  }
1521
+ total;
1522
+ valid;
1523
+ invalid;
1708
1524
  };
1709
- DatabaseModule = _ts_decorate12([
1710
- (0, import_common41.Global)(),
1711
- (0, import_common41.Module)({})
1712
- ], DatabaseModule);
1713
-
1714
- // src/database/decorators/tenant.decorator.ts
1715
- var import_common42 = require("@nestjs/common");
1716
- var Tenant = (0, import_common42.createParamDecorator)((_data, ctx) => {
1717
- const request = ctx.switchToHttp().getRequest();
1718
- const tenantContext = request.app?.get?.(TenantContextService);
1719
- if (!tenantContext) {
1720
- throw new Error("TenantContextService not found.");
1525
+ _ts_decorate12([
1526
+ (0, import_swagger2.ApiProperty)({
1527
+ example: 10
1528
+ }),
1529
+ _ts_metadata8("design:type", Number)
1530
+ ], ImportSummaryDto.prototype, "total", void 0);
1531
+ _ts_decorate12([
1532
+ (0, import_swagger2.ApiProperty)({
1533
+ example: 8
1534
+ }),
1535
+ _ts_metadata8("design:type", Number)
1536
+ ], ImportSummaryDto.prototype, "valid", void 0);
1537
+ _ts_decorate12([
1538
+ (0, import_swagger2.ApiProperty)({
1539
+ example: 2
1540
+ }),
1541
+ _ts_metadata8("design:type", Number)
1542
+ ], ImportSummaryDto.prototype, "invalid", void 0);
1543
+ var ImportResponseDto = class {
1544
+ static {
1545
+ __name(this, "ImportResponseDto");
1721
1546
  }
1722
- return tenantContext.getTenant();
1723
- });
1547
+ success;
1548
+ message;
1549
+ created;
1550
+ updated;
1551
+ skipped;
1552
+ rows;
1553
+ summary;
1554
+ };
1555
+ _ts_decorate12([
1556
+ (0, import_swagger2.ApiProperty)({
1557
+ example: true
1558
+ }),
1559
+ _ts_metadata8("design:type", Boolean)
1560
+ ], ImportResponseDto.prototype, "success", void 0);
1561
+ _ts_decorate12([
1562
+ (0, import_swagger2.ApiProperty)({
1563
+ example: "Import complete."
1564
+ }),
1565
+ _ts_metadata8("design:type", String)
1566
+ ], ImportResponseDto.prototype, "message", void 0);
1567
+ _ts_decorate12([
1568
+ (0, import_swagger2.ApiPropertyOptional)({
1569
+ example: 3
1570
+ }),
1571
+ _ts_metadata8("design:type", Number)
1572
+ ], ImportResponseDto.prototype, "created", void 0);
1573
+ _ts_decorate12([
1574
+ (0, import_swagger2.ApiPropertyOptional)({
1575
+ example: 2
1576
+ }),
1577
+ _ts_metadata8("design:type", Number)
1578
+ ], ImportResponseDto.prototype, "updated", void 0);
1579
+ _ts_decorate12([
1580
+ (0, import_swagger2.ApiPropertyOptional)({
1581
+ example: 1
1582
+ }),
1583
+ _ts_metadata8("design:type", Number)
1584
+ ], ImportResponseDto.prototype, "skipped", void 0);
1585
+ _ts_decorate12([
1586
+ (0, import_swagger2.ApiPropertyOptional)({
1587
+ type: [
1588
+ ValidatedRowDto
1589
+ ]
1590
+ }),
1591
+ _ts_metadata8("design:type", Array)
1592
+ ], ImportResponseDto.prototype, "rows", void 0);
1593
+ _ts_decorate12([
1594
+ (0, import_swagger2.ApiPropertyOptional)({
1595
+ type: ImportSummaryDto
1596
+ }),
1597
+ _ts_metadata8("design:type", typeof ImportSummaryDto === "undefined" ? Object : ImportSummaryDto)
1598
+ ], ImportResponseDto.prototype, "summary", void 0);
1724
1599
 
1725
1600
  // src/database/dto/select-options-query.dto.ts
1726
- var import_swagger = require("@nestjs/swagger");
1601
+ var import_swagger3 = require("@nestjs/swagger");
1727
1602
  var import_class_transformer = require("class-transformer");
1728
1603
  var import_class_validator = require("class-validator");
1729
1604
  function _ts_decorate13(decorators, target, key, desc2) {
@@ -1733,10 +1608,10 @@ function _ts_decorate13(decorators, target, key, desc2) {
1733
1608
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1734
1609
  }
1735
1610
  __name(_ts_decorate13, "_ts_decorate");
1736
- function _ts_metadata8(k, v) {
1611
+ function _ts_metadata9(k, v) {
1737
1612
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1738
1613
  }
1739
- __name(_ts_metadata8, "_ts_metadata");
1614
+ __name(_ts_metadata9, "_ts_metadata");
1740
1615
  var SelectOptionsQueryDto = class {
1741
1616
  static {
1742
1617
  __name(this, "SelectOptionsQueryDto");
@@ -1752,16 +1627,16 @@ var SelectOptionsQueryDto = class {
1752
1627
  groupIdKey;
1753
1628
  };
1754
1629
  _ts_decorate13([
1755
- (0, import_swagger.ApiPropertyOptional)({
1630
+ (0, import_swagger3.ApiPropertyOptional)({
1756
1631
  description: "Search term to filter by label",
1757
1632
  example: "united"
1758
1633
  }),
1759
1634
  (0, import_class_validator.IsOptional)(),
1760
1635
  (0, import_class_validator.IsString)(),
1761
- _ts_metadata8("design:type", String)
1636
+ _ts_metadata9("design:type", String)
1762
1637
  ], SelectOptionsQueryDto.prototype, "search", void 0);
1763
1638
  _ts_decorate13([
1764
- (0, import_swagger.ApiPropertyOptional)({
1639
+ (0, import_swagger3.ApiPropertyOptional)({
1765
1640
  description: "Maximum number of results",
1766
1641
  example: 20,
1767
1642
  default: 20
@@ -1770,10 +1645,10 @@ _ts_decorate13([
1770
1645
  (0, import_class_transformer.Type)(() => Number),
1771
1646
  (0, import_class_validator.IsInt)(),
1772
1647
  (0, import_class_validator.Min)(1),
1773
- _ts_metadata8("design:type", Number)
1648
+ _ts_metadata9("design:type", Number)
1774
1649
  ], SelectOptionsQueryDto.prototype, "limit", void 0);
1775
1650
  _ts_decorate13([
1776
- (0, import_swagger.ApiPropertyOptional)({
1651
+ (0, import_swagger3.ApiPropertyOptional)({
1777
1652
  description: "Number of results to skip",
1778
1653
  example: 0,
1779
1654
  default: 0
@@ -1782,67 +1657,67 @@ _ts_decorate13([
1782
1657
  (0, import_class_transformer.Type)(() => Number),
1783
1658
  (0, import_class_validator.IsInt)(),
1784
1659
  (0, import_class_validator.Min)(0),
1785
- _ts_metadata8("design:type", Number)
1660
+ _ts_metadata9("design:type", Number)
1786
1661
  ], SelectOptionsQueryDto.prototype, "offset", void 0);
1787
1662
  _ts_decorate13([
1788
- (0, import_swagger.ApiPropertyOptional)({
1663
+ (0, import_swagger3.ApiPropertyOptional)({
1789
1664
  description: "Comma-separated values to fetch specific options",
1790
1665
  example: "1,2,3"
1791
1666
  }),
1792
1667
  (0, import_class_validator.IsOptional)(),
1793
1668
  (0, import_class_validator.IsString)(),
1794
- _ts_metadata8("design:type", String)
1669
+ _ts_metadata9("design:type", String)
1795
1670
  ], SelectOptionsQueryDto.prototype, "values", void 0);
1796
1671
  _ts_decorate13([
1797
- (0, import_swagger.ApiPropertyOptional)({
1672
+ (0, import_swagger3.ApiPropertyOptional)({
1798
1673
  description: "Comma-separated IDs to exclude from results (already selected)",
1799
1674
  example: "5,10"
1800
1675
  }),
1801
1676
  (0, import_class_validator.IsOptional)(),
1802
1677
  (0, import_class_validator.IsString)(),
1803
- _ts_metadata8("design:type", String)
1678
+ _ts_metadata9("design:type", String)
1804
1679
  ], SelectOptionsQueryDto.prototype, "excludeIds", void 0);
1805
1680
  _ts_decorate13([
1806
- (0, import_swagger.ApiPropertyOptional)({
1681
+ (0, import_swagger3.ApiPropertyOptional)({
1807
1682
  description: "Column name for option value",
1808
1683
  example: "id",
1809
1684
  default: "id"
1810
1685
  }),
1811
1686
  (0, import_class_validator.IsOptional)(),
1812
1687
  (0, import_class_validator.IsString)(),
1813
- _ts_metadata8("design:type", String)
1688
+ _ts_metadata9("design:type", String)
1814
1689
  ], SelectOptionsQueryDto.prototype, "valueKey", void 0);
1815
1690
  _ts_decorate13([
1816
- (0, import_swagger.ApiPropertyOptional)({
1691
+ (0, import_swagger3.ApiPropertyOptional)({
1817
1692
  description: "Column name for option label",
1818
1693
  example: "name",
1819
1694
  default: "name"
1820
1695
  }),
1821
1696
  (0, import_class_validator.IsOptional)(),
1822
1697
  (0, import_class_validator.IsString)(),
1823
- _ts_metadata8("design:type", String)
1698
+ _ts_metadata9("design:type", String)
1824
1699
  ], SelectOptionsQueryDto.prototype, "labelKey", void 0);
1825
1700
  _ts_decorate13([
1826
- (0, import_swagger.ApiPropertyOptional)({
1701
+ (0, import_swagger3.ApiPropertyOptional)({
1827
1702
  description: "Column name for option description",
1828
1703
  example: "description"
1829
1704
  }),
1830
1705
  (0, import_class_validator.IsOptional)(),
1831
1706
  (0, import_class_validator.IsString)(),
1832
- _ts_metadata8("design:type", String)
1707
+ _ts_metadata9("design:type", String)
1833
1708
  ], SelectOptionsQueryDto.prototype, "descriptionKey", void 0);
1834
1709
  _ts_decorate13([
1835
- (0, import_swagger.ApiPropertyOptional)({
1710
+ (0, import_swagger3.ApiPropertyOptional)({
1836
1711
  description: "Column name for group ID",
1837
1712
  example: "regionId"
1838
1713
  }),
1839
1714
  (0, import_class_validator.IsOptional)(),
1840
1715
  (0, import_class_validator.IsString)(),
1841
- _ts_metadata8("design:type", String)
1716
+ _ts_metadata9("design:type", String)
1842
1717
  ], SelectOptionsQueryDto.prototype, "groupIdKey", void 0);
1843
1718
 
1844
1719
  // src/database/dto/success-response.dto.ts
1845
- var import_swagger2 = require("@nestjs/swagger");
1720
+ var import_swagger4 = require("@nestjs/swagger");
1846
1721
  var import_class_validator2 = require("class-validator");
1847
1722
  function _ts_decorate14(decorators, target, key, desc2) {
1848
1723
  var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
@@ -1851,10 +1726,10 @@ function _ts_decorate14(decorators, target, key, desc2) {
1851
1726
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1852
1727
  }
1853
1728
  __name(_ts_decorate14, "_ts_decorate");
1854
- function _ts_metadata9(k, v) {
1729
+ function _ts_metadata10(k, v) {
1855
1730
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1856
1731
  }
1857
- __name(_ts_metadata9, "_ts_metadata");
1732
+ __name(_ts_metadata10, "_ts_metadata");
1858
1733
  var SuccessResponseDto = class {
1859
1734
  static {
1860
1735
  __name(this, "SuccessResponseDto");
@@ -1863,24 +1738,24 @@ var SuccessResponseDto = class {
1863
1738
  message;
1864
1739
  };
1865
1740
  _ts_decorate14([
1866
- (0, import_swagger2.ApiProperty)({
1741
+ (0, import_swagger4.ApiProperty)({
1867
1742
  example: true
1868
1743
  }),
1869
1744
  (0, import_class_validator2.IsNotEmpty)(),
1870
1745
  (0, import_class_validator2.IsBoolean)(),
1871
- _ts_metadata9("design:type", Boolean)
1746
+ _ts_metadata10("design:type", Boolean)
1872
1747
  ], SuccessResponseDto.prototype, "success", void 0);
1873
1748
  _ts_decorate14([
1874
- (0, import_swagger2.ApiProperty)({
1749
+ (0, import_swagger4.ApiProperty)({
1875
1750
  example: "Operation completed successfully"
1876
1751
  }),
1877
1752
  (0, import_class_validator2.IsNotEmpty)(),
1878
1753
  (0, import_class_validator2.IsString)(),
1879
- _ts_metadata9("design:type", String)
1754
+ _ts_metadata10("design:type", String)
1880
1755
  ], SuccessResponseDto.prototype, "message", void 0);
1881
1756
 
1882
1757
  // src/database/dto/table-response.dto.ts
1883
- var import_swagger3 = require("@nestjs/swagger");
1758
+ var import_swagger5 = require("@nestjs/swagger");
1884
1759
  function _ts_decorate15(decorators, target, key, desc2) {
1885
1760
  var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
1886
1761
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
@@ -1888,10 +1763,10 @@ function _ts_decorate15(decorators, target, key, desc2) {
1888
1763
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1889
1764
  }
1890
1765
  __name(_ts_decorate15, "_ts_decorate");
1891
- function _ts_metadata10(k, v) {
1766
+ function _ts_metadata11(k, v) {
1892
1767
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1893
1768
  }
1894
- __name(_ts_metadata10, "_ts_metadata");
1769
+ __name(_ts_metadata11, "_ts_metadata");
1895
1770
  var TableResponseDto = class {
1896
1771
  static {
1897
1772
  __name(this, "TableResponseDto");
@@ -1902,26 +1777,26 @@ var TableResponseDto = class {
1902
1777
  activeViewId;
1903
1778
  };
1904
1779
  _ts_decorate15([
1905
- (0, import_swagger3.ApiProperty)(),
1906
- _ts_metadata10("design:type", Array)
1780
+ (0, import_swagger5.ApiProperty)(),
1781
+ _ts_metadata11("design:type", Array)
1907
1782
  ], TableResponseDto.prototype, "result", void 0);
1908
1783
  _ts_decorate15([
1909
- (0, import_swagger3.ApiProperty)(),
1910
- _ts_metadata10("design:type", Number)
1784
+ (0, import_swagger5.ApiProperty)(),
1785
+ _ts_metadata11("design:type", Number)
1911
1786
  ], TableResponseDto.prototype, "count", void 0);
1912
1787
  _ts_decorate15([
1913
- (0, import_swagger3.ApiProperty)(),
1914
- _ts_metadata10("design:type", typeof TableViewState === "undefined" ? Object : TableViewState)
1788
+ (0, import_swagger5.ApiProperty)(),
1789
+ _ts_metadata11("design:type", typeof TableViewState === "undefined" ? Object : TableViewState)
1915
1790
  ], TableResponseDto.prototype, "state", void 0);
1916
1791
  _ts_decorate15([
1917
- (0, import_swagger3.ApiPropertyOptional)({
1792
+ (0, import_swagger5.ApiPropertyOptional)({
1918
1793
  nullable: true
1919
1794
  }),
1920
- _ts_metadata10("design:type", Object)
1795
+ _ts_metadata11("design:type", Object)
1921
1796
  ], TableResponseDto.prototype, "activeViewId", void 0);
1922
1797
 
1923
1798
  // src/database/filter/filter.processor.ts
1924
- var import_drizzle_orm2 = require("drizzle-orm");
1799
+ var import_drizzle_orm = require("drizzle-orm");
1925
1800
  var FilterProcessor = class {
1926
1801
  static {
1927
1802
  __name(this, "FilterProcessor");
@@ -1939,58 +1814,58 @@ var FilterProcessor = class {
1939
1814
  switch (f.operator) {
1940
1815
  case "equals":
1941
1816
  if (def.type === "boolean") return [
1942
- (0, import_drizzle_orm2.eq)(col, val === "true" || val === 1)
1817
+ (0, import_drizzle_orm.eq)(col, val === "true" || val === 1)
1943
1818
  ];
1944
1819
  return [
1945
- (0, import_drizzle_orm2.eq)(col, val)
1820
+ (0, import_drizzle_orm.eq)(col, val)
1946
1821
  ];
1947
1822
  case "notEquals":
1948
1823
  if (def.type === "boolean") return [
1949
- (0, import_drizzle_orm2.ne)(col, val === "true" || val === 1)
1824
+ (0, import_drizzle_orm.ne)(col, val === "true" || val === 1)
1950
1825
  ];
1951
1826
  return [
1952
- (0, import_drizzle_orm2.ne)(col, val)
1827
+ (0, import_drizzle_orm.ne)(col, val)
1953
1828
  ];
1954
1829
  case "contains":
1955
1830
  return [
1956
- (0, import_drizzle_orm2.ilike)(col, `%${val}%`)
1831
+ (0, import_drizzle_orm.ilike)(col, `%${val}%`)
1957
1832
  ];
1958
1833
  case "notContains":
1959
1834
  return [
1960
- (0, import_drizzle_orm2.notIlike)(col, `%${val}%`)
1835
+ (0, import_drizzle_orm.notIlike)(col, `%${val}%`)
1961
1836
  ];
1962
1837
  case "gt":
1963
1838
  return [
1964
- (0, import_drizzle_orm2.gt)(col, val)
1839
+ (0, import_drizzle_orm.gt)(col, val)
1965
1840
  ];
1966
1841
  case "gte":
1967
1842
  return [
1968
- (0, import_drizzle_orm2.gte)(col, val)
1843
+ (0, import_drizzle_orm.gte)(col, val)
1969
1844
  ];
1970
1845
  case "lt":
1971
1846
  return [
1972
- (0, import_drizzle_orm2.lt)(col, val)
1847
+ (0, import_drizzle_orm.lt)(col, val)
1973
1848
  ];
1974
1849
  case "lte":
1975
1850
  return [
1976
- (0, import_drizzle_orm2.lte)(col, val)
1851
+ (0, import_drizzle_orm.lte)(col, val)
1977
1852
  ];
1978
1853
  default:
1979
1854
  return [];
1980
1855
  }
1981
1856
  });
1982
- return conditions.length ? (0, import_drizzle_orm2.and)(...conditions) : void 0;
1857
+ return conditions.length ? (0, import_drizzle_orm.and)(...conditions) : void 0;
1983
1858
  }
1984
1859
  // Builds a search WHERE — OR across all string fields when columnId is 'all', otherwise a single ilike
1985
1860
  static buildSearch(search, fieldMap) {
1986
1861
  if (!search?.value) return void 0;
1987
1862
  if (search.columnId === "all") {
1988
- const conditions = Object.values(fieldMap).filter((def2) => "column" in def2 && def2.type === "string").map((def2) => (0, import_drizzle_orm2.ilike)(def2.column, `%${search.value}%`));
1989
- return conditions.length ? (0, import_drizzle_orm2.or)(...conditions) : void 0;
1863
+ const conditions = Object.values(fieldMap).filter((def2) => "column" in def2 && def2.type === "string").map((def2) => (0, import_drizzle_orm.ilike)(def2.column, `%${search.value}%`));
1864
+ return conditions.length ? (0, import_drizzle_orm.or)(...conditions) : void 0;
1990
1865
  }
1991
1866
  const def = fieldMap[search.columnId];
1992
1867
  if (!def || !("column" in def)) return void 0;
1993
- return (0, import_drizzle_orm2.ilike)(def.column, `%${search.value}%`);
1868
+ return (0, import_drizzle_orm.ilike)(def.column, `%${search.value}%`);
1994
1869
  }
1995
1870
  // Maps each SortCondition to an asc/desc SQL expression
1996
1871
  static buildOrderBy(sort = [], fieldMap) {
@@ -1998,15 +1873,15 @@ var FilterProcessor = class {
1998
1873
  const def = fieldMap[s.field];
1999
1874
  if (!def || !("column" in def)) return [];
2000
1875
  return [
2001
- s.direction === "asc" ? (0, import_drizzle_orm2.asc)(def.column) : (0, import_drizzle_orm2.desc)(def.column)
1876
+ s.direction === "asc" ? (0, import_drizzle_orm.asc)(def.column) : (0, import_drizzle_orm.desc)(def.column)
2002
1877
  ];
2003
1878
  });
2004
1879
  }
2005
1880
  };
2006
1881
 
2007
1882
  // src/database/repositories/primary-base.repository.ts
2008
- var import_common43 = require("@nestjs/common");
2009
- var import_drizzle_orm3 = require("drizzle-orm");
1883
+ var import_common41 = require("@nestjs/common");
1884
+ var import_drizzle_orm2 = require("drizzle-orm");
2010
1885
  function snakeToCamel(str) {
2011
1886
  return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
2012
1887
  }
@@ -2035,16 +1910,17 @@ var PrimaryBaseRepository = class {
2035
1910
  constructor(database, table) {
2036
1911
  this.database = database;
2037
1912
  this.table = table;
2038
- const dbTableName = (0, import_drizzle_orm3.getTableName)(table);
1913
+ const dbTableName = (0, import_drizzle_orm2.getTableName)(table);
2039
1914
  this.tableName = snakeToCamel(dbTableName);
2040
- this.logger = new import_common43.Logger(this.constructor.name);
1915
+ this.logger = new import_common41.Logger(this.constructor.name);
2041
1916
  this.logger.debug(`Initialized ${this.constructor.name}`);
2042
1917
  this.logger.debug(`Table name: '${dbTableName}' -> query key: '${this.tableName}'`);
2043
1918
  }
2044
1919
  // Creates a new record and returns it
2045
- async create(data) {
1920
+ async create(data, tx) {
2046
1921
  this.logger.log("Creating record");
2047
- const results = await this.db.insert(this.table).values(data).returning();
1922
+ const db = tx ?? this.db;
1923
+ const results = await db.insert(this.table).values(data).returning();
2048
1924
  const record = results[0];
2049
1925
  if (!record) throw new Error(`${this.tableName}: database operation returned no record`);
2050
1926
  return record;
@@ -2070,16 +1946,35 @@ var PrimaryBaseRepository = class {
2070
1946
  this.logger.debug("Finding multiple records");
2071
1947
  return this.model.findMany(options);
2072
1948
  }
2073
- // Builds a select query with optional custom fields, join, filter, ordering, and pagination
1949
+ // Builds a select query with optional custom fields, joins, filter, grouping, ordering, and pagination
2074
1950
  buildSelectQuery(options) {
2075
- const base = options?.select ? this.db.select(options.select).from(this.table) : this.db.select().from(this.table);
2076
- const joined = options?.leftJoin ? base.leftJoin(options.leftJoin.table, options.leftJoin.on) : base;
2077
- const filtered = options?.where ? joined.where(options.where) : joined;
2078
- const ordered = options?.orderBy?.length ? filtered.orderBy(...options.orderBy) : filtered;
2079
- const limited = options?.limit ? ordered.limit(options.limit) : ordered;
2080
- return options?.offset ? limited.offset(options.offset) : limited;
2081
- }
2082
- // Returns paginated result and total count, with optional custom select, LEFT JOIN, and ordering
1951
+ let query = (options?.select ? this.db.select(options.select).from(this.table) : this.db.select().from(this.table)).$dynamic();
1952
+ if (options?.leftJoin) {
1953
+ query = query.leftJoin(options.leftJoin.table, options.leftJoin.on);
1954
+ }
1955
+ if (options?.leftJoins) {
1956
+ for (const join of options.leftJoins) {
1957
+ query = query.leftJoin(join.table, join.on);
1958
+ }
1959
+ }
1960
+ if (options?.where) {
1961
+ query = query.where(options.where);
1962
+ }
1963
+ if (options?.groupBy?.length) {
1964
+ query = query.groupBy(...options.groupBy);
1965
+ }
1966
+ if (options?.orderBy?.length) {
1967
+ query = query.orderBy(...options.orderBy);
1968
+ }
1969
+ if (options?.limit) {
1970
+ query = query.limit(options.limit);
1971
+ }
1972
+ if (options?.offset) {
1973
+ query = query.offset(options.offset);
1974
+ }
1975
+ return query;
1976
+ }
1977
+ // Returns paginated result and total count, with optional custom select, LEFT JOINs, GROUP BY, and ordering
2083
1978
  async findAllAndCount(options) {
2084
1979
  const [count, result] = await Promise.all([
2085
1980
  this.count(options?.where),
@@ -2091,37 +1986,41 @@ var PrimaryBaseRepository = class {
2091
1986
  };
2092
1987
  }
2093
1988
  // Updates a record by ID and returns the updated record
2094
- async update(id, data) {
1989
+ async update(id, data, tx) {
2095
1990
  this.logger.log(`Updating record with ID: ${id}`);
1991
+ const db = tx ?? this.db;
2096
1992
  const idColumn = this.table.id;
2097
1993
  if (!idColumn) throw new Error(`Table '${this.tableName}' has no 'id' column`);
2098
- const results = await this.db.update(this.table).set(data).where((0, import_drizzle_orm3.eq)(idColumn, id)).returning();
1994
+ const results = await db.update(this.table).set(data).where((0, import_drizzle_orm2.eq)(idColumn, id)).returning();
2099
1995
  const record = results[0];
2100
1996
  if (!record) throw new Error(`${this.tableName}: database operation returned no record`);
2101
1997
  return record;
2102
1998
  }
2103
1999
  // Updates all records matching the SQL condition and returns the affected count
2104
- async updateMany(where, data) {
2000
+ async updateMany(where, data, tx) {
2105
2001
  this.logger.log("Updating multiple records");
2106
- const result = await this.db.update(this.table).set(data).where(where);
2002
+ const db = tx ?? this.db;
2003
+ const result = await db.update(this.table).set(data).where(where);
2107
2004
  return {
2108
2005
  count: result.rowCount ?? 0
2109
2006
  };
2110
2007
  }
2111
2008
  // Deletes a record by ID and returns the deleted record
2112
- async delete(id) {
2009
+ async delete(id, tx) {
2113
2010
  this.logger.log(`Deleting record with ID: ${id}`);
2011
+ const db = tx ?? this.db;
2114
2012
  const idColumn = this.table.id;
2115
2013
  if (!idColumn) throw new Error(`Table '${this.tableName}' has no 'id' column`);
2116
- const results = await this.db.delete(this.table).where((0, import_drizzle_orm3.eq)(idColumn, id)).returning();
2014
+ const results = await db.delete(this.table).where((0, import_drizzle_orm2.eq)(idColumn, id)).returning();
2117
2015
  const record = results[0];
2118
2016
  if (!record) throw new Error(`${this.tableName}: database operation returned no record`);
2119
2017
  return record;
2120
2018
  }
2121
2019
  // Deletes all records matching the SQL condition and returns the affected count
2122
- async deleteMany(where) {
2020
+ async deleteMany(where, tx) {
2123
2021
  this.logger.log("Deleting multiple records");
2124
- const result = await this.db.delete(this.table).where(where);
2022
+ const db = tx ?? this.db;
2023
+ const result = await db.delete(this.table).where(where);
2125
2024
  return {
2126
2025
  count: result.rowCount ?? 0
2127
2026
  };
@@ -2130,7 +2029,7 @@ var PrimaryBaseRepository = class {
2130
2029
  async count(where) {
2131
2030
  this.logger.debug("Counting records");
2132
2031
  let query = this.db.select({
2133
- count: import_drizzle_orm3.sql`count(*)::int`
2032
+ count: import_drizzle_orm2.sql`count(*)::int`
2134
2033
  }).from(this.table).$dynamic();
2135
2034
  if (where) {
2136
2035
  query = query.where(where);
@@ -2143,9 +2042,14 @@ var PrimaryBaseRepository = class {
2143
2042
  const count = await this.count(where);
2144
2043
  return count > 0;
2145
2044
  }
2045
+ // Executes the callback within a database transaction
2046
+ async transaction(callback) {
2047
+ return this.db.transaction(callback);
2048
+ }
2146
2049
  // Finds records formatted as select dropdown options with optional search, pagination, and grouping
2147
2050
  async findForSelect(config) {
2148
2051
  this.logger.debug("Finding records for select dropdown");
2052
+ const selectFn = config.distinct ? this.db.selectDistinct.bind(this.db) : this.db.select.bind(this.db);
2149
2053
  const parsedValues = typeof config.values === "string" ? config.values.split(",").map((v) => v.trim()).filter(Boolean) : config.values;
2150
2054
  const parsedExcludeIds = typeof config.excludeIds === "string" ? config.excludeIds.split(",").map((v) => v.trim()).filter(Boolean) : config.excludeIds ?? [];
2151
2055
  const tableColumns = this.table;
@@ -2173,7 +2077,7 @@ var PrimaryBaseRepository = class {
2173
2077
  const groupIdCol = tableColumns[config.groupId];
2174
2078
  if (groupIdCol) selectCols.groupId = groupIdCol;
2175
2079
  }
2176
- let valuesQuery = this.db.select(selectCols).from(this.table).$dynamic();
2080
+ let valuesQuery = selectFn(selectCols).from(this.table).$dynamic();
2177
2081
  if (config.joins) {
2178
2082
  for (const join of config.joins) {
2179
2083
  if (join.type === "inner") {
@@ -2183,7 +2087,7 @@ var PrimaryBaseRepository = class {
2183
2087
  }
2184
2088
  }
2185
2089
  }
2186
- const rows2 = await valuesQuery.where((0, import_drizzle_orm3.inArray)(valueCol, parsedValues));
2090
+ const rows2 = await valuesQuery.where((0, import_drizzle_orm2.inArray)(valueCol, parsedValues));
2187
2091
  return {
2188
2092
  options: rows2.map((row) => ({
2189
2093
  value: row.value,
@@ -2204,7 +2108,7 @@ var PrimaryBaseRepository = class {
2204
2108
  const selectFields = {
2205
2109
  value: valueCol,
2206
2110
  label: labelCol,
2207
- totalCount: import_drizzle_orm3.sql`count(*) over()`.mapWith(Number)
2111
+ totalCount: import_drizzle_orm2.sql`count(*) over()`.mapWith(Number)
2208
2112
  };
2209
2113
  if (descriptionCol) selectFields.description = descriptionCol;
2210
2114
  if (config.groupId) {
@@ -2213,16 +2117,16 @@ var PrimaryBaseRepository = class {
2213
2117
  }
2214
2118
  const conditions = [];
2215
2119
  if (config.search) {
2216
- conditions.push((0, import_drizzle_orm3.ilike)(labelCol, `%${config.search}%`));
2120
+ conditions.push((0, import_drizzle_orm2.ilike)(labelCol, `%${config.search}%`));
2217
2121
  }
2218
2122
  if (parsedExcludeIds.length > 0) {
2219
- conditions.push((0, import_drizzle_orm3.notInArray)(valueCol, parsedExcludeIds));
2123
+ conditions.push((0, import_drizzle_orm2.notInArray)(valueCol, parsedExcludeIds));
2220
2124
  }
2221
2125
  if (config.where) {
2222
2126
  for (const [field, val] of Object.entries(config.where)) {
2223
2127
  const column = tableColumns[field];
2224
2128
  if (column) {
2225
- conditions.push((0, import_drizzle_orm3.eq)(column, val));
2129
+ conditions.push((0, import_drizzle_orm2.eq)(column, val));
2226
2130
  }
2227
2131
  }
2228
2132
  }
@@ -2233,7 +2137,7 @@ var PrimaryBaseRepository = class {
2233
2137
  const orderByCol = orderByKey ? tableColumns[orderByKey] ?? labelCol : labelCol;
2234
2138
  const limit = Number(config.limit) || 20;
2235
2139
  const offset = Number(config.offset) || 0;
2236
- let query = this.db.select(selectFields).from(this.table).$dynamic();
2140
+ let query = selectFn(selectFields).from(this.table).$dynamic();
2237
2141
  if (config.joins) {
2238
2142
  for (const join of config.joins) {
2239
2143
  if (join.type === "inner") {
@@ -2244,14 +2148,14 @@ var PrimaryBaseRepository = class {
2244
2148
  }
2245
2149
  }
2246
2150
  if (conditions.length > 0) {
2247
- query = query.where(conditions.length === 1 ? conditions[0] : (0, import_drizzle_orm3.and)(...conditions));
2151
+ query = query.where(conditions.length === 1 ? conditions[0] : (0, import_drizzle_orm2.and)(...conditions));
2248
2152
  }
2249
2153
  const orderClauses = [];
2250
2154
  if (config.groupId) {
2251
2155
  const groupIdCol = tableColumns[config.groupId];
2252
- if (groupIdCol) orderClauses.push((0, import_drizzle_orm3.asc)(groupIdCol));
2156
+ if (groupIdCol) orderClauses.push((0, import_drizzle_orm2.asc)(groupIdCol));
2253
2157
  }
2254
- orderClauses.push((0, import_drizzle_orm3.asc)(orderByCol));
2158
+ orderClauses.push((0, import_drizzle_orm2.asc)(orderByCol));
2255
2159
  query = query.orderBy(...orderClauses).limit(limit).offset(offset);
2256
2160
  const rows = await query;
2257
2161
  const totalCount = rows.length > 0 ? rows[0].totalCount : 0;
@@ -2277,235 +2181,7 @@ var PrimaryBaseRepository = class {
2277
2181
  const groupRows = await this.db.select({
2278
2182
  id: groupIdCol,
2279
2183
  name: groupNameCol
2280
- }).from(config.groupTable).orderBy((0, import_drizzle_orm3.asc)(groupNameCol));
2281
- resolvedGroups = groupRows.map((r) => ({
2282
- id: r.id,
2283
- name: String(r.name)
2284
- }));
2285
- }
2286
- return {
2287
- options,
2288
- hasMore: offset + limit < totalCount,
2289
- totalCount,
2290
- ...resolvedGroups ? {
2291
- groups: resolvedGroups
2292
- } : {}
2293
- };
2294
- }
2295
- };
2296
-
2297
- // src/database/repositories/tenant-base.repository.ts
2298
- var import_common44 = require("@nestjs/common");
2299
- var import_drizzle_orm4 = require("drizzle-orm");
2300
- var TenantBaseRepository = class {
2301
- static {
2302
- __name(this, "TenantBaseRepository");
2303
- }
2304
- database;
2305
- table;
2306
- logger;
2307
- tableName;
2308
- get db() {
2309
- return this.database.drizzleClient;
2310
- }
2311
- get model() {
2312
- return this.database.drizzleClient.query[this.tableName];
2313
- }
2314
- constructor(database, table) {
2315
- this.database = database;
2316
- this.table = table;
2317
- this.tableName = (0, import_drizzle_orm4.getTableName)(table);
2318
- this.logger = new import_common44.Logger(this.constructor.name);
2319
- this.logger.debug(`Initialized ${this.constructor.name}`);
2320
- }
2321
- // Creates a new record and returns it
2322
- async create(data) {
2323
- this.logger.log("Creating record");
2324
- const results = await this.db.insert(this.table).values(data).returning();
2325
- const record = results[0];
2326
- if (!record) throw new Error(`${this.tableName}: database operation returned no record`);
2327
- return record;
2328
- }
2329
- // Finds a single record by primary key ID
2330
- async findById(id) {
2331
- this.logger.debug(`Finding record by ID: ${id}`);
2332
- const idColumn = this.table.id;
2333
- if (!idColumn) throw new Error(`Table '${this.tableName}' has no 'id' column`);
2334
- const results = await this.db.select().from(this.table).where((0, import_drizzle_orm4.eq)(idColumn, id)).limit(1);
2335
- return results[0] ?? null;
2336
- }
2337
- // Finds a single record matching the given SQL condition
2338
- async findOne(where) {
2339
- this.logger.debug("Finding record with custom query");
2340
- const results = await this.db.select().from(this.table).where(where).limit(1);
2341
- return results[0] ?? null;
2342
- }
2343
- // Finds multiple records with optional SQL filtering, ordering, and pagination
2344
- async findMany(options) {
2345
- this.logger.debug("Finding multiple records");
2346
- let query = this.db.select().from(this.table).$dynamic();
2347
- if (options?.where) {
2348
- query = query.where(options.where);
2349
- }
2350
- if (options?.orderBy) {
2351
- query = query.orderBy(options.orderBy);
2352
- }
2353
- if (options?.limit) {
2354
- query = query.limit(options.limit);
2355
- }
2356
- if (options?.offset) {
2357
- query = query.offset(options.offset);
2358
- }
2359
- return await query;
2360
- }
2361
- // Updates a record by ID and returns the updated record
2362
- async update(id, data) {
2363
- this.logger.log(`Updating record with ID: ${id}`);
2364
- const idColumn = this.table.id;
2365
- if (!idColumn) throw new Error(`Table '${this.tableName}' has no 'id' column`);
2366
- const results = await this.db.update(this.table).set(data).where((0, import_drizzle_orm4.eq)(idColumn, id)).returning();
2367
- const record = results[0];
2368
- if (!record) throw new Error(`${this.tableName}: database operation returned no record`);
2369
- return record;
2370
- }
2371
- // Updates all records matching the SQL condition and returns the affected count
2372
- async updateMany(where, data) {
2373
- this.logger.log("Updating multiple records");
2374
- const result = await this.db.update(this.table).set(data).where(where);
2375
- return {
2376
- count: result.rowCount ?? 0
2377
- };
2378
- }
2379
- // Deletes a record by ID and returns the deleted record
2380
- async delete(id) {
2381
- this.logger.log(`Deleting record with ID: ${id}`);
2382
- const idColumn = this.table.id;
2383
- if (!idColumn) throw new Error(`Table '${this.tableName}' has no 'id' column`);
2384
- const results = await this.db.delete(this.table).where((0, import_drizzle_orm4.eq)(idColumn, id)).returning();
2385
- const record = results[0];
2386
- if (!record) throw new Error(`${this.tableName}: database operation returned no record`);
2387
- return record;
2388
- }
2389
- // Deletes all records matching the SQL condition and returns the affected count
2390
- async deleteMany(where) {
2391
- this.logger.log("Deleting multiple records");
2392
- const result = await this.db.delete(this.table).where(where);
2393
- return {
2394
- count: result.rowCount ?? 0
2395
- };
2396
- }
2397
- // Counts records matching the optional SQL condition
2398
- async count(where) {
2399
- this.logger.debug("Counting records");
2400
- let query = this.db.select({
2401
- count: import_drizzle_orm4.sql`count(*)::int`
2402
- }).from(this.table).$dynamic();
2403
- if (where) {
2404
- query = query.where(where);
2405
- }
2406
- const results = await query;
2407
- return results[0].count;
2408
- }
2409
- // Returns true if at least one record matches the SQL condition
2410
- async exists(where) {
2411
- const count = await this.count(where);
2412
- return count > 0;
2413
- }
2414
- // Finds records formatted as select dropdown options with optional search, pagination, and grouping
2415
- async findForSelect(config) {
2416
- this.logger.debug("Finding records for select dropdown");
2417
- const parsedValues = typeof config.values === "string" ? config.values.split(",").map((v) => v.trim()).filter(Boolean) : config.values;
2418
- const parsedExcludeIds = typeof config.excludeIds === "string" ? config.excludeIds.split(",").map((v) => v.trim()).filter(Boolean) : config.excludeIds ?? [];
2419
- const tableColumns = this.table;
2420
- const valueCol = tableColumns[config.value];
2421
- if (!valueCol) throw new Error(`Column '${config.value}' not found in table '${this.tableName}'`);
2422
- const labelCol = tableColumns[config.label];
2423
- if (!labelCol) throw new Error(`Column '${config.label}' not found in table '${this.tableName}'`);
2424
- if (parsedValues && parsedValues.length > 0) {
2425
- const selectCols = {
2426
- value: valueCol,
2427
- label: labelCol
2428
- };
2429
- if (config.groupId) {
2430
- const groupIdCol = tableColumns[config.groupId];
2431
- if (groupIdCol) selectCols.groupId = groupIdCol;
2432
- }
2433
- const rows2 = await this.db.select(selectCols).from(this.table).where((0, import_drizzle_orm4.inArray)(valueCol, parsedValues));
2434
- return {
2435
- options: rows2.map((row) => ({
2436
- value: row.value,
2437
- label: String(row.label),
2438
- ...config.groupId && row.groupId != null ? {
2439
- groupId: row.groupId
2440
- } : {}
2441
- })),
2442
- hasMore: false,
2443
- ...config.groups ? {
2444
- groups: config.groups
2445
- } : {}
2446
- };
2447
- }
2448
- const selectFields = {
2449
- value: valueCol,
2450
- label: labelCol,
2451
- totalCount: import_drizzle_orm4.sql`count(*) over()`.mapWith(Number)
2452
- };
2453
- if (config.groupId) {
2454
- const groupIdCol = tableColumns[config.groupId];
2455
- if (groupIdCol) selectFields.groupId = groupIdCol;
2456
- }
2457
- const conditions = [];
2458
- if (config.search) {
2459
- conditions.push((0, import_drizzle_orm4.ilike)(labelCol, `%${config.search}%`));
2460
- }
2461
- if (parsedExcludeIds.length > 0) {
2462
- conditions.push((0, import_drizzle_orm4.notInArray)(valueCol, parsedExcludeIds));
2463
- }
2464
- if (config.where) {
2465
- for (const [field, val] of Object.entries(config.where)) {
2466
- const column = tableColumns[field];
2467
- if (column) {
2468
- conditions.push((0, import_drizzle_orm4.eq)(column, val));
2469
- }
2470
- }
2471
- }
2472
- const orderByKey = config.orderBy ? Object.keys(config.orderBy)[0] : void 0;
2473
- const orderByCol = orderByKey ? tableColumns[orderByKey] ?? labelCol : labelCol;
2474
- const limit = Number(config.limit) || 20;
2475
- const offset = Number(config.offset) || 0;
2476
- let query = this.db.select(selectFields).from(this.table).$dynamic();
2477
- if (conditions.length > 0) {
2478
- query = query.where(conditions.length === 1 ? conditions[0] : (0, import_drizzle_orm4.and)(...conditions));
2479
- }
2480
- const orderClauses = [];
2481
- if (config.groupId) {
2482
- const groupIdCol = tableColumns[config.groupId];
2483
- if (groupIdCol) orderClauses.push((0, import_drizzle_orm4.asc)(groupIdCol));
2484
- }
2485
- orderClauses.push((0, import_drizzle_orm4.asc)(orderByCol));
2486
- query = query.orderBy(...orderClauses).limit(limit).offset(offset);
2487
- const rows = await query;
2488
- const totalCount = rows.length > 0 ? rows[0].totalCount : 0;
2489
- const options = rows.map((row) => ({
2490
- value: row.value,
2491
- label: String(row.label),
2492
- ...config.groupId && row.groupId != null ? {
2493
- groupId: row.groupId
2494
- } : {}
2495
- }));
2496
- let resolvedGroups = config.groups;
2497
- if (config.groupTable && config.groupId) {
2498
- const groupTableColumns = config.groupTable;
2499
- const groupIdKey = config.groupIdKey ?? "id";
2500
- const groupNameKey = config.groupLabelKey ?? "name";
2501
- const groupIdCol = groupTableColumns[groupIdKey];
2502
- if (!groupIdCol) throw new Error(`Column '${groupIdKey}' not found in group table`);
2503
- const groupNameCol = groupTableColumns[groupNameKey];
2504
- if (!groupNameCol) throw new Error(`Column '${groupNameKey}' not found in group table`);
2505
- const groupRows = await this.db.select({
2506
- id: groupIdCol,
2507
- name: groupNameCol
2508
- }).from(config.groupTable).orderBy((0, import_drizzle_orm4.asc)(groupNameCol));
2184
+ }).from(config.groupTable).orderBy((0, import_drizzle_orm2.asc)(groupNameCol));
2509
2185
  resolvedGroups = groupRows.map((r) => ({
2510
2186
  id: r.id,
2511
2187
  name: String(r.name)
@@ -2523,13 +2199,13 @@ var TenantBaseRepository = class {
2523
2199
  };
2524
2200
 
2525
2201
  // src/email/email.module.ts
2526
- var import_common46 = require("@nestjs/common");
2527
- var import_config11 = require("@nestjs/config");
2202
+ var import_common43 = require("@nestjs/common");
2203
+ var import_config12 = require("@nestjs/config");
2528
2204
 
2529
2205
  // src/email/email.service.ts
2530
2206
  var import_brevo = require("@getbrevo/brevo");
2531
- var import_common45 = require("@nestjs/common");
2532
- var import_config10 = require("@nestjs/config");
2207
+ var import_common42 = require("@nestjs/common");
2208
+ var import_config11 = require("@nestjs/config");
2533
2209
  function _ts_decorate16(decorators, target, key, desc2) {
2534
2210
  var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
2535
2211
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
@@ -2537,16 +2213,16 @@ function _ts_decorate16(decorators, target, key, desc2) {
2537
2213
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2538
2214
  }
2539
2215
  __name(_ts_decorate16, "_ts_decorate");
2540
- function _ts_metadata11(k, v) {
2216
+ function _ts_metadata12(k, v) {
2541
2217
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
2542
2218
  }
2543
- __name(_ts_metadata11, "_ts_metadata");
2219
+ __name(_ts_metadata12, "_ts_metadata");
2544
2220
  var EmailService = class _EmailService {
2545
2221
  static {
2546
2222
  __name(this, "EmailService");
2547
2223
  }
2548
2224
  configService;
2549
- logger = new import_common45.Logger(_EmailService.name);
2225
+ logger = new import_common42.Logger(_EmailService.name);
2550
2226
  brevoClient;
2551
2227
  senderEmail;
2552
2228
  senderName;
@@ -2979,28 +2655,117 @@ This is an automated message, please do not reply.
2979
2655
  });
2980
2656
  this.logger.log(`Email revert confirmation sent to ${email}`);
2981
2657
  }
2982
- // Verifies Brevo API connectivity a 400 response means the API is reachable
2983
- async verifyConnection() {
2984
- try {
2985
- await this.brevoClient.transactionalEmails.sendTransacEmail({
2986
- sender: {
2987
- email: this.senderEmail,
2988
- name: this.senderName
2989
- },
2990
- to: [
2991
- {
2992
- email: this.senderEmail
2993
- }
2994
- ],
2995
- subject: "Connection Test",
2996
- htmlContent: "<p>Test</p>"
2997
- });
2998
- return true;
2999
- } catch (err) {
3000
- if (err instanceof import_brevo.BrevoError && err.statusCode === 400) {
3001
- return true;
3002
- }
3003
- this.logger.error("Brevo connection verification failed:", err);
2658
+ // Sends an invite email to a new portal user with their set-password link
2659
+ async sendInviteEmail(params) {
2660
+ const { to, name, inviteUrl } = params;
2661
+ const subject = "You have been invited to Vritti AI";
2662
+ const htmlContent = `
2663
+ <!DOCTYPE html>
2664
+ <html>
2665
+ <head>
2666
+ <meta charset="UTF-8">
2667
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
2668
+ </head>
2669
+ <body style="margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; background-color: #f5f5f5;">
2670
+ <table role="presentation" style="width: 100%; border-collapse: collapse;">
2671
+ <tr>
2672
+ <td style="padding: 40px 20px;">
2673
+ <table role="presentation" style="max-width: 600px; margin: 0 auto; background-color: #ffffff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
2674
+ <!-- Header -->
2675
+ <tr>
2676
+ <td style="padding: 40px 40px 20px; text-align: center; border-bottom: 1px solid #e0e0e0;">
2677
+ <h1 style="margin: 0; color: #1a1a1a; font-size: 24px; font-weight: 600;">You're Invited</h1>
2678
+ </td>
2679
+ </tr>
2680
+
2681
+ <!-- Content -->
2682
+ <tr>
2683
+ <td style="padding: 40px;">
2684
+ <p style="margin: 0 0 20px; color: #333333; font-size: 16px; line-height: 1.6;">
2685
+ Hello <strong>${name}</strong>,
2686
+ </p>
2687
+ <p style="margin: 0 0 30px; color: #333333; font-size: 16px; line-height: 1.6;">
2688
+ You have been invited to join Vritti AI. Click the button below to set your password and get started.
2689
+ </p>
2690
+
2691
+ <div style="text-align: center; margin: 30px 0;">
2692
+ <a href="${inviteUrl}" style="display: inline-block; padding: 14px 32px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: #ffffff; text-decoration: none; border-radius: 6px; font-weight: 600; font-size: 16px;">
2693
+ Set Your Password
2694
+ </a>
2695
+ </div>
2696
+
2697
+ <p style="margin: 30px 0 0; color: #666666; font-size: 14px; line-height: 1.6;">
2698
+ If you did not expect this invitation, you can safely ignore this email.
2699
+ </p>
2700
+ </td>
2701
+ </tr>
2702
+
2703
+ <!-- Footer -->
2704
+ <tr>
2705
+ <td style="padding: 30px 40px; border-top: 1px solid #e0e0e0; text-align: center;">
2706
+ <p style="margin: 0; color: #999999; font-size: 12px; line-height: 1.5;">
2707
+ Vritti AI Cloud - Cloud Management Platform
2708
+ </p>
2709
+ <p style="margin: 8px 0 0; color: #999999; font-size: 12px; line-height: 1.5;">
2710
+ This is an automated message, please do not reply.
2711
+ </p>
2712
+ </td>
2713
+ </tr>
2714
+ </table>
2715
+ </td>
2716
+ </tr>
2717
+ </table>
2718
+ </body>
2719
+ </html>
2720
+ `;
2721
+ const textContent = `
2722
+ Hello ${name},
2723
+
2724
+ You have been invited to join Vritti AI. Visit the link below to set your password and get started:
2725
+
2726
+ ${inviteUrl}
2727
+
2728
+ If you did not expect this invitation, you can safely ignore this email.
2729
+
2730
+ ---
2731
+ Vritti AI Cloud - Cloud Management Platform
2732
+ This is an automated message, please do not reply.
2733
+ `.trim();
2734
+ await this.sendEmail({
2735
+ to: [
2736
+ {
2737
+ email: to,
2738
+ name
2739
+ }
2740
+ ],
2741
+ subject,
2742
+ htmlContent,
2743
+ textContent
2744
+ });
2745
+ this.logger.log(`Invite email sent to ${to}`);
2746
+ }
2747
+ // Verifies Brevo API connectivity — a 400 response means the API is reachable
2748
+ async verifyConnection() {
2749
+ try {
2750
+ await this.brevoClient.transactionalEmails.sendTransacEmail({
2751
+ sender: {
2752
+ email: this.senderEmail,
2753
+ name: this.senderName
2754
+ },
2755
+ to: [
2756
+ {
2757
+ email: this.senderEmail
2758
+ }
2759
+ ],
2760
+ subject: "Connection Test",
2761
+ htmlContent: "<p>Test</p>"
2762
+ });
2763
+ return true;
2764
+ } catch (err) {
2765
+ if (err instanceof import_brevo.BrevoError && err.statusCode === 400) {
2766
+ return true;
2767
+ }
2768
+ this.logger.error("Brevo connection verification failed:", err);
3004
2769
  return false;
3005
2770
  }
3006
2771
  }
@@ -3044,10 +2809,10 @@ This is an automated message, please do not reply.
3044
2809
  }
3045
2810
  };
3046
2811
  EmailService = _ts_decorate16([
3047
- (0, import_common45.Injectable)(),
3048
- _ts_metadata11("design:type", Function),
3049
- _ts_metadata11("design:paramtypes", [
3050
- typeof import_config10.ConfigService === "undefined" ? Object : import_config10.ConfigService
2812
+ (0, import_common42.Injectable)(),
2813
+ _ts_metadata12("design:type", Function),
2814
+ _ts_metadata12("design:paramtypes", [
2815
+ typeof import_config11.ConfigService === "undefined" ? Object : import_config11.ConfigService
3051
2816
  ])
3052
2817
  ], EmailService);
3053
2818
 
@@ -3065,10 +2830,10 @@ var EmailModule = class {
3065
2830
  }
3066
2831
  };
3067
2832
  EmailModule = _ts_decorate17([
3068
- (0, import_common46.Global)(),
3069
- (0, import_common46.Module)({
2833
+ (0, import_common43.Global)(),
2834
+ (0, import_common43.Module)({
3070
2835
  imports: [
3071
- import_config11.ConfigModule
2836
+ import_config12.ConfigModule
3072
2837
  ],
3073
2838
  providers: [
3074
2839
  EmailService
@@ -3080,7 +2845,7 @@ EmailModule = _ts_decorate17([
3080
2845
  ], EmailModule);
3081
2846
 
3082
2847
  // src/filters/http-exception.filter.ts
3083
- var import_common47 = require("@nestjs/common");
2848
+ var import_common44 = require("@nestjs/common");
3084
2849
  function _ts_decorate18(decorators, target, key, desc2) {
3085
2850
  var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
3086
2851
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
@@ -3089,7 +2854,7 @@ function _ts_decorate18(decorators, target, key, desc2) {
3089
2854
  }
3090
2855
  __name(_ts_decorate18, "_ts_decorate");
3091
2856
  function getHttpStatusTitle(status) {
3092
- const enumKey = Object.entries(import_common47.HttpStatus).find(([key, value]) => value === status && Number.isNaN(Number(key)))?.[0];
2857
+ const enumKey = Object.entries(import_common44.HttpStatus).find(([key, value]) => value === status && Number.isNaN(Number(key)))?.[0];
3093
2858
  if (!enumKey) {
3094
2859
  return "Error";
3095
2860
  }
@@ -3100,17 +2865,17 @@ var HttpExceptionFilter = class _HttpExceptionFilter {
3100
2865
  static {
3101
2866
  __name(this, "HttpExceptionFilter");
3102
2867
  }
3103
- logger = new import_common47.Logger(_HttpExceptionFilter.name);
2868
+ logger = new import_common44.Logger(_HttpExceptionFilter.name);
3104
2869
  catch(exception, host) {
3105
2870
  const ctx = host.switchToHttp();
3106
2871
  const response = ctx.getResponse();
3107
2872
  const request = ctx.getRequest();
3108
- let status = import_common47.HttpStatus.INTERNAL_SERVER_ERROR;
2873
+ let status = import_common44.HttpStatus.INTERNAL_SERVER_ERROR;
3109
2874
  let type = "about:blank";
3110
2875
  let label;
3111
2876
  let detail = "Internal server error";
3112
2877
  let errors = [];
3113
- if (exception instanceof import_common47.HttpException) {
2878
+ if (this.isHttpException(exception)) {
3114
2879
  status = exception.getStatus();
3115
2880
  const exceptionResponse = exception.getResponse();
3116
2881
  if (typeof exceptionResponse === "object" && exceptionResponse !== null) {
@@ -3144,7 +2909,7 @@ var HttpExceptionFilter = class _HttpExceptionFilter {
3144
2909
  const axiosStatus = exception.response?.status;
3145
2910
  const axiosDetail = exception.response?.data?.message || exception.response?.data?.detail || exception.message;
3146
2911
  const url = exception.config?.url;
3147
- status = import_common47.HttpStatus.BAD_GATEWAY;
2912
+ status = import_common44.HttpStatus.BAD_GATEWAY;
3148
2913
  detail = `Upstream service error${axiosStatus ? ` (${axiosStatus})` : ""}: ${axiosDetail}`;
3149
2914
  this.logger.error(`Upstream API error [${axiosStatus}]: ${axiosDetail} \u2014 URL: ${url}`, exception.stack);
3150
2915
  } else {
@@ -3163,21 +2928,25 @@ var HttpExceptionFilter = class _HttpExceptionFilter {
3163
2928
  };
3164
2929
  response.header("Content-Type", "application/problem+json").status(status).send(problemDetails);
3165
2930
  }
2931
+ // Duck-type check for HttpException — avoids instanceof failing across pnpm package instances
2932
+ isHttpException(error) {
2933
+ return error instanceof Error && typeof error.getStatus === "function" && typeof error.getResponse === "function";
2934
+ }
3166
2935
  // Duck-type check for AxiosError without importing axios
3167
2936
  isAxiosError(error) {
3168
2937
  return error instanceof Error && error.isAxiosError === true;
3169
2938
  }
3170
2939
  };
3171
2940
  HttpExceptionFilter = _ts_decorate18([
3172
- (0, import_common47.Catch)()
2941
+ (0, import_common44.Catch)()
3173
2942
  ], HttpExceptionFilter);
3174
2943
 
3175
2944
  // src/logger/interceptors/http-logger.interceptor.ts
3176
- var import_common49 = require("@nestjs/common");
2945
+ var import_common46 = require("@nestjs/common");
3177
2946
  var import_operators = require("rxjs/operators");
3178
2947
 
3179
2948
  // src/logger/services/logger.service.ts
3180
- var import_common48 = require("@nestjs/common");
2949
+ var import_common45 = require("@nestjs/common");
3181
2950
  var import_winston = require("winston");
3182
2951
  var import_winston_daily_rotate_file = __toESM(require("winston-daily-rotate-file"), 1);
3183
2952
 
@@ -3222,16 +2991,16 @@ function _ts_decorate19(decorators, target, key, desc2) {
3222
2991
  return c > 3 && r && Object.defineProperty(target, key, r), r;
3223
2992
  }
3224
2993
  __name(_ts_decorate19, "_ts_decorate");
3225
- function _ts_metadata12(k, v) {
2994
+ function _ts_metadata13(k, v) {
3226
2995
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
3227
2996
  }
3228
- __name(_ts_metadata12, "_ts_metadata");
3229
- function _ts_param5(paramIndex, decorator) {
2997
+ __name(_ts_metadata13, "_ts_metadata");
2998
+ function _ts_param4(paramIndex, decorator) {
3230
2999
  return function(target, key) {
3231
3000
  decorator(target, key, paramIndex);
3232
3001
  };
3233
3002
  }
3234
- __name(_ts_param5, "_ts_param");
3003
+ __name(_ts_param4, "_ts_param");
3235
3004
  var LoggerService = class _LoggerService {
3236
3005
  static {
3237
3006
  __name(this, "LoggerService");
@@ -3271,9 +3040,9 @@ var LoggerService = class _LoggerService {
3271
3040
  }) : new import_winston.transports.Console({
3272
3041
  level,
3273
3042
  format: import_winston.format.combine(...baseFormatters, import_winston.format.printf((info) => {
3274
- const { timestamp, level: level2, message, context, correlationId, trace } = info;
3043
+ const { timestamp: timestamp2, level: level2, message, context, correlationId, trace } = info;
3275
3044
  const parts = [
3276
- timestamp,
3045
+ timestamp2,
3277
3046
  level2.toUpperCase().padEnd(7),
3278
3047
  correlationId ? `[${correlationId.toString().slice(-6)}]` : "",
3279
3048
  context ? `[${context}]` : "",
@@ -3424,11 +3193,11 @@ ${trace}`;
3424
3193
  }
3425
3194
  };
3426
3195
  LoggerService = _ts_decorate19([
3427
- (0, import_common48.Injectable)(),
3428
- _ts_param5(0, (0, import_common48.Optional)()),
3429
- _ts_param5(1, (0, import_common48.Optional)()),
3430
- _ts_metadata12("design:type", Function),
3431
- _ts_metadata12("design:paramtypes", [
3196
+ (0, import_common45.Injectable)(),
3197
+ _ts_param4(0, (0, import_common45.Optional)()),
3198
+ _ts_param4(1, (0, import_common45.Optional)()),
3199
+ _ts_metadata13("design:type", Function),
3200
+ _ts_metadata13("design:paramtypes", [
3432
3201
  typeof LoggerModuleOptions === "undefined" ? Object : LoggerModuleOptions,
3433
3202
  typeof Logger === "undefined" ? Object : Logger
3434
3203
  ])
@@ -3442,16 +3211,16 @@ function _ts_decorate20(decorators, target, key, desc2) {
3442
3211
  return c > 3 && r && Object.defineProperty(target, key, r), r;
3443
3212
  }
3444
3213
  __name(_ts_decorate20, "_ts_decorate");
3445
- function _ts_metadata13(k, v) {
3214
+ function _ts_metadata14(k, v) {
3446
3215
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
3447
3216
  }
3448
- __name(_ts_metadata13, "_ts_metadata");
3449
- function _ts_param6(paramIndex, decorator) {
3217
+ __name(_ts_metadata14, "_ts_metadata");
3218
+ function _ts_param5(paramIndex, decorator) {
3450
3219
  return function(target, key) {
3451
3220
  decorator(target, key, paramIndex);
3452
3221
  };
3453
3222
  }
3454
- __name(_ts_param6, "_ts_param");
3223
+ __name(_ts_param5, "_ts_param");
3455
3224
  var HttpLoggerInterceptor = class {
3456
3225
  static {
3457
3226
  __name(this, "HttpLoggerInterceptor");
@@ -3555,20 +3324,20 @@ var HttpLoggerInterceptor = class {
3555
3324
  }
3556
3325
  };
3557
3326
  HttpLoggerInterceptor = _ts_decorate20([
3558
- (0, import_common49.Injectable)(),
3559
- _ts_param6(1, (0, import_common49.Optional)()),
3560
- _ts_metadata13("design:type", Function),
3561
- _ts_metadata13("design:paramtypes", [
3327
+ (0, import_common46.Injectable)(),
3328
+ _ts_param5(1, (0, import_common46.Optional)()),
3329
+ _ts_metadata14("design:type", Function),
3330
+ _ts_metadata14("design:paramtypes", [
3562
3331
  typeof LoggerService === "undefined" ? Object : LoggerService,
3563
3332
  typeof HttpLoggerOptions === "undefined" ? Object : HttpLoggerOptions
3564
3333
  ])
3565
3334
  ], HttpLoggerInterceptor);
3566
3335
 
3567
3336
  // src/logger/logger.module.ts
3568
- var import_common51 = require("@nestjs/common");
3337
+ var import_common48 = require("@nestjs/common");
3569
3338
 
3570
3339
  // src/logger/middleware/correlation-id.middleware.ts
3571
- var import_common50 = require("@nestjs/common");
3340
+ var import_common47 = require("@nestjs/common");
3572
3341
  function _ts_decorate21(decorators, target, key, desc2) {
3573
3342
  var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
3574
3343
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
@@ -3576,10 +3345,10 @@ function _ts_decorate21(decorators, target, key, desc2) {
3576
3345
  return c > 3 && r && Object.defineProperty(target, key, r), r;
3577
3346
  }
3578
3347
  __name(_ts_decorate21, "_ts_decorate");
3579
- function _ts_metadata14(k, v) {
3348
+ function _ts_metadata15(k, v) {
3580
3349
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
3581
3350
  }
3582
- __name(_ts_metadata14, "_ts_metadata");
3351
+ __name(_ts_metadata15, "_ts_metadata");
3583
3352
  var CorrelationIdMiddleware = class {
3584
3353
  static {
3585
3354
  __name(this, "CorrelationIdMiddleware");
@@ -3617,9 +3386,9 @@ var CorrelationIdMiddleware = class {
3617
3386
  }
3618
3387
  };
3619
3388
  CorrelationIdMiddleware = _ts_decorate21([
3620
- (0, import_common50.Injectable)(),
3621
- _ts_metadata14("design:type", Function),
3622
- _ts_metadata14("design:paramtypes", [
3389
+ (0, import_common47.Injectable)(),
3390
+ _ts_metadata15("design:type", Function),
3391
+ _ts_metadata15("design:paramtypes", [
3623
3392
  typeof CorrelationIdMiddlewareOptions === "undefined" ? Object : CorrelationIdMiddlewareOptions
3624
3393
  ])
3625
3394
  ], CorrelationIdMiddleware);
@@ -3708,9 +3477,9 @@ function mergeWithDefaults(options = {}) {
3708
3477
  __name(mergeWithDefaults, "mergeWithDefaults");
3709
3478
  function createDefaultLoggerProvider(options) {
3710
3479
  return {
3711
- provide: import_common51.Logger,
3480
+ provide: import_common48.Logger,
3712
3481
  useFactory: /* @__PURE__ */ __name(() => {
3713
- const logger = new import_common51.Logger();
3482
+ const logger = new import_common48.Logger();
3714
3483
  if (options.level) {
3715
3484
  const levels = getLevelsUpTo(options.level);
3716
3485
  logger.setLogLevels?.(levels);
@@ -3740,7 +3509,7 @@ function createLoggerProviders(options = {}) {
3740
3509
  inject: [
3741
3510
  LOGGER_MODULE_OPTIONS,
3742
3511
  {
3743
- token: import_common51.Logger,
3512
+ token: import_common48.Logger,
3744
3513
  optional: true
3745
3514
  }
3746
3515
  ]
@@ -3819,10 +3588,10 @@ var LoggerModule = class _LoggerModule {
3819
3588
  ...asyncProviders,
3820
3589
  // Default logger provider
3821
3590
  {
3822
- provide: import_common51.Logger,
3591
+ provide: import_common48.Logger,
3823
3592
  useFactory: /* @__PURE__ */ __name((opts) => {
3824
3593
  if (opts.provider === "default") {
3825
- const logger = new import_common51.Logger();
3594
+ const logger = new import_common48.Logger();
3826
3595
  if (opts.level) {
3827
3596
  const levels = getLevelsUpTo(opts.level);
3828
3597
  logger.setLogLevels?.(levels);
@@ -3844,7 +3613,7 @@ var LoggerModule = class _LoggerModule {
3844
3613
  inject: [
3845
3614
  LOGGER_MODULE_OPTIONS,
3846
3615
  {
3847
- token: import_common51.Logger,
3616
+ token: import_common48.Logger,
3848
3617
  optional: true
3849
3618
  }
3850
3619
  ]
@@ -3944,24 +3713,24 @@ var LoggerModule = class _LoggerModule {
3944
3713
  }
3945
3714
  };
3946
3715
  LoggerModule = _ts_decorate22([
3947
- (0, import_common51.Global)(),
3948
- (0, import_common51.Module)({})
3716
+ (0, import_common48.Global)(),
3717
+ (0, import_common48.Module)({})
3949
3718
  ], LoggerModule);
3950
3719
 
3951
3720
  // src/root/root.module.ts
3952
- var import_common57 = require("@nestjs/common");
3721
+ var import_common54 = require("@nestjs/common");
3953
3722
 
3954
3723
  // src/root/controllers/app.controller.ts
3955
- var import_common54 = require("@nestjs/common");
3956
- var import_swagger5 = require("@nestjs/swagger");
3724
+ var import_common51 = require("@nestjs/common");
3725
+ var import_swagger7 = require("@nestjs/swagger");
3957
3726
 
3958
3727
  // src/root/docs/app.docs.ts
3959
- var import_common52 = require("@nestjs/common");
3960
- var import_swagger4 = require("@nestjs/swagger");
3728
+ var import_common49 = require("@nestjs/common");
3729
+ var import_swagger6 = require("@nestjs/swagger");
3961
3730
  function ApiHealthCheck() {
3962
- return (0, import_common52.applyDecorators)((0, import_swagger4.ApiOperation)({
3731
+ return (0, import_common49.applyDecorators)((0, import_swagger6.ApiOperation)({
3963
3732
  summary: "Health check endpoint"
3964
- }), (0, import_swagger4.ApiResponse)({
3733
+ }), (0, import_swagger6.ApiResponse)({
3965
3734
  status: 200,
3966
3735
  description: "Returns a welcome message indicating the API is running",
3967
3736
  type: String
@@ -3970,7 +3739,7 @@ function ApiHealthCheck() {
3970
3739
  __name(ApiHealthCheck, "ApiHealthCheck");
3971
3740
 
3972
3741
  // src/root/services/app.service.ts
3973
- var import_common53 = require("@nestjs/common");
3742
+ var import_common50 = require("@nestjs/common");
3974
3743
  function _ts_decorate23(decorators, target, key, desc2) {
3975
3744
  var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
3976
3745
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
@@ -3988,7 +3757,7 @@ var AppService = class {
3988
3757
  }
3989
3758
  };
3990
3759
  AppService = _ts_decorate23([
3991
- (0, import_common53.Injectable)()
3760
+ (0, import_common50.Injectable)()
3992
3761
  ], AppService);
3993
3762
 
3994
3763
  // src/root/controllers/app.controller.ts
@@ -3999,10 +3768,10 @@ function _ts_decorate24(decorators, target, key, desc2) {
3999
3768
  return c > 3 && r && Object.defineProperty(target, key, r), r;
4000
3769
  }
4001
3770
  __name(_ts_decorate24, "_ts_decorate");
4002
- function _ts_metadata15(k, v) {
3771
+ function _ts_metadata16(k, v) {
4003
3772
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4004
3773
  }
4005
- __name(_ts_metadata15, "_ts_metadata");
3774
+ __name(_ts_metadata16, "_ts_metadata");
4006
3775
  var AppController = class {
4007
3776
  static {
4008
3777
  __name(this, "AppController");
@@ -4017,34 +3786,34 @@ var AppController = class {
4017
3786
  }
4018
3787
  };
4019
3788
  _ts_decorate24([
4020
- (0, import_common54.Get)(),
3789
+ (0, import_common51.Get)(),
4021
3790
  Public(),
4022
3791
  ApiHealthCheck(),
4023
- _ts_metadata15("design:type", Function),
4024
- _ts_metadata15("design:paramtypes", []),
4025
- _ts_metadata15("design:returntype", String)
3792
+ _ts_metadata16("design:type", Function),
3793
+ _ts_metadata16("design:paramtypes", []),
3794
+ _ts_metadata16("design:returntype", String)
4026
3795
  ], AppController.prototype, "getHello", null);
4027
3796
  AppController = _ts_decorate24([
4028
- (0, import_swagger5.ApiTags)("Health"),
4029
- (0, import_common54.Controller)(),
4030
- _ts_metadata15("design:type", Function),
4031
- _ts_metadata15("design:paramtypes", [
3797
+ (0, import_swagger7.ApiTags)("Health"),
3798
+ (0, import_common51.Controller)(),
3799
+ _ts_metadata16("design:type", Function),
3800
+ _ts_metadata16("design:paramtypes", [
4032
3801
  typeof AppService === "undefined" ? Object : AppService
4033
3802
  ])
4034
3803
  ], AppController);
4035
3804
 
4036
3805
  // src/root/controllers/csrf.controller.ts
4037
- var import_common56 = require("@nestjs/common");
4038
- var import_swagger7 = require("@nestjs/swagger");
3806
+ var import_common53 = require("@nestjs/common");
3807
+ var import_swagger9 = require("@nestjs/swagger");
4039
3808
 
4040
3809
  // src/root/docs/csrf.docs.ts
4041
- var import_common55 = require("@nestjs/common");
4042
- var import_swagger6 = require("@nestjs/swagger");
3810
+ var import_common52 = require("@nestjs/common");
3811
+ var import_swagger8 = require("@nestjs/swagger");
4043
3812
  function ApiGetCsrfToken() {
4044
- return (0, import_common55.applyDecorators)((0, import_swagger6.ApiOperation)({
3813
+ return (0, import_common52.applyDecorators)((0, import_swagger8.ApiOperation)({
4045
3814
  summary: "Get CSRF token",
4046
3815
  description: "Generates and returns a CSRF token that must be included in all state-changing requests (POST, PUT, PATCH, DELETE). The token should be sent in the X-CSRF-Token header."
4047
- }), (0, import_swagger6.ApiResponse)({
3816
+ }), (0, import_swagger8.ApiResponse)({
4048
3817
  status: 200,
4049
3818
  description: "CSRF token generated successfully",
4050
3819
  schema: {
@@ -4072,16 +3841,16 @@ function _ts_decorate25(decorators, target, key, desc2) {
4072
3841
  return c > 3 && r && Object.defineProperty(target, key, r), r;
4073
3842
  }
4074
3843
  __name(_ts_decorate25, "_ts_decorate");
4075
- function _ts_metadata16(k, v) {
3844
+ function _ts_metadata17(k, v) {
4076
3845
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4077
3846
  }
4078
- __name(_ts_metadata16, "_ts_metadata");
4079
- function _ts_param7(paramIndex, decorator) {
3847
+ __name(_ts_metadata17, "_ts_metadata");
3848
+ function _ts_param6(paramIndex, decorator) {
4080
3849
  return function(target, key) {
4081
3850
  decorator(target, key, paramIndex);
4082
3851
  };
4083
3852
  }
4084
- __name(_ts_param7, "_ts_param");
3853
+ __name(_ts_param6, "_ts_param");
4085
3854
  var CsrfController = class {
4086
3855
  static {
4087
3856
  __name(this, "CsrfController");
@@ -4095,22 +3864,22 @@ var CsrfController = class {
4095
3864
  }
4096
3865
  };
4097
3866
  _ts_decorate25([
4098
- (0, import_common56.Get)("token"),
3867
+ (0, import_common53.Get)("token"),
4099
3868
  Public(),
4100
- (0, import_common56.HttpCode)(import_common56.HttpStatus.OK),
3869
+ (0, import_common53.HttpCode)(import_common53.HttpStatus.OK),
4101
3870
  ApiGetCsrfToken(),
4102
- _ts_param7(0, (0, import_common56.Res)({
3871
+ _ts_param6(0, (0, import_common53.Res)({
4103
3872
  passthrough: true
4104
3873
  })),
4105
- _ts_metadata16("design:type", Function),
4106
- _ts_metadata16("design:paramtypes", [
3874
+ _ts_metadata17("design:type", Function),
3875
+ _ts_metadata17("design:paramtypes", [
4107
3876
  typeof FastifyReply === "undefined" ? Object : FastifyReply
4108
3877
  ]),
4109
- _ts_metadata16("design:returntype", Object)
3878
+ _ts_metadata17("design:returntype", Object)
4110
3879
  ], CsrfController.prototype, "getToken", null);
4111
3880
  CsrfController = _ts_decorate25([
4112
- (0, import_swagger7.ApiTags)("CSRF"),
4113
- (0, import_common56.Controller)("csrf")
3881
+ (0, import_swagger9.ApiTags)("CSRF"),
3882
+ (0, import_common53.Controller)("csrf")
4114
3883
  ], CsrfController);
4115
3884
 
4116
3885
  // src/root/root.module.ts
@@ -4127,7 +3896,7 @@ var RootModule = class {
4127
3896
  }
4128
3897
  };
4129
3898
  RootModule = _ts_decorate26([
4130
- (0, import_common57.Module)({
3899
+ (0, import_common54.Module)({
4131
3900
  controllers: [
4132
3901
  AppController,
4133
3902
  CsrfController
@@ -4347,6 +4116,1066 @@ function normalizePhoneNumber(phone) {
4347
4116
  return phone.startsWith("+") ? phone : `+${phone}`;
4348
4117
  }
4349
4118
  __name(normalizePhoneNumber, "normalizePhoneNumber");
4119
+
4120
+ // src/data-table/data-table.module.ts
4121
+ var import_common62 = require("@nestjs/common");
4122
+ var import_config15 = require("@nestjs/config");
4123
+
4124
+ // src/data-table/data-table.constants.ts
4125
+ var DATA_TABLE_VIEWS_TABLE = Symbol("DATA_TABLE_VIEWS_TABLE");
4126
+
4127
+ // src/data-table/state/controllers/data-table-state.controller.ts
4128
+ var import_common57 = require("@nestjs/common");
4129
+ var import_swagger12 = require("@nestjs/swagger");
4130
+
4131
+ // src/data-table/state/docs/data-table-state.docs.ts
4132
+ var import_common55 = require("@nestjs/common");
4133
+ var import_swagger11 = require("@nestjs/swagger");
4134
+
4135
+ // src/data-table/state/dto/request/upsert-data-table-state.dto.ts
4136
+ var import_swagger10 = require("@nestjs/swagger");
4137
+ var import_class_validator3 = require("class-validator");
4138
+ function _ts_decorate27(decorators, target, key, desc2) {
4139
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
4140
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
4141
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
4142
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
4143
+ }
4144
+ __name(_ts_decorate27, "_ts_decorate");
4145
+ function _ts_metadata18(k, v) {
4146
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4147
+ }
4148
+ __name(_ts_metadata18, "_ts_metadata");
4149
+ var UpsertDataTableStateDto = class {
4150
+ static {
4151
+ __name(this, "UpsertDataTableStateDto");
4152
+ }
4153
+ tableSlug;
4154
+ state;
4155
+ activeViewId;
4156
+ };
4157
+ _ts_decorate27([
4158
+ (0, import_swagger10.ApiProperty)({
4159
+ description: "Unique slug identifying the table",
4160
+ example: "cloud-providers"
4161
+ }),
4162
+ (0, import_class_validator3.IsString)(),
4163
+ (0, import_class_validator3.MaxLength)(100),
4164
+ _ts_metadata18("design:type", String)
4165
+ ], UpsertDataTableStateDto.prototype, "tableSlug", void 0);
4166
+ _ts_decorate27([
4167
+ (0, import_swagger10.ApiProperty)({
4168
+ description: "Full table view state including filters, sort, and column visibility"
4169
+ }),
4170
+ (0, import_class_validator3.IsObject)(),
4171
+ _ts_metadata18("design:type", typeof TableViewState === "undefined" ? Object : TableViewState)
4172
+ ], UpsertDataTableStateDto.prototype, "state", void 0);
4173
+ _ts_decorate27([
4174
+ (0, import_swagger10.ApiPropertyOptional)(),
4175
+ (0, import_class_validator3.IsOptional)(),
4176
+ (0, import_class_validator3.IsUUID)(),
4177
+ _ts_metadata18("design:type", Object)
4178
+ ], UpsertDataTableStateDto.prototype, "activeViewId", void 0);
4179
+
4180
+ // src/data-table/state/docs/data-table-state.docs.ts
4181
+ function ApiUpsertDataTableState() {
4182
+ return (0, import_common55.applyDecorators)((0, import_swagger11.ApiOperation)({
4183
+ summary: "Save live table state",
4184
+ description: "Stores the current filter, sort, and column visibility state in Redis cache. Called on filter Apply and sort column click. State expires after TABLE_STATE_CACHE_TTL seconds."
4185
+ }), (0, import_swagger11.ApiBody)({
4186
+ type: UpsertDataTableStateDto
4187
+ }), (0, import_swagger11.ApiResponse)({
4188
+ status: 200,
4189
+ description: "Live state cached."
4190
+ }), (0, import_swagger11.ApiResponse)({
4191
+ status: 400,
4192
+ description: "Invalid request body."
4193
+ }), (0, import_swagger11.ApiResponse)({
4194
+ status: 401,
4195
+ description: "Unauthorized."
4196
+ }));
4197
+ }
4198
+ __name(ApiUpsertDataTableState, "ApiUpsertDataTableState");
4199
+
4200
+ // src/data-table/state/services/data-table-state.service.ts
4201
+ var import_common56 = require("@nestjs/common");
4202
+ var import_config13 = require("@nestjs/config");
4203
+ function _ts_decorate28(decorators, target, key, desc2) {
4204
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
4205
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
4206
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
4207
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
4208
+ }
4209
+ __name(_ts_decorate28, "_ts_decorate");
4210
+ function _ts_metadata19(k, v) {
4211
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4212
+ }
4213
+ __name(_ts_metadata19, "_ts_metadata");
4214
+ var EMPTY_TABLE_STATE = {
4215
+ filters: [],
4216
+ sort: [],
4217
+ columnVisibility: {},
4218
+ columnOrder: [],
4219
+ columnSizing: {},
4220
+ columnPinning: {
4221
+ left: [],
4222
+ right: []
4223
+ },
4224
+ lockedColumnSizing: false,
4225
+ density: "normal",
4226
+ filterOrder: [],
4227
+ filterVisibility: {},
4228
+ pagination: {
4229
+ limit: 20,
4230
+ offset: 0
4231
+ }
4232
+ };
4233
+ var DataTableStateService = class _DataTableStateService {
4234
+ static {
4235
+ __name(this, "DataTableStateService");
4236
+ }
4237
+ cacheService;
4238
+ configService;
4239
+ logger = new import_common56.Logger(_DataTableStateService.name);
4240
+ constructor(cacheService, configService) {
4241
+ this.cacheService = cacheService;
4242
+ this.configService = configService;
4243
+ }
4244
+ // Returns configured TTL for live table state in seconds, defaulting to 3600 (1h)
4245
+ get stateTtl() {
4246
+ return this.configService.get("TABLE_STATE_CACHE_TTL") ?? 3600;
4247
+ }
4248
+ // Saves live table state and active view ID to Redis; DB is not written
4249
+ async upsertCurrentState(userId, dto) {
4250
+ const key = `dt:${userId}:${dto.tableSlug}`;
4251
+ await this.cacheService.set(key, {
4252
+ state: dto.state,
4253
+ activeViewId: dto.activeViewId ?? null
4254
+ }, this.stateTtl);
4255
+ this.logger.log(`Cached live state for user: ${userId}, table: ${dto.tableSlug}`);
4256
+ }
4257
+ // Returns live table state and active view ID from Redis; returns empty state on miss — no DB query
4258
+ async getCurrentState(userId, tableSlug) {
4259
+ const key = `dt:${userId}:${tableSlug}`;
4260
+ const cached = await this.cacheService.get(key);
4261
+ return cached ?? {
4262
+ state: EMPTY_TABLE_STATE,
4263
+ activeViewId: null
4264
+ };
4265
+ }
4266
+ };
4267
+ DataTableStateService = _ts_decorate28([
4268
+ (0, import_common56.Injectable)(),
4269
+ _ts_metadata19("design:type", Function),
4270
+ _ts_metadata19("design:paramtypes", [
4271
+ typeof CacheService === "undefined" ? Object : CacheService,
4272
+ typeof import_config13.ConfigService === "undefined" ? Object : import_config13.ConfigService
4273
+ ])
4274
+ ], DataTableStateService);
4275
+
4276
+ // src/data-table/state/controllers/data-table-state.controller.ts
4277
+ function _ts_decorate29(decorators, target, key, desc2) {
4278
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
4279
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
4280
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
4281
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
4282
+ }
4283
+ __name(_ts_decorate29, "_ts_decorate");
4284
+ function _ts_metadata20(k, v) {
4285
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4286
+ }
4287
+ __name(_ts_metadata20, "_ts_metadata");
4288
+ function _ts_param7(paramIndex, decorator) {
4289
+ return function(target, key) {
4290
+ decorator(target, key, paramIndex);
4291
+ };
4292
+ }
4293
+ __name(_ts_param7, "_ts_param");
4294
+ var DataTableStateController = class _DataTableStateController {
4295
+ static {
4296
+ __name(this, "DataTableStateController");
4297
+ }
4298
+ dataTableStateService;
4299
+ logger = new import_common57.Logger(_DataTableStateController.name);
4300
+ constructor(dataTableStateService) {
4301
+ this.dataTableStateService = dataTableStateService;
4302
+ }
4303
+ // Saves live table state to Redis cache for the authenticated user's table
4304
+ upsertCurrentState(userId, dto) {
4305
+ this.logger.log(`POST /table-states - User: ${userId}, table: ${dto.tableSlug}`);
4306
+ return this.dataTableStateService.upsertCurrentState(userId, dto);
4307
+ }
4308
+ };
4309
+ _ts_decorate29([
4310
+ (0, import_common57.Post)(),
4311
+ (0, import_common57.HttpCode)(import_common57.HttpStatus.OK),
4312
+ ApiUpsertDataTableState(),
4313
+ _ts_param7(0, UserId()),
4314
+ _ts_param7(1, (0, import_common57.Body)()),
4315
+ _ts_metadata20("design:type", Function),
4316
+ _ts_metadata20("design:paramtypes", [
4317
+ String,
4318
+ typeof UpsertDataTableStateDto === "undefined" ? Object : UpsertDataTableStateDto
4319
+ ]),
4320
+ _ts_metadata20("design:returntype", typeof Promise === "undefined" ? Object : Promise)
4321
+ ], DataTableStateController.prototype, "upsertCurrentState", null);
4322
+ DataTableStateController = _ts_decorate29([
4323
+ (0, import_swagger12.ApiTags)("Table States"),
4324
+ (0, import_swagger12.ApiBearerAuth)(),
4325
+ RequireSession("CLOUD", "ADMIN"),
4326
+ (0, import_common57.Controller)("table-states"),
4327
+ _ts_metadata20("design:type", Function),
4328
+ _ts_metadata20("design:paramtypes", [
4329
+ typeof DataTableStateService === "undefined" ? Object : DataTableStateService
4330
+ ])
4331
+ ], DataTableStateController);
4332
+
4333
+ // src/data-table/views/controllers/data-table-views.controller.ts
4334
+ var import_common61 = require("@nestjs/common");
4335
+ var import_swagger19 = require("@nestjs/swagger");
4336
+
4337
+ // src/data-table/views/docs/data-table-views.docs.ts
4338
+ var import_common58 = require("@nestjs/common");
4339
+ var import_swagger18 = require("@nestjs/swagger");
4340
+
4341
+ // src/data-table/views/dto/entity/data-table-view.dto.ts
4342
+ var import_swagger13 = require("@nestjs/swagger");
4343
+ function _ts_decorate30(decorators, target, key, desc2) {
4344
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
4345
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
4346
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
4347
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
4348
+ }
4349
+ __name(_ts_decorate30, "_ts_decorate");
4350
+ function _ts_metadata21(k, v) {
4351
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4352
+ }
4353
+ __name(_ts_metadata21, "_ts_metadata");
4354
+ var DataTableViewDto = class _DataTableViewDto {
4355
+ static {
4356
+ __name(this, "DataTableViewDto");
4357
+ }
4358
+ id;
4359
+ name;
4360
+ tableSlug;
4361
+ state;
4362
+ isShared;
4363
+ isOwn;
4364
+ createdAt;
4365
+ updatedAt;
4366
+ // Creates a response DTO from a DataTableView entity, computing isOwn by comparing userId
4367
+ static from(view, userId) {
4368
+ const dto = new _DataTableViewDto();
4369
+ dto.id = view.id;
4370
+ dto.name = view.name ?? null;
4371
+ dto.tableSlug = view.tableSlug;
4372
+ dto.state = view.state;
4373
+ dto.isShared = view.isShared;
4374
+ dto.isOwn = view.userId === userId;
4375
+ dto.createdAt = view.createdAt;
4376
+ dto.updatedAt = view.updatedAt ?? null;
4377
+ return dto;
4378
+ }
4379
+ };
4380
+ _ts_decorate30([
4381
+ (0, import_swagger13.ApiProperty)({
4382
+ description: "View unique identifier"
4383
+ }),
4384
+ _ts_metadata21("design:type", String)
4385
+ ], DataTableViewDto.prototype, "id", void 0);
4386
+ _ts_decorate30([
4387
+ (0, import_swagger13.ApiPropertyOptional)({
4388
+ description: "Display name of the view",
4389
+ nullable: true
4390
+ }),
4391
+ _ts_metadata21("design:type", Object)
4392
+ ], DataTableViewDto.prototype, "name", void 0);
4393
+ _ts_decorate30([
4394
+ (0, import_swagger13.ApiProperty)({
4395
+ description: "Slug of the table this view belongs to",
4396
+ example: "cloud-providers"
4397
+ }),
4398
+ _ts_metadata21("design:type", String)
4399
+ ], DataTableViewDto.prototype, "tableSlug", void 0);
4400
+ _ts_decorate30([
4401
+ (0, import_swagger13.ApiProperty)({
4402
+ description: "Stored filter, sort, and column visibility state"
4403
+ }),
4404
+ _ts_metadata21("design:type", typeof TableViewState === "undefined" ? Object : TableViewState)
4405
+ ], DataTableViewDto.prototype, "state", void 0);
4406
+ _ts_decorate30([
4407
+ (0, import_swagger13.ApiProperty)({
4408
+ description: "Whether the view is visible to all users",
4409
+ example: false
4410
+ }),
4411
+ _ts_metadata21("design:type", Boolean)
4412
+ ], DataTableViewDto.prototype, "isShared", void 0);
4413
+ _ts_decorate30([
4414
+ (0, import_swagger13.ApiProperty)({
4415
+ description: "Whether the requesting user owns this view",
4416
+ example: true
4417
+ }),
4418
+ _ts_metadata21("design:type", Boolean)
4419
+ ], DataTableViewDto.prototype, "isOwn", void 0);
4420
+ _ts_decorate30([
4421
+ (0, import_swagger13.ApiProperty)({
4422
+ description: "Creation timestamp"
4423
+ }),
4424
+ _ts_metadata21("design:type", typeof Date === "undefined" ? Object : Date)
4425
+ ], DataTableViewDto.prototype, "createdAt", void 0);
4426
+ _ts_decorate30([
4427
+ (0, import_swagger13.ApiPropertyOptional)({
4428
+ description: "Last updated timestamp",
4429
+ nullable: true
4430
+ }),
4431
+ _ts_metadata21("design:type", Object)
4432
+ ], DataTableViewDto.prototype, "updatedAt", void 0);
4433
+
4434
+ // src/data-table/views/dto/request/create-data-table-view.dto.ts
4435
+ var import_swagger14 = require("@nestjs/swagger");
4436
+ var import_class_validator4 = require("class-validator");
4437
+ function _ts_decorate31(decorators, target, key, desc2) {
4438
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
4439
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
4440
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
4441
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
4442
+ }
4443
+ __name(_ts_decorate31, "_ts_decorate");
4444
+ function _ts_metadata22(k, v) {
4445
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4446
+ }
4447
+ __name(_ts_metadata22, "_ts_metadata");
4448
+ var CreateDataTableViewDto = class {
4449
+ static {
4450
+ __name(this, "CreateDataTableViewDto");
4451
+ }
4452
+ name;
4453
+ tableSlug;
4454
+ state;
4455
+ isShared;
4456
+ };
4457
+ _ts_decorate31([
4458
+ (0, import_swagger14.ApiProperty)({
4459
+ description: "Display name for the saved view",
4460
+ example: "AWS Only"
4461
+ }),
4462
+ (0, import_class_validator4.IsString)(),
4463
+ (0, import_class_validator4.MaxLength)(100),
4464
+ _ts_metadata22("design:type", String)
4465
+ ], CreateDataTableViewDto.prototype, "name", void 0);
4466
+ _ts_decorate31([
4467
+ (0, import_swagger14.ApiProperty)({
4468
+ description: "Unique slug identifying the table",
4469
+ example: "cloud-providers"
4470
+ }),
4471
+ (0, import_class_validator4.IsString)(),
4472
+ (0, import_class_validator4.MaxLength)(100),
4473
+ _ts_metadata22("design:type", String)
4474
+ ], CreateDataTableViewDto.prototype, "tableSlug", void 0);
4475
+ _ts_decorate31([
4476
+ (0, import_swagger14.ApiProperty)({
4477
+ description: "Full table view state including filters, sort, and column visibility"
4478
+ }),
4479
+ (0, import_class_validator4.IsObject)(),
4480
+ _ts_metadata22("design:type", typeof TableViewState === "undefined" ? Object : TableViewState)
4481
+ ], CreateDataTableViewDto.prototype, "state", void 0);
4482
+ _ts_decorate31([
4483
+ (0, import_swagger14.ApiPropertyOptional)({
4484
+ description: "Whether this view is visible to all users",
4485
+ example: false
4486
+ }),
4487
+ (0, import_class_validator4.IsBoolean)(),
4488
+ (0, import_class_validator4.IsOptional)(),
4489
+ _ts_metadata22("design:type", Boolean)
4490
+ ], CreateDataTableViewDto.prototype, "isShared", void 0);
4491
+
4492
+ // src/data-table/views/dto/request/rename-data-table-view.dto.ts
4493
+ var import_swagger15 = require("@nestjs/swagger");
4494
+ var import_class_validator5 = require("class-validator");
4495
+ function _ts_decorate32(decorators, target, key, desc2) {
4496
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
4497
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
4498
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
4499
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
4500
+ }
4501
+ __name(_ts_decorate32, "_ts_decorate");
4502
+ function _ts_metadata23(k, v) {
4503
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4504
+ }
4505
+ __name(_ts_metadata23, "_ts_metadata");
4506
+ var RenameDataTableViewDto = class {
4507
+ static {
4508
+ __name(this, "RenameDataTableViewDto");
4509
+ }
4510
+ name;
4511
+ };
4512
+ _ts_decorate32([
4513
+ (0, import_swagger15.ApiProperty)({
4514
+ description: "New display name for the view",
4515
+ example: "AWS Only"
4516
+ }),
4517
+ (0, import_class_validator5.IsString)(),
4518
+ (0, import_class_validator5.MinLength)(1),
4519
+ (0, import_class_validator5.MaxLength)(100),
4520
+ _ts_metadata23("design:type", String)
4521
+ ], RenameDataTableViewDto.prototype, "name", void 0);
4522
+
4523
+ // src/data-table/views/dto/request/toggle-share-data-table-view.dto.ts
4524
+ var import_swagger16 = require("@nestjs/swagger");
4525
+ var import_class_validator6 = require("class-validator");
4526
+ function _ts_decorate33(decorators, target, key, desc2) {
4527
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
4528
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
4529
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
4530
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
4531
+ }
4532
+ __name(_ts_decorate33, "_ts_decorate");
4533
+ function _ts_metadata24(k, v) {
4534
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4535
+ }
4536
+ __name(_ts_metadata24, "_ts_metadata");
4537
+ var ToggleShareDataTableViewDto = class {
4538
+ static {
4539
+ __name(this, "ToggleShareDataTableViewDto");
4540
+ }
4541
+ isShared;
4542
+ };
4543
+ _ts_decorate33([
4544
+ (0, import_swagger16.ApiProperty)({
4545
+ description: "Whether the view should be visible to all users",
4546
+ example: true
4547
+ }),
4548
+ (0, import_class_validator6.IsBoolean)(),
4549
+ _ts_metadata24("design:type", Boolean)
4550
+ ], ToggleShareDataTableViewDto.prototype, "isShared", void 0);
4551
+
4552
+ // src/data-table/views/dto/request/update-data-table-view.dto.ts
4553
+ var import_swagger17 = require("@nestjs/swagger");
4554
+ var import_class_validator7 = require("class-validator");
4555
+ function _ts_decorate34(decorators, target, key, desc2) {
4556
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
4557
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
4558
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
4559
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
4560
+ }
4561
+ __name(_ts_decorate34, "_ts_decorate");
4562
+ function _ts_metadata25(k, v) {
4563
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4564
+ }
4565
+ __name(_ts_metadata25, "_ts_metadata");
4566
+ var UpdateDataTableViewDto = class {
4567
+ static {
4568
+ __name(this, "UpdateDataTableViewDto");
4569
+ }
4570
+ state;
4571
+ };
4572
+ _ts_decorate34([
4573
+ (0, import_swagger17.ApiProperty)({
4574
+ description: "Updated filter, sort, and column visibility state"
4575
+ }),
4576
+ (0, import_class_validator7.IsObject)(),
4577
+ _ts_metadata25("design:type", typeof TableViewState === "undefined" ? Object : TableViewState)
4578
+ ], UpdateDataTableViewDto.prototype, "state", void 0);
4579
+
4580
+ // src/data-table/views/docs/data-table-views.docs.ts
4581
+ function ApiListDataTableViews() {
4582
+ return (0, import_common58.applyDecorators)((0, import_swagger18.ApiOperation)({
4583
+ summary: "List named table views",
4584
+ description: "Returns the authenticated user's own named views plus all shared views for the given table slug."
4585
+ }), (0, import_swagger18.ApiQuery)({
4586
+ name: "tableSlug",
4587
+ description: "Slug of the table to fetch views for",
4588
+ example: "cloud-providers",
4589
+ required: true
4590
+ }), (0, import_swagger18.ApiResponse)({
4591
+ status: 200,
4592
+ description: "Named views retrieved.",
4593
+ type: [
4594
+ DataTableViewDto
4595
+ ]
4596
+ }), (0, import_swagger18.ApiResponse)({
4597
+ status: 401,
4598
+ description: "Unauthorized."
4599
+ }));
4600
+ }
4601
+ __name(ApiListDataTableViews, "ApiListDataTableViews");
4602
+ function ApiCreateDataTableView() {
4603
+ return (0, import_common58.applyDecorators)((0, import_swagger18.ApiOperation)({
4604
+ summary: "Create named table view",
4605
+ description: "Saves the current table state as a named view snapshot. The name must be unique per user+table."
4606
+ }), (0, import_swagger18.ApiBody)({
4607
+ type: CreateDataTableViewDto
4608
+ }), (0, import_swagger18.ApiResponse)({
4609
+ status: 201,
4610
+ description: "Named view created.",
4611
+ type: DataTableViewDto
4612
+ }), (0, import_swagger18.ApiResponse)({
4613
+ status: 400,
4614
+ description: "Invalid request body."
4615
+ }), (0, import_swagger18.ApiResponse)({
4616
+ status: 401,
4617
+ description: "Unauthorized."
4618
+ }));
4619
+ }
4620
+ __name(ApiCreateDataTableView, "ApiCreateDataTableView");
4621
+ function ApiUpdateDataTableView() {
4622
+ return (0, import_common58.applyDecorators)((0, import_swagger18.ApiOperation)({
4623
+ summary: "Update named table view",
4624
+ description: "Updates the state of an existing named view. Only the owner can update."
4625
+ }), (0, import_swagger18.ApiParam)({
4626
+ name: "id",
4627
+ description: "UUID of the table view to update"
4628
+ }), (0, import_swagger18.ApiBody)({
4629
+ type: UpdateDataTableViewDto
4630
+ }), (0, import_swagger18.ApiResponse)({
4631
+ status: 200,
4632
+ description: "View updated.",
4633
+ type: DataTableViewDto
4634
+ }), (0, import_swagger18.ApiResponse)({
4635
+ status: 400,
4636
+ description: "Validation failed or not owned by caller."
4637
+ }), (0, import_swagger18.ApiResponse)({
4638
+ status: 401,
4639
+ description: "Unauthorized."
4640
+ }), (0, import_swagger18.ApiResponse)({
4641
+ status: 404,
4642
+ description: "View not found."
4643
+ }));
4644
+ }
4645
+ __name(ApiUpdateDataTableView, "ApiUpdateDataTableView");
4646
+ function ApiRenameDataTableView() {
4647
+ return (0, import_common58.applyDecorators)((0, import_swagger18.ApiOperation)({
4648
+ summary: "Rename a named table view",
4649
+ description: "Updates the display name of an existing view. The new name must be unique per user+table. Only the owner can rename."
4650
+ }), (0, import_swagger18.ApiParam)({
4651
+ name: "id",
4652
+ description: "UUID of the table view to rename"
4653
+ }), (0, import_swagger18.ApiBody)({
4654
+ type: RenameDataTableViewDto
4655
+ }), (0, import_swagger18.ApiResponse)({
4656
+ status: 200,
4657
+ description: "View renamed.",
4658
+ type: DataTableViewDto
4659
+ }), (0, import_swagger18.ApiResponse)({
4660
+ status: 400,
4661
+ description: "Not owned by caller."
4662
+ }), (0, import_swagger18.ApiResponse)({
4663
+ status: 401,
4664
+ description: "Unauthorized."
4665
+ }), (0, import_swagger18.ApiResponse)({
4666
+ status: 404,
4667
+ description: "View not found."
4668
+ }), (0, import_swagger18.ApiResponse)({
4669
+ status: 409,
4670
+ description: "A view with this name already exists."
4671
+ }));
4672
+ }
4673
+ __name(ApiRenameDataTableView, "ApiRenameDataTableView");
4674
+ function ApiToggleShareDataTableView() {
4675
+ return (0, import_common58.applyDecorators)((0, import_swagger18.ApiOperation)({
4676
+ summary: "Toggle view sharing",
4677
+ description: "Makes a view visible to all users (shared) or restricts it to the owner only (private). Only the owner can toggle sharing."
4678
+ }), (0, import_swagger18.ApiParam)({
4679
+ name: "id",
4680
+ description: "UUID of the table view"
4681
+ }), (0, import_swagger18.ApiBody)({
4682
+ type: ToggleShareDataTableViewDto
4683
+ }), (0, import_swagger18.ApiResponse)({
4684
+ status: 200,
4685
+ description: "Sharing status updated.",
4686
+ type: DataTableViewDto
4687
+ }), (0, import_swagger18.ApiResponse)({
4688
+ status: 400,
4689
+ description: "Not owned by caller."
4690
+ }), (0, import_swagger18.ApiResponse)({
4691
+ status: 401,
4692
+ description: "Unauthorized."
4693
+ }), (0, import_swagger18.ApiResponse)({
4694
+ status: 404,
4695
+ description: "View not found."
4696
+ }));
4697
+ }
4698
+ __name(ApiToggleShareDataTableView, "ApiToggleShareDataTableView");
4699
+ function ApiDeleteDataTableView() {
4700
+ return (0, import_common58.applyDecorators)((0, import_swagger18.ApiOperation)({
4701
+ summary: "Delete named table view",
4702
+ description: "Permanently deletes a named view. Only the owner can delete their own views."
4703
+ }), (0, import_swagger18.ApiParam)({
4704
+ name: "id",
4705
+ description: "UUID of the table view to delete"
4706
+ }), (0, import_swagger18.ApiResponse)({
4707
+ status: 200,
4708
+ description: "View deleted.",
4709
+ type: DataTableViewDto
4710
+ }), (0, import_swagger18.ApiResponse)({
4711
+ status: 400,
4712
+ description: "Not owned by caller."
4713
+ }), (0, import_swagger18.ApiResponse)({
4714
+ status: 401,
4715
+ description: "Unauthorized."
4716
+ }), (0, import_swagger18.ApiResponse)({
4717
+ status: 404,
4718
+ description: "View not found."
4719
+ }));
4720
+ }
4721
+ __name(ApiDeleteDataTableView, "ApiDeleteDataTableView");
4722
+
4723
+ // src/data-table/views/services/data-table-views.service.ts
4724
+ var import_node_crypto2 = require("crypto");
4725
+ var import_common60 = require("@nestjs/common");
4726
+ var import_config14 = require("@nestjs/config");
4727
+
4728
+ // src/data-table/views/repositories/data-table-views.repository.ts
4729
+ var import_common59 = require("@nestjs/common");
4730
+ var import_drizzle_orm3 = require("drizzle-orm");
4731
+ function _ts_decorate35(decorators, target, key, desc2) {
4732
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
4733
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
4734
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
4735
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
4736
+ }
4737
+ __name(_ts_decorate35, "_ts_decorate");
4738
+ function _ts_metadata26(k, v) {
4739
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4740
+ }
4741
+ __name(_ts_metadata26, "_ts_metadata");
4742
+ function _ts_param8(paramIndex, decorator) {
4743
+ return function(target, key) {
4744
+ decorator(target, key, paramIndex);
4745
+ };
4746
+ }
4747
+ __name(_ts_param8, "_ts_param");
4748
+ var NAMED_VIEWS_LIMIT = 100;
4749
+ var DataTableViewsRepository = class extends PrimaryBaseRepository {
4750
+ static {
4751
+ __name(this, "DataTableViewsRepository");
4752
+ }
4753
+ constructor(database, table) {
4754
+ super(database, table);
4755
+ }
4756
+ // Returns personal (non-shared) named views owned by the user for a given table
4757
+ async findPersonalViewsBySlug(userId, tableSlug) {
4758
+ const t = this.table;
4759
+ return this.db.select().from(this.table).where((0, import_drizzle_orm3.and)((0, import_drizzle_orm3.eq)(t.tableSlug, tableSlug), (0, import_drizzle_orm3.eq)(t.userId, userId), (0, import_drizzle_orm3.eq)(t.isShared, false))).orderBy(t.createdAt).limit(NAMED_VIEWS_LIMIT);
4760
+ }
4761
+ // Returns all shared named views for a given table — visible to all users
4762
+ async findSharedViewsBySlug(tableSlug) {
4763
+ const t = this.table;
4764
+ return this.db.select().from(this.table).where((0, import_drizzle_orm3.and)((0, import_drizzle_orm3.eq)(t.tableSlug, tableSlug), (0, import_drizzle_orm3.eq)(t.isShared, true))).orderBy(t.createdAt).limit(NAMED_VIEWS_LIMIT);
4765
+ }
4766
+ };
4767
+ DataTableViewsRepository = _ts_decorate35([
4768
+ (0, import_common59.Injectable)(),
4769
+ _ts_param8(1, (0, import_common59.Inject)(DATA_TABLE_VIEWS_TABLE)),
4770
+ _ts_metadata26("design:type", Function),
4771
+ _ts_metadata26("design:paramtypes", [
4772
+ typeof PrimaryDatabaseService === "undefined" ? Object : PrimaryDatabaseService,
4773
+ typeof PgTable === "undefined" ? Object : PgTable
4774
+ ])
4775
+ ], DataTableViewsRepository);
4776
+
4777
+ // src/data-table/views/services/data-table-views.service.ts
4778
+ function _ts_decorate36(decorators, target, key, desc2) {
4779
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
4780
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
4781
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
4782
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
4783
+ }
4784
+ __name(_ts_decorate36, "_ts_decorate");
4785
+ function _ts_metadata27(k, v) {
4786
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4787
+ }
4788
+ __name(_ts_metadata27, "_ts_metadata");
4789
+ function computeChecksum(value) {
4790
+ return (0, import_node_crypto2.createHash)("sha256").update(JSON.stringify(value)).digest("hex");
4791
+ }
4792
+ __name(computeChecksum, "computeChecksum");
4793
+ var DataTableViewsService = class _DataTableViewsService {
4794
+ static {
4795
+ __name(this, "DataTableViewsService");
4796
+ }
4797
+ dataTableViewsRepository;
4798
+ cacheService;
4799
+ configService;
4800
+ logger = new import_common60.Logger(_DataTableViewsService.name);
4801
+ constructor(dataTableViewsRepository, cacheService, configService) {
4802
+ this.dataTableViewsRepository = dataTableViewsRepository;
4803
+ this.cacheService = cacheService;
4804
+ this.configService = configService;
4805
+ }
4806
+ // Builds the Redis key for a user's personal (non-shared) views for a given table
4807
+ personalViewsKey(userId, tableSlug) {
4808
+ return `views:personal:${userId}:${tableSlug}`;
4809
+ }
4810
+ // Builds the Redis key for all shared views for a given table — same key for all users
4811
+ sharedViewsKey(tableSlug) {
4812
+ return `views:shared:${tableSlug}`;
4813
+ }
4814
+ // Returns configured TTL for named views in seconds, defaulting to 86400 (24h)
4815
+ get viewsTtl() {
4816
+ return this.configService.get("TABLE_VIEWS_CACHE_TTL") ?? 86400;
4817
+ }
4818
+ // Fetches personal views from cache; falls back to DB and warms cache on miss
4819
+ async getOrCachePersonalViews(userId, tableSlug) {
4820
+ const key = this.personalViewsKey(userId, tableSlug);
4821
+ const cached = await this.cacheService.get(key);
4822
+ if (cached) {
4823
+ this.logger.debug(`Cache hit for personal views: user=${userId}, table=${tableSlug}`);
4824
+ return cached;
4825
+ }
4826
+ const rows = await this.dataTableViewsRepository.findPersonalViewsBySlug(userId, tableSlug);
4827
+ await this.cacheService.set(key, rows, this.viewsTtl);
4828
+ return rows;
4829
+ }
4830
+ // Fetches shared views from cache; falls back to DB and warms cache on miss
4831
+ async getOrCacheSharedViews(tableSlug) {
4832
+ const key = this.sharedViewsKey(tableSlug);
4833
+ const cached = await this.cacheService.get(key);
4834
+ if (cached) {
4835
+ this.logger.debug(`Cache hit for shared views: table=${tableSlug}`);
4836
+ return cached;
4837
+ }
4838
+ const rows = await this.dataTableViewsRepository.findSharedViewsBySlug(tableSlug);
4839
+ await this.cacheService.set(key, rows, this.viewsTtl);
4840
+ return rows;
4841
+ }
4842
+ // Deletes personal and/or shared cache keys based on which pools the mutation affects
4843
+ async invalidateViewsCache(userId, tableSlug, affectsPersonal, affectsShared) {
4844
+ const toDelete = [];
4845
+ if (affectsPersonal) toDelete.push(this.personalViewsKey(userId, tableSlug));
4846
+ if (affectsShared) toDelete.push(this.sharedViewsKey(tableSlug));
4847
+ if (toDelete.length > 0) await this.cacheService.del(...toDelete);
4848
+ }
4849
+ // Returns personal + shared named views — each pool fetched from cache or DB in parallel
4850
+ async findViews(userId, tableSlug) {
4851
+ const [personalRows, sharedRows] = await Promise.all([
4852
+ this.getOrCachePersonalViews(userId, tableSlug),
4853
+ this.getOrCacheSharedViews(tableSlug)
4854
+ ]);
4855
+ return [
4856
+ ...personalRows,
4857
+ ...sharedRows
4858
+ ].map((row) => DataTableViewDto.from(row, userId));
4859
+ }
4860
+ // Creates a named snapshot and invalidates the relevant cache pool
4861
+ async createView(userId, dto) {
4862
+ const view = await this.dataTableViewsRepository.create({
4863
+ userId,
4864
+ tableSlug: dto.tableSlug,
4865
+ name: dto.name,
4866
+ state: dto.state,
4867
+ isShared: dto.isShared ?? false
4868
+ });
4869
+ this.logger.log(`Created view "${dto.name}" for user: ${userId}, table: ${dto.tableSlug}`);
4870
+ const isShared = dto.isShared ?? false;
4871
+ await this.invalidateViewsCache(userId, dto.tableSlug, !isShared, isShared);
4872
+ return DataTableViewDto.from(view, userId);
4873
+ }
4874
+ // Updates the state of a named view — skips DB write if state is unchanged
4875
+ async updateView(userId, id, dto) {
4876
+ const view = await this.dataTableViewsRepository.findById(id);
4877
+ if (!view) throw new NotFoundException("Table view not found.");
4878
+ if (view.userId !== userId) throw new BadRequestException("You do not have permission to update this view.");
4879
+ if (computeChecksum(dto.state) === computeChecksum(view.state)) {
4880
+ this.logger.log(`State unchanged for view ${id} \u2014 skipping DB write`);
4881
+ return DataTableViewDto.from(view, userId);
4882
+ }
4883
+ const updated = await this.dataTableViewsRepository.update(id, {
4884
+ state: dto.state
4885
+ });
4886
+ this.logger.log(`Updated state for view ${id}, user: ${userId}`);
4887
+ await this.invalidateViewsCache(userId, view.tableSlug, !view.isShared, view.isShared);
4888
+ return DataTableViewDto.from(updated, userId);
4889
+ }
4890
+ // Toggles the sharing status of a named view — updates both personal and shared cache
4891
+ async toggleShareView(userId, id, isShared) {
4892
+ const view = await this.dataTableViewsRepository.findById(id);
4893
+ if (!view) throw new NotFoundException("Table view not found.");
4894
+ if (view.userId !== userId) throw new BadRequestException("You do not have permission to share this view.");
4895
+ const updated = await this.dataTableViewsRepository.update(id, {
4896
+ isShared
4897
+ });
4898
+ this.logger.log(`Set isShared=${isShared} for view ${id}, user: ${userId}`);
4899
+ await this.invalidateViewsCache(userId, view.tableSlug, true, true);
4900
+ return DataTableViewDto.from(updated, userId);
4901
+ }
4902
+ // Renames a named view — enforces unique name per user+table, invalidates personal cache
4903
+ async renameView(userId, id, name) {
4904
+ const view = await this.dataTableViewsRepository.findById(id);
4905
+ if (!view) throw new NotFoundException("Table view not found.");
4906
+ if (view.userId !== userId) throw new BadRequestException("You do not have permission to rename this view.");
4907
+ const existing = await this.dataTableViewsRepository.findOne({
4908
+ userId,
4909
+ tableSlug: view.tableSlug,
4910
+ name,
4911
+ isShared: false
4912
+ });
4913
+ if (existing && existing.id !== id) {
4914
+ throw new ConflictException({
4915
+ label: "Name Already Taken",
4916
+ detail: "A view with this name already exists for this table.",
4917
+ errors: [
4918
+ {
4919
+ field: "name",
4920
+ message: "Name already taken"
4921
+ }
4922
+ ]
4923
+ });
4924
+ }
4925
+ const updated = await this.dataTableViewsRepository.update(id, {
4926
+ name
4927
+ });
4928
+ this.logger.log(`Renamed view ${id} to "${name}" for user: ${userId}`);
4929
+ await this.invalidateViewsCache(userId, view.tableSlug, !view.isShared, view.isShared);
4930
+ return DataTableViewDto.from(updated, userId);
4931
+ }
4932
+ // Deletes a named view and invalidates the relevant cache pool
4933
+ async deleteView(userId, id) {
4934
+ const view = await this.dataTableViewsRepository.findById(id);
4935
+ if (!view) throw new NotFoundException("Table view not found.");
4936
+ if (view.userId !== userId) throw new BadRequestException("You do not have permission to delete this view.");
4937
+ await this.dataTableViewsRepository.delete(id);
4938
+ this.logger.log(`Deleted view ${id} for user: ${userId}`);
4939
+ await this.invalidateViewsCache(userId, view.tableSlug, !view.isShared, view.isShared);
4940
+ return DataTableViewDto.from(view, userId);
4941
+ }
4942
+ };
4943
+ DataTableViewsService = _ts_decorate36([
4944
+ (0, import_common60.Injectable)(),
4945
+ _ts_metadata27("design:type", Function),
4946
+ _ts_metadata27("design:paramtypes", [
4947
+ typeof DataTableViewsRepository === "undefined" ? Object : DataTableViewsRepository,
4948
+ typeof CacheService === "undefined" ? Object : CacheService,
4949
+ typeof import_config14.ConfigService === "undefined" ? Object : import_config14.ConfigService
4950
+ ])
4951
+ ], DataTableViewsService);
4952
+
4953
+ // src/data-table/views/controllers/data-table-views.controller.ts
4954
+ function _ts_decorate37(decorators, target, key, desc2) {
4955
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
4956
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
4957
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
4958
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
4959
+ }
4960
+ __name(_ts_decorate37, "_ts_decorate");
4961
+ function _ts_metadata28(k, v) {
4962
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4963
+ }
4964
+ __name(_ts_metadata28, "_ts_metadata");
4965
+ function _ts_param9(paramIndex, decorator) {
4966
+ return function(target, key) {
4967
+ decorator(target, key, paramIndex);
4968
+ };
4969
+ }
4970
+ __name(_ts_param9, "_ts_param");
4971
+ var DataTableViewsController = class _DataTableViewsController {
4972
+ static {
4973
+ __name(this, "DataTableViewsController");
4974
+ }
4975
+ dataTableViewsService;
4976
+ logger = new import_common61.Logger(_DataTableViewsController.name);
4977
+ constructor(dataTableViewsService) {
4978
+ this.dataTableViewsService = dataTableViewsService;
4979
+ }
4980
+ // Returns all named views for the given table — own plus shared
4981
+ findViews(userId, tableSlug) {
4982
+ this.logger.log(`GET /table-views?tableSlug=${tableSlug} - User: ${userId}`);
4983
+ return this.dataTableViewsService.findViews(userId, tableSlug);
4984
+ }
4985
+ // Creates a named snapshot of the current table state
4986
+ createView(userId, dto) {
4987
+ this.logger.log(`POST /table-views - User: ${userId}, table: ${dto.tableSlug}`);
4988
+ return this.dataTableViewsService.createView(userId, dto);
4989
+ }
4990
+ // Updates state of an existing named view
4991
+ updateView(userId, id, dto) {
4992
+ this.logger.log(`PATCH /table-views/${id} - User: ${userId}`);
4993
+ return this.dataTableViewsService.updateView(userId, id, dto);
4994
+ }
4995
+ // Renames an existing named view — enforces unique name per user+table
4996
+ renameView(userId, id, dto) {
4997
+ this.logger.log(`PATCH /table-views/${id}/rename - User: ${userId}`);
4998
+ return this.dataTableViewsService.renameView(userId, id, dto.name);
4999
+ }
5000
+ // Toggles sharing visibility of a named view
5001
+ toggleShareView(userId, id, dto) {
5002
+ this.logger.log(`PATCH /table-views/${id}/share - User: ${userId}`);
5003
+ return this.dataTableViewsService.toggleShareView(userId, id, dto.isShared);
5004
+ }
5005
+ // Deletes a named view owned by the authenticated user
5006
+ deleteView(userId, id) {
5007
+ this.logger.log(`DELETE /table-views/${id} - User: ${userId}`);
5008
+ return this.dataTableViewsService.deleteView(userId, id);
5009
+ }
5010
+ };
5011
+ _ts_decorate37([
5012
+ (0, import_common61.Get)(),
5013
+ ApiListDataTableViews(),
5014
+ _ts_param9(0, UserId()),
5015
+ _ts_param9(1, (0, import_common61.Query)("tableSlug")),
5016
+ _ts_metadata28("design:type", Function),
5017
+ _ts_metadata28("design:paramtypes", [
5018
+ String,
5019
+ String
5020
+ ]),
5021
+ _ts_metadata28("design:returntype", typeof Promise === "undefined" ? Object : Promise)
5022
+ ], DataTableViewsController.prototype, "findViews", null);
5023
+ _ts_decorate37([
5024
+ (0, import_common61.Post)(),
5025
+ (0, import_common61.HttpCode)(import_common61.HttpStatus.CREATED),
5026
+ ApiCreateDataTableView(),
5027
+ _ts_param9(0, UserId()),
5028
+ _ts_param9(1, (0, import_common61.Body)()),
5029
+ _ts_metadata28("design:type", Function),
5030
+ _ts_metadata28("design:paramtypes", [
5031
+ String,
5032
+ typeof CreateDataTableViewDto === "undefined" ? Object : CreateDataTableViewDto
5033
+ ]),
5034
+ _ts_metadata28("design:returntype", typeof Promise === "undefined" ? Object : Promise)
5035
+ ], DataTableViewsController.prototype, "createView", null);
5036
+ _ts_decorate37([
5037
+ (0, import_common61.Patch)(":id"),
5038
+ ApiUpdateDataTableView(),
5039
+ _ts_param9(0, UserId()),
5040
+ _ts_param9(1, (0, import_common61.Param)("id")),
5041
+ _ts_param9(2, (0, import_common61.Body)()),
5042
+ _ts_metadata28("design:type", Function),
5043
+ _ts_metadata28("design:paramtypes", [
5044
+ String,
5045
+ String,
5046
+ typeof UpdateDataTableViewDto === "undefined" ? Object : UpdateDataTableViewDto
5047
+ ]),
5048
+ _ts_metadata28("design:returntype", typeof Promise === "undefined" ? Object : Promise)
5049
+ ], DataTableViewsController.prototype, "updateView", null);
5050
+ _ts_decorate37([
5051
+ (0, import_common61.Patch)(":id/rename"),
5052
+ ApiRenameDataTableView(),
5053
+ _ts_param9(0, UserId()),
5054
+ _ts_param9(1, (0, import_common61.Param)("id")),
5055
+ _ts_param9(2, (0, import_common61.Body)()),
5056
+ _ts_metadata28("design:type", Function),
5057
+ _ts_metadata28("design:paramtypes", [
5058
+ String,
5059
+ String,
5060
+ typeof RenameDataTableViewDto === "undefined" ? Object : RenameDataTableViewDto
5061
+ ]),
5062
+ _ts_metadata28("design:returntype", typeof Promise === "undefined" ? Object : Promise)
5063
+ ], DataTableViewsController.prototype, "renameView", null);
5064
+ _ts_decorate37([
5065
+ (0, import_common61.Patch)(":id/share"),
5066
+ ApiToggleShareDataTableView(),
5067
+ _ts_param9(0, UserId()),
5068
+ _ts_param9(1, (0, import_common61.Param)("id")),
5069
+ _ts_param9(2, (0, import_common61.Body)()),
5070
+ _ts_metadata28("design:type", Function),
5071
+ _ts_metadata28("design:paramtypes", [
5072
+ String,
5073
+ String,
5074
+ typeof ToggleShareDataTableViewDto === "undefined" ? Object : ToggleShareDataTableViewDto
5075
+ ]),
5076
+ _ts_metadata28("design:returntype", typeof Promise === "undefined" ? Object : Promise)
5077
+ ], DataTableViewsController.prototype, "toggleShareView", null);
5078
+ _ts_decorate37([
5079
+ (0, import_common61.Delete)(":id"),
5080
+ ApiDeleteDataTableView(),
5081
+ _ts_param9(0, UserId()),
5082
+ _ts_param9(1, (0, import_common61.Param)("id")),
5083
+ _ts_metadata28("design:type", Function),
5084
+ _ts_metadata28("design:paramtypes", [
5085
+ String,
5086
+ String
5087
+ ]),
5088
+ _ts_metadata28("design:returntype", typeof Promise === "undefined" ? Object : Promise)
5089
+ ], DataTableViewsController.prototype, "deleteView", null);
5090
+ DataTableViewsController = _ts_decorate37([
5091
+ (0, import_swagger19.ApiTags)("Table Views"),
5092
+ (0, import_swagger19.ApiBearerAuth)(),
5093
+ RequireSession("CLOUD", "ADMIN"),
5094
+ (0, import_common61.Controller)("table-views"),
5095
+ _ts_metadata28("design:type", Function),
5096
+ _ts_metadata28("design:paramtypes", [
5097
+ typeof DataTableViewsService === "undefined" ? Object : DataTableViewsService
5098
+ ])
5099
+ ], DataTableViewsController);
5100
+
5101
+ // src/data-table/data-table.module.ts
5102
+ function _ts_decorate38(decorators, target, key, desc2) {
5103
+ var c = arguments.length, r = c < 3 ? target : desc2 === null ? desc2 = Object.getOwnPropertyDescriptor(target, key) : desc2, d;
5104
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc2);
5105
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5106
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
5107
+ }
5108
+ __name(_ts_decorate38, "_ts_decorate");
5109
+ var DataTableModule = class _DataTableModule {
5110
+ static {
5111
+ __name(this, "DataTableModule");
5112
+ }
5113
+ static forRoot(options) {
5114
+ return {
5115
+ global: true,
5116
+ module: _DataTableModule,
5117
+ imports: [
5118
+ import_config15.ConfigModule,
5119
+ CacheModule
5120
+ ],
5121
+ controllers: [
5122
+ DataTableStateController,
5123
+ DataTableViewsController
5124
+ ],
5125
+ providers: [
5126
+ {
5127
+ provide: DATA_TABLE_VIEWS_TABLE,
5128
+ useValue: options.tableViews
5129
+ },
5130
+ DataTableViewsService,
5131
+ DataTableViewsRepository,
5132
+ DataTableStateService
5133
+ ],
5134
+ exports: [
5135
+ DataTableViewsService,
5136
+ DataTableStateService
5137
+ ]
5138
+ };
5139
+ }
5140
+ };
5141
+ DataTableModule = _ts_decorate38([
5142
+ (0, import_common62.Module)({})
5143
+ ], DataTableModule);
5144
+
5145
+ // src/drizzle-pg-core.ts
5146
+ var drizzle_pg_core_exports = {};
5147
+ __reExport(drizzle_pg_core_exports, require("drizzle-orm/pg-core"));
5148
+
5149
+ // src/data-table/schema/data-table-views.table.ts
5150
+ function dataTableViewsColumns() {
5151
+ return {
5152
+ id: (0, drizzle_pg_core_exports.uuid)("id").primaryKey().defaultRandom(),
5153
+ userId: (0, drizzle_pg_core_exports.uuid)("user_id").notNull(),
5154
+ tableSlug: (0, drizzle_pg_core_exports.varchar)("table_slug", {
5155
+ length: 100
5156
+ }).notNull(),
5157
+ name: (0, drizzle_pg_core_exports.varchar)("name", {
5158
+ length: 100
5159
+ }).notNull(),
5160
+ state: (0, drizzle_pg_core_exports.jsonb)("state").notNull().$type(),
5161
+ isShared: (0, drizzle_pg_core_exports.boolean)("is_shared").notNull().default(false),
5162
+ createdAt: (0, drizzle_pg_core_exports.timestamp)("created_at", {
5163
+ withTimezone: true
5164
+ }).notNull().defaultNow(),
5165
+ updatedAt: (0, drizzle_pg_core_exports.timestamp)("updated_at", {
5166
+ withTimezone: true
5167
+ }).$onUpdate(() => /* @__PURE__ */ new Date())
5168
+ };
5169
+ }
5170
+ __name(dataTableViewsColumns, "dataTableViewsColumns");
5171
+ function dataTableViewsIndexes(table) {
5172
+ return [
5173
+ (0, drizzle_pg_core_exports.index)("table_views_user_table_idx").on(table.userId, table.tableSlug),
5174
+ (0, drizzle_pg_core_exports.index)("table_views_shared_slug_idx").on(table.tableSlug, table.isShared),
5175
+ (0, drizzle_pg_core_exports.uniqueIndex)("table_views_user_table_name_shared_unique").on(table.userId, table.tableSlug, table.name, table.isShared)
5176
+ ];
5177
+ }
5178
+ __name(dataTableViewsIndexes, "dataTableViewsIndexes");
4350
5179
  // Annotate the CommonJS export names for ESM import in node:
4351
5180
  0 && (module.exports = {
4352
5181
  AccessToken,
@@ -4359,7 +5188,14 @@ __name(normalizePhoneNumber, "normalizePhoneNumber");
4359
5188
  ConflictException,
4360
5189
  CookieDomain,
4361
5190
  CorrelationIdMiddleware,
5191
+ CreateDataTableViewDto,
5192
+ CreateResponseDto,
5193
+ DATA_TABLE_VIEWS_TABLE,
4362
5194
  DEFAULT_CORRELATION_HEADER,
5195
+ DataTableModule,
5196
+ DataTableStateService,
5197
+ DataTableViewDto,
5198
+ DataTableViewsService,
4363
5199
  DatabaseModule,
4364
5200
  EmailModule,
4365
5201
  EmailService,
@@ -4369,6 +5205,8 @@ __name(normalizePhoneNumber, "normalizePhoneNumber");
4369
5205
  HttpExceptionFilter,
4370
5206
  HttpLoggerInterceptor,
4371
5207
  HttpProblemException,
5208
+ ImportResponseDto,
5209
+ ImportSummaryDto,
4372
5210
  InternalServerErrorException,
4373
5211
  JwtAuthService,
4374
5212
  LOGGER_MODULE_OPTIONS,
@@ -4378,40 +5216,44 @@ __name(normalizePhoneNumber, "normalizePhoneNumber");
4378
5216
  NotAcceptableException,
4379
5217
  NotFoundException,
4380
5218
  NotImplementedException,
4381
- Onboarding,
4382
5219
  PayloadTooLargeException,
4383
5220
  PrimaryBaseRepository,
4384
5221
  PrimaryDatabaseService,
4385
5222
  Public,
4386
- RESET_KEY,
5223
+ REQUIRE_SESSION_KEY,
4387
5224
  RedisCacheProvider,
4388
5225
  RefreshCookieOptions,
4389
5226
  RefreshTokenCookie,
5227
+ RenameDataTableViewDto,
4390
5228
  RequestTimeoutException,
4391
- Reset,
5229
+ RequireSession,
4392
5230
  RootModule,
4393
5231
  SKIP_CSRF_KEY,
4394
5232
  SelectOptionsQueryDto,
4395
5233
  ServiceUnavailableException,
4396
5234
  SessionData,
4397
5235
  SkipCsrf,
5236
+ Subdomain,
4398
5237
  SuccessResponseDto,
4399
5238
  TableResponseDto,
4400
- Tenant,
4401
- TenantBaseRepository,
4402
- TenantContextService,
4403
- TenantDatabaseService,
5239
+ ToggleShareDataTableViewDto,
4404
5240
  TokenType,
4405
5241
  TooManyRequestsException,
4406
5242
  UnauthorizedException,
4407
5243
  UnprocessableEntityException,
4408
5244
  UnsupportedMediaTypeException,
5245
+ UpdateDataTableViewDto,
5246
+ UploadedFile,
5247
+ UpsertDataTableStateDto,
4409
5248
  UserId,
5249
+ ValidatedRowDto,
4410
5250
  ValidationException,
4411
5251
  VrittiAuthGuard,
4412
5252
  addCorrelationIdToResponse,
4413
5253
  configureApiSdk,
4414
5254
  correlationStorage,
5255
+ dataTableViewsColumns,
5256
+ dataTableViewsIndexes,
4415
5257
  defineConfig,
4416
5258
  extractCountryFromPhone,
4417
5259
  generateCorrelationId,