feat: transaction categorization UX improvements and description matching

Add journal entry preview, human-readable account names, auto-apply VAT,
fallback template suggestions, example prompts, invoice match comparison,
and batch result feedback. Also includes user-description-match extension,
describe/batch-describe API routes, improved AI categorization with multi-
suggestion support, and template embedding search.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-02-24 16:02:06 +01:00
co-authored by Claude Opus 4.6
parent 6cef4e11eb
commit 3e7fa45ed6
40 changed files with 2401 additions and 84 deletions
+2 -2
View File
@@ -11,8 +11,8 @@ describe('sectors registry', () => {
expect(SECTORS.length).toBe(6)
})
it('should have 18 total extensions', () => {
expect(getAllExtensions().length).toBe(19)
it('should have 20 total extensions', () => {
expect(getAllExtensions().length).toBe(20)
})
it('should have unique slugs within each sector', () => {
+2
View File
@@ -24,6 +24,7 @@ import {
BarChart3,
Layers,
Puzzle,
TextSearch,
type LucideIcon,
} from 'lucide-react'
@@ -53,6 +54,7 @@ const ICON_MAP: Record<string, LucideIcon> = {
BarChart3,
Layers,
Puzzle,
TextSearch,
}
export function resolveIcon(name: string): LucideIcon {
+2
View File
@@ -7,6 +7,7 @@ import { neBilagaExtension } from '@/extensions/ne-bilaga'
import { aiChatExtension } from '@/extensions/general/ai-chat'
import { invoiceInboxExtension } from '@/extensions/general/invoice-inbox'
import { calendarExtension } from '@/extensions/general/calendar'
import { userDescriptionMatchExtension } from '@/extensions/general/user-description-match'
import type { Extension } from './types'
// ── Enable Banking (PSD2) — opt-in extension ───────────────────────────
@@ -30,6 +31,7 @@ const FIRST_PARTY_EXTENSIONS: Extension[] = [
aiChatExtension,
invoiceInboxExtension,
calendarExtension,
userDescriptionMatchExtension,
// enableBankingExtension, // Uncomment to activate PSD2 bank sync
]
+12
View File
@@ -94,6 +94,18 @@ export const SECTORS: Sector[] = [
longDescription:
'Se alla fakturadatum och deadlines i en interaktiv kalender med manads-, vecko- och dagsvy.',
},
{
slug: 'user-description-match',
name: 'Beskrivningsmatchning',
sector: 'general',
category: 'operations',
icon: 'TextSearch',
dataPattern: 'core',
readsCoreTables: ['transactions', 'mapping_rules'],
description: 'Matcha transaktioner med egna beskrivningar',
longDescription:
'Beskriv vad en transaktion gäller med egna ord och få smarta bokföringsförslag. Systemet lär sig av dina beskrivningar och applicerar automatiskt på framtida transaktioner från samma leverantör.',
},
{
slug: 'enable-banking',
name: 'Bankintegration (PSD2)',
+1
View File
@@ -16,6 +16,7 @@ const WORKSPACES: Record<WorkspaceKey, ComponentType<WorkspaceComponentProps>> =
'general/invoice-inbox': dynamic(() => import('@/components/extensions/general/InvoiceInboxWorkspace')),
'general/calendar': dynamic(() => import('@/components/extensions/general/CalendarWorkspace')),
'general/enable-banking': dynamic(() => import('@/components/extensions/general/EnableBankingWorkspace')),
'general/user-description-match': dynamic(() => import('@/components/extensions/general/UserDescriptionMatchWorkspace')),
// Restaurant
'restaurant/food-cost': dynamic(() => import('@/components/extensions/restaurant/FoodCostWorkspace')),
'restaurant/earnings-per-liter': dynamic(() => import('@/components/extensions/restaurant/EarningsPerLiterWorkspace')),