diff --git a/client/components/admin/BankSyncAdminCard.jsx b/client/components/admin/BankSyncAdminCard.jsx
index 1706f3c..e0eb6e3 100644
--- a/client/components/admin/BankSyncAdminCard.jsx
+++ b/client/components/admin/BankSyncAdminCard.jsx
@@ -52,8 +52,8 @@ export default function BankSyncAdminCard() {
toast.error('Sync interval must be between 0.5 and 168 hours.');
return;
}
- if (!Number.isFinite(days) || days < 1 || days > 730) {
- toast.error('Transaction history must be between 1 and 730 days.');
+ if (!Number.isFinite(days) || days < 1 || days > 90) {
+ toast.error('Transaction history must be between 1 and 90 days — SimpleFIN Bridge does not support longer windows.');
return;
}
setSaving(true);
@@ -146,21 +146,21 @@ export default function BankSyncAdminCard() {
{/* Transaction history lookback */}
-
+
Transaction history
- How far back to fetch on first connect. Re-syncs only fetch recent activity.
+ How far back to fetch transactions. Maximum 90 days — this is a hard limit imposed by SimpleFIN Bridge and cannot be exceeded.
setSyncDays(e.target.value)}
+ onChange={e => setSyncDays(Math.min(90, Math.max(1, parseInt(e.target.value, 10) || 90)))}
className="w-20 text-sm text-right"
/>
days
diff --git a/client/components/data/BankSyncSection.jsx b/client/components/data/BankSyncSection.jsx
index 5b0deda..a798470 100644
--- a/client/components/data/BankSyncSection.jsx
+++ b/client/components/data/BankSyncSection.jsx
@@ -184,6 +184,7 @@ function AccountRow({ account, sourceId, expanded, onToggleExpand, onToggleMonit
export default function BankSyncSection({ onConnectionChange }) {
const [enabled, setEnabled] = useState(null);
+ const [syncDays, setSyncDays] = useState(90);
const [connections, setConnections] = useState([]);
const [accountsBySource, setAccountsBySource] = useState({});
const [accountsLoading, setAccountsLoading] = useState({});
@@ -220,6 +221,7 @@ export default function BankSyncSection({ onConnectionChange }) {
api.dataSources({ type: 'provider_sync' }),
]);
setEnabled(status.enabled);
+ setSyncDays(status.sync_days ?? 90);
const conns = Array.isArray(sources) ? sources.filter(s => s.provider === 'simplefin') : [];
setConnections(conns);
onConnectionChange?.(conns[0] || null);
@@ -252,7 +254,11 @@ export default function BankSyncSection({ onConnectionChange }) {
setSyncing(id);
try {
const result = await api.syncDataSource(id);
- toast.success(`Synced — ${result.transactionsNew} new transaction(s).`);
+ if (result.errlist) {
+ toast.warning(`Synced ${result.transactionsNew} new transaction(s), but some connections need attention: ${result.errlist}`);
+ } else {
+ toast.success(`Synced — ${result.transactionsNew} new transaction(s).`);
+ }
await load();
} catch (err) {
toast.error(err.message || 'Sync failed');
@@ -302,10 +308,11 @@ export default function BankSyncSection({ onConnectionChange }) {
}
};
- function isStale(conn) {
- if (!conn.last_error) return false;
- if (!conn.last_sync_at) return true;
- return Date.now() - new Date(conn.last_sync_at).getTime() > 24 * 60 * 60 * 1000;
+ function connWarning(conn) {
+ if (!conn.last_error) return null;
+ if (conn.status === 'error') return { kind: 'error', label: 'Sync error' };
+ // Partial errlist: sync succeeded but some bank connections need attention
+ return { kind: 'partial', label: 'Some connections need attention' };
}
if (enabled === null) {
@@ -338,17 +345,21 @@ export default function BankSyncSection({ onConnectionChange }) {
const accsError = accountsErrorBySource[conn.id];
const monitoredCount = accounts.filter(a => a.monitored).length;
+ const warning = connWarning(conn);
return (