feat(documenso): version-aware field placement + void abstractions
Adds DOCUMENSO_API_VERSION env (default v1) plus per-port override. Introduces placeFields, placeDefaultSignatureFields, and voidDocument that hide v1 (per-field POST, pixel coords) vs v2 (bulk POST, percent + fieldMeta) differences. cancelDocument now voids in Documenso first and treats transient void failures as recoverable so the CRM stays the system of record. 16 unit specs cover dispatch, layout math, idempotent 404, and v1 pixel conversion. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -24,6 +24,7 @@ import {
|
||||
createDocument as documensoCreate,
|
||||
sendDocument as documensoSend,
|
||||
downloadSignedPdf,
|
||||
voidDocument as documensoVoid,
|
||||
} from '@/lib/services/documenso-client';
|
||||
import type {
|
||||
CreateDocumentInput,
|
||||
@@ -832,7 +833,20 @@ export async function cancelDocument(
|
||||
throw new ConflictError(`Document is already ${existing.status}`);
|
||||
}
|
||||
|
||||
// PR2 will wire the Documenso void here.
|
||||
// CRM is the system of record for cancellation status. A transient
|
||||
// Documenso failure shouldn't block the user from marking the doc cancelled
|
||||
// here — voidDocument already treats 404 as success, and the periodic
|
||||
// webhook receiver will reconcile if the remote void eventually lands.
|
||||
if (existing.documensoId) {
|
||||
try {
|
||||
await documensoVoid(existing.documensoId, portId);
|
||||
} catch (err) {
|
||||
logger.warn(
|
||||
{ err, documentId, documensoId: existing.documensoId },
|
||||
'Documenso void failed; cancelling locally anyway',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const [updated] = await db
|
||||
.update(documents)
|
||||
|
||||
Reference in New Issue
Block a user