* 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
45 lines
1.5 KiB
TypeScript
45 lines
1.5 KiB
TypeScript
/**
|
|
* Guard against schema-strictness regression on MCP tool inputs.
|
|
*
|
|
* Every tool's `inputSchema` must declare `additionalProperties: false` so
|
|
* agents receive a clear rejection on typos/hallucinated fields instead of a
|
|
* silent ignore. This is item 8 of the agent-native API plan
|
|
* (dev_docs/api_ai_architecture/PLAN.md).
|
|
*
|
|
* If this test fires on a newly authored tool, add the field to the tool's
|
|
* top-level inputSchema. Don't relax the guard.
|
|
*/
|
|
import { describe, it, expect } from 'vitest'
|
|
import { tools } from '../server'
|
|
import { TOOL_SCOPE_MAP } from '@/lib/auth/api-keys'
|
|
import { isTenantWriteScope } from '../company-routing'
|
|
|
|
describe('MCP tool inputSchema strictness', () => {
|
|
it('every tool inputSchema has additionalProperties: false at the top level', () => {
|
|
const missing = tools
|
|
.filter((t) => {
|
|
const schema = t.inputSchema as Record<string, unknown> | undefined
|
|
return !schema || schema.additionalProperties !== false
|
|
})
|
|
.map((t) => t.name)
|
|
expect(missing).toEqual([])
|
|
})
|
|
|
|
it('every tenant write tool has a scope that the central role guard can classify', () => {
|
|
const allowedNonTenantWrites = new Set([
|
|
'gnubok_audit_package',
|
|
'gnubok_feedback',
|
|
])
|
|
const missing = tools
|
|
.filter(
|
|
(tool) =>
|
|
tool.annotations.readOnlyHint !== true &&
|
|
!isTenantWriteScope(TOOL_SCOPE_MAP[tool.name]) &&
|
|
!allowedNonTenantWrites.has(tool.name)
|
|
)
|
|
.map((tool) => tool.name)
|
|
|
|
expect(missing).toEqual([])
|
|
})
|
|
})
|