Skip to main content

Collaborators, Partners, and Other Collaborations

This page is the source-reviewed rulebook for collaboration behavior in the backend. It separates four concepts that are easy to mix up in product language:

  • Team members are users inside the same company. They are managed by company invitations and UserCompanyRole. See Team Member Management.
  • Collaborators are invited users outside the normal team roster. They are represented by CollaborationInvitation and Collaborator.
  • Company partners are company-to-company relationships. They are represented by CompanyConnectionRequest and CompanyRelationship.
  • Shares are object-level grants to collaborators, companies, users, or external token recipients.

Entity Map

AreaMain recordsWhat it means
Collaborator invitationCollaborationInvitation, CollaboratorA user invites an external collaborator or partner contact by email.
Collaborator sharesCollaboratorPipelineShare, CollaboratorTalentPoolShare, CollaboratorTalentShare, CollaboratorJobShareA collaborator receives access to a specific pipeline, talent pool, talent, or job.
Company connectionCompanyConnectionRequest, CompanyRelationshipOne company asks another company to establish a formal business relationship.
Company sharesTalentPoolCompanyShare, PipelineCompanyShare, CvCollectionCompanyShare, SharedTalentListCompanyShareA company shares a resource with another company.
External sharesTalentPoolExternalShare, TalentExternalShare, SharedTalentListExternalShare, CvCollectionExternalShare, ContactExternalShare, UserProfileExternalShareA resource is shared by email token without creating a collaborator or company relationship.
Job seeker profile invitationJobSeekerProfileInvitationA job seeker invites an employer to view their active profile and add them to a talent pool.
Audit and notificationsCompanyShareAudit, CompanyNotificationPreferenceCompany share events are logged and notification preferences control who is emailed.

Collaboration Layers

Use the right layer for the intended relationship:

ScenarioUseDo not use
Add a user to a company's internal staffTeam member invitationCollaborator invitation
Invite an external person to collaborate on selected resourcesCollaborator invitationCompany connection request
Establish a business relationship between two companiesCompany connection requestDirect CompanyRelationship mutation
Share a pipeline, talent pool, CV collection, or shared list with another companyCompany shareCollaborator share
Send a limited public link to a person by emailExternal shareCollaborator or company relationship
Let an employer view a job seeker's active profileJob seeker profile invitationCollaborator invitation
note

The active relationship enum is RelationshipType.PARTNERSHIP. There is no PARTNER relationship enum in the current Prisma schema.

Collaborator Invitations

Collaborator invitations are handled by CollaborationResolver and the collaboration-management services.

Creation Rules

  • The caller must be authenticated.
  • createCollaborationInvitation uses PlanLimitGuard with maxCollaborationInvites.
  • The invitation email is normalized before duplicate checks.
  • A pending, unexpired invitation blocks another invitation to the same email in the same scope.
  • If the invitee already has a user account, an existing ACTIVE or PENDING collaboration blocks a duplicate collaboration.
  • The token is generated with 32 random bytes and stored as hex.
  • Default expiry is 7 days; the core service allows 1 to 30 days.
  • A CollaborationInvitation and a PENDING Collaborator are created together.
  • If initial pipelineIds are supplied and no roleId is supplied, the service tries to assign the RDS role named External Sales.
  • Job seeker CV connection-style collaborator invites pass no pipelineIds, so roleId stays null and the UI can distinguish the intent.

The invitation link format is:

/message/accept?token=<token>&type=collaboration&invitedEmail=<email>

Status Lifecycle

StatusMeaning
PENDINGThe invitation exists and the collaborator record is waiting for acceptance.
ACCEPTEDThe invitee accepted and the collaborator becomes active.
DECLINEDThe invitee declined. Shares are cleaned up and the pending collaborator is removed.
EXPIREDThe token expired before acceptance.
CANCELLEDThe inviter cancelled the pending invitation. Shares are cleaned up and the pending collaborator is removed.

Acceptance Rules

  • Token acceptance and dashboard acceptance both require authentication in the current resolver.
  • The authenticated user's email must match the invitation email.
  • Token acceptance allows selectedCompanyId to be omitted, so a new invitee can accept before creating or selecting a company.
  • Dashboard acceptance by invitation ID currently requires selectedCompanyId.
  • The service rejects expired invitations and marks them EXPIRED.
  • The service rejects accepted, declined, cancelled, or expired invitations unless the request is an idempotent accept by the same already-active collaborator.
  • On successful acceptance, the invitation becomes ACCEPTED and the collaborator becomes ACTIVE.
  • The invitation.accepted event is emitted.
  • ContactAutoCreateListener creates a contact in the inviter's company when a collaborator accepts, using the event company ID or the inviter's selected company.

