Fix/invoice delivery and payment accounts (#1116)

* fix: reconcile annual reports with final closing entries

* test: cover annual report depreciation and VAT balances

* Merge remote-tracking branch 'origin/main' into fix/usr-fdbck-ch

* fix: show exact invoice delivery details

* fix: use currency account in invoice emails

* fix: address invoice delivery review feedback

* fix: harden invoice delivery and payment accounts

* test: assert RLS-denied zero-row updates

* fix: close remaining invoice compliance gaps

* fix: harden invoice archive authorization

* fix: close invoice delivery review findings

* fix: verify delivery finalization results

* fix: cap combined invoice email recipients

* fix: close final invoice compliance findings

* fix: prevent stale payment account saves

* test: prove invoice delivery isolation

* fix: close invoice privacy review findings

* test: normalize delivery retention dates
This commit is contained in:
Mattsson
2026-07-23 09:54:02 +02:00
committed by GitHub
parent 321e684523
commit 466e55a015
83 changed files with 6619 additions and 671 deletions
+45
View File
@@ -355,6 +355,51 @@ describe('withApiV1: idempotency', () => {
const body = await res.json()
expect(body.error.code).toBe('VALIDATION_ERROR')
})
it('hashes a cloned body and leaves the original readable by the handler', async () => {
mockValidate.mockResolvedValue({
userId: 'user-1',
companyId: 'company-1',
scopes: ['invoices:write'],
mode: 'live',
})
mockServiceClient.mockReturnValue(makeSupabaseStub({ company_id: 'company-1', role: 'owner' }))
mockCheckIdempotency.mockResolvedValue(null)
let observedBody: unknown
const handler = withApiV1(
'invoices.create',
async (request, ctx) => {
observedBody = await request.json()
return ok({ ok: true }, { requestId: ctx.requestId })
},
{ requireScope: 'invoices:write' },
)
const requestBody = { customer_id: 'cust-1', additional_cc: ['copy@example.test'] }
const response = await handler(
makeRequest('https://x.test/api/v1/companies/company-1/invoices', {
method: 'POST',
headers: {
Authorization: 'Bearer gnubok_sk_x',
'Idempotency-Key': 'key-body-readable',
'Content-Type': 'application/json',
},
body: JSON.stringify(requestBody),
}),
companyParams('company-1'),
)
expect(response.status).toBe(200)
expect(observedBody).toEqual(requestBody)
expect(mockCheckIdempotency).toHaveBeenCalledWith(
expect.anything(),
'user-1',
'company-1',
'key-body-readable',
expect.any(String),
)
})
})
describe('withApiV1: dry-run', () => {