@adaptware/eagles-db 0.5.8 → 0.5.9

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 (49) hide show
  1. package/client/edge.js +74 -41
  2. package/client/index-browser.js +78 -44
  3. package/client/index.d.ts +14441 -7888
  4. package/client/index.js +74 -41
  5. package/client/libquery_engine-darwin.dylib.node +0 -0
  6. package/client/package.json +1 -1
  7. package/client/schema.prisma +138 -92
  8. package/client/wasm.js +74 -41
  9. package/package.json +1 -1
  10. package/prisma/.DS_Store +0 -0
  11. package/prisma/migrations/20260519120000_migrate_shortlisted_to_selected/migration.sql +2 -0
  12. package/prisma/schema/.DS_Store +0 -0
  13. package/prisma/schema/applications.prisma +0 -2
  14. package/prisma/schema/assessmentRoundAnalytics.prisma +0 -2
  15. package/prisma/schema/assignmentRoundAnalytics.prisma +0 -2
  16. package/prisma/schema/evaluationPlan.prisma +0 -32
  17. package/prisma/schema/interview.prisma +32 -44
  18. package/prisma/schema/interviewRoundAnalytics.prisma +35 -37
  19. package/prisma/schema/migrations/20260519120000_add_analytics_schema/migration.sql +84 -0
  20. package/prisma/schema/migrations/20260625120000_add_interviewer_analytics/migration.sql +26 -0
  21. package/prisma/schema/migrations/20260629120000_add_user_lifecycle_activity_events/migration.sql +13 -0
  22. package/prisma/schema/migrations/20260629140000_drop_organisation_org_code/migration.sql +2 -0
  23. package/prisma/schema/migrations/20260629160000_employee_codes_dual_interviewer_analytics/migration.sql +87 -0
  24. package/prisma/schema/migrations/20260630120000_add_application_sources/migration.sql +38 -0
  25. package/prisma/schema/migrations/20260701120000_add_source_effectiveness_analytics/migration.sql +40 -0
  26. package/prisma/schema/migrations/20260702120000_add_analytics_daily_tables/migration.sql +232 -0
  27. package/prisma/schema/migrations/20260716120000_evaluation_category_four_values/migration.sql +204 -0
  28. package/prisma/schema/migrations/20260716130000_application_withdrawn_analytics/migration.sql +31 -0
  29. package/prisma/schema/ongoingEvaluation.prisma +0 -1
  30. package/prisma/schema/organisation.prisma +2 -0
  31. package/prisma/schema/schema.prisma +1 -1
  32. package/prisma/schema/usage.prisma +96 -0
  33. package/prisma/schema/migrations/20260522120000_ongoing_evaluation_record_kind/migration.sql +0 -25
  34. package/prisma/schema/migrations/20260523120000_replace_record_kind_with_is_committed/migration.sql +0 -24
  35. package/prisma/schema/migrations/20260528120000_drop_job_description_recommendation_config/migration.sql +0 -2
  36. package/prisma/schema/migrations/20260710120000_add_resume_rendered_export_fields/migration.sql +0 -9
  37. package/prisma/schema/migrations/20260714120000_add_job_description_display_html_document/migration.sql +0 -8
  38. package/prisma/schema/migrations/20260716120000_add_offer_letters/migration.sql +0 -183
  39. package/prisma/schema/migrations/20260716140000_offer_schema_refinements/migration.sql +0 -13
  40. package/prisma/schema/migrations/20260716160000_offer_schema_hardening/migration.sql +0 -95
  41. package/prisma/schema/migrations/20260716180000_offer_letter_template_config/migration.sql +0 -2
  42. package/prisma/schema/migrations/20260716190000_add_evaluation_focus_areas/migration.sql +0 -6
  43. package/prisma/schema/migrations/20260717120000_offer_workflow_approval/migration.sql +0 -30
  44. package/prisma/schema/migrations/20260720120000_offer_letter_template_is_draft/migration.sql +0 -5
  45. package/prisma/schema/migrations/20260720140000_offer_status_split/migration.sql +0 -51
  46. package/prisma/schema/migrations/20260720140001_offer_status_split_backfill/migration.sql +0 -37
  47. package/prisma/schema/migrations/20260722120000_offer_draft_edited_html/migration.sql +0 -13
  48. package/prisma/schema/migrations/20260723150000_offer_withdraw_actor_no_show_reason/migration.sql +0 -10
  49. package/prisma/schema/migrations/20260724120000_open_job_offer_accepted_declined_counts/migration.sql +0 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adaptware/eagles-db",
