Commit Graph

8 Commits

Author SHA1 Message Date
ephraimduncan 88e836ddbc refactor(pdf): deslop AcroForm import cleanup 2026-05-27 00:39:43 +00:00
ephraimduncan 874243700f fix(pdf): stabilize AcroForm imports 2026-05-27 00:16:03 +00:00
ephraimduncan 824117d47e refactor(pdf): move AcroForm import from upload to editor button
Per-product direction: AcroForm widget to Documenso field creation
should not happen automatically on upload. It must be a deliberate,
opt-in action on a draft envelope.

- Revert AcroForm extraction from create-envelope (route) and
  create-envelope-items upload paths. They no longer thread
  acroFormFields into envelope items or run the extractor.

- Stop flattening on upload (flattenForm: false) so widgets survive
  in the stored PDF until the user opts in.

- New tRPC mutation envelope.field.importFromPdf is the single entry
  point. It loads each item's stored PDF, extracts widgets, creates
  Field rows assigned to the first signable recipient (creating a
  placeholder Recipient 1 SIGNER when none exist), flattens the PDF
  in place, swaps documentDataId, and emits FIELD_CREATED audit log
  entries on DOCUMENT envelopes.

- Editor fields panel gains an "Import from PDF form" button next to
  "Detect with AI", gated to DRAFT envelopes. Success toasts the
  count and revalidates the editor.

- Rewrite acroform-import.spec.ts e2e to the new flow: upload
  preserves widgets and creates zero fields; service call creates
  fields, flattens PDF, audits, and cleans up old DocumentData.

- Invert four DOCUMENT-upload assertions in form-flattening.spec.ts
  to match the new preserve-widgets, no-auto-flatten contract.
  Template and template-to-doc flatten behavior is unchanged.
2026-05-22 18:48:08 +00:00
ephraimduncan b8a11df768 feat(pdf): import AcroForm widgets as Documenso fields on upload
Detect AcroForm widgets (text, checkbox, radio, dropdown, signature) at upload
time and reuse their geometry as Documenso fields instead of stripping them via
form.flatten(). Imported fields land in the editor as ordinary Field rows
assigned to the first signable recipient, removing the manual re-placement step
users hit when preparing PDFs in Adobe Acrobat.

Extraction runs before normalizePdf so widget geometry is still readable.
Text fields go through a name+format heuristic that maps DATE/NUMBER/EMAIL/
NAME/INITIALS/TEXT, with AcroForm /AA format actions taking precedence over
name tokens. Coordinates are converted via per-rotation transforms (0/90/180/
270) against the rendered page dimensions; widgets fully off-page are
dropped, partial overlap is clamped. Signed signatures (SignatureField.
isSigned()) are detected and skip both the import and the form flatten so
the signature stays valid. Encrypted PDFs, XFA hybrids, malformed PDFs, and
internal extractor errors all return an empty result with skipReason set so
the upload proceeds untouched.

Every imported field carries fieldMeta.source = 'acroform' (new optional on
ZBaseFieldMeta) for future provenance queries. DOCUMENT envelopes emit a
per-field FIELD_CREATED audit entry matching create-envelope-fields.ts.
Recipient assignment picks the first Recipient with role SIGNER or APPROVER
sorted by (signingOrder asc nulls last, id asc); when no signable recipient
exists, a placeholder Recipient 1 SIGNER is created mirroring the
placeholder-pipeline behaviour.
2026-05-21 04:05:12 +00:00
David Nguyen 8671f269e8 fix: lint project (#2693) 2026-05-08 16:04:22 +10:00
David Nguyen 48fb066b9a feat: allow editing pending envelope titles (#2604) 2026-03-19 14:03:30 +11:00
David Nguyen 0b605d61c6 feat: add envelope pdf replacement (#2602) 2026-03-18 22:53:28 +11:00
David Nguyen 7ea664214a feat: add embedded envelopes (#2564)
## Description

Add envelopes V2 embedded support

---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-03-06 14:11:27 +11:00