fix(import): SIE bulk-delete on service client + provider/reporting/b… (#724)
* fix(import): SIE bulk-delete on service client + provider/reporting/banking fixes Rebuilt branch onto main as a single commit. - import: run SIE bulk-delete RPCs on the service client to escape the 8s statement_timeout; undo_sie_import now takes an explicit actor (p_user_id) so its owner/admin gate works when auth.uid() is NULL on the service client (migration 20260624120000) + pg-real regression test - providers: distinguish missing Fortnox license from expired connection; provider_consent_tokens PK regression test - reports: include unmapped BAS expense groups in the income statement - enable-banking: reconnect closed/expired bank sessions in place - bookkeeping: surface linked invoices as underlag on the verifikat view - scripts: track BL cleanup/diagnostic tooling; data files (*.csv) are git-ignored and consentId is now a required arg with no silent default Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(import): add Cache-Control header to journal entry references response --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
db8983ba9e
commit
43925bc2d3
@@ -23,7 +23,7 @@ interface BankConnectionStatusProps {
|
||||
connection: BankConnection
|
||||
onSync: (connectionId: string) => void
|
||||
onDisconnect: (connectionId: string) => void
|
||||
onReconnect?: (bank: { name: string; country: string }) => void
|
||||
onReconnect?: (connection: BankConnection) => void
|
||||
onManageAccounts?: (connectionId: string) => void
|
||||
isSyncing?: boolean
|
||||
}
|
||||
@@ -132,21 +132,18 @@ export function BankConnectionStatus({
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
{isConnectionExpired && onReconnect && (
|
||||
{(isConnectionExpired || isConnectionError) && onReconnect && (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => onReconnect({
|
||||
name: connection.bank_name,
|
||||
country: (connection.provider as string)?.split('-').pop()?.toUpperCase() || 'SE',
|
||||
})}
|
||||
onClick={() => onReconnect(connection)}
|
||||
>
|
||||
Förnya anslutning
|
||||
</Button>
|
||||
)}
|
||||
{isConnectionError && (
|
||||
<Button
|
||||
variant="outline"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => onSync(connection.id)}
|
||||
disabled={isSyncing}
|
||||
|
||||
@@ -165,6 +165,52 @@ export default function BankingSettingsPanel() {
|
||||
}
|
||||
}
|
||||
|
||||
// Re-authorize an existing connection in place — no disconnect required.
|
||||
// Posts to /connect with the existing connection_id so the server reuses the
|
||||
// same row (revoking the dead session, issuing fresh authorization), then
|
||||
// hands off to the bank's consent screen. The OAuth callback drives the row
|
||||
// back through account selection to active.
|
||||
async function handleReconnect(connection: BankConnection) {
|
||||
if (connectingRef.current) return
|
||||
connectingRef.current = true
|
||||
setIsConnecting(true)
|
||||
setConnectingBankName(connection.bank_name)
|
||||
|
||||
try {
|
||||
const country = (connection.provider as string)?.split('-').pop()?.toUpperCase() || 'SE'
|
||||
const response = await fetch('/api/extensions/ext/enable-banking/connect', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
connection_id: connection.id,
|
||||
aspsp_name: connection.bank_name,
|
||||
aspsp_country: country,
|
||||
}),
|
||||
})
|
||||
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error)
|
||||
}
|
||||
|
||||
window.location.href = data.authorization_url
|
||||
} catch (error) {
|
||||
console.error('[enable-banking] Reconnect flow failed', {
|
||||
message: error instanceof Error ? error.message : String(error),
|
||||
connectionId: connection.id,
|
||||
})
|
||||
toast({
|
||||
title: 'Fel',
|
||||
description: error instanceof Error ? error.message : 'Kunde inte förnya anslutningen',
|
||||
variant: 'destructive',
|
||||
})
|
||||
connectingRef.current = false
|
||||
setIsConnecting(false)
|
||||
setConnectingBankName(null)
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSyncTransactions(connectionId: string) {
|
||||
setSyncingConnectionId(connectionId)
|
||||
|
||||
@@ -214,6 +260,9 @@ export default function BankingSettingsPanel() {
|
||||
variant: 'destructive',
|
||||
})
|
||||
setShowCsvFallback(true)
|
||||
// Refresh so a now-expired connection (e.g. closed PSD2 session) moves
|
||||
// into "Åtgärd krävs" and surfaces the "Förnya anslutning" button.
|
||||
fetchConnections()
|
||||
}
|
||||
|
||||
setSyncingConnectionId(null)
|
||||
@@ -382,7 +431,7 @@ export default function BankingSettingsPanel() {
|
||||
connection={connection}
|
||||
onSync={handleSyncTransactions}
|
||||
onDisconnect={handleDisconnectBank}
|
||||
onReconnect={handleConnectBank}
|
||||
onReconnect={handleReconnect}
|
||||
onManageAccounts={() => setPickerConnectionId(connection.id)}
|
||||
isSyncing={syncingConnectionId === connection.id}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user