diff --git a/cli/src/__tests__/company-import-export-e2e.test.ts b/cli/src/__tests__/company-import-export-e2e.test.ts index a2074658..9c141a13 100644 --- a/cli/src/__tests__/company-import-export-e2e.test.ts +++ b/cli/src/__tests__/company-import-export-e2e.test.ts @@ -449,7 +449,7 @@ describe("paperclipai company import/export e2e", () => { ); expect(previewExisting.errors).toEqual([]); - expect(previewExisting.plan.companyAction).toBe("update"); + expect(previewExisting.plan.companyAction).toBe("none"); expect(previewExisting.plan.agentPlans.some((plan) => plan.action === "create")).toBe(true); expect(previewExisting.plan.projectPlans.some((plan) => plan.action === "create")).toBe(true); expect(previewExisting.plan.issuePlans.some((plan) => plan.action === "create")).toBe(true); @@ -474,7 +474,7 @@ describe("paperclipai company import/export e2e", () => { { apiBase, configPath }, ); - expect(importedExisting.company.action).toBe("updated"); + expect(importedExisting.company.action).toBe("unchanged"); expect(importedExisting.agents.some((agent) => agent.action === "created")).toBe(true); const twiceImportedAgents = await api>( diff --git a/cli/src/__tests__/company.test.ts b/cli/src/__tests__/company.test.ts new file mode 100644 index 00000000..acb05d86 --- /dev/null +++ b/cli/src/__tests__/company.test.ts @@ -0,0 +1,50 @@ +import { describe, expect, it } from "vitest"; +import { resolveCompanyImportApiPath } from "../commands/client/company.js"; + +describe("resolveCompanyImportApiPath", () => { + it("uses company-scoped preview route for existing-company dry runs", () => { + expect( + resolveCompanyImportApiPath({ + dryRun: true, + targetMode: "existing_company", + companyId: "company-123", + }), + ).toBe("/api/companies/company-123/imports/preview"); + }); + + it("uses company-scoped apply route for existing-company imports", () => { + expect( + resolveCompanyImportApiPath({ + dryRun: false, + targetMode: "existing_company", + companyId: "company-123", + }), + ).toBe("/api/companies/company-123/imports/apply"); + }); + + it("keeps global routes for new-company imports", () => { + expect( + resolveCompanyImportApiPath({ + dryRun: true, + targetMode: "new_company", + }), + ).toBe("/api/companies/import/preview"); + + expect( + resolveCompanyImportApiPath({ + dryRun: false, + targetMode: "new_company", + }), + ).toBe("/api/companies/import"); + }); + + it("throws when an existing-company import is missing a company id", () => { + expect(() => + resolveCompanyImportApiPath({ + dryRun: true, + targetMode: "existing_company", + companyId: " ", + }) + ).toThrow(/require a companyId/i); + }); +}); diff --git a/cli/src/commands/client/company.ts b/cli/src/commands/client/company.ts index 17824dbd..9ad14fd5 100644 --- a/cli/src/commands/client/company.ts +++ b/cli/src/commands/client/company.ts @@ -114,6 +114,24 @@ function parseCsvValues(input: string | undefined): string[] { return Array.from(new Set(input.split(",").map((part) => part.trim()).filter(Boolean))); } +export function resolveCompanyImportApiPath(input: { + dryRun: boolean; + targetMode: "new_company" | "existing_company"; + companyId?: string | null; +}): string { + if (input.targetMode === "existing_company") { + const companyId = input.companyId?.trim(); + if (!companyId) { + throw new Error("Existing-company imports require a companyId to resolve the API route."); + } + return input.dryRun + ? `/api/companies/${companyId}/imports/preview` + : `/api/companies/${companyId}/imports/apply`; + } + + return input.dryRun ? "/api/companies/import/preview" : "/api/companies/import"; +} + export function isHttpUrl(input: string): boolean { return /^https?:\/\//i.test(input.trim()); } @@ -576,17 +594,19 @@ export function registerCompanyCommands(program: Command): void { agents, collisionStrategy: collision, }; + const importApiPath = resolveCompanyImportApiPath({ + dryRun: Boolean(opts.dryRun), + targetMode: targetPayload.mode, + companyId: targetPayload.mode === "existing_company" ? targetPayload.companyId : null, + }); if (opts.dryRun) { - const preview = await ctx.api.post( - "/api/companies/import/preview", - payload, - ); + const preview = await ctx.api.post(importApiPath, payload); printOutput(preview, { json: ctx.json }); return; } - const imported = await ctx.api.post("/api/companies/import", payload); + const imported = await ctx.api.post(importApiPath, payload); printOutput(imported, { json: ctx.json }); } catch (err) { handleCommandError(err);