Fix/supp ag fb (#1023)
* fix: prevent credit notes from entering payment flow * fix: persist and display customer personal numbers * feat: configure automatic invoice reminder days * fix: issue credit notes through send flow * chore: add repository agent guidance * feat(mcp): route tools across user companies * fix(articles): delete unused register entries * feat(invoices): improve issued invoice actions * feat(supplier-invoices): retain uploaded source documents * docs: record implementation decisions * feat: enhance customer personal number handling and validation - Updated CustomerForm to allow personal numbers in the format of "********-1234" for individual customers. - Added validation to ensure personal numbers are only accepted for individual customers in CreateCustomerSchema. - Implemented masking and encryption for personal numbers to enhance data protection. - Introduced new utility functions for masking and encrypting personal numbers. - Added database migration to enforce unique constraints on credit note relationships and prevent duplicate entries. - Enhanced error handling and logging for credit note issuance and invoice processing. - Updated tests to cover new credit note creation guards and personal number handling. * test: enhance list companies test with supabase query mocks
This commit is contained in:
@@ -26,6 +26,7 @@ const PERSISTED_EVENT_TYPES: CoreEventType[] = [
|
||||
'period.locked',
|
||||
'period.year_closed',
|
||||
'customer.created',
|
||||
'article.deleted',
|
||||
'supplier.created',
|
||||
'receipt.matched',
|
||||
'receipt.confirmed',
|
||||
@@ -98,6 +99,9 @@ function extractEntityId(payload: Record<string, unknown>): string | null {
|
||||
if (typeof payload.invoiceId === 'string') {
|
||||
return payload.invoiceId
|
||||
}
|
||||
if (typeof payload.articleId === 'string') {
|
||||
return payload.articleId
|
||||
}
|
||||
|
||||
// For journal_entry.corrected: use the corrected entry's ID
|
||||
if ('corrected' in payload) {
|
||||
|
||||
+2
-1
@@ -87,6 +87,7 @@ export type CoreEvent =
|
||||
// Articles (artikelregister)
|
||||
| { type: 'article.created'; payload: { article: Article; userId: string; companyId: string } }
|
||||
| { type: 'article.updated'; payload: { article: Article; userId: string; companyId: string } }
|
||||
| { type: 'article.deleted'; payload: { articleId: string; userId: string; companyId: string } }
|
||||
// Suppliers
|
||||
| { type: 'supplier.created'; payload: { supplier: Supplier; userId: string; companyId: string } }
|
||||
// Receipts
|
||||
@@ -174,7 +175,7 @@ export type CoreEvent =
|
||||
success: boolean // true iff the tool returned without throwing AND was invoked (not denied)
|
||||
isError: boolean // matches the JSON-RPC tool-result isError flag returned to the client
|
||||
errorCode: string | null // structured error code from tool-result.toToolError when applicable
|
||||
errorKind: 'execution' | 'scope_denied' | 'capability_denied' | 'unknown_tool' | 'test_key_write_blocked' | null
|
||||
errorKind: 'execution' | 'scope_denied' | 'capability_denied' | 'company_access_denied' | 'unknown_tool' | 'test_key_write_blocked' | null
|
||||
errorMessage: string | null // human-readable error message (truncated to 500 chars), null on success.
|
||||
// Raw material for clustering real agent failures into curated gotchas:
|
||||
// errorCode alone can't distinguish "period locked" from "unbalanced".
|
||||
|
||||
Reference in New Issue
Block a user