Eb and skills (#152)
* fix: improve date filter UX with partial dates and Apply button (GNU-18) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: enhance banking settings with connection handling and integrity checks --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
8c5b8eaa42
commit
1756af6c5e
@@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import { useState, useEffect } from 'react'
|
||||
import { useState, useEffect, useRef } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Button } from '@/components/ui/button'
|
||||
@@ -26,6 +26,7 @@ export default function BankingSettingsPanel() {
|
||||
const [syncingConnectionId, setSyncingConnectionId] = useState<string | null>(null)
|
||||
const [isConnecting, setIsConnecting] = useState(false)
|
||||
const [connectingBankName, setConnectingBankName] = useState<string | null>(null)
|
||||
const connectingRef = useRef(false)
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
const [showCsvFallback, setShowCsvFallback] = useState(false)
|
||||
|
||||
@@ -49,6 +50,8 @@ export default function BankingSettingsPanel() {
|
||||
}
|
||||
|
||||
async function handleConnectBank(bank: Bank) {
|
||||
if (connectingRef.current) return
|
||||
connectingRef.current = true
|
||||
setIsConnecting(true)
|
||||
setConnectingBankName(bank.name)
|
||||
|
||||
@@ -92,6 +95,7 @@ export default function BankingSettingsPanel() {
|
||||
description: error instanceof Error ? error.message : 'Kunde inte ansluta bank',
|
||||
variant: 'destructive',
|
||||
})
|
||||
connectingRef.current = false
|
||||
setIsConnecting(false)
|
||||
setConnectingBankName(null)
|
||||
setShowCsvFallback(true)
|
||||
|
||||
@@ -101,18 +101,37 @@ export const enableBankingExtension: Extension = {
|
||||
psu_type: psuType,
|
||||
})
|
||||
|
||||
// Clean up any stale pending connections for this user+bank
|
||||
// to avoid conflicts with the new authorization
|
||||
const { data: staleConnections } = await supabase
|
||||
// Reject if there's already a recent pending connection for this user+bank
|
||||
// to prevent double-click race conditions that confuse the bank's consent flow
|
||||
const { data: recentPending } = await supabase
|
||||
.from('bank_connections')
|
||||
.select('id')
|
||||
.select('id, created_at')
|
||||
.eq('user_id', user.id)
|
||||
.eq('bank_name', aspsp_name)
|
||||
.eq('status', 'pending')
|
||||
.order('created_at', { ascending: false })
|
||||
.limit(1)
|
||||
.maybeSingle()
|
||||
|
||||
if (staleConnections && staleConnections.length > 0) {
|
||||
if (recentPending) {
|
||||
const pendingAge = Date.now() - new Date(recentPending.created_at).getTime()
|
||||
const STALE_THRESHOLD_MS = 5 * 60 * 1000 // 5 minutes
|
||||
|
||||
if (pendingAge < STALE_THRESHOLD_MS) {
|
||||
log.info('[enable-banking] Rejecting duplicate connect — recent pending exists', {
|
||||
existing_id: recentPending.id,
|
||||
age_ms: pendingAge,
|
||||
})
|
||||
return NextResponse.json(
|
||||
{ error: 'En anslutning pågår redan. Vänta och försök igen.' },
|
||||
{ status: 409 }
|
||||
)
|
||||
}
|
||||
|
||||
// Clean up stale pending connections (older than threshold)
|
||||
log.info('[enable-banking] Cleaning up stale pending connections', {
|
||||
count: staleConnections.length,
|
||||
stale_id: recentPending.id,
|
||||
age_ms: pendingAge,
|
||||
})
|
||||
await supabase
|
||||
.from('bank_connections')
|
||||
|
||||
Reference in New Issue
Block a user