Archestra Backend Development
SkillAI & modelsUse when adding or changing Archestra backend routes, models, services, API request/response schemas, endpoint permissions, or OpenAPI/codegen for the generated API client.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Archestra Backend Development skill
What this skill tells your AI
The instructions your AI receives, as published by archestra-ai/archestra in .agents/skills/archestra-dev-backend/SKILL.md and read by ahel’s review.
Use this skill before changing files under platform/backend/ (except unit tests — see archestra-dev-backend-tests). Run all commands from platform/.
Adding or changing an API endpoint
- Add a
RouteIdentry inplatform/shared/routes.tsand set it as the route schema'soperationId. - Add the route handler (see Route layout and Route conventions below).
- Add the endpoint to
requiredEndpointPermissionsMapinplatform/shared/access-control.ts(see The 403 footgun). - Check the MCP-tool mirror (see below).
- Run codegen, then validation (see Codegen and Validation).
Route layout
- New routes live in per-entity folders:
backend/src/routes/<entity>/<entity>.routes.tsholds ALL of that entity's endpoints; tests are one file per endpoint in the same folder, named<action>.<entity>.route.test.ts(seeroutes/app/for a full example). - Canonical reference: copy the shape of
backend/src/routes/virtual-api-key/virtual-api-key.routes.tsandcreate.virtual-api-key.route.test.ts. - Legacy flat modules (
routes/agent.ts,routes/user.ts, ...) still exist — extend them only for their own entity; new entities get a folder. - Registration is automatic:
registerApiRoutesinbackend/src/server.tsiteratesObject.values(routes)fromroutes/index.ts(androutes/index.ee.tsfor enterprise routes), so the default re-export in the index file is mandatory or the route silently never registers.
The 403 footgun (deny by default)
- Every new endpoint MUST be added to
requiredEndpointPermissionsMapinplatform/shared/access-control.ts, keyed by itsRouteId. The auth middleware (backend/src/auth/fastify-plugin/middleware.ts,isAuthorized) looks the route up byoperationIdand denies with 403 when the entry is missing. - The map is
Partial<Record<RouteId, Permissions>>— NOT compiler-enforced; forgetting it compiles fine and fails at runtime. - An empty entry
{}means "any authenticated user". Match permissions with similar existing routes. - Evaluate RBAC from the database, never from the session-cookie cache — the cookie can carry a stale
activeOrganizationIdsnapshot. Followbackend/src/auth/utils.ts(member role + custom roles resolved via models).
Route conventions
- Plugins are typed as
FastifyPluginAsyncZod(fastify-type-provider-zod); schemas are Zod. - Wrap response schemas with
constructResponseSchemafrom@/typesfor consistent 400/401/403/404/500 responses. - Errors:
throw new ApiError(status, message)(from@/types) only — neverreply.status().send(...); the central error handler formats{ error: { message, type } }. - Routes that pass ordinary API authentication have
request.userandrequest.organizationId— no redundant null checks. Public, webhook, and callback routes exempted inbackend/src/auth/fastify-plugin/middleware.tsfollow their own authentication contracts; the/api/prefix alone is not a guarantee. - Pagination: use
PaginationQuerySchema+createPaginatedResponseSchemafrom@archestra/sharedfor bounded tables needing page counts. For write-hot or unbounded logs, useCursorQuerySchema+createCursorPaginatedResponseSchema; fetchlimit + 1rows and do not calculate totals. - Sorting:
SortingQuerySchemaorcreateSortingQuerySchemafrom@/types.
Data access
- All DB queries go through
backend/src/models/— never inline Drizzle in routes or services. Create a model file for new entities; business logic stays in services. - Batch-load related data to avoid N+1 (e.g.
AgentTeamModel.getTeamsForAgentsinbackend/src/models/agent-team.ts), never per-item queries in a loop. - Entity types come from drizzle-zod (
createSelectSchema/createInsertSchema/createUpdateSchema+z.infer), never hand-written interfaces. See the Database Types section inplatform/AGENTS.md. - Schema changes: use the
archestra-dev-migrationsskill.
MCP-tool mirror
- When an endpoint's request/response schema changes, check for a mirrored
archestra__*tool inbackend/src/archestra-mcp-server/and update itsinputSchemaand handler in sync. - New tools need a
TOOL_PERMISSIONSentry inbackend/src/archestra-mcp-server/rbac.ts— that one IS compile-enforced (Record<ArchestraToolShortName, ...>).
Codegen
After any route/schema change, regenerate and commit the outputs — CI runs pnpm codegen and fails on uncommitted diffs (.github/workflows/on-pull-requests.yml):
pnpm codegen # from platform/: everything (backend openapi + access-control docs + MCP-server docs, shared api-client + theme css, Grafana dashboard variants via python3)
Or piecewise, in this order: cd backend && pnpm codegen (writes the repo-root docs/openapi.json + docs), then cd shared && CODEGEN=true pnpm codegen:api-client. The CODEGEN=true is required: with it, shared/hey-api/openapi-ts.ts reads the committed docs/openapi.json; without it, it hits a live http://localhost:9000/openapi.json and silently ignores the spec you just regenerated.
Validation
pnpm type-check
pnpm lint
pnpm test
cd backend && pnpm knip # runs knip:dev AND knip:production — CI runs both; --production ignores tests, so a test-only export fails it
Adding config / env vars
- Name:
ARCHESTRA_<PRODUCT_AREA>_<THING>. Then: parse/validate inbackend/src/config.ts(+ tests inconfig.test.tsfor custom parsers) → list inplatform/.env.examplewith a comment → document in../docs/pages/platform-deployment.md→ expose viabackend/src/routes/config.ts+useFeature()if the frontend needs it.
Related skills
archestra-dev-backend-tests— unit tests, mocking rules, DB fixtures.archestra-dev-migrations— Drizzle schema and migration changes.archestra-dev-frontend— consuming the regenerated API client.
Signals
- GitHub stars
- 4k
- Forks
- 1k
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
archestra-dev-backend- Source
- github.com/archestra-ai/archestra