feat(import): support Wise balance statements (#1368)
* feat(import): support Wise balance statements * fix(import): fail closed on ambiguous Wise rows * fix(import): guard Wise statement netted-fee assumption with running-balance continuity check Swedish accounting review asked whether balance-statement Total fees is netted into Amount. It is: Running Balance moves by exactly the signed Amount per row, so a separate fee row would double-count the cost. Codify the assumption with a pairwise continuity warning (order-agnostic, chain resets across skipped rows) and document the decision. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(api): cap bank-import validation payload and harden issue assertion CodeRabbit review: bound the VALIDATION_ERROR issues array to 20 entries with issue_count carrying the full total, so a large malformed file cannot balloon the response or log sink. Gate stays format-agnostic on purpose: error severity means do-not-ingest for every parser, and no non-Wise parser emits per-row errors alongside parsed transactions today. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
0510d4c13f
commit
24911abde0
@@ -35,7 +35,8 @@ export default function BankFilePreviewStep({
|
||||
onBack,
|
||||
}: BankFilePreviewStepProps) {
|
||||
const { transactions, stats, issues, date_from, date_to } = parseResult
|
||||
const hasIssues = issues.filter((i) => i.severity === 'error').length > 0
|
||||
const errors = issues.filter((i) => i.severity === 'error')
|
||||
const hasIssues = errors.length > 0
|
||||
const warnings = issues.filter((i) => i.severity === 'warning')
|
||||
// Wise/camt.053 files can mix currencies per row: the parser-level totals
|
||||
// sum across currencies, so income/expenses are grouped per currency here.
|
||||
@@ -190,11 +191,15 @@ export default function BankFilePreviewStep({
|
||||
<CardContent className="pt-6">
|
||||
<div className="flex gap-3">
|
||||
<AlertTriangle className="h-5 w-5 text-destructive flex-shrink-0 mt-0.5" />
|
||||
<div>
|
||||
<div className="min-w-0 space-y-2">
|
||||
<p className="font-medium text-destructive">Filen innehåller fel som förhindrar import</p>
|
||||
<p className="text-sm text-muted-foreground mt-1">
|
||||
Kontrollera felet ovan och försök ladda upp en korrigerad fil.
|
||||
</p>
|
||||
<div className="max-h-32 space-y-1 overflow-y-auto">
|
||||
{errors.map((issue, i) => (
|
||||
<p key={i} className="text-xs text-muted-foreground">
|
||||
Rad {issue.row}: {issue.message}
|
||||
</p>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
|
||||
Reference in New Issue
Block a user