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:
Mattsson
2026-03-30 13:20:07 +02:00
committed by GitHub
co-authored by Claude Opus 4.6
parent 8c5b8eaa42
commit 1756af6c5e
9 changed files with 500 additions and 7 deletions
@@ -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)
+25 -6
View File
@@ -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')