3
- "version": "0.5.8",
3
+ "version": "0.5.9",
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
+ -- Migrate legacy terminal-positive status to SELECTED (SHORTLISTED enum value retained but unused).
2
+ UPDATE applications SET status = 'SELECTED' WHERE status = 'SHORTLISTED';
Binary file
@@ -41,8 +41,6 @@ model Application {
41
41
  status ApplicationStatus @default(PENDING)
42
42
  /// Mirror of Offer.status for list filters and combined status chips
43
43
  offer_status OfferStatus?
44
- /// Mirror of Offer.substatus for in-flight detail while offer is OPEN
45
- offer_substatus OfferSubstatus?
46
44
  evaluation_plan EvaluationPlan? @relation(fields: [evaluation_plan_id], references: [id])
47
45
  candidate User @relation(fields: [candidate_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
48
46
  organisation Organisation @relation(fields: [organisation_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
@@ -29,7 +29,6 @@ model AssessmentRoundAnalytics {
29
29
  round_name String?
30
30
  evaluation_category EvaluationCategory?
31
31
  round_type RoundType?
32
- round_format EvaluationRoundFormat?
33
32
  plan_order_no Int?
34
33
  plan_type EvaluationPlanType?
35
34
  is_custom Boolean @default(false)
@@ -86,7 +85,6 @@ model AssessmentRoundAnalyticsDaily {
86
85
  round_name String?
87
86
  evaluation_category EvaluationCategory?
88
87
  round_type RoundType?
89
- round_format EvaluationRoundFormat?
90
88
  plan_order_no Int?
91
89
  plan_type EvaluationPlanType?
92
90
  is_custom Boolean @default(false)
@@ -19,7 +19,6 @@ model AssignmentRoundAnalytics {
19
19
  round_name String?
20
20
  evaluation_category EvaluationCategory?
21
21
  round_type RoundType?
22
- round_format EvaluationRoundFormat?
23
22
  plan_order_no Int?
24
23
  plan_type EvaluationPlanType?
25
24
  is_custom Boolean @default(false)
@@ -76,7 +75,6 @@ model AssignmentRoundAnalyticsDaily {
76
75
  round_name String?
77
76
  evaluation_category EvaluationCategory?
78
77
  round_type RoundType?
79
- round_format EvaluationRoundFormat?
80
78
  plan_order_no Int?
81
79
  plan_type EvaluationPlanType?
82
80
  is_custom Boolean @default(false)
@@ -16,37 +16,6 @@ enum EvaluationCategory {
16
16
  @@schema("public")
17
17
  }
18
18
 
19
- enum EvaluationRoundFormat {
20
- // ────────────────
21
- // Screening formats
22
- // ────────────────
23
- PHONE_CALL
24
- VIDEO_CALL_AI_ASSISTED
25
- VIDEO_CALL_UNASSISTED
26
-
27
- // ────────────────
28
- // Assessment formats
29
- // ────────────────
30
- AI_GENERATED_TEST
31
- UPLOADED_TEST
32
- EXTERNAL_PLATFORM
33
-
34
- // ────────────────
35
- // Assignment formats
36
- // ────────────────
37
- AI_GENERATED_ASSIGNMENT
38
- UPLOADED_ASSIGNMENT
39
-
40
- // ────────────────
41
- // Interview formats
42
- // ────────────────
43
- TREADSPACE_AI_ASSISTED
44
- EXTERNAL_VIDEO_AI_ASSISTED
45
- EXTERNAL_VIDEO_UNASSISTED
46
-
47
- @@schema("public")
48
- }
49
-
50
19
  enum EvaluationType {
51
20
  // New (In active use now)
52
21
  TREADSPACE_AI_ASSISTED
@@ -88,7 +57,6 @@ model EvaluationPlan {
88
57
  assignment_library_id String?
89
58
  title String
90
59
  description String?
91
- format EvaluationRoundFormat?
92
60
  focus_areas String[]
93
61
  topics String[]
94
62
  assignee String?
@@ -10,15 +10,6 @@ enum InterviewStatus {
10
10
  @@schema("public")
11
11
  }
12
12
 
13
- enum InterviewFeedback {
14
- STRONG_HIRE
15
- HIRE
16
- NO_HIRE
17
- STRONG_NO_HIRE
18
-
19
- @@schema("public")
20
- }
21
-
22
13
  enum InterviewPlatform {
23
14
  TREADSPACE
24
15
  ZOOM
@@ -34,7 +25,7 @@ enum AiAssistanceMode {
34
25
  }
35
26
 
36
27
  model Interview {
37
- id String @id @default(uuid())
28
+ id String @id @default(uuid())
38
29
  /// Foreign keys
39
30
  organisation_id String
40
31
  candidate_id String
@@ -46,6 +37,7 @@ model Interview {
46
37
  calendar_event_id String?
47
38
  /// Data
48
39
  room_name String?
40
+ /// @deprecated Prefer `ai_feedback.feedback` (narrative string on AI feedback JSON).
49
41
  interview_summary String[]
50
42
  scheduled_start_time DateTime?
51
43
  scheduled_end_time DateTime?
@@ -55,20 +47,17 @@ model Interview {
55
47
  duration Int?
56
48
  /// @deprecated Prefer `recording_document_id` + `Document` (type INTERVIEW_RECORDING).
57
49
  recording_url String?
58
- recording_document_id String? @unique
59
- evaluation_type EvaluationType? @default(TREADSPACE_AI_ASSISTED)
60
- ai_assistance_mode AiAssistanceMode? @default(ASSISTED)
61
- interview_status InterviewStatus @default(SCHEDULED)
62
- interview_platform InterviewPlatform @default(TREADSPACE)
63
- /// Old Feedback fields will be deprecated soon
64
- ai_interview_feedback InterviewFeedback?
65
- interview_feedback InterviewFeedback?
50
+ recording_document_id String? @unique
51
+ evaluation_type EvaluationType? @default(TREADSPACE_AI_ASSISTED)
52
+ ai_assistance_mode AiAssistanceMode? @default(ASSISTED)
53
+ interview_status InterviewStatus @default(SCHEDULED)
54
+ interview_platform InterviewPlatform @default(TREADSPACE)
66
55
  overall_feedback String?
67
- interview_rating Float? // Overall rating out of 100 based on evaluation
68
- /// New Feedback fields
56
+ /// Feedback JSON fields
57
+ /// AI overall payload: `{ score, rating, feedback? }` where `feedback` is the
58
+ /// narrative summary string (replaces deprecated `interview_summary`).
69
59
  ai_feedback Json?
70
60
  human_feedback Json?
71
- interviewer_feedback Json?
72
61
  section_feedback Json[]
73
62
  interview_preparation Json?
74
63
  final_feedback Json?
@@ -82,37 +71,36 @@ model Interview {
82
71
  evaluated_at DateTime?
83
72
 
84
73
  /// Self-scheduling
85
- reschedule_count Int @default(0)
74
+ reschedule_count Int @default(0)
86
75
  last_rescheduled_at DateTime?
87
76
  first_assigned_at DateTime?
88
77
  /// True while the candidate is waiting on recruiter action (typically a
89
78
  /// reassign) after they submitted alternate slots via "None match" /
90
79
  /// "Suggest times". Cleared whenever the recruiter routes a fresh
91
80
  /// request via `upsertInterviewRequestRecord`.
92
- awaiting_recruiter_action Boolean @default(false)
93
-
81
+ awaiting_recruiter_action Boolean @default(false)
94
82
  /// Audit fields
95
- created_at DateTime @default(now())
96
- updated_at DateTime @updatedAt
97
- created_by String
98
- updated_by String
99
- is_active Boolean @default(true)
83
+ created_at DateTime @default(now())
84
+ updated_at DateTime @updatedAt
85
+ created_by String
86
+ updated_by String
87
+ is_active Boolean @default(true)
100
88
  // Relations
101
- candidate User? @relation("CandidateInterviews", fields: [candidate_id], references: [id], onDelete: SetNull)
102
- interviewer User? @relation("InterviewerInterviews", fields: [interviewer_id], references: [id], onDelete: SetNull)
103
- organisation Organisation @relation(fields: [organisation_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
104
- recording_document Document? @relation(fields: [recording_document_id], references: [id], onDelete: SetNull, onUpdate: Cascade)
105
- job_description JobDescription @relation(fields: [job_description_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
106
- resume Resume @relation(fields: [resume_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
107
- evaluation_plan EvaluationPlan? @relation(fields: [evaluation_plan_id], references: [id], onDelete: SetNull, onUpdate: Cascade)
108
- application Application? @relation(fields: [application_id], references: [id], onDelete: SetNull, onUpdate: Cascade)
109
- ongoing_evaluation OngoingEvaluation?
110
- transcripts Transcript[]
111
- suggestions Suggestion[]
112
- feedback Feedback[]
113
- interviewNotes InterviewNotes[]
114
- liveAnalysis LiveAnalysis[]
115
- zoom_meeting ZoomMeeting?
89
+ candidate User? @relation("CandidateInterviews", fields: [candidate_id], references: [id], onDelete: SetNull)
90
+ interviewer User? @relation("InterviewerInterviews", fields: [interviewer_id], references: [id], onDelete: SetNull)
91
+ organisation Organisation @relation(fields: [organisation_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
92
+ recording_document Document? @relation(fields: [recording_document_id], references: [id], onDelete: SetNull, onUpdate: Cascade)
93
+ job_description JobDescription @relation(fields: [job_description_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
94
+ resume Resume @relation(fields: [resume_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
95
+ evaluation_plan EvaluationPlan? @relation(fields: [evaluation_plan_id], references: [id], onDelete: SetNull, onUpdate: Cascade)
96
+ application Application? @relation(fields: [application_id], references: [id], onDelete: SetNull, onUpdate: Cascade)
97
+ ongoing_evaluation OngoingEvaluation?
98
+ transcripts Transcript[]
99
+ suggestions Suggestion[]
100
+ feedback Feedback[]
101
+ interviewNotes InterviewNotes[]
102
+ liveAnalysis LiveAnalysis[]
103
+ zoom_meeting ZoomMeeting?
116
104
 
117
105
  // Indexes
118
106
  @@unique([interviewer_id, candidate_id, evaluation_plan_id])
@@ -24,25 +24,24 @@ model InterviewRoundAnalytics {
24
24
  department String?
25
25
  location String?
26
26
 
27
- round_name String?
28
- evaluation_category EvaluationCategory?
29
- round_type RoundType?
30
- round_format EvaluationRoundFormat?
31
- plan_order_no Int?
32
- plan_type EvaluationPlanType?
33
- is_custom Boolean @default(false)
34
-
35
- interviewer_id String?
36
- interviewer_employee_id String?
37
- interviewer_name String?
27
+ round_name String?
28
+ evaluation_category EvaluationCategory?
29
+ round_type RoundType?
30
+ plan_order_no Int?
31
+ plan_type EvaluationPlanType?
32
+ is_custom Boolean @default(false)
33
+
34
+ interviewer_id String?
35
+ interviewer_employee_id String?
36
+ interviewer_name String?
38
37
 
39
38
  candidate_name String?
40
39
  candidate_email String?
41
40
 
42
- evaluation_type EvaluationType?
43
- ai_assistance_mode AiAssistanceMode?
44
- interview_platform InterviewPlatform?
45
- interview_status InterviewStatus?
41
+ evaluation_type EvaluationType?
42
+ ai_assistance_mode AiAssistanceMode?
43
+ interview_platform InterviewPlatform?
44
+ interview_status InterviewStatus?
46
45
 
47
46
  scheduled_start_at DateTime?
48
47
  scheduled_end_at DateTime?
@@ -52,10 +51,10 @@ model InterviewRoundAnalytics {
52
51
  first_assigned_at DateTime?
53
52
  duration_minutes Int?
54
53
 
55
- human_rating String?
56
- ai_rating String?
57
- recommendation InterviewRecommendation?
58
- ai_disagrees_with_ai Boolean?
54
+ human_rating String?
55
+ ai_rating String?
56
+ recommendation InterviewRecommendation?
57
+ ai_disagrees_with_ai Boolean?
59
58
 
60
59
  difficulty_score Float?
61
60
  supportiveness_score Float?
@@ -92,25 +91,24 @@ model InterviewRoundAnalyticsDaily {
92
91
  department String?
93
92
  location String?
94
93
 
95
- round_name String?
96
- evaluation_category EvaluationCategory?
97
- round_type RoundType?
98
- round_format EvaluationRoundFormat?
99
- plan_order_no Int?
100
- plan_type EvaluationPlanType?
101
- is_custom Boolean @default(false)
94
+ round_name String?
95
+ evaluation_category EvaluationCategory?
96
+ round_type RoundType?
97
+ plan_order_no Int?
98
+ plan_type EvaluationPlanType?
99
+ is_custom Boolean @default(false)
102
100
 
103
- interviewer_id String?
104
- interviewer_employee_id String?
105
- interviewer_name String?
101
+ interviewer_id String?
102
+ interviewer_employee_id String?
103
+ interviewer_name String?
106
104
 
107
105
  candidate_name String?
108
106
  candidate_email String?
109
107
 
110
- evaluation_type EvaluationType?
111
- ai_assistance_mode AiAssistanceMode?
112
- interview_platform InterviewPlatform?
113
- interview_status InterviewStatus?
108
+ evaluation_type EvaluationType?
109
+ ai_assistance_mode AiAssistanceMode?
110
+ interview_platform InterviewPlatform?
111
+ interview_status InterviewStatus?
114
112
 
115
113
  scheduled_start_at DateTime?
116
114
  scheduled_end_at DateTime?
@@ -120,10 +118,10 @@ model InterviewRoundAnalyticsDaily {
120
118
  first_assigned_at DateTime?
121
119
  duration_minutes Int?
122
120
 
123
- human_rating String?
124
- ai_rating String?
125
- recommendation InterviewRecommendation?
126
- ai_disagrees_with_ai Boolean?
121
+ human_rating String?
122
+ ai_rating String?
123
+ recommendation InterviewRecommendation?
124
+ ai_disagrees_with_ai Boolean?
127
125
 
128
126
  difficulty_score Float?
129
127
  supportiveness_score Float?
@@ -0,0 +1,84 @@
1
+ -- CreateSchema
2
+ CREATE SCHEMA IF NOT EXISTS "analytics";
3
+
4
+ -- CreateEnum
5
+ CREATE TYPE "analytics"."RoundResult" AS ENUM ('PASSED', 'FAILED');
6
+
7
+ -- CreateTable
8
+ CREATE TABLE "analytics"."round_analytics" (
9
+ "id" TEXT NOT NULL,
10
+ "organisation_id" TEXT NOT NULL,
11
+ "application_id" TEXT NOT NULL,
12
+ "candidate_id" TEXT NOT NULL,
13
+ "job_description_id" TEXT NOT NULL,
14
+ "evaluation_plan_id" TEXT NOT NULL,
15
+ "round_id" TEXT NOT NULL,
16
+ "round_name" TEXT,
17
+ "evaluation_category" "EvaluationCategory",
18
+ "round_type" "RoundType",
19
+ "assigned_at" TIMESTAMP(3),
20
+ "interview_created_at" TIMESTAMP(3),
21
+ "interview_scheduled_at" TIMESTAMP(3),
22
+ "interview_started_at" TIMESTAMP(3),
23
+ "interview_completed_at" TIMESTAMP(3),
24
+ "interview_evaluated_at" TIMESTAMP(3),
25
+ "round_completed_at" TIMESTAMP(3),
26
+ "round_result" "analytics"."RoundResult",
27
+ "round_result_at" TIMESTAMP(3),
28
+ "scheduling_duration_minutes" INTEGER,
29
+ "interview_duration_minutes" INTEGER,
30
+ "feedback_duration_minutes" INTEGER,
31
+ "decision_duration_minutes" INTEGER,
32
+ "total_round_duration_minutes" INTEGER,
33
+ "is_custom" BOOLEAN NOT NULL DEFAULT false,
34
+ "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
35
+ "updated_at" TIMESTAMP(3) NOT NULL,
36
+
37
+ CONSTRAINT "round_analytics_pkey" PRIMARY KEY ("id")
38
+ );
39
+
40
+ -- CreateTable
41
+ CREATE TABLE "analytics"."job_round_analytics" (
42
+ "id" TEXT NOT NULL,
43
+ "organisation_id" TEXT NOT NULL,
44
+ "job_description_id" TEXT NOT NULL,
45
+ "evaluation_plan_id" TEXT NOT NULL,
46
+ "round_name" TEXT NOT NULL,
47
+ "evaluation_category" "EvaluationCategory",
48
+ "is_custom" BOOLEAN NOT NULL DEFAULT false,
49
+ "assigned_count" INTEGER NOT NULL DEFAULT 0,
50
+ "completed_count" INTEGER NOT NULL DEFAULT 0,
51
+ "passed_count" INTEGER NOT NULL DEFAULT 0,
52
+ "failed_count" INTEGER NOT NULL DEFAULT 0,
53
+ "withdrawn_count" INTEGER NOT NULL DEFAULT 0,
54
+ "no_show_count" INTEGER NOT NULL DEFAULT 0,
55
+ "total_completion_minutes" BIGINT NOT NULL DEFAULT 0,
56
+ "avg_completion_minutes" DOUBLE PRECISION,
57
+ "updated_at" TIMESTAMP(3) NOT NULL,
58
+
59
+ CONSTRAINT "job_round_analytics_pkey" PRIMARY KEY ("id")
60
+ );
61
+
62
+ -- CreateIndex
63
+ CREATE UNIQUE INDEX "round_analytics_round_id_key" ON "analytics"."round_analytics"("round_id");
64
+
65
+ -- CreateIndex
66
+ CREATE INDEX "round_analytics_organisation_id_idx" ON "analytics"."round_analytics"("organisation_id");
67
+
68
+ -- CreateIndex
69
+ CREATE INDEX "round_analytics_job_description_id_idx" ON "analytics"."round_analytics"("job_description_id");
70
+
71
+ -- CreateIndex
72
+ CREATE INDEX "round_analytics_application_id_idx" ON "analytics"."round_analytics"("application_id");
73
+
74
+ -- CreateIndex
75
+ CREATE INDEX "round_analytics_candidate_id_idx" ON "analytics"."round_analytics"("candidate_id");
76
+
77
+ -- CreateIndex
78
+ CREATE INDEX "round_analytics_evaluation_category_idx" ON "analytics"."round_analytics"("evaluation_category");
79
+
80
+ -- CreateIndex
81
+ CREATE INDEX "round_analytics_round_result_idx" ON "analytics"."round_analytics"("round_result");
82
+
83
+ -- CreateIndex
84
+ CREATE UNIQUE INDEX "job_round_analytics_job_description_id_evaluation_plan_id_key" ON "analytics"."job_round_analytics"("job_description_id", "evaluation_plan_id");
@@ -0,0 +1,26 @@
1
+ -- CreateTable
2
+ CREATE TABLE "analytics"."interviewer_analytics" (
3
+ "id" TEXT NOT NULL,
4
+ "organisation_id" TEXT NOT NULL,
5
+ "user_id" TEXT NOT NULL,
6
+ "name" TEXT,
7
+ "employee_id" TEXT,
8
+ "interview_count" INTEGER NOT NULL DEFAULT 0,
9
+ "accepted_count" INTEGER NOT NULL DEFAULT 0,
10
+ "rejected_count" INTEGER NOT NULL DEFAULT 0,
11
+ "unsure_count" INTEGER NOT NULL DEFAULT 0,
12
+ "ai_disagreement_count" INTEGER NOT NULL DEFAULT 0,
13
+ "ai_disagreement_percent" DOUBLE PRECISION,
14
+ "avg_difficulty" DOUBLE PRECISION,
15
+ "avg_supportiveness" DOUBLE PRECISION,
16
+ "avg_topics_coverage_percent" DOUBLE PRECISION,
17
+ "updated_at" TIMESTAMP(3) NOT NULL,
18
+
19
+ CONSTRAINT "interviewer_analytics_pkey" PRIMARY KEY ("id")
20
+ );
21
+
22
+ -- CreateIndex
23
+ CREATE UNIQUE INDEX "interviewer_analytics_organisation_id_user_id_key" ON "analytics"."interviewer_analytics"("organisation_id", "user_id");
24
+
25
+ -- CreateIndex
26
+ CREATE INDEX "interviewer_analytics_organisation_id_idx" ON "analytics"."interviewer_analytics"("organisation_id");
@@ -0,0 +1,13 @@
1
+ -- AlterEnum
2
+ ALTER TYPE "public"."ActivityEventType" ADD VALUE 'USER_INVITED';
3
+ ALTER TYPE "public"."ActivityEventType" ADD VALUE 'USER_INVITATION_RESENT';
4
+ ALTER TYPE "public"."ActivityEventType" ADD VALUE 'USER_CREATED';
5
+ ALTER TYPE "public"."ActivityEventType" ADD VALUE 'USER_INVITATION_ACCEPTED';
6
+ ALTER TYPE "public"."ActivityEventType" ADD VALUE 'USER_INVITATION_EXPIRED';
7
+ ALTER TYPE "public"."ActivityEventType" ADD VALUE 'USER_DEACTIVATED';
8
+ ALTER TYPE "public"."ActivityEventType" ADD VALUE 'USER_REACTIVATED';
9
+ ALTER TYPE "public"."ActivityEventType" ADD VALUE 'USER_ROLE_CHANGED';
10
+ ALTER TYPE "public"."ActivityEventType" ADD VALUE 'USER_PROFILE_COMPLETED';
11
+ ALTER TYPE "public"."ActivityEventType" ADD VALUE 'CANDIDATE_REGISTERED';
12
+ ALTER TYPE "public"."ActivityEventType" ADD VALUE 'CANDIDATE_CREATED';
13
+ ALTER TYPE "public"."ActivityEventType" ADD VALUE 'CANDIDATE_PROFILE_COMPLETED';
@@ -0,0 +1,2 @@
1
+ ALTER TABLE "Organisation" DROP COLUMN IF EXISTS "org_code";
2
+ ALTER TABLE "Organisation" ADD COLUMN IF NOT EXISTS "employee_sequence" INTEGER NOT NULL DEFAULT 1;
@@ -0,0 +1,87 @@
1
+ ALTER TABLE "User" ADD COLUMN IF NOT EXISTS "employee_number" INTEGER;
2
+ ALTER TABLE "User" ADD COLUMN IF NOT EXISTS "employee_code" TEXT;
3
+
4
+ CREATE UNIQUE INDEX IF NOT EXISTS "User_employee_code_key" ON "User"("employee_code");
5
+ CREATE INDEX IF NOT EXISTS "User_organisation_id_employee_number_idx" ON "User"("organisation_id", "employee_number");
6
+
7
+ DROP TABLE IF EXISTS "analytics"."interviewer_analytics";
8
+
9
+ CREATE TABLE "analytics"."interviewer_organisation_analytics" (
10
+ "id" TEXT NOT NULL,
11
+ "organisation_id" TEXT NOT NULL,
12
+ "user_id" TEXT NOT NULL,
13
+ "name" TEXT,
14
+ "employee_id" TEXT,
15
+ "interview_count" INTEGER NOT NULL DEFAULT 0,
16
+ "accepted_count" INTEGER NOT NULL DEFAULT 0,
17
+ "rejected_count" INTEGER NOT NULL DEFAULT 0,
18
+ "unsure_count" INTEGER NOT NULL DEFAULT 0,
19
+ "ai_disagreement_count" INTEGER NOT NULL DEFAULT 0,
20
+ "ai_disagreement_percent" DOUBLE PRECISION,
21
+ "avg_difficulty" DOUBLE PRECISION,
22
+ "avg_supportiveness" DOUBLE PRECISION,
23
+ "avg_topics_coverage_percent" DOUBLE PRECISION,
24
+ "updated_at" TIMESTAMP(3) NOT NULL,
25
+
26
+ CONSTRAINT "interviewer_organisation_analytics_pkey" PRIMARY KEY ("id")
27
+ );
28
+
29
+ CREATE UNIQUE INDEX "interviewer_organisation_analytics_organisation_id_user_id_key"
30
+ ON "analytics"."interviewer_organisation_analytics"("organisation_id", "user_id");
31
+ CREATE INDEX "interviewer_organisation_analytics_organisation_id_idx"
32
+ ON "analytics"."interviewer_organisation_analytics"("organisation_id");
33
+ CREATE INDEX "interviewer_organisation_analytics_organisation_id_user_id_idx"
34
+ ON "analytics"."interviewer_organisation_analytics"("organisation_id", "user_id");
35
+
36
+ CREATE TABLE "analytics"."interviewer_job_analytics" (
37
+ "id" TEXT NOT NULL,
38
+ "organisation_id" TEXT NOT NULL,
39
+ "user_id" TEXT NOT NULL,
40
+ "job_description_id" TEXT NOT NULL,
41
+ "hiring_manager_id" TEXT,
42
+ "department" TEXT,
43
+ "location" TEXT,
44
+ "role_title" TEXT,
45
+ "job_code" TEXT,
46
+ "opened_at" TIMESTAMP(3),
47
+ "name" TEXT,
48
+ "employee_id" TEXT,
49
+ "interview_count" INTEGER NOT NULL DEFAULT 0,
50
+ "accepted_count" INTEGER NOT NULL DEFAULT 0,
51
+ "rejected_count" INTEGER NOT NULL DEFAULT 0,
52
+ "unsure_count" INTEGER NOT NULL DEFAULT 0,
53
+ "ai_disagreement_count" INTEGER NOT NULL DEFAULT 0,
54
+ "ai_disagreement_percent" DOUBLE PRECISION,
55
+ "avg_difficulty" DOUBLE PRECISION,
56
+ "avg_supportiveness" DOUBLE PRECISION,
57
+ "avg_topics_coverage_percent" DOUBLE PRECISION,
58
+ "updated_at" TIMESTAMP(3) NOT NULL,
59
+
60
+ CONSTRAINT "interviewer_job_analytics_pkey" PRIMARY KEY ("id")
61
+ );
62
+
63
+ CREATE UNIQUE INDEX "interviewer_job_analytics_organisation_id_user_id_job_descri_key"
64
+ ON "analytics"."interviewer_job_analytics"("organisation_id", "user_id", "job_description_id");
65
+ CREATE INDEX "interviewer_job_analytics_organisation_id_job_description_id_idx"
66
+ ON "analytics"."interviewer_job_analytics"("organisation_id", "job_description_id");
67
+ CREATE INDEX "interviewer_job_analytics_organisation_id_hiring_manager_id_idx"
68
+ ON "analytics"."interviewer_job_analytics"("organisation_id", "hiring_manager_id");
69
+ CREATE INDEX "interviewer_job_analytics_organisation_id_department_idx"
70
+ ON "analytics"."interviewer_job_analytics"("organisation_id", "department");
71
+ CREATE INDEX "interviewer_job_analytics_organisation_id_location_idx"
72
+ ON "analytics"."interviewer_job_analytics"("organisation_id", "location");
73
+ CREATE INDEX "interviewer_job_analytics_organisation_id_user_id_idx"
74
+ ON "analytics"."interviewer_job_analytics"("organisation_id", "user_id");
75
+
76
+ CREATE INDEX IF NOT EXISTS "job_round_analytics_organisation_id_idx"
77
+ ON "analytics"."job_round_analytics"("organisation_id");
78
+ CREATE INDEX IF NOT EXISTS "job_round_analytics_organisation_id_hiring_manager_id_idx"
79
+ ON "analytics"."job_round_analytics"("organisation_id", "hiring_manager_id");
80
+ CREATE INDEX IF NOT EXISTS "job_round_analytics_job_description_id_idx"
81
+ ON "analytics"."job_round_analytics"("job_description_id");
82
+
83
+ CREATE INDEX IF NOT EXISTS "pipeline_distribution_analytics_job_description_id_idx"
84
+ ON "analytics"."pipeline_distribution_analytics"("job_description_id");
85
+
86
+ CREATE INDEX IF NOT EXISTS "open_job_analytics_job_description_id_idx"
87
+ ON "analytics"."open_job_analytics"("job_description_id");
@@ -0,0 +1,38 @@
1
+ -- CreateEnum
2
+ CREATE TYPE "public"."SourceCategory" AS ENUM ('JOB_BOARD', 'REFERRAL', 'AGENCY', 'SOCIAL_MEDIA', 'CAREERS_PAGE', 'EVENT', 'OTHER');
3
+
4
+ -- CreateTable
5
+ CREATE TABLE "public"."Source" (
6
+ "id" TEXT NOT NULL,
7
+ "organisation_id" TEXT NOT NULL,
8
+ "name" TEXT NOT NULL,
9
+ "category" "public"."SourceCategory",
10
+ "parent_source_id" TEXT,
11
+ "colour" TEXT,
12
+ "description" TEXT,
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
+
17
+ CONSTRAINT "Source_pkey" PRIMARY KEY ("id")
18
+ );
19
+
20
+ -- CreateIndex
21
+ CREATE UNIQUE INDEX "Source_organisation_id_name_key" ON "public"."Source"("organisation_id", "name");
22
+ CREATE INDEX "Source_organisation_id_idx" ON "public"."Source"("organisation_id");
23
+ CREATE INDEX "Source_organisation_id_category_idx" ON "public"."Source"("organisation_id", "category");
24
+ CREATE INDEX "Source_organisation_id_is_active_idx" ON "public"."Source"("organisation_id", "is_active");
25
+ CREATE INDEX "Source_parent_source_id_idx" ON "public"."Source"("parent_source_id");
26
+
27
+ -- AddForeignKey
28
+ ALTER TABLE "public"."Source" ADD CONSTRAINT "Source_organisation_id_fkey" FOREIGN KEY ("organisation_id") REFERENCES "public"."Organisation"("id") ON DELETE CASCADE ON UPDATE CASCADE;
29
+ ALTER TABLE "public"."Source" ADD CONSTRAINT "Source_parent_source_id_fkey" FOREIGN KEY ("parent_source_id") REFERENCES "public"."Source"("id") ON DELETE SET NULL ON UPDATE CASCADE;
30
+
31
+ -- AlterTable
32
+ ALTER TABLE "public"."Application" ADD COLUMN "source_id" TEXT;
33
+
34
+ -- CreateIndex
35
+ CREATE INDEX "Application_source_id_idx" ON "public"."Application"("source_id");
36
+
37
+ -- AddForeignKey
38
+ ALTER TABLE "public"."Application" ADD CONSTRAINT "Application_source_id_fkey" FOREIGN KEY ("source_id") REFERENCES "public"."Source"("id") ON DELETE SET NULL ON UPDATE CASCADE;
@@ -0,0 +1,40 @@
1
+ CREATE TABLE "analytics"."source_effectiveness_analytics" (
2
+ "id" TEXT NOT NULL,
3
+ "organisation_id" TEXT NOT NULL,
4
+ "job_description_id" TEXT NOT NULL,
5
+ "source_id" TEXT NOT NULL,
6
+ "source_name" TEXT NOT NULL,
7
+ "source_category" "public"."SourceCategory",
8
+ "source_colour" TEXT,
9
+ "job_code" TEXT,
10
+ "job_number" INTEGER,
11
+ "role_title" TEXT,
12
+ "hiring_manager_id" TEXT,
13
+ "applications_count" INTEGER NOT NULL DEFAULT 0,
14
+ "screened_count" INTEGER NOT NULL DEFAULT 0,
15
+ "evaluated_count" INTEGER NOT NULL DEFAULT 0,
16
+ "rejected_count" INTEGER NOT NULL DEFAULT 0,
17
+ "shortlisted_count" INTEGER NOT NULL DEFAULT 0,
18
+ "offered_count" INTEGER NOT NULL DEFAULT 0,
19
+ "offer_accepted_count" INTEGER NOT NULL DEFAULT 0,
20
+ "offer_declined_count" INTEGER NOT NULL DEFAULT 0,
21
+ "withdrawn_count" INTEGER NOT NULL DEFAULT 0,
22
+ "hired_count" INTEGER NOT NULL DEFAULT 0,
23
+ "total_fit_score" DOUBLE PRECISION NOT NULL DEFAULT 0,
24
+ "fit_score_sample_count" INTEGER NOT NULL DEFAULT 0,
25
+ "average_fit_score" DOUBLE PRECISION,
26
+ "updated_at" TIMESTAMP(3) NOT NULL,
27
+
28
+ CONSTRAINT "source_effectiveness_analytics_pkey" PRIMARY KEY ("id")
29
+ );
30
+
31
+ CREATE UNIQUE INDEX "source_effectiveness_analytics_organisation_id_job_descripti_key"
32
+ ON "analytics"."source_effectiveness_analytics"("organisation_id", "job_description_id", "source_id");
33
+ CREATE INDEX "source_effectiveness_analytics_organisation_id_idx"
34
+ ON "analytics"."source_effectiveness_analytics"("organisation_id");
35
+ CREATE INDEX "source_effectiveness_analytics_organisation_id_source_id_idx"
36
+ ON "analytics"."source_effectiveness_analytics"("organisation_id", "source_id");
37
+ CREATE INDEX "source_effectiveness_analytics_organisation_id_hiring_manag_idx"
38
+ ON "analytics"."source_effectiveness_analytics"("organisation_id", "hiring_manager_id");
39
+ CREATE INDEX "source_effectiveness_analytics_job_description_id_idx"
40
+ ON "analytics"."source_effectiveness_analytics"("job_description_id");