Decline, Cancel, and Resend

ActionWho can do itRules
Decline by tokenAuthenticated matching inviteePending only; cleans collaborator shares and removes the pending collaborator.
Decline by IDAuthenticated matching inviteePending only; accepts a reason argument, but the current schema does not persist the reason.
CancelOriginal inviterPending only; cleans collaborator shares and removes the pending collaborator.
ResendOriginal inviterOnly declined, expired, or cancelled invitations; pending and accepted invitations cannot be resent. Resend generates a new token and 7-day expiry.

Collaborator Management

CollaboratorStatus values are:

StatusMeaning
PENDINGCreated with the invitation but not accepted yet.
ACTIVEAccepted and allowed to participate.
INACTIVETemporarily disabled by the inviter.
LEFTThe collaborator left or was removed.

Status and role rules:

  • The inviter and collaborator can read their shared collaborator records.
  • listMyCollaborators returns records where the current user is either inviter or collaborator.
  • Only the inviter can set a collaborator to INACTIVE.
  • Only the inviter can reactivate an INACTIVE collaborator.
  • Only the collaborator can move themselves to LEFT.
  • A PENDING collaborator cannot be manually activated; acceptance must go through the invitation flow.
  • LEFT collaborators cannot be reactivated.
  • Only the inviter can update a collaborator's role.
  • leaveCollaboration can only be called by the active collaborator.
  • removeCollaborator can only be called by the inviter.
  • Leave and remove operations clean up collaborator shares, delete the collaborator row, and delete the linked invitation row.

Collaborator Resource Shares

Collaborator shares are not company-wide. They grant a specific collaborator access to a specific resource.

ResourceModelPermission enumMain creation checks
PipelineCollaboratorPipelineShareAccessPermission (VIEW, EDIT, MANAGE)Caller must be in the collaboration, collaborator must be ACTIVE, and caller must own the pipeline or belong to the pipeline company.
Talent poolCollaboratorTalentPoolShareAccessPermission (VIEW, EDIT, MANAGE)Caller must be in the collaboration, collaborator must be ACTIVE, and caller must have pool owner or company access.
TalentCollaboratorTalentSharePermissionLevel (READ_ONLY, EDIT, ADMIN)Resolver resolves the sharing relationship; update and unshare require collaboration permission on the source collaborator.
JobCollaboratorJobShareAccessPermission (VIEW, EDIT, MANAGE)Caller must be the job creator or belong to the job company. Duplicate collaborator/job pairs are blocked.

Additional talent-share behavior:

  • READ_ONLY talent shares cannot be extracted into another talent pool.
  • EDIT and ADMIN talent shares can be extracted into a target talent pool when the caller has permission.
  • Extraction creates a new Talent with source SHARED, links the active CV, and preserves share notes.
Current implementation note

CollaboratorJobShareService does not currently enforce the same collaborator-participant and ACTIVE status checks used by pipeline and talent-pool collaborator shares. It checks whether the caller can share the job, then creates, updates, or removes the collaborator job share.

Company Connection Requests

Company connection requests are the partner relationship workflow. They are handled by CompanyConnectionRequestResolver and company-collaboration/connection-requests.

Creation Rules

  • The caller must be authenticated.
  • createCompanyConnectionRequest uses PlanLimitGuard with maxConnectionRequestsPerMonth.
  • The caller must belong to the source company.
  • The caller must have an admin role in the source company. The service treats Company Admin and Super Admin as admin roles.
  • The request targets a company email. If a company with that email exists, toCompanyId is linked.
  • Duplicate pending requests are blocked by [fromCompanyId, toCompanyEmail, relationshipType].
  • Existing relationships are checked in both directions before a new request is created.
  • Connection tokens expire after 14 days.

Relationship Types

Current RelationshipType values:

  • PARTNERSHIP
  • ACQUISITION
  • STRATEGIC_ALLIANCE
  • BROKERAGE
  • CLIENT
  • RECRUITER

Acceptance, Decline, and Cancel

ActionWho can do itRules
Accept by tokenTarget company adminAuthenticated; validates target company membership and admin role. If the target company was not linked, the approver must administer a company whose email matches the request email.
Accept by IDTarget company adminSame approval rules as token acceptance; can include responseMessage.
Decline by tokenTarget company memberAuthenticated; membership is required, but the decline path is not admin-only.
Decline by IDTarget company memberSame as token decline; can include responseMessage.
CancelRequester or source company adminPending only.

When accepted, the service creates two CompanyRelationship rows:

