@adaptware/eagles-db 0.3.1 → 0.3.3

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 (38) hide show
  1. package/bin/db-cli.js +3 -24
  2. package/client/edge.js +25 -7
  3. package/client/index-browser.js +20 -2
  4. package/client/index.d.ts +2335 -229
  5. package/client/index.js +25 -7
  6. package/client/package.json +1 -1
  7. package/client/schema.prisma +25 -0
  8. package/client/wasm.js +20 -2
  9. package/dist/index.d.ts +3 -3
  10. package/dist/index.js +6 -6
  11. package/package.json +4 -4
  12. package/prisma/.DS_Store +0 -0
  13. package/prisma/schema/assessment.prisma +4 -0
  14. package/prisma/schema/interview.prisma +6 -0
  15. package/prisma/schema/migrations/20260415120000_remove_job_profile_current_phase/migration.sql +2 -0
  16. package/prisma/schema/migrations/20260422120000_add_integration_provider_zoom/migration.sql +2 -0
  17. package/prisma/schema/migrations/20260422140000_add_zoom_meeting_tables/migration.sql +57 -0
  18. package/prisma/schema/migrations/20260422180000_add_zoom_webhook_event/migration.sql +18 -0
  19. package/prisma/schema/migrations/20260423140000_add_interview_platform/migration.sql +6 -0
  20. package/prisma/schema/migrations/20260423150000_remove_interview_zoom_topic/migration.sql +2 -0
  21. package/prisma/schema/migrations/20260423160000_zoom_meeting_uuid/migration.sql +4 -0
  22. package/prisma/schema/migrations/20260423170000_zoom_meeting_uuid_prisma_sync/migration.sql +2 -0
  23. package/prisma/schema/migrations/20260424120000_auth_module_user_provider_unique/migration.sql +5 -0
  24. package/prisma/schema/migrations/20260424130000_zoom_meeting_zoom_host_user_id/migration.sql +6 -0
  25. package/prisma/schema/migrations/20260425100000_zoom_participant_user_enum/migration.sql +22 -0
  26. package/prisma/schema/migrations/20260425110000_zoom_participant_zoom_id_required/migration.sql +13 -0
  27. package/prisma/schema/migrations/20260425120000_zoom_participant_id_nullable/migration.sql +4 -0
  28. package/prisma/schema/migrations/20260429140000_drop_evaluation_plan_job_order_unique/migration.sql +5 -0
  29. package/prisma/schema/migrations/20260429180000_eval_plan_timeline_optional_ongoing_duration/migration.sql +15 -0
  30. package/prisma/schema/migrations/20260430120000_drop_assessment_library_metadata_fields/migration.sql +8 -0
  31. package/prisma/schema/migrations/20260430140000_drop_question_question_type/migration.sql +5 -0
  32. package/prisma/schema/migrations/20260513120000_add_organisation_config/migration.sql +56 -0
  33. package/prisma/schema/migrations/20260514120000_dedupe_organisation_config/migration.sql +20 -0
  34. package/prisma/schema/migrations/20260515120000_add_interview_ai_assistance_mode/migration.sql +5 -0
  35. package/prisma/schema/migrations/migration_lock.toml +3 -0
  36. package/prisma/schema/organisation.prisma +2 -0
  37. package/prisma/schema/organisationConfig.prisma +12 -0
  38. package/client/libquery_engine-darwin.dylib.node +0 -0
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "prisma-client-17abc0eaab024e3bb9622409063f1d33a662a30fd34525f7d646a2a84b60b322",
2
+ "name": "prisma-client-aca3d15a72e451cc2405fa69b2ca1472cd244bd3adbc759a3a1110b5337d97b4",
3
3
  "main": "index.js",
4
4
  "types": "index.d.ts",
5
5
  "browser": "index-browser.js",
