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.

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

Method Path Module Required roles Public? Used by Source Reference in a prompt
GET /v1/applications applications membercompany-admincompany-memberteros-ops No opspool ApplicationsController.findAll
POST /v1/applications applications memberteros-ops No opspool ApplicationsController.create
GET /v1/applications/:id applications membercompany-admincompany-memberteros-ops No ops ApplicationsController.findOne
GET /v1/applications/:id/job-posting applications membercompany-admincompany-memberteros-ops No pool ApplicationsController.findJobPostingForApplication
POST /v1/applications/:id/offer/accept applications company-admincompany-memberteros-ops No ops ApplicationsController.acceptOffer
POST /v1/applications/:id/stage-events applications company-admincompany-memberteros-ops No ops ApplicationsController.createStageEvent
PATCH /v1/applications/:id/withdraw applications memberteros-ops No pool ApplicationsController.withdraw
GET /v1/audit-logs audit teros-ops-admin No ops AuditLogController.findAll
GET /v1/audit-logs/actors audit teros-ops-admin No ops AuditLogController.findActors
GET /v1/candidate-profiles candidate-profiles teros-opsteros-ops-admin No ops CandidateProfilesController.findAll
POST /v1/candidate-profiles candidate-profiles member No opspool CandidateProfilesController.createOwn
GET /v1/candidate-profiles/admin/failed-resume-conversions candidate-profiles teros-ops-admin No ops CandidateProfilesController.listFailedResumeConversionsForAdmin
GET /v1/candidate-profiles/admin/legacy-file-migration candidate-profiles teros-ops-admin No ops CandidateProfilesController.getLegacyFileMigrationStatus
POST /v1/candidate-profiles/admin/legacy-file-migration/run-next-batch candidate-profiles teros-ops-admin No ops CandidateProfilesController.runLegacyFileMigrationBatch
GET /v1/candidate-profiles/by-sub/:workosUserSub candidate-profiles company-admincompany-memberteros-opsteros-ops-admin No ops CandidateProfilesController.findBySub
PATCH /v1/candidate-profiles/by-sub/:workosUserSub candidate-profiles teros-opsteros-ops-admin No ops CandidateProfilesController.updateBySub
POST /v1/candidate-profiles/by-sub/:workosUserSub/approve candidate-profiles teros-opsteros-ops-admin No ops CandidateProfilesController.approveBySub
POST /v1/candidate-profiles/by-sub/:workosUserSub/ignore candidate-profiles teros-opsteros-ops-admin No ops CandidateProfilesController.ignoreBySub
DELETE /v1/candidate-profiles/by-sub/:workosUserSub/invitation candidate-profiles teros-opsteros-ops-admin No ops CandidateProfilesController.revokeInvitation
GET /v1/candidate-profiles/by-sub/:workosUserSub/invitation candidate-profiles teros-opsteros-ops-admin No ops CandidateProfilesController.findActiveInvitation
POST /v1/candidate-profiles/by-sub/:workosUserSub/invitation candidate-profiles teros-opsteros-ops-admin No ops CandidateProfilesController.createInvitation
GET /v1/candidate-profiles/by-sub/:workosUserSub/notes candidate-profiles company-admincompany-memberteros-opsteros-ops-admin No ops CandidateProfilesController.findNotesBySub
POST /v1/candidate-profiles/by-sub/:workosUserSub/notes candidate-profiles teros-opsteros-ops-admin No ops CandidateProfilesController.createNoteBySub
PATCH /v1/candidate-profiles/by-sub/:workosUserSub/notes/:noteId candidate-profiles teros-opsteros-ops-admin No ops CandidateProfilesController.updateNoteBySub
PATCH /v1/candidate-profiles/by-sub/:workosUserSub/owner candidate-profiles teros-ops-admin No ops CandidateProfilesController.reassignOwnerBySub
DELETE /v1/candidate-profiles/by-sub/:workosUserSub/profile-picture candidate-profiles teros-opsteros-ops-admin No ops CandidateProfilesController.deleteProfilePictureBySub
GET /v1/candidate-profiles/by-sub/:workosUserSub/profile-picture candidate-profiles company-admincompany-memberteros-opsteros-ops-admin No ops CandidateProfilesController.findProfilePictureBySub
POST /v1/candidate-profiles/by-sub/:workosUserSub/profile-picture candidate-profiles teros-opsteros-ops-admin No ops CandidateProfilesController.updateProfilePictureBySub
DELETE /v1/candidate-profiles/by-sub/:workosUserSub/public-resume-link candidate-profiles teros-opsteros-ops-admin No ops CandidateProfilesController.voidPublicResumeLink
GET /v1/candidate-profiles/by-sub/:workosUserSub/public-resume-link candidate-profiles teros-opsteros-ops-admin No ops CandidateProfilesController.findActivePublicResumeLink
POST /v1/candidate-profiles/by-sub/:workosUserSub/public-resume-link candidate-profiles teros-opsteros-ops-admin No ops CandidateProfilesController.createPublicResumeLink
POST /v1/candidate-profiles/by-sub/:workosUserSub/recover candidate-profiles teros-opsteros-ops-admin No ops CandidateProfilesController.recoverBySub
GET /v1/candidate-profiles/by-sub/:workosUserSub/resume candidate-profiles company-admincompany-memberteros-opsteros-ops-admin No ops CandidateProfilesController.findResumeBySub
POST /v1/candidate-profiles/by-sub/:workosUserSub/resume candidate-profiles teros-opsteros-ops-admin No ops CandidateProfilesController.updateResumeBySub
POST /v1/candidate-profiles/by-sub/:workosUserSub/resume-conversion/retry candidate-profiles teros-ops-admin No ops CandidateProfilesController.retryResumeConversionBySub
GET /v1/candidate-profiles/by-sub/:workosUserSub/resume-markdown candidate-profiles teros-opsteros-ops-admin No ops CandidateProfilesController.findResumeMarkdownBySub
PATCH /v1/candidate-profiles/by-sub/:workosUserSub/resume-markdown candidate-profiles teros-opsteros-ops-admin No ops CandidateProfilesController.updateResumeMarkdownBySub
GET /v1/candidate-profiles/by-sub/:workosUserSub/resume-profile-suggestions candidate-profiles teros-opsteros-ops-admin No ops CandidateProfilesController.findResumeProfileSuggestionsBySub
POST /v1/candidate-profiles/by-sub/:workosUserSub/unapprove candidate-profiles teros-opsteros-ops-admin No ops CandidateProfilesController.unapproveBySub
POST /v1/candidate-profiles/manual candidate-profiles teros-opsteros-ops-admin No ops CandidateProfilesController.createManual
GET /v1/candidate-profiles/me candidate-profiles member No pool CandidateProfilesController.findOwn
PATCH /v1/candidate-profiles/me candidate-profiles member No pool CandidateProfilesController.updateOwn
POST /v1/candidate-profiles/me/onboarding candidate-profiles member No pool CandidateProfilesController.saveOnboardingStep1
POST /v1/candidate-profiles/me/onboarding/complete candidate-profiles member No pool CandidateProfilesController.completeOnboardingFinal
DELETE /v1/candidate-profiles/me/profile-picture candidate-profiles member No pool CandidateProfilesController.deleteOwnProfilePicture
GET /v1/candidate-profiles/me/profile-picture candidate-profiles member No pool CandidateProfilesController.findOwnProfilePicture
POST /v1/candidate-profiles/me/profile-picture candidate-profiles member No pool CandidateProfilesController.updateOwnProfilePicture
GET /v1/candidate-profiles/me/resume candidate-profiles member No pool CandidateProfilesController.findOwnResume
POST /v1/candidate-profiles/me/resume candidate-profiles member No pool CandidateProfilesController.updateOwnResume
GET /v1/candidate-profiles/me/resume-markdown candidate-profiles member No pool CandidateProfilesController.findOwnResumeMarkdown
GET /v1/candidate-profiles/me/resume-profile-suggestions candidate-profiles member No pool CandidateProfilesController.findOwnResumeProfileSuggestions
GET /v1/candidate-profiles/me/status candidate-profiles member No pool CandidateProfilesController.findOwnStatus
POST /v1/candidate-profiles/resume-prefill candidate-profiles teros-opsteros-ops-admin No ops CandidateProfilesController.prefillFromResume
GET /v1/public/invitation/:token candidate-profiles anonymous Yes pool PublicInvitationController.validateInvitation
POST /v1/public/invitation/:token/redeem candidate-profiles anonymous Yes pool PublicInvitationController.redeemInvitation
GET /v1/public/resume/:token candidate-profiles anonymous Yes ops PublicResumeController.getPublicResume
GET /v1/public/resume/:token/profile-picture candidate-profiles anonymous Yes ops PublicResumeController.getPublicResumeProfilePicture
GET /health health anonymous Yes debug HealthController.check
GET /v1/job-posting-requests job-posting-requests teros-opscompany-admin No ops JobPostingRequestsController.list
POST /v1/job-posting-requests job-posting-requests teros-opscompany-admin No ops JobPostingRequestsController.create
POST /v1/job-posting-requests/:id/disable job-posting-requests teros-opscompany-admin No ops JobPostingRequestsController.disable
GET /v1/public/job-posting-requests/:token job-posting-requests anonymous Yes ops PublicJobPostingRequestsController.get
PATCH /v1/public/job-posting-requests/:token job-posting-requests anonymous Yes ops PublicJobPostingRequestsController.update
POST /v1/public/job-posting-requests/:token/draft job-posting-requests anonymous Yes ops PublicJobPostingRequestsController.draft
POST /v1/public/job-posting-requests/:token/submit job-posting-requests anonymous Yes ops PublicJobPostingRequestsController.submit
GET /v1/job-postings job-postings membercompany-admincompany-memberteros-ops No opspool JobPostingsController.findAll
POST /v1/job-postings job-postings company-adminteros-ops No ops JobPostingsController.create
GET /v1/job-postings/:id job-postings membercompany-admincompany-memberteros-ops No ops JobPostingsController.findOne
PATCH /v1/job-postings/:id job-postings company-adminteros-ops No ops JobPostingsController.update
POST /v1/job-postings/:id/close job-postings company-adminteros-ops No ops JobPostingsController.close
DELETE /v1/job-postings/:id/public-link job-postings company-adminteros-ops No ops JobPostingsController.voidPublicLink
GET /v1/job-postings/:id/public-link job-postings company-adminteros-ops No ops JobPostingsController.findActivePublicLink
POST /v1/job-postings/:id/public-link job-postings company-adminteros-ops No ops JobPostingsController.createPublicLink
GET /v1/public/job-postings/:token job-postings anonymous Yes ops PublicJobPostingsController.getPublicJobPosting
GET /v1/ops-dashboard/metrics ops-dashboard company-admincompany-memberteros-ops No ops OpsDashboardController.metrics
GET /v1/organizations organizations company-admincompany-memberteros-ops No ops OrganizationsController.findAll
POST /v1/organizations organizations teros-ops No ops OrganizationsController.create
DELETE /v1/organizations/:id organizations company-adminteros-ops No OrganizationsController.remove
GET /v1/organizations/:id organizations company-admincompany-memberteros-ops No OrganizationsController.findOne
PATCH /v1/organizations/:id organizations company-adminteros-ops No OrganizationsController.update
GET /v1/organizations/:id/members organizations company-admincompany-memberteros-ops No ops OrganizationsController.findMembers
POST /v1/organizations/:id/sync organizations teros-ops No OrganizationsController.sync
POST /v1/organizations/sync-all organizations teros-ops-admin No ops OrganizationsController.bulkSync
GET /v1/skills skills teros-ops-admin No ops SkillsController.list
PATCH /v1/skills/:id/parent skills teros-ops-admin No ops SkillsController.setParent
POST /v1/skills/approve skills teros-ops-admin No ops SkillsController.approve
POST /v1/skills/normalize skills teros-ops-admin No ops SkillsController.normalize
POST /v1/skills/reject skills teros-ops-admin No ops SkillsController.reject

When a PR changes a controller decorator, this table changes on next build. If a role moves from teros-ops-adminteros-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.