--- description: Every API route checks company access and actor permissions, logs mutations to the activity log, and returns consistent HTTP errors. globs: "server/src/routes/**" alwaysApply: false --- # API route expectations ## Scope and purpose This rule applies to new or changed HTTP routes under `server/src/routes/`. Paperclip is a multi-company control plane, so each route must keep one company's data away from another company's actors. ## Auth model - The base path is `/api`. - Board access is treated as full-control operator context. - Agent access uses bearer API keys (`agent_api_keys`), hashed at rest. - Agent keys must not access other companies. ## Requirements When you add or change an endpoint: - Apply company access checks. Use the helpers in `server/src/routes/authz.ts`, such as `assertCompanyAccess`, instead of a new check. - Enforce actor permissions (board vs agent), for example with `assertBoard` or `assertBoardOrAgent`. - Write an activity log entry for each mutation. - Return consistent HTTP errors (`400/401/403/404/409/422/500`). The API reference for callers is in `docs/api/`. Update it when a public endpoint changes. ## Review criteria Flag a route that reads or writes company data without a company access check. Flag a route that lets an agent key reach another company. Flag a mutation with no activity log entry. Flag an error response outside the status codes above or an error that hides a failure behind a success status.