Add bank synchronization features with FinTS support and update dependencies
This commit is contained in:
92
convex/bank/sync.ts
Normal file
92
convex/bank/sync.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
import { action } from "../_generated/server";
|
||||
import { v } from "convex/values";
|
||||
import { internal } from "../_generated/api";
|
||||
import { getAuthUserId } from "@convex-dev/auth/server";
|
||||
import { hasComdirectCredentials } from "./comdirectProvider";
|
||||
import { getFintsConfigStatus } from "./fintsConfig";
|
||||
import type { Doc } from "../_generated/dataModel";
|
||||
|
||||
type CapabilitiesResult = {
|
||||
comdirectRestAvailable: boolean;
|
||||
fintsReady: boolean;
|
||||
fintsMissing: string[];
|
||||
fintsWarnings: string[];
|
||||
useFinTsDirect: boolean;
|
||||
};
|
||||
|
||||
export const getCapabilities = action({
|
||||
args: {},
|
||||
returns: v.object({
|
||||
comdirectRestAvailable: v.boolean(),
|
||||
fintsReady: v.boolean(),
|
||||
fintsMissing: v.array(v.string()),
|
||||
fintsWarnings: v.array(v.string()),
|
||||
useFinTsDirect: v.boolean(),
|
||||
}),
|
||||
handler: async (ctx): Promise<CapabilitiesResult> => {
|
||||
const userId = await getAuthUserId(ctx);
|
||||
if (!userId) throw new Error("Nicht angemeldet");
|
||||
|
||||
const comdirectRestAvailable = hasComdirectCredentials();
|
||||
await ctx.runMutation(internal.bank.internal.upsertBankConfig, {
|
||||
userId,
|
||||
comdirectHasCredentials: comdirectRestAvailable,
|
||||
});
|
||||
|
||||
const bankConfig: Doc<"bankConfig"> | null = await ctx.runQuery(
|
||||
internal.bank.internal.getBankConfig,
|
||||
{ userId },
|
||||
);
|
||||
const preference: "auto" | "comdirect" | "fints" =
|
||||
bankConfig?.providerPreference ?? "auto";
|
||||
const fintsStatus = getFintsConfigStatus({
|
||||
blz: bankConfig?.fints.blz,
|
||||
url: bankConfig?.fints.url,
|
||||
login: bankConfig?.fints.login,
|
||||
productId: bankConfig?.fints.productId,
|
||||
});
|
||||
|
||||
const useFinTsDirect: boolean =
|
||||
preference === "fints" || (preference === "auto" && !comdirectRestAvailable);
|
||||
|
||||
return {
|
||||
comdirectRestAvailable,
|
||||
fintsReady: fintsStatus.ready,
|
||||
fintsMissing: fintsStatus.missing,
|
||||
fintsWarnings: fintsStatus.warnings,
|
||||
useFinTsDirect,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const run = action({
|
||||
args: {
|
||||
from: v.string(),
|
||||
to: v.string(),
|
||||
accountId: v.optional(v.id("accounts")),
|
||||
pin: v.optional(v.string()),
|
||||
},
|
||||
returns: v.object({
|
||||
importedCount: v.number(),
|
||||
skippedCount: v.number(),
|
||||
provider: v.union(v.literal("comdirect"), v.literal("fints")),
|
||||
awaitingTan: v.boolean(),
|
||||
}),
|
||||
handler: async (ctx, args): Promise<{
|
||||
importedCount: number;
|
||||
skippedCount: number;
|
||||
provider: "comdirect" | "fints";
|
||||
awaitingTan: boolean;
|
||||
}> => {
|
||||
const userId = await getAuthUserId(ctx);
|
||||
if (!userId) throw new Error("Nicht angemeldet");
|
||||
|
||||
return await ctx.runAction(internal.bank.orchestrator.runSyncInternal, {
|
||||
userId,
|
||||
from: args.from,
|
||||
to: args.to,
|
||||
accountId: args.accountId,
|
||||
pin: args.pin,
|
||||
});
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user