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:
Matt Ciaccio
2026-04-28 02:22:04 +02:00
parent af2db06244
commit da44e8ecbe
5 changed files with 551 additions and 5 deletions

View File

@@ -27,6 +27,7 @@ export const SETTING_KEYS = {
// Documenso / EOI
documensoApiUrlOverride: 'documenso_api_url_override',
documensoApiKeyOverride: 'documenso_api_key_override',
documensoApiVersionOverride: 'documenso_api_version_override',
documensoEoiTemplateId: 'documenso_eoi_template_id',
eoiDefaultPathway: 'eoi_default_pathway',
@@ -119,18 +120,21 @@ export async function getPortEmailConfig(portId: string): Promise<PortEmailConfi
// ─── Documenso ──────────────────────────────────────────────────────────────
export type EoiPathway = 'documenso-template' | 'inapp';
export type DocumensoApiVersion = 'v1' | 'v2';
export interface PortDocumensoConfig {
apiUrl: string;
apiKey: string;
apiVersion: DocumensoApiVersion;
eoiTemplateId: string | null;
defaultPathway: EoiPathway;
}
export async function getPortDocumensoConfig(portId: string): Promise<PortDocumensoConfig> {
const [apiUrl, apiKey, eoiTemplateId, defaultPathway] = await Promise.all([
const [apiUrl, apiKey, apiVersion, eoiTemplateId, defaultPathway] = await Promise.all([
readSetting<string>(SETTING_KEYS.documensoApiUrlOverride, portId),
readSetting<string>(SETTING_KEYS.documensoApiKeyOverride, portId),
readSetting<DocumensoApiVersion>(SETTING_KEYS.documensoApiVersionOverride, portId),
readSetting<string>(SETTING_KEYS.documensoEoiTemplateId, portId),
readSetting<EoiPathway>(SETTING_KEYS.eoiDefaultPathway, portId),
]);
@@ -138,6 +142,7 @@ export async function getPortDocumensoConfig(portId: string): Promise<PortDocume
return {
apiUrl: apiUrl ?? env.DOCUMENSO_API_URL,
apiKey: apiKey ?? env.DOCUMENSO_API_KEY,
apiVersion: apiVersion ?? env.DOCUMENSO_API_VERSION,
eoiTemplateId: eoiTemplateId ?? null,
defaultPathway: defaultPathway ?? 'documenso-template',
};