Skip to content

Commit

Permalink
Reconnect accounts
Browse files Browse the repository at this point in the history
  • Loading branch information
pontusab committed Dec 16, 2024
1 parent ddef9c0 commit 220ce23
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 87 deletions.
42 changes: 0 additions & 42 deletions apps/dashboard/jobs/tasks/bank/accounts/update-reference.ts

This file was deleted.

7 changes: 0 additions & 7 deletions apps/dashboard/jobs/tasks/bank/sync/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { logger, schemaTask } from "@trigger.dev/sdk/v3";
import { revalidateCache } from "jobs/utils/revalidate-cache";
import { triggerSequenceAndWait } from "jobs/utils/trigger-sequence";
import { z } from "zod";
import { updateReference } from "../accounts/update-reference";
import { transactionNotifications } from "../notifications/transactions";
import { syncAccount } from "./account";

Expand Down Expand Up @@ -141,12 +140,6 @@ export const syncConnection = schemaTask({
.update({ status: "disconnected" })
.eq("id", connectionId);
}

if (data.provider === "gocardless") {
await updateReference.trigger({
referenceId: data.reference_id,
});
}
} catch (error) {
logger.error("Failed to check connection status by accounts", {
error,
Expand Down
68 changes: 68 additions & 0 deletions apps/dashboard/jobs/tasks/reconnect/connection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { client } from "@midday/engine/client";
import { createClient } from "@midday/supabase/job";
import { schemaTask } from "@trigger.dev/sdk/v3";
import { syncConnection } from "jobs/tasks/bank/sync/connection";
import { z } from "zod";

export const reconnectConnection = schemaTask({
id: "reconnect-connection",
maxDuration: 1000,
retry: {
maxAttempts: 2,
},
schema: z.object({
teamId: z.string().uuid(),
connectionId: z.string().uuid(),
provider: z.string(),
}),
run: async ({ teamId, connectionId, provider }) => {
const supabase = createClient();

if (provider === "gocardless") {
// We need to update the reference of the connection
const connection = await client.connections[":reference"].$get({
param: { reference: teamId },
});

const connectionResponse = await connection.json();
const referenceId = connectionResponse?.data.id;

// Update the reference_id of the new connection
if (referenceId) {
await supabase
.from("bank_connections")
.update({
reference_id: referenceId,
})
.eq("id", connectionId);
}

// The account_ids can be different between the old and new connection
// So we need to check for account_reference and update
const accounts = await client.accounts.$get({
query: {
id: referenceId,
provider: "gocardless",
},
});

const accountsResponse = await accounts.json();

await Promise.all(
accountsResponse.data.map(async (account) => {
await supabase
.from("bank_accounts")
.update({
account_id: account.id,
})
.eq("account_reference", account.resource_id);
}),
);
}

await syncConnection.trigger({
connectionId,
manualSync: true,
});
},
});
5 changes: 4 additions & 1 deletion apps/dashboard/src/actions/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -429,8 +429,11 @@ export const updateEntriesSchema = z.object({

export const manualSyncTransactionsSchema = z.object({
connectionId: z.string().uuid(),
});

export const reconnectConnectionSchema = z.object({
connectionId: z.string().uuid(),
provider: z.string(),
type: z.enum(["reconnect", "sync"]),
});

export const createGoCardLessLinkSchema = z.object({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import { authActionClient } from "@/actions/safe-action";
import { manualSyncTransactionsSchema } from "@/actions/schema";
import { client } from "@midday/engine/client";
import { LogEvents } from "@midday/events/events";
import { syncConnection } from "jobs/tasks/bank/sync/connection";

Expand All @@ -15,36 +14,11 @@ export const manualSyncTransactionsAction = authActionClient
channel: LogEvents.TransactionsManualSync.channel,
},
})
.action(
async ({
parsedInput: { connectionId, provider, type },
ctx: { user, supabase },
}) => {
if (provider === "gocardless" && type === "reconnect") {
// We need to update the reference of the connection
const connection = await client.connections[":reference"].$get({
param: { reference: user.team_id! },
});
.action(async ({ parsedInput: { connectionId } }) => {
const event = await syncConnection.trigger({
connectionId,
manualSync: true,
});

const connectionResponse = await connection.json();

// Update the reference_id of the new connection
// In GoCardLess terms this is the requisition id
if (connectionResponse.data) {
await supabase
.from("bank_connections")
.update({
reference_id: connectionResponse.data.id,
})
.eq("id", connectionId);
}
}

const event = await syncConnection.trigger({
connectionId,
manualSync: true,
});

return event;
},
);
return event;
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"use server";

import { authActionClient } from "@/actions/safe-action";
import { reconnectConnectionSchema } from "@/actions/schema";
import { LogEvents } from "@midday/events/events";
import { reconnectConnection } from "jobs/tasks/reconnect/connection";

export const reconnectConnectionAction = authActionClient
.schema(reconnectConnectionSchema)
.metadata({
name: "reconnect-connection",
track: {
event: LogEvents.ReconnectConnection.name,
channel: LogEvents.ReconnectConnection.channel,
},
})
.action(
async ({ parsedInput: { connectionId, provider }, ctx: { user } }) => {
const event = await reconnectConnection.trigger({
teamId: user.team_id!,
connectionId,
provider,
});

return event;
},
);
27 changes: 23 additions & 4 deletions apps/dashboard/src/components/bank-connections.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client";

import { manualSyncTransactionsAction } from "@/actions/transactions/manual-sync-transactions-action";
import { reconnectConnectionAction } from "@/actions/transactions/reconnect-connection-action";
import { useSyncStatus } from "@/hooks/use-sync-status";
import { connectionStatus } from "@/utils/connection-status";
import {
Expand Down Expand Up @@ -167,6 +168,27 @@ export function BankConnection({ connection }: BankConnectionProps) {
},
});

const reconnectConnection = useAction(reconnectConnectionAction, {
onExecute: () => setSyncing(true),
onSuccess: ({ data }) => {
if (data) {
setRunId(data.id);
setAccessToken(data.publicAccessToken);
}
},
onError: () => {
setSyncing(false);
setRunId(undefined);
setStatus("FAILED");

toast({
duration: 3500,
variant: "error",
title: "Something went wrong please try again.",
});
},
});

useEffect(() => {
if (isSyncing) {
toast({
Expand Down Expand Up @@ -204,19 +226,16 @@ export function BankConnection({ connection }: BankConnectionProps) {
// NOTE: GoCardLess reconnect flow (redirect from API route)
useEffect(() => {
if (params.step === "reconnect" && params.id) {
manualSyncTransactions.execute({
reconnectConnection.execute({
connectionId: params.id,
provider: connection.provider,
type: "reconnect",
});
}
}, [params]);

const handleManualSync = () => {
manualSyncTransactions.execute({
connectionId: connection.id,
provider: connection.provider,
type: "sync",
});
};

Expand Down
4 changes: 4 additions & 0 deletions packages/events/src/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,4 +255,8 @@ export const LogEvents = {
name: "Create Customer Tag",
channel: "customer",
},
ReconnectConnection: {
name: "Reconnect Connection",
channel: "bank",
},
};

0 comments on commit 220ce23

Please sign in to comment.