Skip to content

Permissions Matrix

This table is not edited by hand. It is regenerated on every build by apps/docs/scripts/generate-permissions-matrix.ts, which walks apps/api/src/**/*.controller.ts with ts-morph and extracts each method’s HTTP verb, path, @Roles(...), and @Public() posture directly from the source. If a controller method declares no access posture at all, the build fails — see Drift control.

  • Method / Path — the HTTP verb and the live route, with the API’s global /v1 prefix already applied (per apps/api/src/main.ts). The health route is intentionally exempt from the prefix.
  • Module — the directory under apps/api/src/ the controller lives in.
  • Required roles — the literal arguments to @Roles(...). Empty for public routes.
  • Public? — Yes if the method or its containing controller is marked @Public(), or if the class name matches *Public*Controller.
  • Used by — the apps/* workspaces whose source contains a literal URL targeting the endpoint. Static scan only — call sites that build URLs through a helper function (buildUrl(resource, id)) are invisible, so a blank cell means either the endpoint is genuinely unused or its callers compose the URL dynamically. An endpoint marked role-restricted to one audience but showing the other app as a caller is a drift signal worth investigating.
  • Source — a deep link to the controller method on GitHub.
  • Reference in a prompt — click the clipboard button to copy a single self-contained sentence identifying the endpoint (verb, path, source file:line, controller and handler, access posture, and known callers). Paste it at the top of a prompt to an AI coding agent so it has every field from the row without context-switching.

109 routes detected — generated at build time from apps/api/src/**/*.controller.ts. This page cannot drift from the live API.

