@adaptware/eagles-db 0.1.81 → 0.1.82

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/client/edge.js +68 -9
  2. package/client/index-browser.js +63 -4
  3. package/client/index.d.ts +6230 -314
  4. package/client/index.js +68 -9
  5. package/client/package.json +1 -1
  6. package/client/schema.prisma +102 -5
  7. package/client/wasm.js +63 -4
  8. package/package.json +1 -1
  9. package/prisma/.DS_Store +0 -0
  10. package/prisma/migrations/20260415120000_remove_job_profile_current_phase/migration.sql +2 -0
  11. package/prisma/migrations/20260422120000_add_integration_provider_zoom/migration.sql +2 -0
  12. package/prisma/migrations/20260422140000_add_zoom_meeting_tables/migration.sql +57 -0
  13. package/prisma/migrations/20260422180000_add_zoom_webhook_event/migration.sql +18 -0
  14. package/prisma/migrations/20260423140000_add_interview_platform/migration.sql +6 -0
  15. package/prisma/migrations/20260423150000_remove_interview_zoom_topic/migration.sql +2 -0
  16. package/prisma/migrations/20260423160000_zoom_meeting_uuid/migration.sql +4 -0
  17. package/prisma/migrations/20260424120000_auth_module_user_provider_unique/migration.sql +5 -0
  18. package/prisma/migrations/20260424130000_zoom_meeting_zoom_host_user_id/migration.sql +6 -0
  19. package/prisma/migrations/20260425100000_zoom_participant_user_enum/migration.sql +22 -0
  20. package/prisma/migrations/20260425110000_zoom_participant_zoom_id_required/migration.sql +13 -0
  21. package/prisma/migrations/20260425120000_zoom_participant_id_nullable/migration.sql +4 -0
  22. package/prisma/migrations/migration_lock.toml +3 -0
  23. package/prisma/schema/authModule.prisma +10 -5
  24. package/prisma/schema/integration.prisma +14 -10
  25. package/prisma/schema/interview.prisma +7 -0
  26. package/prisma/schema/user.prisma +1 -0
  27. package/prisma/schema/zoomMeeting.prisma +79 -0
  28. package/client/libquery_engine-darwin.dylib.node +0 -0
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "prisma-client-b3c805181fbbb2c8de0276b771e7216b71c0ca43032bf8d6968ea412e21a3503",
2
+ "name": "prisma-client-8998d26d2f1ef17bbd9d1b29add72c8f38339c98ed1cca6f9bbd1425c1e16bb0",
3
3
  "main": "index.js",
4
4
  "types": "index.d.ts",
5
5
  "browser": "index-browser.js",
