@adaptware/eagles-db 0.3.2 → 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.
- package/bin/db-cli.js +3 -24
- package/client/edge.js +25 -7
- package/client/index-browser.js +20 -2
- package/client/index.d.ts +2335 -229
- package/client/index.js +25 -7
- package/client/package.json +1 -1
- package/client/schema.prisma +25 -0
- package/client/wasm.js +20 -2
- package/dist/index.d.ts +3 -3
- package/dist/index.js +6 -6
- package/package.json +4 -4
- package/prisma/.DS_Store +0 -0
- package/prisma/schema/interview.prisma +6 -0
- package/prisma/schema/migrations/20260415120000_remove_job_profile_current_phase/migration.sql +2 -0
- package/prisma/schema/migrations/20260422120000_add_integration_provider_zoom/migration.sql +2 -0
- package/prisma/schema/migrations/20260422140000_add_zoom_meeting_tables/migration.sql +57 -0
- package/prisma/schema/migrations/20260422180000_add_zoom_webhook_event/migration.sql +18 -0
- package/prisma/schema/migrations/20260423140000_add_interview_platform/migration.sql +6 -0
- package/prisma/schema/migrations/20260423150000_remove_interview_zoom_topic/migration.sql +2 -0
- package/prisma/schema/migrations/20260423160000_zoom_meeting_uuid/migration.sql +4 -0
- package/prisma/schema/migrations/20260423170000_zoom_meeting_uuid_prisma_sync/migration.sql +2 -0
- package/prisma/schema/migrations/20260424120000_auth_module_user_provider_unique/migration.sql +5 -0
- package/prisma/schema/migrations/20260424130000_zoom_meeting_zoom_host_user_id/migration.sql +6 -0
- package/prisma/schema/migrations/20260425100000_zoom_participant_user_enum/migration.sql +22 -0
- package/prisma/schema/migrations/20260425110000_zoom_participant_zoom_id_required/migration.sql +13 -0
- package/prisma/schema/migrations/20260425120000_zoom_participant_id_nullable/migration.sql +4 -0
- package/prisma/schema/migrations/20260429140000_drop_evaluation_plan_job_order_unique/migration.sql +5 -0
- package/prisma/schema/migrations/20260429180000_eval_plan_timeline_optional_ongoing_duration/migration.sql +15 -0
- package/prisma/schema/migrations/20260430120000_drop_assessment_library_metadata_fields/migration.sql +8 -0
- package/prisma/schema/migrations/20260430140000_drop_question_question_type/migration.sql +5 -0
- package/prisma/schema/migrations/20260513120000_add_organisation_config/migration.sql +56 -0
- package/prisma/schema/migrations/20260514120000_dedupe_organisation_config/migration.sql +20 -0
- package/prisma/schema/migrations/20260515120000_add_interview_ai_assistance_mode/migration.sql +5 -0
- package/prisma/schema/migrations/migration_lock.toml +3 -0
- package/prisma/schema/organisation.prisma +1 -0
- package/prisma/schema/organisationConfig.prisma +12 -0
- package/client/libquery_engine-darwin.dylib.node +0 -0
package/client/package.json
CHANGED
package/client/schema.prisma
CHANGED
|
@@ -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
|
|
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
|
|
6
|
-
export * from
|
|
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
|
|
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: [
|
|
4
|
+
log: ['error', 'warn', 'info'],
|
|
5
5
|
});
|
|
6
6
|
// Export all Prisma types
|
|
7
|
-
export * from
|
|
7
|
+
export * from '../client/index.js';
|
|
8
8
|
// Graceful shutdown
|
|
9
|
-
process.on(
|
|
9
|
+
process.on('beforeExit', async () => {
|
|
10
10
|
await prisma.$disconnect();
|
|
11
11
|
});
|
|
12
|
-
process.on(
|
|
12
|
+
process.on('SIGINT', async () => {
|
|
13
13
|
await prisma.$disconnect();
|
|
14
14
|
process.exit(0);
|
|
15
15
|
});
|
|
16
|
-
process.on(
|
|
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.
|
|
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
|
},
|
package/prisma/.DS_Store
ADDED
|
Binary file
|
|
@@ -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,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,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,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");
|
package/prisma/schema/migrations/20260425110000_zoom_participant_zoom_id_required/migration.sql
ADDED
|
@@ -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;
|
package/prisma/schema/migrations/20260429140000_drop_evaluation_plan_job_order_unique/migration.sql
ADDED
|
@@ -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,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,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
|
+
}
|
|
Binary file
|