MethodPathModuleRequired rolesPublic?Used bySourceReference in a prompt
GET/v1/applicationsapplicationsmembercompany-admincompany-memberteros-opsNoopspoolApplicationsController.findAll
POST/v1/applicationsapplicationsmembercompany-adminteros-opsNoopspoolApplicationsController.create
GET/v1/applications/:idapplicationsmembercompany-admincompany-memberteros-opsNoopsApplicationsController.findOne
GET/v1/applications/:id/job-postingapplicationsmembercompany-admincompany-memberteros-opsNopoolApplicationsController.findJobPostingForApplication
POST/v1/applications/:id/offer/acceptapplicationscompany-admincompany-memberteros-opsNoopsApplicationsController.acceptOffer
POST/v1/applications/:id/stage-eventsapplicationscompany-admincompany-memberteros-opsNoopsApplicationsController.createStageEvent
PATCH/v1/applications/:id/withdrawapplicationsmemberteros-opsNopoolApplicationsController.withdraw
GET/v1/audit-logsauditteros-ops-adminNoopsAuditLogController.findAll
GET/v1/audit-logs/actorsauditteros-ops-adminNoopsAuditLogController.findActors
POST/v1/candidate-freshness/candidates/:candidateProfileId/runcandidate-freshnessteros-ops-adminNoopsCandidateFreshnessController.runCandidate
POST/v1/candidate-freshness/runcandidate-freshnessteros-ops-adminNo—CandidateFreshnessController.runActivePool
POST/v1/internal/candidate-freshness/linkedincandidate-freshnessanonymousYes—InternalLinkedInFreshnessController.check
GET/v1/candidate-profilescandidate-profilesteros-opsteros-ops-adminNoopsCandidateProfilesController.findAll
POST/v1/candidate-profilescandidate-profilesmemberNoopspoolCandidateProfilesController.createOwn
GET/v1/candidate-profiles/admin/failed-resume-conversionscandidate-profilesteros-ops-adminNoopsCandidateProfilesController.listFailedResumeConversionsForAdmin
GET/v1/candidate-profiles/admin/legacy-file-migrationcandidate-profilesteros-ops-adminNoopsCandidateProfilesController.getLegacyFileMigrationStatus
POST/v1/candidate-profiles/admin/legacy-file-migration/run-next-batchcandidate-profilesteros-ops-adminNoopsCandidateProfilesController.runLegacyFileMigrationBatch
GET/v1/candidate-profiles/by-sub/:workosUserSubcandidate-profilescompany-admincompany-memberteros-opsteros-ops-adminNoopsCandidateProfilesController.findBySub
PATCH/v1/candidate-profiles/by-sub/:workosUserSubcandidate-profilesteros-opsteros-ops-adminNoopsCandidateProfilesController.updateBySub
POST/v1/candidate-profiles/by-sub/:workosUserSub/approvecandidate-profilesteros-opsteros-ops-adminNoopsCandidateProfilesController.approveBySub
POST/v1/candidate-profiles/by-sub/:workosUserSub/ignorecandidate-profilesteros-opsteros-ops-adminNoopsCandidateProfilesController.ignoreBySub
DELETE/v1/candidate-profiles/by-sub/:workosUserSub/invitationcandidate-profilesteros-opsteros-ops-adminNoopsCandidateProfilesController.revokeInvitation
GET/v1/candidate-profiles/by-sub/:workosUserSub/invitationcandidate-profilesteros-opsteros-ops-adminNoopsCandidateProfilesController.findActiveInvitation
POST/v1/candidate-profiles/by-sub/:workosUserSub/invitationcandidate-profilesteros-opsteros-ops-adminNoopsCandidateProfilesController.createInvitation
GET/v1/candidate-profiles/by-sub/:workosUserSub/notescandidate-profilescompany-admincompany-memberteros-opsteros-ops-adminNoopsCandidateProfilesController.findNotesBySub
POST/v1/candidate-profiles/by-sub/:workosUserSub/notescandidate-profilesteros-opsteros-ops-adminNoopsCandidateProfilesController.createNoteBySub
PATCH/v1/candidate-profiles/by-sub/:workosUserSub/notes/:noteIdcandidate-profilesteros-opsteros-ops-adminNoopsCandidateProfilesController.updateNoteBySub
PATCH/v1/candidate-profiles/by-sub/:workosUserSub/ownercandidate-profilesteros-ops-adminNoopsCandidateProfilesController.reassignOwnerBySub
DELETE/v1/candidate-profiles/by-sub/:workosUserSub/profile-picturecandidate-profilesteros-opsteros-ops-adminNoopsCandidateProfilesController.deleteProfilePictureBySub
GET/v1/candidate-profiles/by-sub/:workosUserSub/profile-picturecandidate-profilescompany-admincompany-memberteros-opsteros-ops-adminNoopsCandidateProfilesController.findProfilePictureBySub
POST/v1/candidate-profiles/by-sub/:workosUserSub/profile-picturecandidate-profilesteros-opsteros-ops-adminNoopsCandidateProfilesController.updateProfilePictureBySub
DELETE/v1/candidate-profiles/by-sub/:workosUserSub/public-resume-linkcandidate-profilesteros-opsteros-ops-adminNoopsCandidateProfilesController.voidPublicResumeLink
GET/v1/candidate-profiles/by-sub/:workosUserSub/public-resume-linkcandidate-profilesteros-opsteros-ops-adminNoopsCandidateProfilesController.findActivePublicResumeLink
POST/v1/candidate-profiles/by-sub/:workosUserSub/public-resume-linkcandidate-profilesteros-opsteros-ops-adminNoopsCandidateProfilesController.createPublicResumeLink
POST/v1/candidate-profiles/by-sub/:workosUserSub/recovercandidate-profilesteros-opsteros-ops-adminNoopsCandidateProfilesController.recoverBySub
GET/v1/candidate-profiles/by-sub/:workosUserSub/resumecandidate-profilescompany-admincompany-memberteros-opsteros-ops-adminNoopsCandidateProfilesController.findResumeBySub
POST/v1/candidate-profiles/by-sub/:workosUserSub/resumecandidate-profilesteros-opsteros-ops-adminNoopsCandidateProfilesController.updateResumeBySub
POST/v1/candidate-profiles/by-sub/:workosUserSub/resume-conversion/retrycandidate-profilesteros-ops-adminNoopsCandidateProfilesController.retryResumeConversionBySub
GET/v1/candidate-profiles/by-sub/:workosUserSub/resume-markdowncandidate-profilesteros-opsteros-ops-adminNoopsCandidateProfilesController.findResumeMarkdownBySub
PATCH/v1/candidate-profiles/by-sub/:workosUserSub/resume-markdowncandidate-profilesteros-opsteros-ops-adminNoopsCandidateProfilesController.updateResumeMarkdownBySub
GET/v1/candidate-profiles/by-sub/:workosUserSub/resume-profile-suggestionscandidate-profilesteros-opsteros-ops-adminNoopsCandidateProfilesController.findResumeProfileSuggestionsBySub
POST/v1/candidate-profiles/by-sub/:workosUserSub/unapprovecandidate-profilesteros-opsteros-ops-adminNoopsCandidateProfilesController.unapproveBySub
POST/v1/candidate-profiles/manualcandidate-profilesteros-opsteros-ops-adminNoopsCandidateProfilesController.createManual
GET/v1/candidate-profiles/mecandidate-profilesmemberNopoolCandidateProfilesController.findOwn
PATCH/v1/candidate-profiles/mecandidate-profilesmemberNopoolCandidateProfilesController.updateOwn
POST/v1/candidate-profiles/me/onboardingcandidate-profilesmemberNopoolCandidateProfilesController.saveOnboardingStep1
POST/v1/candidate-profiles/me/onboarding/completecandidate-profilesmemberNopoolCandidateProfilesController.completeOnboardingFinal
DELETE/v1/candidate-profiles/me/profile-picturecandidate-profilesmemberNopoolCandidateProfilesController.deleteOwnProfilePicture
GET/v1/candidate-profiles/me/profile-picturecandidate-profilesmemberNopoolCandidateProfilesController.findOwnProfilePicture
POST/v1/candidate-profiles/me/profile-picturecandidate-profilesmemberNopoolCandidateProfilesController.updateOwnProfilePicture
GET/v1/candidate-profiles/me/resumecandidate-profilesmemberNopoolCandidateProfilesController.findOwnResume
POST/v1/candidate-profiles/me/resumecandidate-profilesmemberNopoolCandidateProfilesController.updateOwnResume
GET/v1/candidate-profiles/me/resume-markdowncandidate-profilesmemberNopoolCandidateProfilesController.findOwnResumeMarkdown
GET/v1/candidate-profiles/me/resume-profile-suggestionscandidate-profilesmemberNopoolCandidateProfilesController.findOwnResumeProfileSuggestions
GET/v1/candidate-profiles/me/statuscandidate-profilesmemberNopoolCandidateProfilesController.findOwnStatus
POST/v1/candidate-profiles/resume-prefillcandidate-profilesteros-opsteros-ops-adminNoopsCandidateProfilesController.prefillFromResume
GET/v1/public/invitation/:tokencandidate-profilesanonymousYespoolPublicInvitationController.validateInvitation
POST/v1/public/invitation/:token/redeemcandidate-profilesanonymousYespoolPublicInvitationController.redeemInvitation
GET/v1/public/resume/:tokencandidate-profilesanonymousYesopsPublicResumeController.getPublicResume
GET/v1/public/resume/:token/profile-picturecandidate-profilesanonymousYesopsPublicResumeController.getPublicResumeProfilePicture
GET/v1/candidate-reviewscandidate-reviewsteros-opsteros-ops-adminNoopsCandidateReviewsController.list
PATCH/v1/candidate-reviews/:id/moderationcandidate-reviewsteros-opsteros-ops-adminNoopsCandidateReviewsController.moderate
GET/v1/public/candidate-reviewscandidate-reviewsanonymousYes—CandidateReviewsController.listPublic
POST/v1/public/candidate-reviewscandidate-reviewsanonymousYespoolCandidateReviewsController.submit
GET/v1/public/candidate-reviews/:id/profile-picturecandidate-reviewsanonymousYes—CandidateReviewsController.findPublicProfilePicture
POST/v1/admin/documents/:documentId/approvedocumentsteros-opsteros-ops-adminNoopsDocumentsController.approve
GET/v1/admin/documents/:documentId/filedocumentsteros-opsteros-ops-adminNoopsDocumentsController.getDocumentFile
POST/v1/admin/documents/:documentId/rejectdocumentsteros-opsteros-ops-adminNoopsDocumentsController.reject
GET/v1/admin/documents/pendingdocumentsteros-opsteros-ops-adminNoopsDocumentsController.listPending
GET/v1/admin/users/:userId/payment-eligibilitydocumentsteros-opsteros-ops-adminNoopsDocumentsController.getPaymentEligibility
GET/v1/document-types/:id/variants/:variantId/templatedocumentsmemberNopoolDocumentsController.getTemplate
GET/v1/users/me/documentsdocumentsmemberNopoolDocumentsController.listOwn
POST/v1/users/me/documents/:typeIddocumentsmemberNopoolDocumentsController.uploadOwn
GET/v1/users/me/gating-statusdocumentsmemberNopoolDocumentsController.getOwnGatingStatus
GET/healthhealthanonymousYesdebugHealthController.check
GET/v1/job-posting-requestsjob-posting-requeststeros-opscompany-adminNoopsJobPostingRequestsController.list
POST/v1/job-posting-requestsjob-posting-requeststeros-opscompany-adminNoopsJobPostingRequestsController.create
POST/v1/job-posting-requests/:id/disablejob-posting-requeststeros-opscompany-adminNoopsJobPostingRequestsController.disable
GET/v1/public/job-posting-requests/:tokenjob-posting-requestsanonymousYesopsPublicJobPostingRequestsController.get
PATCH/v1/public/job-posting-requests/:tokenjob-posting-requestsanonymousYesopsPublicJobPostingRequestsController.update
POST/v1/public/job-posting-requests/:token/draftjob-posting-requestsanonymousYesopsPublicJobPostingRequestsController.draft
POST/v1/public/job-posting-requests/:token/submitjob-posting-requestsanonymousYesopsPublicJobPostingRequestsController.submit
GET/v1/job-postingsjob-postingsmembercompany-admincompany-memberteros-opsNoopspoolJobPostingsController.findAll
POST/v1/job-postingsjob-postingscompany-adminteros-opsNoopsJobPostingsController.create
GET/v1/job-postings/:idjob-postingsmembercompany-admincompany-memberteros-opsNoopsJobPostingsController.findOne
PATCH/v1/job-postings/:idjob-postingscompany-adminteros-opsNoopsJobPostingsController.update
POST/v1/job-postings/:id/closejob-postingscompany-adminteros-opsNoopsJobPostingsController.close
DELETE/v1/job-postings/:id/public-linkjob-postingscompany-adminteros-opsNoopsJobPostingsController.voidPublicLink
GET/v1/job-postings/:id/public-linkjob-postingscompany-adminteros-opsNoopsJobPostingsController.findActivePublicLink
POST/v1/job-postings/:id/public-linkjob-postingscompany-adminteros-opsNoopsJobPostingsController.createPublicLink
GET/v1/job-postings/:id/suggested-candidatesjob-postingscompany-adminteros-opsNoopsJobPostingsController.findSuggestedCandidates
POST/v1/job-postings/:id/suggested-candidates/:candidateProfileId/feedbackjob-postingscompany-adminteros-opsNoopsJobPostingsController.createSuggestedCandidateFeedback
POST/v1/job-postings/:id/suggested-candidates/refreshjob-postingscompany-adminteros-opsNoopsJobPostingsController.refreshSuggestedCandidates
GET/v1/public/job-postings/:tokenjob-postingsanonymousYesopsPublicJobPostingsController.getPublicJobPosting
GET/v1/ops-dashboard/metricsops-dashboardcompany-admincompany-memberteros-opsNoopsOpsDashboardController.metrics
GET/v1/organizationsorganizationscompany-admincompany-memberteros-opsNoopsOrganizationsController.findAll
POST/v1/organizationsorganizationsteros-opsNoopsOrganizationsController.create
DELETE/v1/organizations/:idorganizationscompany-adminteros-opsNo—OrganizationsController.remove
GET/v1/organizations/:idorganizationscompany-admincompany-memberteros-opsNo—OrganizationsController.findOne
PATCH/v1/organizations/:idorganizationscompany-adminteros-opsNo—OrganizationsController.update
GET/v1/organizations/:id/linked-engineersorganizationscompany-admincompany-memberteros-opsNoopsOrganizationsController.findLinkedEngineers
GET/v1/organizations/:id/membersorganizationscompany-admincompany-memberteros-opsNoopsOrganizationsController.findMembers
POST/v1/organizations/:id/syncorganizationsteros-opsNo—OrganizationsController.sync
POST/v1/organizations/sync-allorganizationsteros-ops-adminNoopsOrganizationsController.bulkSync
GET/v1/skillsskillsteros-opsteros-ops-adminNoopsSkillsController.list
PATCH/v1/skills/:id/parentskillsteros-ops-adminNoopsSkillsController.setParent
POST/v1/skills/approveskillsteros-ops-adminNoopsSkillsController.approve
POST/v1/skills/normalizeskillsteros-ops-adminNoopsSkillsController.normalize
POST/v1/skills/rejectskillsteros-ops-adminNoopsSkillsController.reject

When a PR changes a controller decorator, this table changes on next build. If a role moves from teros-ops-admin → teros-ops, the diff is visible in the generated JSON (and therefore in the deployed site preview). Reviewers should treat any unexplained roles change as a blocker until the author articulates intent.