fix(documents): idempotency, perf, contract pipeline, observability

- A1: idempotency gate in handleDocumentCompleted (prevents duplicate files on Documenso retry)
- A3: LEFT JOIN port_id move to outer WHERE (uses idx_docs_signed_file_id)
- G-C5: contract_sent / contract_signed auto-advance triggers in sendDocument + handleDocumentCompleted
- 0-byte signed PDF guard before storage.put
- portId in outer catch + poll worker
- Sanitize storagePath/storageBucket in aggregated files API
- Audit log for handleDocumentCompleted file insert
- Replace em-dashes in aggregated group labels with colons
- G-I6: delete orphaned hub-counts route + getHubTabCounts service fn

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-11 13:56:46 +02:00
parent c0e5af8b92
commit c761b4b911
6 changed files with 138 additions and 123 deletions

View File

@@ -4,16 +4,19 @@
* Verifies that:
* - `listDocuments` with tab='eoi_queue' returns only EOI docs in
* draft/sent/partially_signed status
* - `getHubTabCounts` reports the correct eoi_queue count
* - Other doc types (NDA, contract, welcome_letter) are excluded
* - Completed/expired EOIs are excluded (those belong to other tabs)
*
* (Note: `getHubTabCounts` and the /hub-counts route were removed when the
* hub rebuild dropped the count-strip KPI surface — the count assertions
* that used to live here went with them.)
*/
import { describe, it, expect } from 'vitest';
import { db } from '@/lib/db';
import { documents } from '@/lib/db/schema/documents';
import { getHubTabCounts, listDocuments } from '@/lib/services/documents.service';
import { listDocuments } from '@/lib/services/documents.service';
import { makePort, makeClient } from '../helpers/factories';
describe('documents hub — eoi_queue tab', () => {
@@ -84,43 +87,6 @@ describe('documents hub — eoi_queue tab', () => {
expect(docs.every((d) => ['sent', 'partially_signed'].includes(d.status))).toBe(true);
});
it('reports the correct eoi_queue count via getHubTabCounts', async () => {
const port = await makePort();
const client = await makeClient({ portId: port.id });
await db.insert(documents).values([
{
portId: port.id,
clientId: client.id,
documentType: 'eoi',
title: 'EOI A',
status: 'draft',
createdBy: 'seed',
},
{
portId: port.id,
clientId: client.id,
documentType: 'eoi',
title: 'EOI B',
status: 'sent',
createdBy: 'seed',
},
{
portId: port.id,
clientId: client.id,
documentType: 'contract',
title: 'Contract X',
status: 'sent',
createdBy: 'seed',
},
]);
const counts = await getHubTabCounts(port.id, undefined);
expect(counts.eoi_queue).toBe(2);
// The contract should not bump eoi_queue.
expect(counts.all).toBe(3);
});
it('returns an empty list when no in-flight EOIs exist', async () => {
const port = await makePort();
const client = await makeClient({ portId: port.id });
@@ -146,8 +112,5 @@ describe('documents hub — eoi_queue tab', () => {
{},
);
expect(result.data).toHaveLength(0);
const counts = await getHubTabCounts(port.id, undefined);
expect(counts.eoi_queue).toBe(0);
});
});