# Recruiting — Agent Guidance

Module-level rules and invariants for the Recruiting (ATS) module. Read this before touching any file under `Recruiting/`. For Offers-specific patterns, also read `Offers/CLAUDE.md`.

## Scope

This module = everything under `src/pages/dashboard/Recruiting/`. It includes `Offers/` and the shell `Applicants/` directory. Do **not** look for ATS logic outside this tree.

## Permissions

Every route is wrapped with `PermissionsGuard` using `ROUTE_PERMISSIONS.ATS` in `index.tsx`. Never add fine-grained permission checks inside individual pages — the guard is the single gate.

## Routing

Always use `recruitingRoutes.*` helpers from `routes.ts` when linking or navigating. Never hardcode path strings like `/recruiting/offers/:id`. If a route is missing from `recruitingRoutes`, add it there first.

## Query keys

Always use `jobKeys.*` or `applicantsKeys.*` from `queries.ts`. Never define inline keys like `['jobs', id]` in a hook. When a new query is added, add its key factory to `queries.ts` first.

## Services

All Axios calls belong in `services.ts`. Base URL is `/ats/admin`. Naming: `verb + Resource` (e.g. `createJob`, `getJobPostings`, `updateJobApplicationFormVisibility`). No service calls in components or pages.

## i18n

Primary namespace is `ats`. Always use `useLokaliseTranslation('ats')` or `useLokaliseTranslation(['ats', 'general'])`. Never hardcode user-facing strings.

## Theming

Pages that render HuGo design system components must call `useHuGoTheme()` at the page level. Pair with `useHideHeader()` on screens that take over the full viewport.

## `useUploadFile`

Generic hook — accepts `uploadService` as a parameter. Never hard-wire the upload hook to a specific service function. The hook checks `uploadedFile.status === 'error'` to distinguish success from failure (the service always resolves, never rejects on upload errors).

## Shared table states

Use `TableError`, `TableNoInternetConnection`, `TableSkeleton`, and `CandidatesTableEmptyState` from `components/` — do not create one-off error/loading states for tables.

## `Applicants/` directory

The cross-offer applicants list is a shell — no active features. `Applicants/index.tsx` and `Applicants/hooks/useApplicants.ts` exist but the page is not wired to real data. Do not add features here without a ticket that explicitly activates the section.

## `JobDetailsForm`

Used inside add/edit candidate drawers. It renders the application source selector and pipeline stage selector. Import from `components/JobDetailsForm` — do not recreate these fields inline.
