/** * Enumeration of every business/domain error code the API can return. * * This is the single source of truth for error identification across the * whole monorepo: `apps/api` throws errors carrying one of these codes, * and `apps/web` maps each code to a localized, user-facing label (see * `apps/web/src/services/error-message.service.ts`). Neither side should * ever hardcode a raw error string that the other side has to guess at — * the code is the contract. * * When adding a new failure case in the API: * 1. Add a new member here. * 2. Throw it via `HttpError` (apps/api/src/lib/http-error.ts). * 3. Add its translation in `ErrorMessageService` (apps/web). */ export enum ErrorCode { /** Request body/query failed zod schema validation. */ VALIDATION_ERROR = "VALIDATION_ERROR", /** Signup attempted with an email that already has a profile. */ EMAIL_ALREADY_IN_USE = "EMAIL_ALREADY_IN_USE", /** Login failed — wrong email or wrong password (never say which). */ INVALID_CREDENTIALS = "INVALID_CREDENTIALS", /** Request required a session cookie/JWT that is missing, invalid, or stale. */ NOT_AUTHENTICATED = "NOT_AUTHENTICATED", /** No route/resource matches the request. */ NOT_FOUND = "NOT_FOUND", /** Unexpected/unhandled failure — the catch-all, always logged server-side. */ INTERNAL_ERROR = "INTERNAL_ERROR", } /** * Shape of every JSON error body the API returns, whatever the failure. * Kept intentionally small and stable: `code` is what clients should * branch on, `message` is a human-readable (English, developer-facing) * description useful for logs/debugging — never shown to end users as-is, * since end-user-facing text is localized client-side from `code`. */ export interface ApiErrorResponse { /** Machine-readable error identifier — see {@link ErrorCode}. */ code: ErrorCode; /** Developer-facing description (English). Not localized, not for UI display. */ message: string; /** Present only for VALIDATION_ERROR: per-field error messages from zod. */ details?: Record; }