fix: SIE import voucher range bugs + remove describe transaction (#161)

* fix: fix SIE import voucher range bugs from multi-tenant migration and remove describe transaction feature

- Fix reserve_voucher_range RPC parameter mismatch (p_user_id → p_company_id) causing duplicate voucher errors
- Fix create-accounts onConflict from user_id to company_id
- Add reserve-then-adjust pattern: pre-reserve voucher range before batch insert, release unused range on partial failure
- Add release_voucher_range DB function for safe rollback
- Remove DescribeTransactionDialog, describe/batch-describe API routes, and related schemas (feature superseded)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address Greptile review — voucher range race condition and orphaned entries

- Add p_reserved_highest upper-bound guard to release_voucher_range to prevent
  rolling back past numbers claimed by concurrent operations
- Move highestInsertedVoucher tracking to after both headers AND lines succeed,
  preventing orphaned journal entries with no lines from being counted as "used"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-04-02 10:48:13 +02:00
committed by GitHub
co-authored by Claude Opus 4.6
parent 197beb1c58
commit 9dceb6285c
12 changed files with 103 additions and 1635 deletions
@@ -6,7 +6,7 @@ import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Checkbox } from '@/components/ui/checkbox'
import { cn, formatCurrency, formatDate } from '@/lib/utils'
import { ArrowUpRight, ArrowDownRight, FileText, Loader2, MessageSquareText, Paperclip } from 'lucide-react'
import { ArrowUpRight, ArrowDownRight, FileText, Loader2, Paperclip } from 'lucide-react'
import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from '@/components/ui/info-tooltip'
import { getAccountName, formatAccountWithName } from '@/lib/bookkeeping/client-account-names'
import { getTemplateById } from '@/lib/bookkeeping/booking-templates'
@@ -26,7 +26,7 @@ interface TransactionInboxCardProps {
onMarkPrivate: (id: string) => void
onOpenMatchDialog: (transaction: TransactionWithInvoice) => void
onOpenCategoryDialog: (transaction: TransactionWithInvoice) => void
onOpenDescribe?: (transaction: TransactionWithInvoice) => void
onOpenQuickReview?: (transaction: TransactionWithInvoice, suggestion: SuggestedCategory) => void
onOpenTemplateReview?: (transaction: TransactionWithInvoice, templateId: string) => void
onToggleSelect: (id: string) => void
@@ -45,7 +45,7 @@ export default function TransactionInboxCard({
onMarkPrivate,
onOpenMatchDialog,
onOpenCategoryDialog,
onOpenDescribe,
onOpenQuickReview,
onOpenTemplateReview,
onToggleSelect,
@@ -239,20 +239,6 @@ export default function TransactionInboxCard({
</Button>
) : null}
{/* Describe transaction */}
{onOpenDescribe && (
<Button
size="sm"
variant="outline"
className="h-9 text-xs"
onClick={() => onOpenDescribe(transaction)}
disabled={isProcessing || isDisabled}
>
<MessageSquareText className="mr-1.5 h-3 w-3" />
Beskriv...
</Button>
)}
{/* Open category dialog / template picker */}
<Button
size="sm"