procbay-schema 1.0.64 → 1.0.66

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "procbay-schema",
3
- "version": "1.0.64",
3
+ "version": "1.0.66",
4
4
  "description": "A set of utilities for managing Prisma database schemas, seeding, and maintenance operations for the Procure-to-Pay system",
5
5
  "main": "src/prisma/index.js",
6
6
  "type": "module",
@@ -0,0 +1,5 @@
1
+ -- CreateEnum
2
+ CREATE TYPE "EnvironmentEnum" AS ENUM ('PRODUCTION', 'SANDBOX');
3
+
4
+ -- AlterTable
5
+ ALTER TABLE "users" ADD COLUMN "user_environment" "EnvironmentEnum" NOT NULL DEFAULT 'PRODUCTION';
@@ -39,6 +39,11 @@ enum StatusEnum {
39
39
  Suspended
40
40
  }
41
41
 
42
+ enum EnvironmentEnum {
43
+ PRODUCTION
44
+ SANDBOX
45
+ }
46
+
42
47
  model User {
43
48
  id Int @id @default(autoincrement())
44
49
  uuid String? @unique @default(uuid())
@@ -68,6 +73,7 @@ model User {
68
73
  is_deleted Boolean @default(false)
69
74
  deleted_at DateTime? @db.Timestamptz(6)
70
75
  deleted_by Int?
76
+ user_environment EnvironmentEnum @default(PRODUCTION)
71
77
  user_roles UserRole[]
72
78
  user_department UserDepartment[]
73
79
  approval_hierarchy ApprovalHierarchy[]
@@ -199,14 +199,27 @@ function parseArgs() {
199
199
  *
200
200
  * @param {string[]} [countryFilter] - Optional array of country names to filter geographic data
201
201
  * @param {string[]} [industryFilter] - Optional array of industry names to filter content data
202
+ * @param {Object} [options] - Additional options
203
+ * @param {string} [options.schema] - Target PostgreSQL schema (for multi-schema support)
204
+ * @param {Object} [options.prismaClient] - Custom Prisma client (for multi-schema support)
202
205
  */
203
206
  export async function main(
204
207
  countryFilter = ["India", "United States", "Canada"],
205
- industryFilter = ["Healthcare"]
208
+ industryFilter = ["Healthcare"],
209
+ options = {}
206
210
  ) {
207
211
  let connectionManager;
208
212
  let seederManager;
209
213
 
214
+ // Extract options
215
+ const {
216
+ schema = process.env.TARGET_SCHEMA || "procbay_schema",
217
+ prismaClient = null,
218
+ } = options;
219
+
220
+ // Use custom prisma client if provided, otherwise use global
221
+ const activePrisma = prismaClient || prisma;
222
+
210
223
  try {
211
224
  // Initialize seeder manager with auto-config selection
212
225
  const environment = process.env.NODE_ENV || "development";
@@ -235,6 +248,7 @@ export async function main(
235
248
  console.log("\n================= SEED PROCESS STARTED =================");
236
249
  console.log(`Node version: ${process.version}`);
237
250
  console.log(`Environment: ${environment}`);
251
+ console.log(`Target Schema: ${schema}`);
238
252
  console.log(`Memory usage: ${JSON.stringify(process.memoryUsage())}`);
239
253
  console.log(
240
254
  `Database URL: ${
@@ -254,7 +268,9 @@ export async function main(
254
268
  industryFilter = args.industries || [];
255
269
  }
256
270
 
257
- logger.header("🌱 DATABASE SEEDING PROCESS");
271
+ logger.header(
272
+ `🌱 DATABASE SEEDING PROCESS ${schema !== "procbay_schema" ? `[Schema: ${schema}]` : ""}`
273
+ );
258
274
 
259
275
  if (countryFilter.length > 0) {
260
276
  logger.info(`Country filter applied: ${countryFilter.join(", ")}`);
@@ -270,7 +286,11 @@ export async function main(
270
286
  logger.info("Starting geographic data seeding...");
271
287
  try {
272
288
  // Run the geographic data seeding with connection retries
273
- await seedGeographicDataWithRetry(countryFilter, seederManager);
289
+ await seedGeographicDataWithRetry(
290
+ countryFilter,
291
+ seederManager,
292
+ activePrisma
293
+ );
274
294
  logger.success("Geographic data seeded successfully");
275
295
  } catch (error) {
276
296
  logger.error(`Geographic data seeding failed: ${error.message}`);
@@ -282,7 +302,7 @@ export async function main(
282
302
  // Seed base/core data next
283
303
  logger.info("Starting core data seeding...");
284
304
  try {
285
- await seedCoreDataWithRetry(seederManager);
305
+ await seedCoreDataWithRetry(seederManager, activePrisma);
286
306
  logger.success("Core data seeded successfully");
287
307
  } catch (error) {
288
308
  logger.error(`Core data seeding failed: ${error.message}`);
@@ -294,7 +314,11 @@ export async function main(
294
314
  // Seed catalog and content data
295
315
  logger.info("Starting content data seeding...");
296
316
  try {
297
- await seedContentDataWithRetry(seederManager, industryFilter);
317
+ await seedContentDataWithRetry(
318
+ seederManager,
319
+ industryFilter,
320
+ activePrisma
321
+ );
298
322
  logger.success("Content data seeded successfully");
299
323
  } catch (error) {
300
324
  logger.error(`Content data seeding failed: ${error.message}`);
@@ -336,10 +360,12 @@ export async function main(
336
360
  *
337
361
  * @param {string[]} [countryFilter] - Optional array of country names to filter by
338
362
  * @param {Object} [seederManager] - Seeder manager with performance configuration
363
+ * @param {Object} [activePrisma] - Prisma client instance
339
364
  */
340
365
  export async function seedGeographicData(
341
366
  countryFilter = [],
342
- seederManager = null
367
+ seederManager = null,
368
+ activePrisma = prisma
343
369
  ) {
344
370
  logger.header("🌎 GEOGRAPHIC DATA SEEDING");
345
371
 
@@ -355,7 +381,7 @@ export async function seedGeographicData(
355
381
  );
356
382
 
357
383
  try {
358
- await prisma.$transaction(
384
+ await activePrisma.$transaction(
359
385
  async (tx) => {
360
386
  // Always seed all regions and subregions regardless of country filter
361
387
  logger.info(`Seeding ${colors.highlight("regions")}...`);
@@ -439,12 +465,13 @@ export async function seedGeographicData(
439
465
  async function seedGeographicDataWithRetry(
440
466
  countryFilter = [],
441
467
  seederManager = null,
468
+ activePrisma = prisma,
442
469
  maxRetries = 3
443
470
  ) {
444
471
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
445
472
  try {
446
473
  logger.info(`Geographic data seeding attempt ${attempt}/${maxRetries}`);
447
- await seedGeographicData(countryFilter, seederManager);
474
+ await seedGeographicData(countryFilter, seederManager, activePrisma);
448
475
  return; // Success, exit the function
449
476
  } catch (error) {
450
477
  logger.warn(
@@ -464,8 +491,10 @@ async function seedGeographicDataWithRetry(
464
491
 
465
492
  /**
466
493
  * Seeds core data (users, roles, permissions, etc.)
494
+ * @param {Object} [seederManager] - Seeder manager with performance configuration
495
+ * @param {Object} [activePrisma] - Prisma client instance
467
496
  */
468
- export async function seedCoreData(seederManager) {
497
+ export async function seedCoreData(seederManager, activePrisma = prisma) {
469
498
  logger.header("👤 CORE DATA SEEDING");
470
499
 
471
500
  try {
@@ -473,53 +502,59 @@ export async function seedCoreData(seederManager) {
473
502
  const coreDataItems = [
474
503
  {
475
504
  name: "Serial Number Configurations",
476
- fn: (prisma, seederMgr) =>
477
- seedSerialNumberConfigurations(prisma, seederMgr),
505
+ fn: (prismaClient, seederMgr) =>
506
+ seedSerialNumberConfigurations(prismaClient, seederMgr),
478
507
  },
479
508
  {
480
509
  name: "Departments",
481
- fn: (prisma, seederMgr) => seedDepartments(prisma, seederMgr),
510
+ fn: (prismaClient, seederMgr) =>
511
+ seedDepartments(prismaClient, seederMgr),
482
512
  },
483
513
  {
484
514
  name: "Currencies",
485
- fn: (prisma, seederMgr) => seedCurrencies(prisma, seederMgr),
515
+ fn: (prismaClient, seederMgr) =>
516
+ seedCurrencies(prismaClient, seederMgr),
486
517
  },
487
518
  {
488
519
  name: "Users",
489
- fn: (prisma, seederMgr) => seedUsers(prisma, seederMgr),
520
+ fn: (prismaClient, seederMgr) => seedUsers(prismaClient, seederMgr),
490
521
  },
491
522
  {
492
523
  name: "Roles",
493
- fn: (prisma, seederMgr) => seedRoles(prisma, seederMgr),
524
+ fn: (prismaClient, seederMgr) => seedRoles(prismaClient, seederMgr),
494
525
  },
495
526
  {
496
527
  name: "Permissions",
497
- fn: (prisma, seederMgr) => seedPermissions(prisma, seederMgr),
528
+ fn: (prismaClient, seederMgr) =>
529
+ seedPermissions(prismaClient, seederMgr),
498
530
  },
499
531
  {
500
532
  name: "Role permissions",
501
- fn: (prisma, seederMgr) => seedRolePermission(prisma, seederMgr),
533
+ fn: (prismaClient, seederMgr) =>
534
+ seedRolePermission(prismaClient, seederMgr),
502
535
  },
503
536
  {
504
537
  name: "User roles",
505
- fn: (prisma, seederMgr) => seedUserRole(prisma, seederMgr),
538
+ fn: (prismaClient, seederMgr) => seedUserRole(prismaClient, seederMgr),
506
539
  },
507
540
  {
508
541
  name: "User event configurations",
509
- fn: (prisma, seederMgr) =>
510
- seedUserEventConfigurations(prisma, seederMgr),
542
+ fn: (prismaClient, seederMgr) =>
543
+ seedUserEventConfigurations(prismaClient, seederMgr),
511
544
  },
512
545
  {
513
546
  name: "Templates",
514
- fn: (prisma, seederMgr) => seedTemplates(prisma, seederMgr),
547
+ fn: (prismaClient, seederMgr) => seedTemplates(prismaClient, seederMgr),
515
548
  },
516
549
  {
517
550
  name: "Email Templates",
518
- fn: (prisma, seederMgr) => seedEmailTemplate(prisma, seederMgr),
551
+ fn: (prismaClient, seederMgr) =>
552
+ seedEmailTemplate(prismaClient, seederMgr),
519
553
  },
520
554
  {
521
555
  name: "Dynamic Forms",
522
- fn: (prisma, seederMgr) => seedDynamicForm(prisma, seederMgr),
556
+ fn: (prismaClient, seederMgr) =>
557
+ seedDynamicForm(prismaClient, seederMgr),
523
558
  },
524
559
  ];
525
560
 
@@ -531,7 +566,7 @@ export async function seedCoreData(seederManager) {
531
566
  // Run core seeders in sequence
532
567
  for (const item of coreDataItems) {
533
568
  logger.info(`Seeding ${colors.highlight(item.name)}...`);
534
- await item.fn(prisma, seederManager);
569
+ await item.fn(activePrisma, seederManager);
535
570
  progress.update();
536
571
  }
537
572
 
@@ -544,11 +579,15 @@ export async function seedCoreData(seederManager) {
544
579
  }
545
580
 
546
581
  // Add retry wrappers for each seeding phase
547
- async function seedCoreDataWithRetry(seederManager, maxRetries = 3) {
582
+ async function seedCoreDataWithRetry(
583
+ seederManager,
584
+ activePrisma = prisma,
585
+ maxRetries = 3
586
+ ) {
548
587
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
549
588
  try {
550
589
  logger.info(`Core data seeding attempt ${attempt}/${maxRetries}`);
551
- await seedCoreData(seederManager);
590
+ await seedCoreData(seederManager, activePrisma);
552
591
  return; // Success, exit the function
553
592
  } catch (error) {
554
593
  logger.warn(
@@ -571,10 +610,12 @@ async function seedCoreDataWithRetry(seederManager, maxRetries = 3) {
571
610
  *
572
611
  * @param {Object} [seederManager] - Seeder manager with performance configuration
573
612
  * @param {string[]} [industryFilter] - Optional array of industry names to filter
613
+ * @param {Object} [activePrisma] - Prisma client instance
574
614
  */
575
615
  export async function seedContentData(
576
616
  seederManager = null,
577
- industryFilter = []
617
+ industryFilter = [],
618
+ activePrisma = prisma
578
619
  ) {
579
620
  logger.header("📋 CONTENT DATA SEEDING");
580
621
 
@@ -591,14 +632,14 @@ export async function seedContentData(
591
632
  // Seed industries first and get the industry ID map
592
633
  logger.info(`Seeding ${colors.highlight("Industries")}...`);
593
634
  const industryIdMap = await seedIndustries(
594
- prisma,
635
+ activePrisma,
595
636
  seederManager,
596
637
  industryFilter
597
638
  );
598
639
 
599
640
  // Seed categories using the industry ID map for filtering
600
641
  logger.info(`Seeding ${colors.highlight("Categories")}...`);
601
- await seedCategories(prisma, seederManager, industryIdMap);
642
+ await seedCategories(activePrisma, seederManager, industryIdMap);
602
643
 
603
644
  logger.success(
604
645
  `Content data seeding completed successfully ${
@@ -615,12 +656,13 @@ export async function seedContentData(
615
656
  async function seedContentDataWithRetry(
616
657
  seederManager = null,
617
658
  industryFilter = [],
659
+ activePrisma = prisma,
618
660
  maxRetries = 3
619
661
  ) {
620
662
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
621
663
  try {
622
664
  logger.info(`Content data seeding attempt ${attempt}/${maxRetries}`);
623
- await seedContentData(seederManager, industryFilter);
665
+ await seedContentData(seederManager, industryFilter, activePrisma);
624
666
  return; // Success, exit the function
625
667
  } catch (error) {
626
668
  logger.warn(