Four post-testing bugs fixed: signature field placement coordinate math, delete button clickability, client selector pre-selection with manual email entry, and text fill fallback to drawText for flat PDFs. SUMMARY.md updated with full bug fix documentation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
7.5 KiB
phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, duration, completed
| phase | plan | subsystem | tags | requires | provides | affects | tech-stack | key-files | key-decisions | patterns-established | requirements-completed | duration | completed | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 05-pdf-fill-and-field-mapping | 04 | documents/pdf-fill |
|
|
|
|
|
|
|
|
|
30min | 2026-03-20 |
Phase 5 Plan 04: Human Verification Checkpoint + Bug Fixes Summary
Four bugs found during human testing were fixed: signature field misplacement, unclickable delete button, client selector pre-selection with manual email entry, and text fill data silently dropped from output PDF.
Performance
- Duration: ~30 min (bug fixes after checkpoint)
- Completed: 2026-03-20
- Bugs fixed: 4
- Commits: 3 (Bugs 1+2 in same file, Bugs 3 and 4 separate)
- Files modified: 6 + 1 migration created
Accomplishments
Bug 1 — Signature field placement lands in wrong position (FIXED)
Root cause: renderFields() called containerRef.current?.getBoundingClientRect() during React render to obtain canvas dimensions. containerRect.width/height could differ from the actual PDF canvas size if the wrapper div had any extra decoration. Also, calling getBoundingClientRect() during render is unreliable.
Fix: Used pageInfo.width/height (set from react-pdf's page.onLoadSuccess) as the authoritative rendered canvas dimensions. Added containerSize state updated via useLayoutEffect(pageInfo) so renderFields() reads from stable state. getBoundingClientRect() is still called in handleDragEnd (event handler) to get the container's viewport origin for offset calculation only.
Commit: 126e10d
Bug 2 — Cannot click the x button to delete a signature field (FIXED)
Root cause: dnd-kit's default sensor captured all pointerdown events inside DndContext, including on the delete button.
Fix (two-part):
- Configured
MouseSensor+TouchSensorwithactivationConstraint: { distance: 5 }— drag only activates after 5px movement, so a button click does not start a drag. - Added
onPointerDown={(e) => e.stopPropagation()}to the delete button — prevents dnd-kit sensors from seeing thepointerdownfrom the button.
Field overlay divs now have zIndex: 10 and the button zIndex: 11.
Commit: 126e10d (same file as Bug 1)
Bug 3 — Client selector should default to document's client; allow manual email entry (FIXED)
Root cause: PreparePanel received a single currentClientId prop (resolved assignedClientId ?? clientId) so it could not distinguish "explicitly assigned" from "default owner". No email input existed.
Fix:
page.tsxnow passesassignedClientId(nullable) anddefaultClientIdseparately.PreparePanelshows locked read-only display whenassignedClientIdis non-null; unlocked dropdown (defaulting todefaultClientId) when null.- Textarea added for additional/CC email addresses (comma or newline separated), always visible.
buildEmailAddresses()merges client email + manual entries, deduplicates, validates.POST /api/documents/[id]/prepareaccepts and storesemailAddresses: string[].- Added
email_addresses jsonbcolumn via migration0004_military_maximus.sql(applied).
Commit: 05915aa
Bug 4 — Text fill fields do nothing in the prepared PDF (FIXED)
Root cause: preparePdf() silently caught all AcroForm errors with no fallback. Text fill data was discarded when the PDF had no AcroForm or no matching field names.
Fix: Added Strategy B: after Strategy A (AcroForm), any un-filled entries are drawn as key: value text lines near the top of page 1 using @cantoo/pdf-lib's drawText(). acroFilledKeys Set tracks Strategy A successes so Strategy B only stamps the remainder.
Commit: ef10dd5
Task Commits
| Commit | Description | Bugs |
|---|---|---|
126e10d |
fix(05-04): fix signature field placement coordinate math | 1, 2 |
05915aa |
fix(05-04): pre-select document client and add manual email entry | 3 |
ef10dd5 |
fix(05-04): always stamp text fill data into prepared PDF | 4 |
Files Created/Modified
| File | Change |
|---|---|
FieldPlacer.tsx |
Coordinate math, sensor config, delete button guard |
PreparePanel.tsx |
Locked client, manual email textarea, emailAddresses |
page.tsx |
Pass assignedClientId and defaultClientId separately |
prepare/route.ts |
Accept and store emailAddresses array |
prepare-document.ts |
Strategy B drawText fallback for text fill |
schema.ts |
Added emailAddresses jsonb field |
0004_military_maximus.sql |
New migration: email_addresses column |
Deviations from Plan
None — these were continuation bug fixes from human testing, not plan deviations.