Talent Management
Talents are user profiles organized into company-scoped talent pools. The system supports multiple creation paths, CV management with AI parsing, multi-level sharing, and skill-based recommendations.
Talent Sources
| Source | Enum Value | Description |
|---|---|---|
| Manual entry | MANUAL_ENTRY | Recruiter adds user directly |
| CV upload | CV_UPLOAD | Created during CV upload flow |
| Direct application | APPLICATION_DIRECT | User self-applies to a job |
| Invited | INVITED | Employer accepted a job seeker's profile invitation |
| Inbound email | BULK_IMPORT | Parsed from jobs+slug@aiqlick.com |
| Referral | REFERRAL | Referred by another user |
| LinkedIn import | LINKEDIN_IMPORT | Imported from LinkedIn |
| Internal transfer | INTERNAL_TRANSFER | Moved between companies |
| Shared | SHARED | Extracted from a collaborator's shared talent |
When a job seeker sends a profile invitation and an employer accepts it, a talent record is automatically created with source: INVITED and assigned to the employer's Default talent pool. This ensures invited talents are immediately visible on the company's talents page. The INVITED source also controls automatic notification delivery — only invited candidates receive automatic emails for pipeline status changes and interview scheduling.
Talent Pools
Each company has a Default talent pool created automatically. Talents belong to a pool via the @@unique([userId, talentPoolId]) constraint -- a user can appear only once per pool.
A special Public Talent Pool (ID: a0000000-0000-0000-0000-000000000001) exists for independent job seekers with no company association.
Pool statuses: ACTIVE, INACTIVE, ARCHIVED, DRAFT
Key Queries
# List company talent pools
query {
talentPools {
id
name
status
isPublic
company { id name }
}
}
# Get talents in a pool
query {
talentPool(id: "pool-uuid") {
talents {
id
user { firstName lastName email }
activeCv { id url }
}
skills { skill { name } required proficiency }
}
}
# Get all company talents (owned + shared)
query {
companyTalents(companyId: "company-uuid") {
id
source
user { firstName lastName }
}
}
Key Mutations
# Add talent to pool
mutation {
addTalent(createTalentInput: {
userId: "user-uuid"
talentPoolId: "pool-uuid"
}) { id }
}
# Create a new talent pool with skill requirements
mutation {
createTalentPool(createTalentPoolInput: {
name: "Senior Engineers"
description: "Experienced backend developers"
companyId: "company-uuid"
skills: [
{ skillId: "skill-uuid", required: true, proficiency: ADVANCED }
]
}) { id name }
}
CV Management
Each talent can have multiple CVs with one marked as the active CV (talent.activeCvId). CVs are stored in S3 and parsed by the AI service into 11 structured tables (CvProfile, CvWorkExperience, CvEducation, CvCertification, CvLanguage, CvProject, CvPublication, CvAward, CvVolunteer, CvJobPreference, CvMetadata).
CV ownership is dual: the CV table has a FK to Talent set to SET NULL (not CASCADE). When a talent is deleted, the user's CVs are preserved.
Auto-selection logic when creating a candidate: the system prioritizes a provided cvId, then the talent's activeCvId, then the most recent CV.
Talent Sharing
Three sharing mechanisms exist, each with different scopes:
1. Company-to-Company Sharing (TalentShare)
Share individual talents between companies with permission control.
mutation {
shareTalent(input: {
talentId: "talent-uuid"
sharedByCompanyId: "company-a"
sharedWithCompanyId: "company-b"
permissionLevel: READ_ONLY
notes: "Strong React candidate"
}) { id permissionLevel }
}
# Bulk share
mutation {
bulkShareTalents(input: {
talentIds: ["t1", "t2", "t3"]
sharedByCompanyId: "company-a"
sharedWithCompanyId: "company-b"
permissionLevel: EDIT
}) { id }
}
Permission levels: READ_ONLY, EDIT, ADMIN
2. Talent Pool Sharing
Pools can be shared at three levels:
| Level | Model | Scope |
|---|---|---|
| User share | TalentPoolUserShare | Individual user with VIEW/EDIT/MANAGE |
| Company share | TalentPoolCompanyShare | Entire company with VIEW/EDIT/MANAGE |
| External share | TalentPoolExternalShare | Token-based link with expiration |
# External share (generates email with link)
mutation {
createTalentPoolExternalShare(createTalentPoolExternalShareInput: {
talentPoolId: "pool-uuid"
email: "client@partner.com"
expirationHours: 72
}) { id token expiresAt accessCount }
}
# Public access via token (no auth required)
query {
talentPoolByToken(token: "secure-token") {
name
talents { id user { firstName lastName } }
}
}
3. Collaborator Talent Sharing
For companies with active collaboration relationships. Requires both parties to have ACTIVE collaborator status and a valid relationship (direct invitation or common inviter).
mutation {
shareTalentWithCollaborator(input: {
toCollaboratorId: "collab-uuid"
talentId: "talent-uuid"
permissionLevel: READ_ONLY
notes: "Great React developer"
}) { success share { id } }
}
Talents can only be shared from their owner's organization. The system validates that the talent's pool belongs to the sharer's company before allowing the share.
Talent Recommendations
The recommendation engine scores talents against pool skill requirements using weighted proficiency matching:
score = (required ? 1.5 : 1.0) * (talentProficiency / requiredProficiency) * experienceMultiplier
Proficiency scores: BASIC=1, INTERMEDIATE=2, ADVANCED=3, EXPERT=4.
query {
talentRecommendations(input: {
talentPoolId: "pool-uuid"
limit: 20
minScore: 0.3
}) {
recommendations {
talent { id user { firstName lastName } }
matchScore
skillMatches { skill { name } hasSkill scoreContribution }
}
totalCount
averageScore
}
}
Talent Notes
Internal notes can be attached directly to talent profiles, independent of any job candidacy. This fills the gap for sourcing workflows where recruiters need to capture observations before a talent is linked to a specific job.
See Talent Notes for the full API and access control details.
Export
Talents and candidates can be exported to CSV via presigned S3 URLs (1-hour expiry):
mutation {
exportCompanyTalents(companyId: "company-uuid", talentIds: ["t1", "t2"])
}
# Returns a presigned S3 download URL