Company A -> Company B
Company B -> Company A

This makes the relationship visible from both companies.

Prefer the request workflow

Direct CompanyRelationship CRUD mutations still exist and are protected only by authentication in the current resolver, with a separate super-admin query for paginated admin listing. Product and backend flows should prefer connection requests because they enforce admin approval and create bidirectional relationship rows.

Company Resource Shares

Company shares grant another company access to a resource. The shared company receives access through one of the company share tables:

ResourceModelPermission enum
Talent poolTalentPoolCompanyShareAccessPermission
PipelinePipelineCompanyShareAccessPermission
CV collectionCvCollectionCompanyShareAccessPermission
Shared talent listSharedTalentListCompanyShareAccessPermission

Company share service rules:

  • Creating a company share requires an admin role in the source company.
  • Updating or deleting a company share requires an admin role in the source company or the original share creator.
  • Viewing shares is allowed for company members.
  • The shared-company relationship check currently logs a warning when no relationship exists; it does not block share creation.
  • Share creation, permission changes, and revocation are logged through CompanyShareAuditService.
  • Share notifications are routed through CompanyCollaborationNotificationService.

Audit actions use ShareActionType:

  • CREATED
  • UPDATED
  • DELETED
  • ACCESSED
  • PERMISSION_CHANGED
  • REVOKED

External Token Shares

External shares are email-token links. They do not create a collaborator, company connection, or company relationship.

Common external-share fields:

  • email
  • token
  • expiresAt
  • accessCount
  • isActive

Use external shares when the recipient should only receive a limited link. Use collaborator or company shares when the recipient should have an ongoing authenticated relationship in the platform.

Job Seeker Profile Invitations

Job seeker profile invitations are a separate collaboration path handled by JobSeekerInvitationResolver.

Send Rules

  • The sender must be authenticated.
  • The sender must be in JOB_SEEKER view mode.
  • The sender must have an active CV.
  • A duplicate pending invitation to the same employer email is blocked.
  • The token is generated with 32 random bytes and stored as hex.
  • The invitation expires after 30 days.
  • The employer receives a link at:
/invitations/job-seeker/accept?token=<token>

Accept and Decline Rules

  • Accepting requires authentication.
  • The accepting employer must belong to the selected company.
  • If the job seeker already has a talent record in one of that company's talent pools, it is reused and set to LIVE_ACTIVE.
  • Otherwise the service finds or creates the company's Default talent pool.
  • A new talent record is created with source: INVITED, the job seeker's active CV, and cvMode: LIVE_ACTIVE.
  • The invitation stores acceptedBy, acceptedCompanyId, and talentId.
  • Declining by token is public but requires the provided employerEmail to exactly match the invitation email.
  • The job seeker can cancel only pending invitations.
  • The job seeker can delete only non-pending invitation history rows. Accepted invitation deletion preserves the underlying talent record.
  • Resend is allowed for declined, expired, or cancelled invitations. Pending and accepted invitations cannot be resent.

Notification Preferences

CompanyNotificationPreference controls company collaboration email behavior:

FieldDefault
notifyOnConnectionRequesttrue
notifyOnConnectionAcceptedtrue
notifyOnConnectionDeclinedtrue
notifyOnResourceSharedtrue
notifyOnResourceUnsharedtrue
notifyOnPermissionChangedtrue
enableDailyDigestfalse
enableWeeklyDigesttrue
digestRecipients[]
notificationEmails[]

If no explicit notification emails are configured, company admins are used as recipients.

Plan Limits

Collaboration-related plan limit keys in the backend are:

Limit keyUsed by
maxCollaborationInvitesCollaborator invitation creation
maxConnectionRequestsPerMonthCompany connection request creation
maxSharedTalentListsShared talent list creation
maxUsersPerCompanyTeam member invitation creation

Resource creation has its own plan limits outside this page, such as talent pools, pipelines, jobs, CV collections, contacts, meetings, and interviews.

Security Notes

  • CollaborationResolver and CompanyConnectionRequestResolver are guarded by JwtAuthGuard.
  • Job seeker profile invitation accept requires authentication; get-by-token and decline-by-token are public.
  • Collaborator and company share permissions are resource-specific and should not be treated as interchangeable with company roles.
  • AccessPermission is used by resource shares that support VIEW, EDIT, and MANAGE.
  • PermissionLevel is used by collaborator talent shares and supports READ_ONLY, EDIT, and ADMIN.
  • Company connection acceptance is admin-only; decline is target-company-member-only in the current service.
  • Company share relationship checks are advisory in code today, not a hard authorization gate.