@adaptware/eagles-db 0.5.49 → 0.5.51

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 (60) hide show
  1. package/client/edge.js +67 -26
  2. package/client/index-browser.js +60 -20
  3. package/client/index.d.ts +4472 -2581
  4. package/client/index.js +67 -26
  5. package/client/package.json +1 -1
  6. package/client/schema.prisma +156 -78
  7. package/client/wasm.js +67 -26
  8. package/package.json +1 -1
  9. package/prisma/schema/interview.prisma +11 -6
  10. package/prisma/schema/migrations/20260522120000_ongoing_evaluation_record_kind/migration.sql +25 -0
  11. package/prisma/schema/migrations/20260523120000_replace_record_kind_with_is_committed/migration.sql +24 -0
  12. package/prisma/schema/migrations/20260528120000_drop_job_description_recommendation_config/migration.sql +2 -0
  13. package/prisma/schema/migrations/20260710120000_add_resume_rendered_export_fields/migration.sql +9 -0
  14. package/prisma/schema/migrations/20260714120000_add_job_description_display_html_document/migration.sql +8 -0
  15. package/prisma/schema/migrations/20260716120000_add_offer_letters/migration.sql +183 -0
  16. package/prisma/schema/migrations/20260716140000_offer_schema_refinements/migration.sql +13 -0
  17. package/prisma/schema/migrations/20260716160000_offer_schema_hardening/migration.sql +95 -0
  18. package/prisma/schema/migrations/20260716180000_offer_letter_template_config/migration.sql +2 -0
  19. package/prisma/schema/migrations/20260716190000_add_evaluation_focus_areas/migration.sql +6 -0
  20. package/prisma/schema/migrations/20260717120000_offer_workflow_approval/migration.sql +30 -0
  21. package/prisma/schema/migrations/20260720120000_offer_letter_template_is_draft/migration.sql +5 -0
  22. package/prisma/schema/migrations/20260720140000_offer_status_split/migration.sql +51 -0
  23. package/prisma/schema/migrations/20260720140001_offer_status_split_backfill/migration.sql +37 -0
  24. package/prisma/schema/migrations/20260722120000_offer_draft_edited_html/migration.sql +13 -0
  25. package/prisma/schema/migrations/20260723150000_offer_withdraw_actor_no_show_reason/migration.sql +10 -0
  26. package/prisma/schema/migrations/20260724120000_open_job_offer_accepted_declined_counts/migration.sql +7 -0
  27. package/prisma/schema/migrations/20260811120000_add_integration_provider_razorpay/migration.sql +6 -0
  28. package/prisma/schema/migrations/20260812120000_add_billing_transactions/migration.sql +49 -0
  29. package/prisma/schema/migrations/20260812130000_drop_billing_transaction_gst_snapshots/migration.sql +3 -0
  30. package/prisma/schema/migrations/20260812180000_billing_transaction_invoice_number/migration.sql +5 -0
  31. package/prisma/schema/migrations/20260813120000_payment_webhooks_gst_refunds/migration.sql +79 -0
  32. package/prisma/schema/migrations/20260813140000_platform_gst_profiles/migration.sql +49 -0
  33. package/prisma/schema/migrations/20260813150000_rename_gst_profiles/migration.sql +53 -0
  34. package/prisma/schema/migrations/20260813160000_remove_gst_billing/migration.sql +16 -0
  35. package/prisma/schema/migrations/20260813170000_billing_licensing_unrecoverable/migration.sql +2 -0
  36. package/prisma/schema/migrations/20260813180000_billing_transaction_payment_method/migration.sql +2 -0
  37. package/prisma/schema/migrations/20260814090000_billing_transaction_purchaser_email/migration.sql +2 -0
  38. package/prisma/schema/migrations/20260816100000_billing_product_organisations/migration.sql +35 -0
  39. package/prisma/schema/migrations/20260816120000_merge_billing_product_organisations/migration.sql +25 -0
  40. package/prisma/schema/migrations/20260817120000_billing_payment_mismatch/migration.sql +7 -0
  41. package/prisma/schema/migrations/20260819120000_billing_product_prices/migration.sql +62 -0
  42. package/prisma/schema/migrations/20260819140000_billing_exchange_rates/migration.sql +25 -0
  43. package/prisma/schema/migrations/20260820120000_billing_transaction_failure_category/migration.sql +31 -0
  44. package/prisma/schema/migrations/20260820130000_backfill_billing_transaction_failure_details/migration.sql +23 -0
  45. package/prisma/schema/migrations/20260820140000_drop_billing_product_price_overrides/migration.sql +2 -0
  46. package/prisma/schema/migrations/20260821120000_drop_billing_product_and_mock_licensing/migration.sql +38 -0
  47. package/prisma/schema/migrations/20260824120000_billing_transaction_purchase_display_name/migration.sql +2 -0
  48. package/prisma/schema/migrations/20260831120000_user_communication_email/migration.sql +6 -0
  49. package/prisma/schema/migrations/20260901143000_assessment_question_bank_state/migration.sql +15 -0
  50. package/prisma/schema/migrations/20260902120000_question_category_two_values/migration.sql +16 -0
  51. package/prisma/schema/migrations/20260902143000_question_bank_item_key/migration.sql +17 -0
  52. package/prisma/schema/migrations/20260903120000_split_round_type_assessment/migration.sql +9 -0
  53. package/prisma/schema/migrations/20260904110000_restore_round_type_assessment_enum/migration.sql +5 -0
  54. package/prisma/schema/migrations/20260904120000_revert_wrong_split_assessment_round_types/migration.sql +42 -0
  55. package/prisma/schema/migrations/20260909140000_profile_interview_session/migration.sql +99 -0
  56. package/prisma/schema/migrations/20260911120000_unify_profile_interview_into_interview/migration.sql +139 -0
  57. package/client/libquery_engine-darwin.dylib.node +0 -0
  58. package/prisma/.DS_Store +0 -0
  59. package/prisma/migrations/20260519120000_migrate_shortlisted_to_selected/migration.sql +0 -2
  60. package/prisma/schema/.DS_Store +0 -0
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "prisma-client-0fae5beb1aff3688f99d1ad980cc6f865eb79b0a0597d272d2787f77760a1ad8",
2
+ "name": "prisma-client-4e6f805656df4c59e0046fea246403b8423d087978def9271e6a24a95c6ec7d3",
3
3
  "main": "index.js",
