Skip to main content

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

SourceEnum ValueDescription
Manual entryMANUAL_ENTRYRecruiter adds user directly
CV uploadCV_UPLOADCreated during CV upload flow
Direct applicationAPPLICATION_DIRECTUser self-applies to a job
InvitedINVITEDEmployer accepted a job seeker's profile invitation
Inbound emailBULK_IMPORTParsed from jobs+slug@aiqlick.com
ReferralREFERRALReferred by another user
LinkedIn importLINKEDIN_IMPORTImported from LinkedIn
Internal transferINTERNAL_TRANSFERMoved between companies
SharedSHAREDExtracted from a collaborator's shared talent
Job Seeker Invitation Flow

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).

info

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:

LevelModelScope
User shareTalentPoolUserShareIndividual user with VIEW/EDIT/MANAGE
Company shareTalentPoolCompanyShareEntire company with VIEW/EDIT/MANAGE
External shareTalentPoolExternalShareToken-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 } }
}
warning

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