From e7b5673439b019dd3447965c1f161d3acef25722 Mon Sep 17 00:00:00 2001 From: Dotta Date: Sat, 7 Nov 2026 20:25:04 -0600 Subject: [PATCH] fix(server): document the company export request body in the API catalog POST /exports and /exports/preview registered no request body, so agents that discover operations through the API catalog sent none. The defaults export only the company and agents, and an agent then told a user that the company had no projects or skills to export. Register companyPortabilityExportSchema and describe the include defaults, as the legacy /export route already does. Co-Authored-By: Claude Opus 5.5 --- server/src/__tests__/openapi-routes.test.ts | 9 +++++++++ server/src/routes/openapi.ts | 12 ++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/server/src/__tests__/openapi-routes.test.ts b/server/src/__tests__/openapi-routes.test.ts index 9dcba27a991..e70b913ba2d 100644 --- a/server/src/__tests__/openapi-routes.test.ts +++ b/server/src/__tests__/openapi-routes.test.ts @@ -331,6 +331,15 @@ function loadSpecRoutes() { } describe("openapi routes", () => { + it("documents the export include body so agents can request projects and skills", () => { + const spec = buildOpenApiSpec(); + for (const path of ["/api/companies/{companyId}/exports", "/api/companies/{companyId}/exports/preview"]) { + const operation = spec.paths[path].post; + const body = operation.requestBody.content["application/json"].schema; + expect(body.properties.include.properties).toMatchObject({ projects: expect.anything(), skills: expect.anything() }); + expect(operation.description).toMatch(/include\.projects/); + } + }); it("documents generic webhook provenance headers and accepted responses without a provider-specific endpoint", () => { const spec = buildOpenApiSpec(); const operation = spec.paths["/api/routine-triggers/public/{publicId}/fire"].post; diff --git a/server/src/routes/openapi.ts b/server/src/routes/openapi.ts index d6745237251..405bfa1f99f 100644 --- a/server/src/routes/openapi.ts +++ b/server/src/routes/openapi.ts @@ -2187,7 +2187,11 @@ registry.registerPath({ path: "/api/companies/{companyId}/exports", tags: ["companies"], summary: "Export company data", - request: { params: z.object({ companyId: z.string() }) }, + description: "Omitting include exports only the company and agents (projects, skills and issues default to false); set include.projects and include.skills for a reusable company setup.", + request: { + params: z.object({ companyId: z.string() }), + body: jsonBody(companyPortabilityExportSchema), + }, responses: { 200: r.ok(), 401: r.unauthorized }, }); @@ -2196,7 +2200,11 @@ registry.registerPath({ path: "/api/companies/{companyId}/exports/preview", tags: ["companies"], summary: "Preview company export", - request: { params: z.object({ companyId: z.string() }) }, + description: "Omitting include exports only the company and agents (projects, skills and issues default to false); set include.projects and include.skills for a reusable company setup.", + request: { + params: z.object({ companyId: z.string() }), + body: jsonBody(companyPortabilityExportSchema), + }, responses: { 200: r.ok(), 401: r.unauthorized }, });