feat: payment matching audit trail and partial payments (#89)
* feat: payment matching audit trail, partial payments, and match improvements - Add payment_match_log table (append-only audit trail per BFL 7:1) with immutability triggers and proper RLS - Add invoice_payments table for partial payment tracking, mirroring supplier_invoice_payments pattern - Add remaining_amount column + partially_paid status to invoices - Add match-log.ts service for recording match/unmatch state transitions - Improve match-invoice route: support partial payments, record audit log, emit payment.matched events, handle storno conflicts - Improve match-supplier-invoice route: audit logging, partial payment support - Update invoice-entries.ts for partial payment journal entries - Update transaction ingest to detect and auto-suggest invoice matches - Update bank-reconciliation to handle partial payment state - Add invoice_payments, payment_match_log types and helpers - Extend tests for match-invoice route and transaction ingest Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address review feedback — payment matching correctness bugs - P1: Return 500 on non-23505 payment insert failures instead of silently continuing with corrupted invoice state (both routes) - P1: Fix foreign-currency partial payment matching — use proportional remaining SEK amount instead of full total_sek - P2: Check error when clearing journal_entry_id after storno - P2: Add updated_at column + trigger to invoice_payments table - P2: Make supplier_invoice_payments.user_id NOT NULL after backfill 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:
co-authored by
Claude Opus 4.6
parent
fdcc94102a
commit
7c3518a080
+22
-1
@@ -32,7 +32,7 @@ export type CustomerType =
|
||||
| 'non_eu_business' // Non-EU company
|
||||
|
||||
// Invoice status
|
||||
export type InvoiceStatus = 'draft' | 'sent' | 'paid' | 'overdue' | 'cancelled' | 'credited'
|
||||
export type InvoiceStatus = 'draft' | 'sent' | 'paid' | 'partially_paid' | 'overdue' | 'cancelled' | 'credited'
|
||||
|
||||
// Invoice document type
|
||||
export type InvoiceDocumentType = 'invoice' | 'proforma' | 'delivery_note'
|
||||
@@ -438,6 +438,25 @@ export interface SupplierInvoicePayment {
|
||||
created_at: string
|
||||
}
|
||||
|
||||
// Invoice Payment (partial payments)
|
||||
export interface InvoicePayment {
|
||||
id: string
|
||||
user_id: string
|
||||
invoice_id: string
|
||||
|
||||
payment_date: string
|
||||
amount: number
|
||||
currency: string
|
||||
exchange_rate: number | null
|
||||
exchange_rate_difference: number
|
||||
|
||||
journal_entry_id: string | null
|
||||
transaction_id: string | null
|
||||
notes: string | null
|
||||
|
||||
created_at: string
|
||||
}
|
||||
|
||||
// Invoice
|
||||
export interface Invoice {
|
||||
id: string
|
||||
@@ -498,6 +517,7 @@ export interface Invoice {
|
||||
// Payment tracking
|
||||
paid_at: string | null
|
||||
paid_amount: number | null
|
||||
remaining_amount: number
|
||||
|
||||
created_at: string
|
||||
updated_at: string
|
||||
@@ -505,6 +525,7 @@ export interface Invoice {
|
||||
// Relations (populated when fetched)
|
||||
customer?: Customer
|
||||
items?: InvoiceItem[]
|
||||
payments?: InvoicePayment[]
|
||||
}
|
||||
|
||||
// Invoice Item
|
||||
|
||||
Reference in New Issue
Block a user