CV Collections
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 } }
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:
| Level | Scope |
|---|---|
VIEW | Read-only access to collection and its CVs |
EDIT | Add/remove CVs, update collection metadata |
MANAGE | Full access including sharing and deletion |
Deleting a collection cascades through CvCollectionItem and all share tables. The underlying CV records are not deleted.