@@ -324,14 +324,13 @@ model AssignmentLibrary {
324
324
  enum AuthProvider {
325
325
  GOOGLE
326
326
  MICROSOFT
327
+ ZOOM
327
328
  }
328
329
 
329
330
  model AuthModule {
330
- id String @id @default(uuid())
331
-
332
- user_id String
333
- user User @relation("UserAuthModule", fields: [user_id], references: [id], onDelete: Cascade)
334
-
331
+ id String @id @default(uuid())
332
+ user_id String
333
+ /// The provider of the authentication module
335
334
  provider AuthProvider
336
335
  provider_account_id String? @db.Text
337
336
 
@@ -345,9 +344,15 @@ model AuthModule {
345
344
  scope String?
346
345
  is_active Boolean @default(true)
347
346
 
347
+ /// Provider-specific JSON (e.g. Zoom: email, display); tokens remain in encrypted columns.
348
+ metadata Json @default("{}")
349
+
348
350
  created_at DateTime @default(now())
349
351
  updated_at DateTime @updatedAt
350
352
 
353
+ user User @relation("UserAuthModule", fields: [user_id], references: [id], onDelete: Cascade)
354
+
355
+ @@unique([user_id, provider])
351
356
  @@unique([provider, provider_account_id])
352
357
  @@index([user_id])
353
358
  }
@@ -643,11 +648,15 @@ enum IntegrationProvider {
643
648
  NAUKRI
644
649
  ZOHO_RECRUIT
645
650
  LINKEDIN
651
+ GOOGLE
652
+ MICROSOFT
653
+ ZOOM
646
654
  }
647
655
 
648
656
  enum IntegrationAuthType {
649
657
  OAUTH2
650
658
  API_KEY
659
+ SSO
651
660
  }
652
661
 
653
662
  enum SyncDirection {
@@ -750,6 +759,11 @@ enum InterviewFeedback {
750
759
  STRONG_NO_HIRE
751
760
  }
752
761
 
762
+ enum InterviewPlatform {
763
+ TREADSPACE
764
+ ZOOM
765
+ }
766
+
753
767
  model Interview {
754
768
  id String @id @default(uuid())
755
769
  /// Foreign keys
@@ -769,6 +783,7 @@ model Interview {
769
783
  actual_end_time DateTime?
770
784
  recording_url String?
771
785
  interview_status InterviewStatus @default(SCHEDULED)
786
+ interview_platform InterviewPlatform @default(TREADSPACE)
772
787
  google_event_id String?
773
788
  /// Old Feedback fields will be deprecated soon
774
789
  ai_interview_feedback InterviewFeedback?
@@ -803,6 +818,7 @@ model Interview {
803
818
  feedback Feedback[]
804
819
  interviewNotes InterviewNotes[]
805
820
  liveAnalysis LiveAnalysis[]
821
+ zoom_meeting ZoomMeeting?
806
822
 
807
823
  @@unique([interviewer_id, candidate_id, evaluation_plan_id])
808
824
  @@index([candidate_id])
@@ -1401,6 +1417,7 @@ model User {
1401
1417
  assigned_job_profiles JobProfile[] @relation("ProfileAssignee")
1402
1418
  user_auth_modules AuthModule[] @relation("UserAuthModule")
1403
1419
  refresh_token_auth RefreshToken[] @relation("TokenRefresh")
1420
+ zoom_meeting_participants ZoomMeetingParticipant[]
1404
1421
  notes Notes[]
1405
1422
 
1406
1423
  name String?
@@ -1440,3 +1457,83 @@ model UserProfile {
1440
1457
 
1441
1458
  work_experience Json?
1442
1459
  }
1460
+
1461
+ /// Expected attendee slot when persisting interview-linked Zoom participants (`CANDIDATE` | `INTERVIEWER`).
1462
+ enum ZoomMeetingParticipantRole {
1463
+ CANDIDATE
1464
+ INTERVIEWER
1465
+ }
1466
+
1467
+ /// Zoom meeting linked 1:1 to an interview; Zoom REST host is `zoom_host_user_id`.
1468
+ model ZoomMeeting {
1469
+ id String @id @default(uuid())
1470
+ /// One Zoom row per interview.
1471
+ interview_id String @unique
1472
+ interview Interview @relation(fields: [interview_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
1473
+
1474
+ /// Treadspace user id whose Zoom User-OAuth token created this meeting; required for PATCH/DELETE on Zoom REST.
1475
+ /// Set from the Zoom host `userId` in `ZoomMeetingDAO.upsertZoomParticipants` (same user as `POST /users/me/meetings`).
1476
+ zoom_host_user_id String
1477
+
1478
+ /// Zoom REST/API meeting id (same value used as Meeting SDK `meetingNumber` / JWT `mn`).
1479
+ zoom_meeting_id String
1480
+ /// Zoom meeting **instance** UUID from REST create (`uuid`) and RTMS/webhooks (`meeting_uuid`).
1481
+ zoom_meeting_uuid String?
1482
+ join_url String
1483
+ start_url String?
1484
+ password String?
1485
+ topic String?
1486
+
1487
+ scheduled_start_time DateTime?
1488
+ scheduled_end_time DateTime?
1489
+
1490
+ is_active Boolean @default(true)
1491
+
1492
+ created_at DateTime @default(now())
1493
+ updated_at DateTime @updatedAt
1494
+ /// Audit; kept aligned with `zoom_host_user_id` when the meeting is recreated under a new host.
1495
+ created_by String
1496
+ updated_by String
1497
+
1498
+ participants ZoomMeetingParticipant[]
1499
+
1500
+ @@index([interview_id])
1501
+ @@index([zoom_meeting_id])
1502
+ @@index([zoom_meeting_uuid])
1503
+ }
1504
+
1505
+ /// Expected participants for a `ZoomMeeting`: links to `User` (candidate / interviewer). Replaced on each meeting upsert.
1506
+ model ZoomMeetingParticipant {
1507
+ id String @id @default(uuid())
1508
+ zoom_meeting_row_id String
1509
+ zoom_meeting ZoomMeeting @relation(fields: [zoom_meeting_row_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
1510
+ user_id String
1511
+ user User @relation(fields: [user_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
1512
+ /// Zoom account id (`AuthModule.provider_account_id`) when this `user_id` has linked Zoom; usually set for interviewer, often null for candidate.
1513
+ zoom_participant_id String?
1514
+ role ZoomMeetingParticipantRole
1515
+
1516
+ is_active Boolean @default(true)
1517
+
1518
+ created_at DateTime @default(now())
1519
+ updated_at DateTime @updatedAt
1520
+ created_by String
1521
+ updated_by String
1522
+
1523
+ @@index([zoom_meeting_row_id])
1524
+ @@index([user_id])
1525
+ @@index([zoom_participant_id])
1526
+ }
1527
+
1528
+ /// Ledger of processed Zoom webhook deliveries: one row per `dedupe_key` (request id or body hash).
1529
+ /// Stops double-handling when Zoom retries the same notification (e.g. RTMS, `meeting.started`).
1530
+ model ZoomWebhookEvent {
1531
+ id String @id @default(uuid())
1532
+ /// Stable key: SHA-256 of raw request body, or `x-zm-trackingid` when present.
1533
+ dedupe_key String @unique
1534
+ event String
1535
+ created_at DateTime @default(now())
1536
+
1537
+ @@index([event])
1538
+ @@index([created_at])
1539
+ }
package/client/wasm.js CHANGED
@@ -307,6 +307,7 @@ exports.Prisma.AuthModuleScalarFieldEnum = {
307
307
  token_type: 'token_type',
308
308
  scope: 'scope',
309
309
  is_active: 'is_active',
310
+ metadata: 'metadata',
310
311
  created_at: 'created_at',
311
312
  updated_at: 'updated_at'
312
313
  };
@@ -533,6 +534,7 @@ exports.Prisma.InterviewScalarFieldEnum = {
533
534
  actual_end_time: 'actual_end_time',
534
535
  recording_url: 'recording_url',
535
536
  interview_status: 'interview_status',
537
+ interview_platform: 'interview_platform',
536
538
  google_event_id: 'google_event_id',
537
539
  ai_interview_feedback: 'ai_interview_feedback',
538
540
  interview_feedback: 'interview_feedback',
@@ -885,6 +887,45 @@ exports.Prisma.UserProfileScalarFieldEnum = {
885
887
  work_experience: 'work_experience'
886
888
  };
887
889
 
890
+ exports.Prisma.ZoomMeetingScalarFieldEnum = {
891
+ id: 'id',
892
+ interview_id: 'interview_id',
893
+ zoom_host_user_id: 'zoom_host_user_id',
894
+ zoom_meeting_id: 'zoom_meeting_id',
895
+ zoom_meeting_uuid: 'zoom_meeting_uuid',
896
+ join_url: 'join_url',
897
+ start_url: 'start_url',
898
+ password: 'password',
899
+ topic: 'topic',
900
+ scheduled_start_time: 'scheduled_start_time',
901
+ scheduled_end_time: 'scheduled_end_time',
902
+ is_active: 'is_active',
903
+ created_at: 'created_at',
904
+ updated_at: 'updated_at',
905
+ created_by: 'created_by',
906
+ updated_by: 'updated_by'
907
+ };
908
+
909
+ exports.Prisma.ZoomMeetingParticipantScalarFieldEnum = {
910
+ id: 'id',
911
+ zoom_meeting_row_id: 'zoom_meeting_row_id',
912
+ user_id: 'user_id',
913
+ zoom_participant_id: 'zoom_participant_id',
914
+ role: 'role',
915
+ is_active: 'is_active',
916
+ created_at: 'created_at',
917
+ updated_at: 'updated_at',
918
+ created_by: 'created_by',
919
+ updated_by: 'updated_by'
920
+ };
921
+
922
+ exports.Prisma.ZoomWebhookEventScalarFieldEnum = {
923
+ id: 'id',
924
+ dedupe_key: 'dedupe_key',
925
+ event: 'event',
926
+ created_at: 'created_at'
927
+ };
928
+
888
929
  exports.Prisma.SortOrder = {
889
930
  asc: 'asc',
890
931
  desc: 'desc'
@@ -960,7 +1001,8 @@ exports.AssignmentStatus = exports.$Enums.AssignmentStatus = {
960
1001
 
961
1002
  exports.AuthProvider = exports.$Enums.AuthProvider = {
962
1003
  GOOGLE: 'GOOGLE',
963
- MICROSOFT: 'MICROSOFT'
1004
+ MICROSOFT: 'MICROSOFT',
1005
+ ZOOM: 'ZOOM'
964
1006
  };
965
1007
 
966
1008
  exports.JobType = exports.$Enums.JobType = {
@@ -1020,12 +1062,16 @@ exports.DurationUnit = exports.$Enums.DurationUnit = {
1020
1062
  exports.IntegrationProvider = exports.$Enums.IntegrationProvider = {
1021
1063
  NAUKRI: 'NAUKRI',
1022
1064
  ZOHO_RECRUIT: 'ZOHO_RECRUIT',
1023
- LINKEDIN: 'LINKEDIN'
1065
+ LINKEDIN: 'LINKEDIN',
1066
+ GOOGLE: 'GOOGLE',
1067
+ MICROSOFT: 'MICROSOFT',
1068
+ ZOOM: 'ZOOM'
1024
1069
  };
1025
1070
 
1026
1071
  exports.IntegrationAuthType = exports.$Enums.IntegrationAuthType = {
1027
1072
  OAUTH2: 'OAUTH2',
1028
- API_KEY: 'API_KEY'
1073
+ API_KEY: 'API_KEY',
1074
+ SSO: 'SSO'
1029
1075
  };
1030
1076
 
1031
1077
  exports.SyncDirection = exports.$Enums.SyncDirection = {
@@ -1057,6 +1103,11 @@ exports.InterviewStatus = exports.$Enums.InterviewStatus = {
1057
1103
  EVALUATED: 'EVALUATED'
1058
1104
  };
1059
1105
 
1106
+ exports.InterviewPlatform = exports.$Enums.InterviewPlatform = {
1107
+ TREADSPACE: 'TREADSPACE',
1108
+ ZOOM: 'ZOOM'
1109
+ };
1110
+
1060
1111
  exports.InterviewFeedback = exports.$Enums.InterviewFeedback = {
1061
1112
  STRONG_HIRE: 'STRONG_HIRE',
1062
1113
  HIRE: 'HIRE',
@@ -1141,6 +1192,11 @@ exports.FirstLoginStatus = exports.$Enums.FirstLoginStatus = {
1141
1192
  COMPLETED: 'COMPLETED'
1142
1193
  };
1143
1194
 
1195
+ exports.ZoomMeetingParticipantRole = exports.$Enums.ZoomMeetingParticipantRole = {
1196
+ CANDIDATE: 'CANDIDATE',
1197
+ INTERVIEWER: 'INTERVIEWER'
1198
+ };
1199
+
1144
1200
  exports.Prisma.ModelName = {
1145
1201
  CandidateQuestionResponse: 'CandidateQuestionResponse',
1146
1202
  UserRole: 'UserRole',
@@ -1184,7 +1240,10 @@ exports.Prisma.ModelName = {
1184
1240
  Suggestion: 'Suggestion',
1185
1241
  Transcript: 'Transcript',
1186
1242
  User: 'User',
1187
- UserProfile: 'UserProfile'
1243
+ UserProfile: 'UserProfile',
1244
+ ZoomMeeting: 'ZoomMeeting',
1245
+ ZoomMeetingParticipant: 'ZoomMeetingParticipant',
1246
+ ZoomWebhookEvent: 'ZoomWebhookEvent'
1188
1247
  };
1189
1248
 
1190
1249
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adaptware/eagles-db",
3
- "version": "0.1.81",
3
+ "version": "0.1.82",
4
4
  "description": "A Prisma client package for Treadspace database operations",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
Binary file
@@ -0,0 +1,2 @@
1
+ -- AlterTable
2
+ ALTER TABLE "JobProfile" DROP COLUMN IF EXISTS "current_phase";
@@ -0,0 +1,2 @@
1
+ -- AlterEnum (re-run safe only if your PG version supports IF NOT EXISTS; otherwise apply once)
2
+ ALTER TYPE "IntegrationProvider" ADD VALUE 'ZOOM';
@@ -0,0 +1,57 @@
1
+ -- CreateTable
2
+ CREATE TABLE "ZoomMeeting" (
3
+ "id" TEXT NOT NULL,
4
+ "interview_id" TEXT NOT NULL,
5
+ "zoom_meeting_id" TEXT NOT NULL,
6
+ "meeting_number" TEXT NOT NULL,
7
+ "join_url" TEXT NOT NULL,
8
+ "start_url" TEXT,
9
+ "password" TEXT,
10
+ "topic" TEXT,
11
+ "scheduled_start_time" TIMESTAMP(3),
12
+ "scheduled_end_time" TIMESTAMP(3),
13
+ "is_active" BOOLEAN NOT NULL DEFAULT true,
14
+ "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
15
+ "updated_at" TIMESTAMP(3) NOT NULL,
16
+ "created_by" TEXT NOT NULL,
17
+ "updated_by" TEXT NOT NULL,
18
+
19
+ CONSTRAINT "ZoomMeeting_pkey" PRIMARY KEY ("id")
20
+ );
21
+
22
+ -- CreateTable
23
+ CREATE TABLE "ZoomMeetingParticipant" (
24
+ "id" TEXT NOT NULL,
25
+ "zoom_meeting_row_id" TEXT NOT NULL,
26
+ "zoom_participant_id" TEXT,
27
+ "user_name" TEXT,
28
+ "user_email" TEXT,
29
+ "role" TEXT,
30
+ "join_time" TIMESTAMP(3),
31
+ "leave_time" TIMESTAMP(3),
32
+ "is_active" BOOLEAN NOT NULL DEFAULT true,
33
+ "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
34
+ "updated_at" TIMESTAMP(3) NOT NULL,
35
+ "created_by" TEXT NOT NULL,
36
+ "updated_by" TEXT NOT NULL,
37
+
38
+ CONSTRAINT "ZoomMeetingParticipant_pkey" PRIMARY KEY ("id")
39
+ );
40
+
41
+ -- CreateIndex
42
+ CREATE UNIQUE INDEX "ZoomMeeting_interview_id_key" ON "ZoomMeeting"("interview_id");
43
+
44
+ -- CreateIndex
45
+ CREATE INDEX "ZoomMeeting_interview_id_idx" ON "ZoomMeeting"("interview_id");
46
+
47
+ -- CreateIndex
48
+ CREATE INDEX "ZoomMeeting_zoom_meeting_id_idx" ON "ZoomMeeting"("zoom_meeting_id");
49
+
50
+ -- CreateIndex
51
+ CREATE INDEX "ZoomMeetingParticipant_zoom_meeting_row_id_idx" ON "ZoomMeetingParticipant"("zoom_meeting_row_id");
52
+
53
+ -- AddForeignKey
54
+ ALTER TABLE "ZoomMeeting" ADD CONSTRAINT "ZoomMeeting_interview_id_fkey" FOREIGN KEY ("interview_id") REFERENCES "Interview"("id") ON DELETE CASCADE ON UPDATE CASCADE;
55
+
56
+ -- AddForeignKey
57
+ ALTER TABLE "ZoomMeetingParticipant" ADD CONSTRAINT "ZoomMeetingParticipant_zoom_meeting_row_id_fkey" FOREIGN KEY ("zoom_meeting_row_id") REFERENCES "ZoomMeeting"("id") ON DELETE CASCADE ON UPDATE CASCADE;
@@ -0,0 +1,18 @@
1
+ -- CreateTable
2
+ CREATE TABLE "ZoomWebhookEvent" (
3
+ "id" TEXT NOT NULL,
4
+ "dedupe_key" TEXT NOT NULL,
5
+ "event" TEXT NOT NULL,
6
+ "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
7
+
8
+ CONSTRAINT "ZoomWebhookEvent_pkey" PRIMARY KEY ("id")
9
+ );
10
+
11
+ -- CreateIndex
12
+ CREATE UNIQUE INDEX "ZoomWebhookEvent_dedupe_key_key" ON "ZoomWebhookEvent"("dedupe_key");
13
+
14
+ -- CreateIndex
15
+ CREATE INDEX "ZoomWebhookEvent_event_idx" ON "ZoomWebhookEvent"("event");
16
+
17
+ -- CreateIndex
18
+ CREATE INDEX "ZoomWebhookEvent_created_at_idx" ON "ZoomWebhookEvent"("created_at");
@@ -0,0 +1,6 @@
1
+ -- CreateEnum
2
+ CREATE TYPE "InterviewPlatform" AS ENUM ('TREADSPACE', 'ZOOM');
3
+
4
+ -- AlterTable
5
+ ALTER TABLE "Interview" ADD COLUMN "interview_platform" "InterviewPlatform" NOT NULL DEFAULT 'TREADSPACE';
6
+ ALTER TABLE "Interview" ADD COLUMN "zoom_topic" TEXT;
@@ -0,0 +1,2 @@
1
+ -- AlterTable
2
+ ALTER TABLE "Interview" DROP COLUMN IF EXISTS "zoom_topic";
@@ -0,0 +1,4 @@
1
+ -- Zoom meeting instance UUID for RTMS `meeting.rtms_started` correlation (webhook `meeting_uuid`).
2
+ ALTER TABLE "ZoomMeeting" ADD COLUMN IF NOT EXISTS "zoom_meeting_uuid" TEXT;
3
+
4
+ CREATE INDEX IF NOT EXISTS "ZoomMeeting_zoom_meeting_uuid_idx" ON "ZoomMeeting"("zoom_meeting_uuid");
@@ -0,0 +1,5 @@
1
+ -- AlterTable
2
+ ALTER TABLE "AuthModule" ADD COLUMN "metadata" JSONB NOT NULL DEFAULT '{}';
3
+
4
+ -- CreateIndex
5
+ CREATE UNIQUE INDEX "AuthModule_user_id_provider_key" ON "AuthModule"("user_id", "provider");
@@ -0,0 +1,6 @@
1
+ -- AlterTable
2
+ ALTER TABLE "ZoomMeeting" ADD COLUMN "zoom_host_user_id" TEXT;
3
+
4
+ UPDATE "ZoomMeeting" SET "zoom_host_user_id" = "created_by";
5
+
6
+ ALTER TABLE "ZoomMeeting" ALTER COLUMN "zoom_host_user_id" SET NOT NULL;
@@ -0,0 +1,22 @@
1
+ -- CreateEnum
2
+ CREATE TYPE "ZoomMeetingParticipantRole" AS ENUM ('CANDIDATE', 'INTERVIEWER');
3
+
4
+ -- Participant rows are re-derived on the next Zoom meeting upsert; old webhook denormalized rows are dropped.
5
+ TRUNCATE TABLE "ZoomMeetingParticipant";
6
+
7
+ -- AlterTable
8
+ ALTER TABLE "ZoomMeetingParticipant" DROP COLUMN "zoom_participant_id",
9
+ DROP COLUMN "user_name",
10
+ DROP COLUMN "user_email",
11
+ DROP COLUMN "join_time",
12
+ DROP COLUMN "leave_time",
13
+ DROP COLUMN "role";
14
+
15
+ ALTER TABLE "ZoomMeetingParticipant" ADD COLUMN "role" "ZoomMeetingParticipantRole" NOT NULL;
16
+ ALTER TABLE "ZoomMeetingParticipant" ADD COLUMN "user_id" TEXT NOT NULL;
17
+
18
+ -- AddForeignKey
19
+ ALTER TABLE "ZoomMeetingParticipant" ADD CONSTRAINT "ZoomMeetingParticipant_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
20
+
21
+ -- CreateIndex
22
+ CREATE INDEX "ZoomMeetingParticipant_user_id_idx" ON "ZoomMeetingParticipant"("user_id");
@@ -0,0 +1,13 @@
1
+ -- AlterTable
2
+ ALTER TABLE "ZoomMeetingParticipant" ADD COLUMN "zoom_participant_id" TEXT NOT NULL DEFAULT '';
3
+
4
+ UPDATE "ZoomMeetingParticipant" zmp
5
+ SET "zoom_participant_id" = COALESCE(NULLIF(TRIM(am."provider_account_id"), ''), '')
6
+ FROM "AuthModule" am
7
+ WHERE am."user_id" = zmp."user_id"
8
+ AND am."provider"::text = 'ZOOM'
9
+ AND am."is_active" = true;
10
+
11
+ ALTER TABLE "ZoomMeetingParticipant" ALTER COLUMN "zoom_participant_id" DROP DEFAULT;
12
+
13
+ CREATE INDEX "ZoomMeetingParticipant_zoom_participant_id_idx" ON "ZoomMeetingParticipant"("zoom_participant_id");
@@ -0,0 +1,4 @@
1
+ -- Optional: only present when that User has Zoom OAuth linked (typically interviewer; often unknown for candidate).
2
+ UPDATE "ZoomMeetingParticipant" SET "zoom_participant_id" = NULL WHERE "zoom_participant_id" = '';
3
+
4
+ ALTER TABLE "ZoomMeetingParticipant" ALTER COLUMN "zoom_participant_id" DROP NOT NULL;
@@ -0,0 +1,3 @@
1
+ # Please do not edit this file manually
2
+ # It should be added in your version-control system (e.g. Git)
3
+ provider = "postgresql"
@@ -1,14 +1,13 @@
1
1
  enum AuthProvider {
2
2
  GOOGLE
3
3
  MICROSOFT
4
+ ZOOM
4
5
  }
5
6
 
6
7
  model AuthModule {
7
- id String @id @default(uuid())
8
-
9
- user_id String
10
- user User @relation("UserAuthModule", fields: [user_id], references: [id], onDelete: Cascade)
11
-
8
+ id String @id @default(uuid())
9
+ user_id String
10
+ /// The provider of the authentication module
12
11
  provider AuthProvider
13
12
  provider_account_id String? @db.Text
14
13
 
@@ -22,9 +21,15 @@ model AuthModule {
22
21
  scope String?
23
22
  is_active Boolean @default(true)
24
23
 
24
+ /// Provider-specific JSON (e.g. Zoom: email, display); tokens remain in encrypted columns.
25
+ metadata Json @default("{}")
26
+
25
27
  created_at DateTime @default(now())
26
28
  updated_at DateTime @updatedAt
27
29
 
30
+ user User @relation("UserAuthModule", fields: [user_id], references: [id], onDelete: Cascade)
31
+
32
+ @@unique([user_id, provider])
28
33
  @@unique([provider, provider_account_id])
29
34
  @@index([user_id])
30
35
  }
@@ -2,11 +2,15 @@ enum IntegrationProvider {
2
2
  NAUKRI
3
3
  ZOHO_RECRUIT
4
4
  LINKEDIN
5
+ GOOGLE
6
+ MICROSOFT
7
+ ZOOM
5
8
  }
6
9
 
7
10
  enum IntegrationAuthType {
8
11
  OAUTH2
9
12
  API_KEY
13
+ SSO
10
14
  }
11
15
 
12
16
  enum SyncDirection {
@@ -29,17 +33,17 @@ enum SyncStatus {
29
33
  }
30
34
 
31
35
  model IntegrationCredential {
32
- id String @id @default(uuid())
33
- organisation_id String?
34
- provider IntegrationProvider
35
- auth_type IntegrationAuthType
36
- access_token String?
37
- refresh_token String?
36
+ id String @id @default(uuid())
37
+ organisation_id String?
38
+ provider IntegrationProvider
39
+ auth_type IntegrationAuthType
40
+ access_token String?
41
+ refresh_token String?
38
42
  token_expires_at DateTime?
39
- api_key String?
40
- api_secret String?
41
- metadata Json @default("{}")
42
- is_active Boolean @default(true)
43
+ api_key String?
44
+ api_secret String?
45
+ metadata Json @default("{}")
46
+ is_active Boolean @default(true)
43
47
 
44
48
  organisation Organisation? @relation(fields: [organisation_id], references: [id], onDelete: Cascade)
45
49
 
@@ -15,6 +15,11 @@ enum InterviewFeedback {
15
15
  STRONG_NO_HIRE
16
16
  }
17
17
 
18
+ enum InterviewPlatform {
19
+ TREADSPACE
20
+ ZOOM
21
+ }
22
+
18
23
  model Interview {
19
24
  id String @id @default(uuid())
20
25
  /// Foreign keys
@@ -34,6 +39,7 @@ model Interview {
34
39
  actual_end_time DateTime?
35
40
  recording_url String?
36
41
  interview_status InterviewStatus @default(SCHEDULED)
42
+ interview_platform InterviewPlatform @default(TREADSPACE)
37
43
  google_event_id String?
38
44
  /// Old Feedback fields will be deprecated soon
39
45
  ai_interview_feedback InterviewFeedback?
@@ -68,6 +74,7 @@ model Interview {
68
74
  feedback Feedback[]
69
75
  interviewNotes InterviewNotes[]
70
76
  liveAnalysis LiveAnalysis[]
77
+ zoom_meeting ZoomMeeting?
71
78
  @@unique([interviewer_id, candidate_id, evaluation_plan_id])
72
79
  @@index([candidate_id])
73
80
  @@index([interviewer_id])
@@ -54,6 +54,7 @@ model User {
54
54
  assigned_job_profiles JobProfile[] @relation("ProfileAssignee")
55
55
  user_auth_modules AuthModule[] @relation("UserAuthModule")
56
56
  refresh_token_auth RefreshToken[] @relation("TokenRefresh")
57
+ zoom_meeting_participants ZoomMeetingParticipant[]
57
58
  notes Notes[]
58
59
 
59
60
  name String?