Skip to main content

CV Collections

No Frontend UI

CV Collections are currently a backend-only feature. All GraphQL mutations and queries documented below work correctly, but there is no frontend UI to manage collections. Integration requires building the collection management pages in the frontend.

CV collections group CVs into named sets for specific workflows such as shortlists, hiring campaigns, or client presentations. Collections support per-CV metadata, notes, and the same three-tier sharing pattern used by talent pools.

Creating Collections

Collections are company-scoped and subject to plan limits.

mutation {
createCvCollection(input: {
name: "Frontend Shortlist Q1"
description: "Top React/Next.js candidates"
companyId: "company-uuid"
}) { id name description createdAt }
}

mutation {
updateCvCollection(input: {
id: "collection-uuid"
name: "Updated Name"
}) { id name updatedAt }
}

mutation { removeCvCollection(id: "collection-uuid") { success message } }
warning

Creating collections is guarded by @CheckPlanLimit('maxCvCollections'). The limit is defined on the company's active plan.

Managing CVs

Add or remove individual CVs from a collection:

mutation {
addCVToCollection(input: {
cvCollectionId: "collection-uuid"
cvId: "cv-uuid"
}) { id cv { id url } }
}

mutation {
removeCVFromCollection(input: {
cvCollectionId: "collection-uuid"
cvId: "cv-uuid"
}) { success message }
}

Querying Collections

# List accessible collections
query { cvCollections { id name description createdAt } }

# Detail view with items
query {
cvCollection(id: "collection-uuid") {
id
name
description
cvItems { id cv { id url talent { user { firstName lastName } } } }
}
}

# Collections shared with current user
query { cvCollectionsSharedWithMe { id name description } }

Sharing

CV collections support three sharing mechanisms, all managed through dedicated resolvers.

Company Share

mutation {
createCvCollectionCompanyShare(input: {
cvCollectionId: "collection-uuid"
companyId: "target-company-uuid"
permissionLevel: VIEW
}) { id permissionLevel }
}

query { CvCollectionCompanyShares(cvCollectionId: "collection-uuid") { id companyId permissionLevel } }
mutation { removeCvCollectionCompanyShare(id: "share-uuid") { success } }

User Share

mutation {
createCvCollectionUserShare(input: {
cvCollectionId: "collection-uuid"
userId: "user-uuid"
permissionLevel: EDIT
}) { id permissionLevel }
}

query { CvCollectionUserShares(cvCollectionId: "collection-uuid") { id userId permissionLevel } }
mutation { removeCvCollectionUserShare(id: "share-uuid") { success } }

External Token Share

mutation {
createCvCollectionExternalShare(input: {
cvCollectionId: "collection-uuid"
email: "client@partner.com"
expirationHours: 72
}) { id token expiresAt isActive accessCount }
}

# Public access (no auth required)
query { getSharedCvCollectionByToken(token: "secure-token") { id name cvItems { cv { id url } } } }

mutation { removeCvCollectionExternalShare(id: "share-uuid") { success } }

Access Control

The service enforces creator/owner permissions before allowing updates or deletions. Permission levels for shares follow the same pattern as talent pools:

LevelScope
VIEWRead-only access to collection and its CVs
EDITAdd/remove CVs, update collection metadata
MANAGEFull access including sharing and deletion
info

Deleting a collection cascades through CvCollectionItem and all share tables. The underlying CV records are not deleted.