BillTracker/services/bankSyncConfigService.cts

111 lines
3.5 KiB
TypeScript
Raw Normal View History

'use strict';
// import required so Node type-strips this .cts (it has no other import).
import type { Db } from '../types/db';
const { getSetting, setSetting } = require('../db/database.cts');
const SYNC_DAYS_MAX = 45; // SimpleFIN Bridge hard limit — requests beyond this return an error
const SYNC_DAYS_EFFECTIVE = 44; // 1-day buffer so request latency never tips over the hard limit
const SYNC_DAYS_DEFAULT = 30; // routine sync window (initial seed always uses SYNC_DAYS_EFFECTIVE)
const SYNC_INTERVAL_DEFAULT = 4; // hours
interface BankSyncConfig {
enabled: boolean;
sync_days: number;
seed_days: number;
sync_days_max: number;
sync_interval_hours: number;
debug_logging: boolean;
}
function getBankSyncConfig(): BankSyncConfig {
const dbValue = getSetting('bank_sync_enabled');
const envValue = process.env.BANK_SYNC_ENABLED;
let enabled: boolean;
if (dbValue !== null && dbValue !== undefined && dbValue !== '') {
enabled = dbValue === 'true';
} else if (envValue !== undefined && envValue !== '') {
enabled = envValue === 'true';
} else {
enabled = false;
}
const syncDaysDb = parseInt(getSetting('simplefin_sync_days') || '', 10);
const syncDaysEnv = parseInt(process.env.SIMPLEFIN_SYNC_DAYS || '', 10);
const rawSyncDays =
Number.isFinite(syncDaysDb) && syncDaysDb > 0
? syncDaysDb
: Number.isFinite(syncDaysEnv) && syncDaysEnv > 0
? syncDaysEnv
: SYNC_DAYS_DEFAULT;
const syncDays = Math.min(rawSyncDays, SYNC_DAYS_EFFECTIVE);
const intervalDb = parseFloat(getSetting('simplefin_sync_interval_hours') || '');
const intervalEnv = parseFloat(process.env.SIMPLEFIN_SYNC_INTERVAL_HOURS || '');
const syncIntervalHours =
Number.isFinite(intervalDb) && intervalDb >= 0.5
? intervalDb
: Number.isFinite(intervalEnv) && intervalEnv >= 0.5
? intervalEnv
: SYNC_INTERVAL_DEFAULT;
const debugDb = getSetting('simplefin_debug_logging');
const debugEnv = process.env.SIMPLEFIN_DEBUG_LOGGING;
const debugLogging = debugDb === 'true' || (!debugDb && debugEnv === 'true');
return {
enabled,
sync_days: syncDays,
seed_days: SYNC_DAYS_EFFECTIVE,
sync_days_max: SYNC_DAYS_MAX,
sync_interval_hours: syncIntervalHours,
debug_logging: debugLogging,
};
}
function setBankSyncEnabled(enabled: boolean): BankSyncConfig {
setSetting('bank_sync_enabled', enabled ? 'true' : 'false');
return getBankSyncConfig();
}
function setSyncIntervalHours(hours: number | string): BankSyncConfig {
const n = parseFloat(hours as string);
if (!Number.isFinite(n) || n < 0.5 || n > 168) {
throw Object.assign(new Error('sync_interval_hours must be between 0.5 and 168'), {
status: 400,
});
}
setSetting('simplefin_sync_interval_hours', String(Math.round(n * 10) / 10));
return getBankSyncConfig();
}
function setSyncDays(days: number | string): BankSyncConfig {
const n = parseInt(days as string, 10);
if (!Number.isFinite(n) || n < 1 || n > SYNC_DAYS_MAX) {
throw Object.assign(
new Error(`sync_days must be between 1 and ${SYNC_DAYS_MAX} (SimpleFIN Bridge hard limit)`),
{ status: 400 },
);
}
setSetting('simplefin_sync_days', String(n));
return getBankSyncConfig();
}
function setDebugLogging(enabled: boolean): BankSyncConfig {
setSetting('simplefin_debug_logging', enabled ? 'true' : 'false');
return getBankSyncConfig();
}
module.exports = {
getBankSyncConfig,
setBankSyncEnabled,
setSyncIntervalHours,
setSyncDays,
setDebugLogging,
SYNC_DAYS_MAX,
SYNC_DAYS_EFFECTIVE,
SYNC_DAYS_DEFAULT,
};