@@ -180,10 +180,14 @@ model Assessment {
180
180
  //data
181
181
  score Float?
182
182
  feedback Json?
183
+ // Scheduled Deadline Window
183
184
  scheduled_start_time DateTime?
184
185
  scheduled_end_time DateTime?
186
+ /// Actual Start and End Time
185
187
  actual_start_time DateTime?
186
188
  actual_end_time DateTime?
189
+ /// Attempt Expires At
190
+ attempt_expires_at DateTime?
187
191
  /// Audit fields
188
192
  created_at DateTime @default(now())
189
193
  updated_at DateTime @updatedAt
@@ -754,6 +758,11 @@ enum InterviewPlatform {
754
758
  ZOOM
755
759
  }
756
760
 
761
+ enum AiAssistanceMode {
762
+ NONE
763
+ ASSISTED
764
+ }
765
+
757
766
  model Interview {
758
767
  id String @id @default(uuid())
759
768
  /// Foreign keys
@@ -819,6 +828,7 @@ model Interview {
819
828
  interviewNotes InterviewNotes[]
820
829
  liveAnalysis LiveAnalysis[]
821
830
  zoom_meeting ZoomMeeting?
831
+ ai_assistance_mode AiAssistanceMode @default(ASSISTED)
822
832
 
823
833
  @@unique([interviewer_id, candidate_id, evaluation_plan_id])
824
834
  @@index([candidate_id])
@@ -1140,10 +1150,25 @@ model Organisation {
1140
1150
  integration_credentials IntegrationCredential[]
1141
1151
  zoho_sync_mappings ZohoSyncMapping[]
1142
1152
  assessments Assessment[]
1153
+ timezone String @default("Asia/Kolkata")
1154
+ organisation_configs OrganisationConfig[]
1143
1155
 
1144
1156
  @@index([name])
1145
1157
  }
1146
1158
 
1159
+ model OrganisationConfig {
1160
+ id String @id @default(uuid())
1161
+ organisation_id String
1162
+ config_key String
1163
+ value Json
1164
+ created_at DateTime @default(now())
1165
+ updated_at DateTime @updatedAt
1166
+ organisation Organisation @relation(fields: [organisation_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
1167
+
1168
+ @@unique([organisation_id, config_key])
1169
+ @@map("organisationConfig")
1170
+ }
1171
+
1147
1172
  model Permission {
1148
1173
  id String @id @default(uuid())
1149
1174
  permissions String[] @default([])
package/client/wasm.js CHANGED
@@ -225,6 +225,7 @@ exports.Prisma.AssessmentScalarFieldEnum = {
225
225
  scheduled_end_time: 'scheduled_end_time',
226
226
  actual_start_time: 'actual_start_time',
227
227
  actual_end_time: 'actual_end_time',
228
+ attempt_expires_at: 'attempt_expires_at',
228
229
  created_at: 'created_at',
229
230
  updated_at: 'updated_at',
230
231
  created_by: 'created_by',
@@ -550,7 +551,8 @@ exports.Prisma.InterviewScalarFieldEnum = {
550
551
  updated_at: 'updated_at',
551
552
  created_by: 'created_by',
552
553
  updated_by: 'updated_by',
553
- is_active: 'is_active'
554
+ is_active: 'is_active',
555
+ ai_assistance_mode: 'ai_assistance_mode'
554
556
  };
555
557
 
556
558
  exports.Prisma.InterviewNotesScalarFieldEnum = {
@@ -717,7 +719,17 @@ exports.Prisma.OrganisationScalarFieldEnum = {
717
719
  updated_by: 'updated_by',
718
720
  is_active: 'is_active',
719
721
  alias: 'alias',
720
- logo: 'logo'
722
+ logo: 'logo',
723
+ timezone: 'timezone'
724
+ };
725
+
726
+ exports.Prisma.OrganisationConfigScalarFieldEnum = {
727
+ id: 'id',
728
+ organisation_id: 'organisation_id',
729
+ config_key: 'config_key',
730
+ value: 'value',
731
+ created_at: 'created_at',
732
+ updated_at: 'updated_at'
721
733
  };
722
734
 
723
735
  exports.Prisma.PermissionScalarFieldEnum = {
@@ -1112,6 +1124,11 @@ exports.InterviewFeedback = exports.$Enums.InterviewFeedback = {
1112
1124
  STRONG_NO_HIRE: 'STRONG_NO_HIRE'
1113
1125
  };
1114
1126
 
1127
+ exports.AiAssistanceMode = exports.$Enums.AiAssistanceMode = {
1128
+ NONE: 'NONE',
1129
+ ASSISTED: 'ASSISTED'
1130
+ };
1131
+
1115
1132
  exports.JobDescriptionStatus = exports.$Enums.JobDescriptionStatus = {
1116
1133
  CREATED: 'CREATED',
1117
1134
  DRAFT: 'DRAFT',
@@ -1211,6 +1228,7 @@ exports.Prisma.ModelName = {
1211
1228
  Notes: 'Notes',
1212
1229
  OngoingEvaluation: 'OngoingEvaluation',
1213
1230
  Organisation: 'Organisation',
1231
+ OrganisationConfig: 'OrganisationConfig',
1214
1232
  Permission: 'Permission',
1215
1233
  AsyncOperation: 'AsyncOperation',
1216
1234
  Question: 'Question',
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { PrismaClient } from "../client/index.js";
1
+ import { PrismaClient } from '../client/index.js';
2
2
  export declare const prisma: PrismaClient<{
3
3
  log: ("error" | "info" | "warn")[];
4
4
  }, "error" | "info" | "warn", import("../client/runtime/library.js").DefaultArgs>;
5
- export type { PrismaClient } from "../client/index.js";
6
- export * from "../client/index.js";
5
+ export type { PrismaClient } from '../client/index.js';
6
+ export * from '../client/index.js';
7
7
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,19 +1,19 @@
1
- import { PrismaClient } from "../client/index.js";
1
+ import { PrismaClient } from '../client/index.js';
2
2
  // Never enable Prisma `query` logging — it prints full SQL to stdout.
3
3
  export const prisma = new PrismaClient({
4
- log: ["error", "warn", "info"],
4
+ log: ['error', 'warn', 'info'],
5
5
  });
6
6
  // Export all Prisma types
7
- export * from "../client/index.js";
7
+ export * from '../client/index.js';
8
8
  // Graceful shutdown
9
- process.on("beforeExit", async () => {
9
+ process.on('beforeExit', async () => {
10
10
  await prisma.$disconnect();
11
11
  });
12
- process.on("SIGINT", async () => {
12
+ process.on('SIGINT', async () => {
13
13
  await prisma.$disconnect();
14
14
  process.exit(0);
15
15
  });
16
- process.on("SIGTERM", async () => {
16
+ process.on('SIGTERM', async () => {
17
17
  await prisma.$disconnect();
18
18
  process.exit(0);
19
19
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adaptware/eagles-db",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "A Prisma client package for Treadspace database operations",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -8,6 +8,9 @@
8
8
  "registry": "https://registry.npmjs.org/"
9
9
  },
10
10
  "type": "module",
11
+ "prisma": {
12
+ "schema": "./prisma/schema/schema.prisma"
13
+ },
11
14
  "exports": {
12
15
  ".": {
13
16
  "types": "./dist/index.d.ts",
@@ -19,9 +22,6 @@
19
22
  "scripts": {
20
23
  "build": "tsc",
21
24
  "dev": "tsc --watch",
22
- "migrate:dev": "prisma migrate dev --schema prisma/schema",
23
- "migrate:deploy": "prisma migrate deploy --schema prisma/schema",
24
- "studio": "prisma studio --schema prisma/schema",
25
25
  "generate": "prisma generate --schema prisma/schema",
26
26
  "update": "yarn run generate && yarn run build"
27
27
  },
Binary file
@@ -8,10 +8,14 @@ model Assessment {
8
8
  //data
9
9
  score Float?
10
10
  feedback Json?
11
+ // Scheduled Deadline Window
11
12
  scheduled_start_time DateTime?
12
13
  scheduled_end_time DateTime?
14
+ /// Actual Start and End Time
13
15
  actual_start_time DateTime?
14
16
  actual_end_time DateTime?
17
+ /// Attempt Expires At
18
+ attempt_expires_at DateTime?
15
19
  /// Audit fields
16
20
  created_at DateTime @default(now())
17
21
  updated_at DateTime @updatedAt
@@ -20,6 +20,11 @@ enum InterviewPlatform {
20
20
  ZOOM
21
21
  }
22
22
 
23
+ enum AiAssistanceMode {
24
+ NONE
25
+ ASSISTED
26
+ }
27
+
23
28
  model Interview {
24
29
  id String @id @default(uuid())
25
30
  /// Foreign keys
@@ -85,6 +90,7 @@ model Interview {
85
90
  interviewNotes InterviewNotes[]
86
91
  liveAnalysis LiveAnalysis[]
87
92
  zoom_meeting ZoomMeeting?
93
+ ai_assistance_mode AiAssistanceMode @default(ASSISTED)
88
94
 
89
95
  @@unique([interviewer_id, candidate_id, evaluation_plan_id])
90
96
  @@index([candidate_id])
@@ -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,2 @@
1
+ -- No-op migration (keeps migration history contiguous; safe if already applied in DB).
2
+ SELECT 1;
@@ -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,5 @@
1
+ -- DropUnique: allows reorder/swap without a two-phase order_no dance; ordering is enforced in app logic.
2
+ ALTER TABLE "EvaluationPlan" DROP CONSTRAINT IF EXISTS "EvaluationPlan_job_description_id_order_no_key";
3
+
4
+ -- Non-unique index for lookups by job + order (e.g. swap).
5
+ CREATE INDEX "EvaluationPlan_job_description_id_order_no_idx" ON "EvaluationPlan"("job_description_id", "order_no");
@@ -0,0 +1,15 @@
1
+ -- EvaluationPlan.timeline optional (legacy column; app uses duration/deadline/duration_unit).
2
+ ALTER TABLE "EvaluationPlan" ALTER COLUMN "timeline" DROP NOT NULL;
3
+
4
+ -- OngoingEvaluation: denormalized duration fields; migrate legacy timeline into duration (minutes) then drop timeline.
5
+ ALTER TABLE "OngoingEvaluation" ADD COLUMN "duration" INTEGER;
6
+ ALTER TABLE "OngoingEvaluation" ADD COLUMN "deadline" INTEGER;
7
+ ALTER TABLE "OngoingEvaluation" ADD COLUMN "duration_unit" "DurationUnit";
8
+
9
+ UPDATE "OngoingEvaluation"
10
+ SET
11
+ "duration" = "timeline",
12
+ "duration_unit" = 'MINUTES'::"DurationUnit"
13
+ WHERE "timeline" IS NOT NULL AND "duration" IS NULL;
14
+
15
+ ALTER TABLE "OngoingEvaluation" DROP COLUMN IF EXISTS "timeline";
@@ -0,0 +1,8 @@
1
+ -- Remove unused AssessmentLibrary metadata columns.
2
+ ALTER TABLE "AssessmentLibrary" DROP COLUMN IF EXISTS "assessment_type";
3
+ ALTER TABLE "AssessmentLibrary" DROP COLUMN IF EXISTS "description";
4
+ ALTER TABLE "AssessmentLibrary" DROP COLUMN IF EXISTS "assessment_category";
5
+ ALTER TABLE "AssessmentLibrary" DROP COLUMN IF EXISTS "created_by_ai";
6
+
7
+ -- Enum only referenced by dropped column.
8
+ DROP TYPE IF EXISTS "AssessmentCategory";
@@ -0,0 +1,5 @@
1
+ -- DropQuestion.question_type and enum QuestionType (replaced by structure-based inference in app code)
2
+
3
+ ALTER TABLE "Question" DROP COLUMN IF EXISTS "question_type";
4
+
5
+ DROP TYPE IF EXISTS "QuestionType";
@@ -0,0 +1,56 @@
1
+ -- CreateTable
2
+ CREATE TABLE IF NOT EXISTS "organisationConfig" (
3
+ "id" TEXT NOT NULL,
4
+ "organisation_id" TEXT NOT NULL,
5
+ "config_key" TEXT NOT NULL,
6
+ "value" JSONB NOT NULL,
7
+ "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
8
+ "updated_at" TIMESTAMP(3) NOT NULL,
9
+
10
+ CONSTRAINT "organisationConfig_pkey" PRIMARY KEY ("id")
11
+ );
12
+
13
+ -- CreateIndex (idempotent for re-runs)
14
+ CREATE UNIQUE INDEX IF NOT EXISTS "organisationConfig_organisation_id_config_key_key" ON "organisationConfig"("organisation_id", "config_key");
15
+
16
+ -- AddForeignKey (ignore if exists)
17
+ DO $$
18
+ BEGIN
19
+ IF NOT EXISTS (
20
+ SELECT 1 FROM pg_constraint WHERE conname = 'organisationConfig_organisation_id_fkey'
21
+ ) THEN
22
+ ALTER TABLE "organisationConfig" ADD CONSTRAINT "organisationConfig_organisation_id_fkey" FOREIGN KEY ("organisation_id") REFERENCES "Organisation"("id") ON DELETE CASCADE ON UPDATE CASCADE;
23
+ END IF;
24
+ END $$;
25
+
26
+ -- Backfill from legacy column when present, then drop column.
27
+ -- IMPORTANT: Backfill runs only while `ai_assisted_interview_visible` still exists on
28
+ -- `"Organisation"`. If this migration applied once successfully, revoke + redeploy will
29
+ -- NOT re-insert—a column restore or manual INSERT is needed for replay scenarios.
30
+ DO $$
31
+ BEGIN
32
+ IF EXISTS (
33
+ SELECT 1
34
+ FROM pg_catalog.pg_attribute a
35
+ INNER JOIN pg_catalog.pg_class c ON c.oid = a.attrelid
36
+ INNER JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
37
+ WHERE n.nspname = ANY (current_schemas(true))
38
+ AND c.relkind = 'r'
39
+ AND c.relname = 'Organisation'
40
+ AND a.attname = 'ai_assisted_interview_visible'
41
+ AND a.attnum > 0
42
+ AND NOT a.attisdropped
43
+ ) THEN
44
+ INSERT INTO "organisationConfig" ("id", "organisation_id", "config_key", "value", "created_at", "updated_at")
45
+ SELECT gen_random_uuid()::text, "id", 'ai_assisted_interview_visible', to_jsonb(false), CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
46
+ FROM "Organisation"
47
+ WHERE "ai_assisted_interview_visible" IS FALSE
48
+ ON CONFLICT ("organisation_id", "config_key") DO NOTHING;
49
+
50
+ ALTER TABLE "Organisation" DROP COLUMN "ai_assisted_interview_visible";
51
+
52
+ RAISE NOTICE 'organisationConfig: backfilled from ai_assisted_interview_visible and dropped legacy column.';
53
+ ELSE
54
+ RAISE NOTICE 'organisationConfig: skipped backfill (column ai_assisted_interview_visible not found on "Organisation"—already migrated, empty DB, or non-matching search_path).';
55
+ END IF;
56
+ END $$;
@@ -0,0 +1,20 @@
1
+ -- Remove duplicate (organisation_id, config_key) rows, keeping the newest by updated_at.
2
+ -- Safe to run multiple times; no-op when already unique.
3
+ DELETE FROM "organisationConfig" d
4
+ WHERE EXISTS (
5
+ SELECT 1
6
+ FROM (
7
+ SELECT
8
+ "id",
9
+ ROW_NUMBER() OVER (
10
+ PARTITION BY "organisation_id", "config_key"
11
+ ORDER BY "updated_at" DESC NULLS LAST, "id" DESC
12
+ ) AS rn
13
+ FROM "organisationConfig"
14
+ ) k
15
+ WHERE k."id" = d."id"
16
+ AND k.rn > 1
17
+ );
18
+
19
+ CREATE UNIQUE INDEX IF NOT EXISTS "organisationConfig_organisation_id_config_key_key"
20
+ ON "organisationConfig"("organisation_id", "config_key");
@@ -0,0 +1,5 @@
1
+ -- CreateEnum
2
+ CREATE TYPE "AiAssistanceMode" AS ENUM ('NONE', 'ASSISTED');
3
+
4
+ -- AlterTable
5
+ ALTER TABLE "Interview" ADD COLUMN "ai_assistance_mode" "AiAssistanceMode" NOT NULL DEFAULT 'ASSISTED';
@@ -0,0 +1,3 @@
1
+ # Please do not edit this file manually
2
+ # It should be added in your version-control system (i.e. Git)
3
+ provider = "postgresql"
@@ -43,6 +43,8 @@ model Organisation {
43
43
  integration_credentials IntegrationCredential[]
44
44
  zoho_sync_mappings ZohoSyncMapping[]
45
45
  assessments Assessment[]
46
+ timezone String @default("Asia/Kolkata")
47
+ organisation_configs OrganisationConfig[]
46
48
 
47
49
  @@index([name])
48
50
  }
@@ -0,0 +1,12 @@
1
+ model OrganisationConfig {
2
+ id String @id @default(uuid())
3
+ organisation_id String
4
+ config_key String
5
+ value Json
6
+ created_at DateTime @default(now())
7
+ updated_at DateTime @updatedAt
8
+ organisation Organisation @relation(fields: [organisation_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
9
+
10
+ @@unique([organisation_id, config_key])
11
+ @@map("organisationConfig")
12
+ }