diff --git a/.changeset/fancy-ends-dance.md b/.changeset/fancy-ends-dance.md new file mode 100644 index 000000000..4435362f1 --- /dev/null +++ b/.changeset/fancy-ends-dance.md @@ -0,0 +1,5 @@ +--- +"@exactly/server": patch +--- + +🐛 handle failed onboarding tasks in manteca diff --git a/server/test/utils/manteca.test.ts b/server/test/utils/manteca.test.ts index 256ae36de..bf3551aaa 100644 --- a/server/test/utils/manteca.test.ts +++ b/server/test/utils/manteca.test.ts @@ -350,6 +350,22 @@ describe("manteca utils", () => { expect(result.status).toBe("NOT_AVAILABLE"); }); + it("returns ONBOARDING when user has failed required tasks", async () => { + vi.spyOn(globalThis, "fetch").mockResolvedValueOnce( + mockFetchResponse({ + ...mockOnboardingUser, + onboarding: { + EMAIL_VALIDATION: { required: true, status: "COMPLETED" }, + IDENTITY_VALIDATION: { required: true, status: "FAILED" }, + }, + }), + ); + + const result = await manteca.getProvider(account, "AR"); + + expect(result.status).toBe("ONBOARDING"); + }); + it("returns NOT_STARTED when user has pending required tasks", async () => { vi.spyOn(globalThis, "fetch").mockResolvedValueOnce( mockFetchResponse({ diff --git a/server/utils/ramps/manteca.ts b/server/utils/ramps/manteca.ts index 1b0c86fcf..ba462b882 100644 --- a/server/utils/ramps/manteca.ts +++ b/server/utils/ramps/manteca.ts @@ -267,10 +267,23 @@ export async function getProvider( if (mantecaUser.status === "INACTIVE") { return { onramp: { currencies: [], cryptoCurrencies: [] }, status: "NOT_AVAILABLE" }; } - const hasPendingTasks = Object.values(mantecaUser.onboarding).some( - (task) => task.required && task.status === "PENDING", - ); - if (hasPendingTasks) { + + if (Object.values(mantecaUser.onboarding).some((task) => task.required && task.status === "FAILED")) { + // TODO handle failed required tasks + withScope((scope) => { + scope.addEventProcessor((event) => { + if (event.exception?.values?.[0]) event.exception.values[0].type = "has failed tasks"; + return event; + }); + captureException(new Error("has failed tasks"), { + level: "warning", + fingerprint: ["{{ default }}", "has failed tasks"], + }); + }); + return { onramp: { currencies, cryptoCurrencies: [] }, status: "ONBOARDING" }; + } + + if (Object.values(mantecaUser.onboarding).some((task) => task.required && task.status === "PENDING")) { withScope((scope) => { scope.addEventProcessor((event) => { if (event.exception?.values?.[0]) event.exception.values[0].type = "has pending tasks"; @@ -279,7 +292,6 @@ export async function getProvider( captureException(new Error("has pending tasks"), { level: "warning", fingerprint: ["{{ default }}", "has pending tasks"], - contexts: { mantecaUser }, }); }); return { onramp: { currencies, cryptoCurrencies: [] }, status: "NOT_STARTED" }; @@ -545,7 +557,7 @@ export const BalancesResponse = object({ updatedAt: string(), }); -const onboardingTaskStatus = ["PENDING", "COMPLETED", "IN_PROGRESS"] as const; +const onboardingTaskStatus = ["COMPLETED", "FAILED", "IN_PROGRESS", "PENDING"] as const; const OnboardingTaskInfo = optional( object({ required: boolean(),