4
4
  "types": "index.d.ts",
5
5
  "browser": "default.js",
@@ -414,58 +414,62 @@ enum ApplicationOfferSubstatus {
414
414
 
415
415
  model Application {
416
416
  /// Primary key
417
- id String @id @default(uuid())
417
+ id String @id @default(uuid())
418
418
  /// Foreign keys
419
- organisation_id String
420
- candidate_id String
421
- resume_id String
422
- job_description_id String
423
- evaluation_plan_id String?
424
- recruiter_id String?
425
- source_id String?
419
+ organisation_id String
420
+ candidate_id String
421
+ resume_id String
422
+ job_description_id String
423
+ evaluation_plan_id String?
424
+ recruiter_id String?
425
+ source_id String?
426
426
  /// Data fields
427
- fit_check_score Float?
428
- applied_at DateTime @default(now())
429
- round_no Int @default(0)
430
- is_jaf_completed Boolean @default(false)
431
- proceed_to_next_round Boolean? @default(false)
432
- evaluationComment String?
427
+ fit_check_score Float?
428
+ applied_at DateTime @default(now())
429
+ round_no Int @default(0)
430
+ is_jaf_completed Boolean @default(false)
431
+ proceed_to_next_round Boolean? @default(false)
432
+ evaluationComment String?
433
433
  /// Candidate flag (orthogonal to ApplicationStatus). Latest actor/comment only.
434
- is_flagged Boolean @default(false)
435
- flag_comment String?
436
- flagged_at DateTime?
437
- flagged_by String?
438
- unflag_comment String?
439
- unflagged_at DateTime?
440
- unflagged_by String?
441
- fit_check_status FitCheckStatus?
442
- status ApplicationStatus @default(PENDING)
434
+ is_flagged Boolean @default(false)
435
+ flag_comment String?
436
+ flagged_at DateTime?
437
+ flagged_by String?
438
+ unflag_comment String?
439
+ unflagged_at DateTime?
440
+ unflagged_by String?
441
+ fit_check_status FitCheckStatus?
442
+ status ApplicationStatus @default(PENDING)
443
443
  /// Fine-grained offer-stage state. Meaningful only when status = OFFER (or was OFFER for a terminal-substatus that flipped to REJECTED / JOINED).
444
- offer_substatus ApplicationOfferSubstatus?
444
+ offer_substatus ApplicationOfferSubstatus?
445
445
  /// Audit fields
446
- created_at DateTime @default(now())
447
- updated_at DateTime @updatedAt
448
- created_by String
449
- updated_by String
450
- is_active Boolean @default(true)
446
+ created_at DateTime @default(now())
447
+ updated_at DateTime @updatedAt
448
+ created_by String
449
+ updated_by String
450
+ is_active Boolean @default(true)
451
+ fit_check_report_document_id String? @unique
452
+ fit_check_report_updated_flag Boolean @default(false)
453
+ fit_check_report_data Json? @default("{}")
451
454
  /// Relations
452
- evaluation_plan EvaluationPlan? @relation(fields: [evaluation_plan_id], references: [id])
453
- candidate User @relation(fields: [candidate_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
454
- organisation Organisation @relation(fields: [organisation_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
455
- resume Resume @relation(fields: [resume_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
456
- job_description JobDescription @relation(fields: [job_description_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
457
- fit_check FitCheck?
458
- recruiter User? @relation("ApplicationRecruiter", fields: [recruiter_id], references: [id])
459
- source Source? @relation(fields: [source_id], references: [id], onDelete: SetNull)
460
- interviews Interview[]
461
- assignments Assignment[]
462
- ongoing_evaluations OngoingEvaluation[]
463
- activity_logs ActivityLog[]
464
- notes Notes[]
465
- conversations Conversation[]
466
- communication_messages CommunicationMessage[]
467
- job_application_responses JobApplicationResponse[]
468
- offer Offer?
455
+ evaluation_plan EvaluationPlan? @relation(fields: [evaluation_plan_id], references: [id])
456
+ candidate User @relation(fields: [candidate_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
457
+ organisation Organisation @relation(fields: [organisation_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
458
+ resume Resume @relation(fields: [resume_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
459
+ job_description JobDescription @relation(fields: [job_description_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
460
+ fit_check FitCheck?
461
+ recruiter User? @relation("ApplicationRecruiter", fields: [recruiter_id], references: [id])
462
+ source Source? @relation(fields: [source_id], references: [id], onDelete: SetNull)
463
+ interviews Interview[]
464
+ assignments Assignment[]
465
+ ongoing_evaluations OngoingEvaluation[]
466
+ activity_logs ActivityLog[]
467
+ notes Notes[]
468
+ conversations Conversation[]
469
+ communication_messages CommunicationMessage[]
470
+ job_application_responses JobApplicationResponse[]
471
+ offer Offer?
472
+ fit_check_report_document Document? @relation("ApplicationFitCheckReportDocument", fields: [fit_check_report_document_id], references: [id], onDelete: SetNull)
469
473
 
470
474
  @@unique([candidate_id, job_description_id]) // Ensures candidate applies only once per job
471
475
  @@index([candidate_id])
@@ -552,6 +556,8 @@ model AssessmentLibrary {
552
556
  created_by String
553
557
  updated_by String
554
558
  is_active Boolean @default(true)
559
+ /// Frozen question plan, batch cursor, and bank-generation status (JSON).
560
+ generation_state Json?
555
561
  organisation Organisation @relation(fields: [organisation_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
556
562
  questions Question[] // One assessment → many questions
557
563
  assessments Assessment[]
@@ -1401,6 +1407,7 @@ model Document {
1401
1407
  offer_letters OfferLetter[] @relation("OfferLetterPdf")
1402
1408
  offer_letter_template_snapshots OfferLetter[] @relation("OfferLetterTemplateSnapshot")
1403
1409
  offer_draft_edited_html Offer[] @relation("OfferDraftEditedHtml")
1410
+ application_fit_check_report Application? @relation("ApplicationFitCheckReportDocument")
1404
1411
 
1405
1412
  // Indexes
1406
1413
  @@index([candidate_id])
@@ -1445,6 +1452,8 @@ model EvaluationCriteria {
1445
1452
 
1446
1453
  enum RoundType {
1447
1454
  ASSESSMENT
1455
+ GENERAL_APTITUDE_ASSESSMENT
1456
+ DOMAIN_KNOWLEDGE_ASSESSMENT
1448
1457
  INTERVIEW
1449
1458
  ASSIGNMENT
1450
1459
  SCREENING
@@ -1539,26 +1548,6 @@ model EvaluationPlan {
1539
1548
  @@schema("public")
1540
1549
  }
1541
1550
 
1542
- model Feedback {
1543
- id String @id @default(uuid())
1544
- interview_id String
1545
- order_no Int
1546
-
1547
- ai_feedback Json?
1548
- human_feedback Json?
1549
-
1550
- created_at DateTime @default(now())
1551
- updated_at DateTime @updatedAt
1552
- created_by String
1553
- updated_by String
1554
- is_active Boolean @default(true)
1555
- interview Interview @relation(fields: [interview_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
1556
-
1557
- @@unique([interview_id, order_no])
1558
- @@index([interview_id])
1559
- @@schema("public")
1560
- }
1561
-
1562
1551
  enum FitCheckStatus {
1563
1552
  RECOMMENDED
1564
1553
  TO_REVIEW
@@ -1970,14 +1959,19 @@ enum AiAssistanceMode {
1970
1959
  model Interview {
1971
1960
  id String @id @default(uuid())
1972
1961
  /// Foreign keys
1973
- organisation_id String
1962
+ organisation_id String?
1974
1963
  candidate_id String
1975
1964
  interviewer_id String?
1976
- evaluation_plan_id String
1965
+ evaluation_plan_id String?
1977
1966
  application_id String?
1978
1967
  resume_id String
1979
- job_description_id String
1968
+ job_description_id String?
1980
1969
  calendar_event_id String?
1970
+ calendar_events Json?
1971
+ /// True for candidate-initiated profile enrichment voice sessions (not hiring).
1972
+ candidate_initiated Boolean @default(false)
1973
+ /// Profile AI: purpose, focusAreas, focusAreaCoverage, etc.
1974
+ candidate_interview_metadata Json?
1981
1975
  /// Data
1982
1976
  room_name String?
1983
1977
  /// @deprecated Prefer `ai_feedback.feedback` (narrative string on AI feedback JSON).
@@ -2038,27 +2032,27 @@ model Interview {
2038
2032
  // Relations
2039
2033
  candidate User? @relation("CandidateInterviews", fields: [candidate_id], references: [id], onDelete: SetNull)
2040
2034
  interviewer User? @relation("InterviewerInterviews", fields: [interviewer_id], references: [id], onDelete: SetNull)
2041
- organisation Organisation @relation(fields: [organisation_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
2035
+ organisation Organisation? @relation(fields: [organisation_id], references: [id], onDelete: SetNull, onUpdate: Cascade)
2042
2036
  recording_document Document? @relation(fields: [recording_document_id], references: [id], onDelete: SetNull, onUpdate: Cascade)
2043
- job_description JobDescription @relation(fields: [job_description_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
2037
+ job_description JobDescription? @relation(fields: [job_description_id], references: [id], onDelete: SetNull, onUpdate: Cascade)
2044
2038
  resume Resume @relation(fields: [resume_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
2045
2039
  evaluation_plan EvaluationPlan? @relation(fields: [evaluation_plan_id], references: [id], onDelete: SetNull, onUpdate: Cascade)
2046
2040
  application Application? @relation(fields: [application_id], references: [id], onDelete: SetNull, onUpdate: Cascade)
2047
2041
  ongoing_evaluation OngoingEvaluation?
2048
2042
  transcripts Transcript[]
2049
2043
  suggestions Suggestion[]
2050
- feedback Feedback[]
2051
2044
  interviewNotes InterviewNotes[]
2052
2045
  liveAnalysis LiveAnalysis[]
2053
2046
  zoom_meeting ZoomMeeting?
2054
2047
 
2055
2048
  // Indexes
2056
- @@unique([interviewer_id, candidate_id, evaluation_plan_id])
2057
2049
  @@index([candidate_id])
2050
+ @@index([candidate_id, candidate_initiated, created_at])
2058
2051
  @@index([interviewer_id])
2059
2052
  @@index([job_description_id])
2060
2053
  @@index([organisation_id, interview_status])
2061
2054
  @@index([interview_status, scheduled_start_time])
2055
+ @@index([candidate_initiated, interview_status])
2062
2056
  @@schema("public")
2063
2057
  }
2064
2058
 
@@ -2381,13 +2375,15 @@ model JobApplicationField {
2381
2375
  updated_by String
2382
2376
  created_at DateTime @default(now())
2383
2377
  updated_at DateTime @updatedAt
2378
+ /// order of question
2379
+ order_no Int? //nullable for now to allow migration
2384
2380
  /// Relations
2385
2381
  organisation Organisation @relation(fields: [organisation_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
2386
2382
  job_application_template JobApplicationTemplate @relation(fields: [template_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
2387
2383
  job_application_responses JobApplicationResponse[]
2388
2384
 
2389
2385
  /// Indexes
2390
- @@index([organisation_id, template_id])
2386
+ @@index([organisation_id, template_id, order_no])
2391
2387
  @@schema("public")
2392
2388
  }
2393
2389
 
@@ -2415,13 +2411,14 @@ model JobApplicationResponse {
2415
2411
  created_by String
2416
2412
  updated_by String
2417
2413
  is_active Boolean @default(true)
2414
+ order_no Int? //nullable for now to allow migration
2418
2415
  /// Relations
2419
2416
  application Application @relation(fields: [application_id], references: [id], onDelete: Cascade, onUpdate: Cascade)
2420
2417
  field JobApplicationField? @relation(fields: [job_application_field_id], references: [id], onDelete: Restrict, onUpdate: Cascade)
2421
2418
  document Document? @relation(fields: [document_id], references: [id], onDelete: SetNull, onUpdate: Cascade)
2422
2419
 
2423
- /// Partial unique on (application_id, job_application_field_id) WHERE job_application_field_id IS NOT NULL — see migration SQL
2424
- @@index([application_id])
2420
+ // / Partial unique on (application_id, job_application_field_id) WHERE job_application_field_id IS NOT NULL — see migration SQL
2421
+ @@index([application_id, is_active, order_no])
2425
2422
  @@index([job_application_field_id])
2426
2423
  @@schema("public")
2427
2424
  }
@@ -2761,13 +2758,15 @@ model AiCostLedgerEntry {
2761
2758
  @@schema("licensing")
2762
2759
  }
2763
2760
 
2764
- /// Immutable assignment history for Hiring Unit department/job changes.
2761
+ /// Immutable assignment history for Hiring Unit department/user/job changes.
2765
2762
  model PurchasedHiringUnitAssignmentEvent {
2766
2763
  id String @id @default(uuid())
2767
2764
  purchased_hiring_unit_id String
2768
2765
  event_kind PurchasedHiringUnitAssignmentEventKind
2769
2766
  previous_department_id String?
2770
2767
  new_department_id String?
2768
+ previous_assigned_user_id String?
2769
+ new_assigned_user_id String?
2771
2770
  previous_job_description_id String?
2772
2771
  new_job_description_id String?
2773
2772
  effective_at DateTime @default(now())
@@ -2880,6 +2879,8 @@ enum PurchasedTopUpStatus {
2880
2879
  enum PurchasedHiringUnitAssignmentEventKind {
2881
2880
  DEPARTMENT_ASSIGNED
2882
2881
  DEPARTMENT_UNASSIGNED
2882
+ USER_ASSIGNED
2883
+ USER_UNASSIGNED
2883
2884
  JOB_LINKED
2884
2885
  JOB_UNLINKED
2885
2886
 
@@ -3001,6 +3002,8 @@ model PurchasedHiringUnit {
3001
3002
  status PurchasedHiringUnitStatus @default(AVAILABLE)
3002
3003
  /// Current department allocation (licensing allocation, not hiring manager).
3003
3004
  department_id String?
3005
+ /// Optional person reservation. Units with this set are consumed before dept/org pools.
3006
+ assigned_user_id String?
3004
3007
  /// Set once when department_id is first assigned; not cleared on reassignment.
3005
3008
  first_assigned_at DateTime?
3006
3009
  /// Optional unit expiry.
@@ -3017,6 +3020,7 @@ model PurchasedHiringUnit {
3017
3020
  organisation Organisation @relation(fields: [organisation_id], references: [id], onDelete: Restrict, onUpdate: Cascade)
3018
3021
  purchased_license_package PurchasedLicensePackage @relation(fields: [purchased_license_package_id], references: [id], onDelete: Restrict, onUpdate: Cascade)
3019
3022
  department Department? @relation(fields: [department_id], references: [id], onDelete: SetNull, onUpdate: Cascade)
3023
+ assigned_user User? @relation("AssignedHiringUnits", fields: [assigned_user_id], references: [id], onDelete: SetNull, onUpdate: Cascade)
3020
3024
  job_description JobDescription? @relation(fields: [job_description_id], references: [id], onDelete: SetNull, onUpdate: Cascade)
3021
3025
  assignment_events PurchasedHiringUnitAssignmentEvent[]
3022
3026
  ledger_entries LicensingLedgerEntry[]
@@ -3025,9 +3029,11 @@ model PurchasedHiringUnit {
3025
3029
  @@index([organisation_id])
3026
3030
  @@index([purchased_license_package_id])
3027
3031
  @@index([department_id])
3032
+ @@index([assigned_user_id])
3028
3033
  @@index([job_description_id])
3029
3034
  @@index([organisation_id, status])
3030
3035
  @@index([organisation_id, department_id])
3036
+ @@index([organisation_id, assigned_user_id])
3031
3037
  @@index([organisation_id, job_description_id])
3032
3038
  @@map("purchased_hiring_units")
3033
3039
  @@schema("licensing")
@@ -3494,6 +3500,15 @@ enum OrganisationSize {
3494
3500
  @@schema("public")
3495
3501
  }
3496
3502
 
3503
+ /// Who may consume unused hiring units. Changing this does not rewrite unit rows.
3504
+ enum HiringUnitAssignmentScope {
3505
+ USER
3506
+ DEPARTMENT
3507
+ ORGANISATION
3508
+
3509
+ @@schema("public")
3510
+ }
3511
+
3497
3512
  model Organisation {
3498
3513
  id String @id @default(uuid())
3499
3514
  name String @unique
@@ -3536,6 +3551,8 @@ model Organisation {
3536
3551
  timezone String @default("Asia/Kolkata")
3537
3552
  /// ISO 3166-1 alpha-2 (e.g. IN).
3538
3553
  country_code String @default("IN")
3554
+ /// Who may consume unused hiring units. Does not rewrite unit rows when changed.
3555
+ hiring_unit_assignment_scope HiringUnitAssignmentScope @default(DEPARTMENT)
3539
3556
  organisation_configs OrganisationConfig[]
3540
3557
  activity_events ActivityEvent[]
3541
3558
  usage_ledger_entries UsageLedgerEntry[]
@@ -3716,12 +3733,24 @@ enum Difficulty {
3716
3733
  @@schema("public")
3717
3734
  }
3718
3735
 
3736
+ enum QuestionCategory {
3737
+ /// Aptitude, logical reasoning, numerical, verbal — non-domain general tests.
3738
+ GENERAL_APTITUDE
3739
+ /// Role/domain/technical knowledge (skills from JD and competencies).
3740
+ DOMAIN_KNOWLEDGE
3741
+
3742
+ @@schema("public")
3743
+ }
3744
+
3719
3745
  model Question {
3720
3746
  id String @id @default(uuid())
3721
3747
  assessment_library_id String?
3722
3748
  evaluation_plan_id String?
3723
3749
  candidate_id String?
3724
3750
  skill String?
3751
+ category QuestionCategory?
3752
+ /// Stable idempotency key for reusable bank rows: `{generationSeed}:{planSlot}`.
3753
+ bank_item_key String?
3725
3754
  question String
3726
3755
  answer String
3727
3756
  options String[] // For MCQ's
@@ -3738,6 +3767,7 @@ model Question {
3738
3767
  evaluationPlan EvaluationPlan? @relation(fields: [evaluation_plan_id], references: [id], onDelete: SetNull)
3739
3768
  candidateResponse CandidateQuestionResponse[]
3740
3769
 
3770
+ @@unique([assessment_library_id, bank_item_key])
3741
3771
  @@schema("public")
3742
3772
  }
3743
3773
 
@@ -3804,6 +3834,25 @@ model ReportingOverviewJobRecruiter {
3804
3834
  @@schema("analytics")
3805
3835
  }
3806
3836
 
3837
+ /// Lifecycle of an AI-authored resume. Legacy/uploaded rows leave this null.
3838
+ enum ResumeStatus {
3839
+ DRAFT
3840
+ GENERATING
3841
+ COMPLETED
3842
+
3843
+ @@schema("public")
3844
+ }
3845
+
3846
+ /// How a resume came to exist. Legacy rows leave this null (read as UPLOADED).
3847
+ enum ResumeOrigin {
3848
+ UPLOADED
3849
+ PARSED
3850
+ AI_GENERATED
3851
+ TAILORED
3852
+
3853
+ @@schema("public")
3854
+ }
3855
+
3807
3856
  model Resume {
3808
3857
  id String @id @default(uuid())
3809
3858
  user_id String?
@@ -3840,8 +3889,34 @@ model Resume {
3840
3889
  candidate_profile CandidateProfile? // one-to-one link
3841
3890
  yearsOfExperience Int?
3842
3891
 
3892
+ /// Lifecycle for AI-authored resumes. Null for legacy/uploaded rows (treated as COMPLETED).
3893
+ status ResumeStatus?
3894
+ /// How this resume came to exist. Null for legacy rows (treated as UPLOADED).
3895
+ origin ResumeOrigin?
3896
+ /// Intake session id echoed to the client so a refresh can resume the conversation.
3897
+ intake_session_id String?
3898
+ /// Durable copy of the chat transcript for the AI intake; Redis is the hot path.
3899
+ conversation_history Json?
3900
+ /// Progress 0-100 reported by the ResumeIntake workflow.
3901
+ intake_progress Int?
3902
+ /// Last Orion execution id for the intake/generate workflow, for tracing.
3903
+ orion_execution_id String?
3904
+
3905
+ /// Raw job description text the candidate pasted to start a tailoring session.
3906
+ tailoring_jd_text String?
3907
+ /// Cached JobDescriptionParser output; computed once per tailoring session.
3908
+ tailoring_jd_parsed Json?
3909
+ /// Cached ResumeGapAnalysis output; computed once per tailoring session.
3910
+ tailoring_gap_analysis Json?
3911
+ /// Working tailoring state: the draft ResumeFormData, tailoring notes, the
3912
+ /// pending contradiction awaiting resolution, and the question counter.
3913
+ /// Scratch space only — the draft is materialised into `resume_data` when the
3914
+ /// candidate saves it.
3915
+ tailoring_draft Json?
3916
+
3843
3917
  @@index([user_id])
3844
3918
  @@index([file_hash])
3919
+ @@index([user_id, status])
3845
3920
  @@schema("public")
3846
3921
  }
3847
3922
 
@@ -4336,6 +4411,8 @@ model User {
4336
4411
  created_by String
4337
4412
  updated_by String
4338
4413
  is_active Boolean @default(true)
4414
+ /// Set when removed from team (Delete); null for active/inactive-only users.
4415
+ deleted_at DateTime?
4339
4416
  is_self_registered Boolean @default(true)
4340
4417
  permission_id String? @unique
4341
4418
  preferences Json? @default("{}")
@@ -4406,7 +4483,8 @@ model User {
4406
4483
  employee_number Int?
4407
4484
  employee_code String? @unique
4408
4485
 
4409
- department_members DepartmentMember[] @relation("DepartmentMemberships")
4486
+ department_members DepartmentMember[] @relation("DepartmentMemberships")
4487
+ assigned_hiring_units PurchasedHiringUnit[] @relation("AssignedHiringUnits")
4410
4488
 
4411
4489
  @@index([role_id])
4412
4490
  @@index([permission_id])