Skip to main content

Entity Relationships

Visual entity-relationship diagrams for the AIQLick database schema. These diagrams are generated from the Prisma schema (aiqlick-backend/prisma/schema.prisma) and show how models relate across the platform.

Related Pages
  • Domain Model — Conceptual overview of core entities and business rules
  • Database Schema — Detailed schema reference with field types, constraints, and enums

How to Read These Diagrams

SymbolMeaning
||--||One-to-one (exactly one on each side)
||--o|One-to-one (optional on right side)
||--o{One-to-many (optional on many side)
||--|{One-to-many (required on many side)
}o--o{Many-to-many
PKPrimary key
FKForeign key
UKUnique constraint

Platform-Wide Domain Map

How the 15 domains connect at a high level:


Identity & Access

Core authentication, authorization, and multi-tenancy models.


Recruitment Core

Job postings, candidates, pipelines, and matching.

Unique constraints: @@unique([pipelineId, jobId]) on PipelineItem, @@unique([jobId, skillId]) on JobSkillRequirement, @@unique([jobId, cvId]) on MatchScore, @@unique([userId, jobId]) on UserJobMatchScore.


Talent Management

Talent profiles, pools, skills, and activity tracking.

Unique constraints: @@unique([userId, talentPoolId]) on Talent, @@unique([talentPoolId, skillId]) on TalentPoolSkill.


CV System

CV documents, extracted skills, and the 11 structured extraction tables.

Structured CV Tables

The 11 structured tables are the sole source of truth for CV data. All reads and writes go through these tables directly. There is no legacy fallback.

CV Collections


Interview Scheduling

Interview lifecycle, calendar bookings, and self-scheduling slot offers.

Unique constraints: @@unique([bookingId, email]) on InterviewBookingAttendee, @@unique([offerId, email]) on InterviewSlotOfferAttendee.


Meetings & Transcription

Video conferencing, real-time transcription, and AI-generated insights.

Unique constraints: @@unique([meetingId, email]) on MeetingAttendee. Transcription uses @@map("transcriptions") for table name compatibility with background-tasks.


Billing & Credits

Subscription plans, Stripe integration, credit system, and AI operation tracking.

XOR constraint: CreditBalance must have exactly one of companyId (employer) or userId (job seeker) — enforced at the database level.

Promo Codes

Unique constraints: @@unique([promoCodeId, userId, subscriptionId]) on PromoCodeRedemption.


Notification System

Multi-channel notification delivery with per-user and per-company preferences.

Unique constraints: @@unique([userId, companyId]) on CompanySpecificNotificationPreference.


Messaging

Direct and group conversations between users.

Unique constraints: @@unique([conversationId, userId]) on ConversationParticipant.


AI Agent System

Company-scoped AI assistants with RAG, tool execution, and document management.

Unique constraints: @@unique([companyId, name]) on Agent, @@unique([agentId, taskCode]) on AgentTaskConfig, @@unique([companyId, agentId, periodStart, periodEnd]) on AgentTokenUsage.


Sharing & Collaboration

External sharing follows a consistent three-table pattern. Collaboration adds cross-company resource sharing.

Three-Table Sharing Pattern

Every shareable entity uses this pattern:

Share TypeTable PatternKey Fields
User Share{Entity}UserShareuserId, permissionLevel
Company Share{Entity}CompanySharecompanyId, sharedById, permissionLevel
External Share{Entity}ExternalSharetoken (UK), expiresAt, accessCount, isActive

Entities with sharing: TalentPool, Pipeline, CvCollection, Talent, SharedTalentList, UserProfile.

Talent Sharing

Collaboration System

User Profile & Job Seeker Sharing


Contacts

Company-scoped contact management with types and notes.


Inbound Email

IMAP-based email ingestion for automated job and CV creation.

Unique constraints: @@unique([address, imapHost, imapPort, imapFolder]) on InboundMailbox, @@unique([mailboxAddress, imapFolder, imapUid]) on InboundEmail, @@unique([inboundEmailId, attemptNumber]) on InboundEmailParseAttempt.


Other Models

System-wide utility models that don't belong to a specific domain.


Complete Model Index

All models organized alphabetically within their domain.

#ModelDomainPrimary RelationsKey Constraints
1AdminAuditLogSystemUser, Company
2AgentAI AgentCompany, User@@unique([companyId, name])
3AgentActivityAI AgentAgent
4AgentBackgroundTaskAI AgentCompany, AgentDocument
5AgentConversationAI AgentAgent, User, Company
6AgentDatabaseConfigAI AgentAgent (1:1)agentId UK
7AgentDocumentAI AgentAgent, Company, User
8AgentDocumentChunkAI AgentAgentDocumentpgvector 1024d
9AgentMessageAI AgentAgentConversation, self-ref
10AgentTaskConfigAI AgentAgent@@unique([agentId, taskCode])
11AgentTokenUsageAI AgentCompany, Agent@@unique([companyId, agentId, periodStart, periodEnd])
12AgentToolExecutionAI AgentAgentConversation, AgentMessage
13AIOperationLogBillingCompany, User, CreditTransaction (1:1)creditTransactionId UK
14ApplicationLogSystemUser, Company
15CandidateRecruitmentUser, Job, Talent, CV
16CandidateNoteRecruitmentCandidate, User
17CollaborationInvitationCollaborationUser, Companytoken UK
18CollaboratorCollaborationCollaborationInvitation (1:1), UserinvitationId UK
19CollaboratorJobShareCollaborationCollaborator, Job@@unique([collaboratorId, jobId])
20CollaboratorPipelineShareCollaborationCollaborator, Pipeline@@unique([collaboratorId, pipelineId])
21CollaboratorTalentPoolShareCollaborationCollaborator, TalentPool@@unique([collaboratorId, talentPoolId])
22CollaboratorTalentShareCollaborationCollaborator (from/to), Talent@@unique([fromCollaboratorId, toCollaboratorId, talentId])
23CompanyIdentityUserCompanyRole, Job, TalentPoolslug UK
24CompanyBillingConfigBillingUser, Company (1:1)@@unique([userId, companyId])
25CompanyConnectionRequestCollaborationCompany@@unique([fromCompanyId, toCompanyEmail, relationshipType])
26CompanyNotificationPreferenceNotificationsCompany (1:1)companyId UK
27CompanyRelationshipCollaborationCompany (A, B)
28CompanyScoringDefaultRecruitmentCompany (1:1)companyId PK
29CompanyShareAuditCollaborationCompany
30CompanySpecificNotificationPreferenceNotificationsUser, Company@@unique([userId, companyId])
31ContactContactsCompany, User, UserCompanyRole
32ContactExternalShareContactsContacttoken UK
33ContactNoteContactsContact, User
34ContactToContactTypesContactsContact, ContactTypecomposite PK
35ContactTypeContactsContactToContactTypesname UK
36ConversationMessagingCompany
37ConversationParticipantMessagingConversation, User@@unique([conversationId, userId])
38CreditBalanceBillingCompany XOR UsercompanyId UK, userId UK
39CreditCostConfigBilling@@unique([modelId, operationType])
40CreditPackBillingCreditPackPurchasename UK, stripePriceId UK
41CreditPackPurchaseBillingCreditPack, User, CompanystripeCheckoutSessionId UK
42CreditTransactionBillingCreditBalance, User
43CVCV SystemTalent, UsermilvusPk UK
44CvAwardCV SystemCV@@index([cvId])
45CvCertificationCV SystemCV@@index([cvId])
46CvCollectionCV SystemCompany
47CvCollectionCompanyShareCV SystemCvCollection, Company
48CvCollectionExternalShareCV SystemCvCollectiontoken UK
49CvCollectionItemCV SystemCvCollection, CVcomposite PK
50CvCollectionUserShareCV SystemCvCollection, User
51CvEducationCV SystemCV@@index([cvId])
55CvJobPreferenceCV SystemCV (1:1)cvId UK
56CvLanguageCV SystemCV@@index([cvId])
57CvMetadataCV SystemCV (1:1)cvId UK
58CvProfileCV SystemCV (1:1)cvId UK
59CvProjectCV SystemCV@@index([cvId])
60CvPublicationCV SystemCV@@index([cvId])
61CVSkillCV SystemCV, Skill@@unique([cvId, skillId])
62CvVolunteerCV SystemCV@@index([cvId])
63CvWorkExperienceCV SystemCV@@index([cvId])
64EmailSystem
65EmailVerificationTokenIdentityUser (1:1)userId UK, token UK
66InboundEmailInbound EmailInboundMailbox, Company, Job, Talent, CV@@unique([mailboxAddress, imapFolder, imapUid])
67InboundEmailAttachmentInbound EmailInboundEmail
68InboundEmailParseAttemptInbound EmailInboundEmail, Attachment@@unique([inboundEmailId, attemptNumber])
69InboundMailboxInbound EmailInboundEmail@@unique([address, imapHost, imapPort, imapFolder])
70InterviewInterviewsCandidate, Job
71InterviewBookingInterviewsInterview (1:1)interviewId UK, externalBookingId UK
72InterviewBookingAttendeeInterviewsInterviewBookingrsvpToken UK, @@unique([bookingId, email])
73InterviewSlotInterviewsInterviewSlotOffer
74InterviewSlotOfferInterviewsCandidate, Job, Interview (1:1)token UK, interviewId UK
75InterviewSlotOfferAttendeeInterviewsInterviewSlotOffer@@unique([offerId, email])
76InvitationIdentityCompany, User, Roletoken UK
77InvoiceBillingSubscription, User, Company, PaymentMethodstripeInvoiceId UK
78JobRecruitmentCompany (3 roles), User (4 roles)
79JobSeekerProfileInvitationSharingTalent, Company
80JobSkillRequirementRecruitmentJob, Skill@@unique([jobId, skillId])
81MatchScoreRecruitmentCV, Job@@unique([jobId, cvId])
82MeetingMeetingsUser, Company, InterviewBooking (1:1)roomName UK, interviewBookingId UK
83MeetingAttendeeMeetingsMeeting, UserrsvpToken UK, @@unique([meetingId, email])
84MeetingInsightMeetingsMeeting, Interview
85MessageMessagingConversation, User, self-ref
86NewsSystemCompany
87NotificationNotificationsUser, Company14 composite indexes
88NotificationDeliveryLogNotificationsNotification
89NotificationTemplateNotificationsname UK
91PasswordResetTokenIdentityUser (1:1)userId UK, token UK
92PaymentMethodBillingUser
93PermissionIdentityRole (M:M)name UK
94PipelineRecruitmentCompany, User
95PipelineCompanyShareSharingPipeline, Company
96PipelineExternalShareSharingPipelinetoken UK
97PipelineItemRecruitmentPipeline, Job@@unique([pipelineId, jobId])
98PipelineScoringConfigRecruitmentPipeline (1:1)pipelineId UK
99PipelineUserShareSharingPipeline, User
100PlanBillingSubscriptionname UK, stripePriceId UK
101PromoCodeBillingUser, PromoCodePurchasecode UK
102PromoCodeInvitationBillingPromoCodetoken UK
103PromoCodePlanBillingPromoCodePurchasename UK, stripePriceId UK
104PromoCodePurchaseBillingPromoCodePlan, UserstripePaymentIntentId UK
105PromoCodeRedemptionBillingPromoCode, User, Subscription, Plan@@unique([promoCodeId, userId, subscriptionId])
106RoleIdentityPermission (M:M), UserCompanyRolename UK
107SharedProfileListSharingCompany, User
108SharedTalentListSharingCompany, User
109SharedTalentListCompanyShareSharingSharedTalentList, Company@@unique([sharedListId, companyId])
110SharedTalentListExternalShareSharingSharedTalentListtoken UK
111SharedTalentListItemSharingSharedTalentList, Talentcomposite PK
112SharedTalentListUserShareSharingSharedTalentList, User@@unique([sharedListId, userId])
113SkillTalentCVSkill, JobSkillRequirementname UK
114StripeEventBillingstripeEventId UK
115SubscriptionBillingPlan, Company, UserstripeSubscriptionId UK
116SystemSettingSystemUserkey UK
117TalentTalentUser, TalentPool, CV@@unique([userId, talentPoolId])
118TalentActivityTalentTalent, Company, User
119TalentExternalShareSharingTalenttoken UK
120TalentNoteTalentTalent, User
121TalentPoolTalentCompany, User
122TalentPoolCompanyShareSharingTalentPool, Company@@unique([talentPoolId, sharedWithCompanyId])
123TalentPoolExternalShareSharingTalentPooltoken UK
124TalentPoolSkillTalentTalentPool, Skill@@unique([talentPoolId, skillId])
125TalentPoolUserShareSharingTalentPool, User@@unique([talentPoolId, userId])
126TalentShareSharingTalent, Company, User@@unique([talentId, sharedWithCompanyId])
127TranscriptionMeetings— (standalone)@@map("transcriptions")
128TwoFactorCodeIdentityUser
129UserCompanyRoleIdentityUser, Company, Role, InvitationinvitationId UK
130UserJobMatchScoreRecruitmentUser, Job@@unique([userId, jobId])
131UserNotificationPreferenceNotificationsUser (1:1)userId UK
132UserProfileCompanyShareSharingUser, Company, SharedProfileList@@unique([userId, sharedWithCompanyId])
133UserProfileExternalShareSharingUsertoken UK
134UserProfileUserShareSharingUser (2)@@unique([userId, sharedWithUserId])

Cross-Domain Connections

Key paths through the schema that span multiple domains:

Recruitment Pipeline

User → UserCompanyRole → Company → Job → Candidate → Interview → InterviewBooking → Meeting → Transcription → MeetingInsight
↑ ↓
Pipeline → PipelineItem
↑ ↓
TalentPool → Talent → CV → Structured Tables

Billing Flow

Plan → Subscription → Company → CreditBalance → CreditTransaction → AIOperationLog
↑ ↓
CreditPack → CreditPackPurchase Background Tasks
(CV extraction, matching,
agent chat, etc.)

AI Agent Pipeline

Company → Agent → AgentDocument → AgentDocumentChunk (pgvector embeddings)

AgentConversation → AgentMessage → AgentToolExecution
↓ ↓
AgentTokenUsage RAG search / DB query / Talent search

Sharing Web

                    ┌── UserShare
Entity (Talent, ───┼── CompanyShare
TalentPool, └── ExternalShare (token-based, 7-day expiry)
Pipeline, etc.)
┌── CollaboratorPipelineShare
Collaborator ───────┼── CollaboratorTalentShare
├── CollaboratorTalentPoolShare
└── CollaboratorJobShare

Schema Patterns

Recurring patterns used throughout the schema.

UUID Primary Keys

All models use uuid primary keys generated by @default(uuid()). No auto-incrementing integers.

Timestamps

Most models include createdAt DateTime @default(now()) and updatedAt DateTime @updatedAt. Some add deletedAt DateTime? for soft deletion.

External Sharing Token Pattern

All external share tables follow this structure:

  • token String @unique — double-UUID format
  • expiresAt DateTime? — 7-day default expiration
  • accessCount Int @default(0) — tracks views
  • isActive Boolean @default(true) — soft revocation
  • email String? — optional recipient

Structured CV Tables

CV extraction writes to 11 typed tables (CvProfile, CvWorkExperience, CvEducation, CvCertification, CvLanguage, CvProject, CvPublication, CvAward, CvVolunteer, CvJobPreference, CvMetadata). These are the sole source of truth for all CV data reads and writes.

Composite Primary Keys

Used for join tables: CvCollectionItem, SharedTalentListItem, ContactToContactTypes. Format: @@id([fieldA, fieldB]).

XOR Constraints

CreditBalance enforces exactly one of companyId or userId via database-level check constraints.

Optimistic Locking

InterviewSlotOffer uses a version Int @default(0) field for concurrent update protection.

Table Name Mapping

Transcription uses @@map("transcriptions") for snake_case table naming compatible with background-tasks AsyncPG queries.