From 15c50f05e33c114cc5bc8bd4d6628e2dbb967e6e Mon Sep 17 00:00:00 2001 From: Paul Huliganga Date: Tue, 21 Apr 2026 15:34:06 -0400 Subject: [PATCH] docs: update README, field-mapping, and EXECUTION-BOARD for Phase 23 and post-redesign fixes Reflects all implementation from this session: 7 post-redesign bug fixes (routing, polling, branding, verification role names, conditional parent 400s, failure UX, template detail history expand), and Phase 23 structured field issue reporting end-to-end. Test count updated to 119/119. Co-Authored-By: Claude Sonnet 4.6 --- README.md | 60 ++++++++++++++++++++++----- docs/agent-harness/EXECUTION-BOARD.md | 43 ++++++++++++++++--- field-mapping.md | 47 +++++++++++++++------ 3 files changed, 122 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index be5a6bb..e521a55 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,7 @@ Then open [http://localhost:8000](http://localhost:8000) in your browser. ### Workflow 1. **Create a project** — the switcher modal opens on first run; name it after the customer. -2. **Connect platforms** — click the Adobe Sign and DocuSign chips in the top bar. +2. **Connect platforms** — click the Adobe Sign and Docusign chips in the top bar. 3. **Review templates** — the Templates view shows readiness badges: - **Ready** (green) — no issues, safe to migrate - **Caveats** (amber) — warnings exist; migration will proceed but check Issues view @@ -141,9 +141,10 @@ Then open [http://localhost:8000](http://localhost:8000) in your browser. - **Migrated** (cobalt) — successfully migrated and up to date - **Needs Update** (amber) — Adobe template modified after last migration 4. **Resolve issues** — check Issues & Warnings before migrating blocked templates. -5. **Migrate** — select templates, click Migrate Selected, configure options (dry run, overwrite, target folder), monitor progress. -6. **Verify** — on the Verification screen, send test envelopes and confirm receipt. -7. **Audit** — History & Audit logs every migration with checksums and export. +5. **Migrate** — select templates, click Migrate Selected, configure options (dry run, overwrite, target folder), monitor progress. Failed rows show the error inline; a summary hint appears if any templates fail. +6. **Review field issues** — successfully migrated templates may show an amber **partial** badge if features were dropped during migration (e.g. cross-recipient conditionals, unsupported operators). Expand any result row to see grouped field-issue details. +7. **Verify** — on the Verification screen, send test envelopes to confirm templates work end-to-end. Polling checks every 30 seconds and times out after 5 minutes; production deployments should use Docusign Connect (webhooks) instead. +8. **Audit** — History & Audit logs every migration with checksums and export. Rows with field issues show the same grouped breakdown on expand. ### Project / customer context @@ -157,7 +158,7 @@ Create one project per customer to keep history and settings separate. ## Running tests ```bash -pytest tests/ -v # full suite (118 tests) +pytest tests/ -v # full suite (119 tests) pytest tests/test_regression.py -v # compose regression only pytest tests/test_regression.py --update-snapshots # regenerate snapshots after intentional changes ``` @@ -228,6 +229,22 @@ Each template is validated before migration: Unsupported features flagged for manual review: conditional HIDE actions, JavaScript validators, calculated fields, webhook associations, niche authentication methods. +## Field issues (partial migration) + +Beyond blockers and warnings, the compose step emits structured **field issues** when a field migrates successfully but something was silently dropped or approximated. Each issue has a machine-readable code: + +| Code | Meaning | +|---|---| +| `CROSS_RECIPIENT_CONDITIONAL` | Show/hide condition references a field on a different recipient — DocuSign does not support cross-recipient conditional logic | +| `UNSUPPORTED_OPERATOR` | Condition uses NOT_EQUALS / GT / LT etc. — only EQUALS is supported | +| `HIDE_ACTION` | Adobe HIDE condition has no DocuSign equivalent — field will always be visible | +| `MULTI_PREDICATE` | AND/OR multi-condition logic reduced to first EQUALS predicate only | +| `INVALID_PARENT_TAB` | Conditional parent references a non-existent tab or a forbidden tab type (signature/auto-fill tabs cannot be parents) | +| `FIELD_TYPE_SKIPPED` | INLINE_IMAGE or PARTICIPATION_STAMP — no DocuSign equivalent, field dropped | +| `PARTIAL_FIELD_TYPE` | FILE_CHOOSER → signerAttachmentTabs, or STAMP → stampTabs — field migrated but behaviour differs | + +Templates with field issues are marked with a **partial** badge in the UI. Field issues are stored in `field_issues[]` on every migration result record and displayed grouped by code in all result views. + --- ## Security @@ -244,6 +261,7 @@ Unsupported features flagged for manual review: conditional HIDE actions, JavaSc src/ models/ normalized_template.py # Platform-agnostic intermediate schema + field_issue.py # Structured field-issue model + issue codes services/ mapping_service.py # Adobe Sign → NormalizedTemplate converter validation_service.py # Pre/post migration checks (blockers + warnings) @@ -265,13 +283,34 @@ web/ config.py # Environment-based settings session.py # Signed cookie session helpers routers/ - auth.py # Adobe Sign + DocuSign OAuth endpoints + auth.py # Adobe Sign + Docusign OAuth endpoints templates.py # Template listing + migration status API migrate.py # Migration trigger, batch, + history API + verify.py # Verification envelope send / status / void static/ - index.html # Web UI (side-by-side browser + migrate flow) - app.js # Vanilla JS frontend - style.css # Styles + status badge colours + index.html # SPA shell (left nav, router outlet, top bar) + css/ + tokens.css # Docusign 2024 brand custom properties + base.css # Reset, typography, utility classes + nav.css # Left sidebar navigation + cards.css # Cards, badges, result rows, field-issue groups + modals.css # Modal dialogs, migration progress + tables.css # Sortable/filterable tables + forms.css # Form inputs, toggles + js/ + app.js # Entry point — router, auth, nav badges + router.js # Hash-based SPA router (#/templates default) + state.js # Global state with pub/sub + api.js # Fetch wrappers for all backend endpoints + auth.js # Auth chips, OAuth flow, toast notifications + templates.js # Templates view + detail (overview/issues/history tabs) + migration.js # Migration modal, progress polling, results view + issues.js # Issues & Warnings view + verification.js # Verification view (send/poll/void envelopes) + history.js # History & Audit view + settings.js # Settings view + project.js # Project/customer context (localStorage) + utils.js # escHtml, formatDate, renderFieldIssues, etc. tests/ test_normalized_schema.py # Normalized model + mapping service tests @@ -283,8 +322,9 @@ tests/ test_upload_upsert.py # Upsert logic unit tests test_api_health.py # Health endpoint test_api_auth.py # OAuth endpoint tests - test_api_templates.py # Template listing + status tests + test_api_templates.py # Template listing + status tests (10 tests) test_api_migrate.py # Migration API tests + test_api_verify.py # Verification envelope API tests (9 tests) test_e2e.py # Full pipeline end-to-end test test_regression.py # Compose output vs snapshots fixtures/expected/ # Regression snapshots (3 real templates) diff --git a/docs/agent-harness/EXECUTION-BOARD.md b/docs/agent-harness/EXECUTION-BOARD.md index 93aaa72..0710af2 100644 --- a/docs/agent-harness/EXECUTION-BOARD.md +++ b/docs/agent-harness/EXECUTION-BOARD.md @@ -1,6 +1,6 @@ # Execution Board (Living Kanban) -*Last updated: 2026-04-21* +*Last updated: 2026-04-21 (post-redesign bug fixes + Phase 23)* --- @@ -208,8 +208,40 @@ - [x] Full backend test suite: **118/118 tests passing** - [x] Update `README.md` — new UI navigation guide, workflow, project context - [x] Update EXECUTION-BOARD.md — all phases complete -- [ ] Push `ui-redesign` branch to Gitea -- [ ] Open PR to `master` +- [x] Push `ui-redesign` branch to Gitea +- [x] Open PR to `master` + +--- + +## Post-Redesign Bug Fixes ✅ (2026-04-21) + +Bugs discovered during live testing after Phase 22. + +- [x] **Docusign branding** — replaced all "DocuSign" with "Docusign" (2024 brand) across 8 frontend files +- [x] **Template detail routing** — `router.js` `parseHash` used wrong slice indices (`slice(0,3)` instead of `slice(0,2)`), causing `#/templates/:id` to always fall through to the list view +- [x] **Migration polling infinite loop** — `pollJob` only checked `'done'`/`'complete'` but backend emits `'completed'`; migration progress spinner never resolved +- [x] **Verification envelope role names** — hardcoded `roleName: "Signer"` meant envelopes sent without tags; now fetches actual template role names from Docusign API before sending, falls back to `"Signer"` only on fetch failure +- [x] **Verification polling rate** — changed from 5 s to 30 s per Docusign rate-limit guidance; added 5-minute timeout with amber "Timed Out" badge; note: production should use Docusign Connect webhooks +- [x] **CONDITIONALTAB_HAS_INVALID_PARENT (400)** — compose was emitting `conditionalParentLabel` pointing to signature/auto-fill tabs (forbidden as parents) or to fields on different recipients (cross-recipient). Fixed by post-processing strip pass in `_strip_invalid_conditionals` +- [x] **Migration modal failure UX** — failed/blocked rows now show the error message in small red text beneath the template name; completion summary shows count + "select View Results for details" hint +- [x] **Template detail history tab** — migration history rows with errors/blockers/warnings now expand inline (matching History & Audit behaviour) + +--- + +## Phase 23 — Structured Field Issue Reporting ✅ (2026-04-21) + +- [x] `src/models/field_issue.py` — `FieldIssue` dataclass with `code`, `field_name`, `message`, `severity`; 7 named codes: `CROSS_RECIPIENT_CONDITIONAL`, `UNSUPPORTED_OPERATOR`, `HIDE_ACTION`, `MULTI_PREDICATE`, `INVALID_PARENT_TAB`, `FIELD_TYPE_SKIPPED`, `PARTIAL_FIELD_TYPE` +- [x] `src/compose_docusign_template.py` — all warning paths now also emit structured `FieldIssue`; cross-recipient detection added (builds `{field_name → assignee}` map, checks predicate fieldName assignee before applying conditional); return signature changed to `(template, warnings, issues)` +- [x] `web/routers/migrate.py` — captures `field_issues` from compose result; all `_migrate_one` return paths include `field_issues: []` +- [x] `web/static/js/utils.js` — `renderFieldIssues()` groups issues by code in collapsible sections; `bindFieldIssueToggles()` wires expand/collapse +- [x] `web/static/js/migration.js` — results view: ⚠️ icon + amber **partial** badge for success-with-issues; field issue groups in expanded rows +- [x] `web/static/js/history.js` — amber **partial** badge + field issue groups in expanded rows +- [x] `web/static/js/templates.js` — template detail history tab shows field issues with partial badge per record +- [x] `web/static/css/cards.css` — `.field-issues-block`, `.field-issue-group`, `.field-issue-row` styles +- [x] `tests/test_regression.py` — updated for 3-tuple compose return +- [x] `tests/test_api_verify.py` — updated for template role-fetch + added fallback test (9 tests) +- [x] Full test suite: **119/119 tests passing** +- [x] Updated `README.md`, `field-mapping.md`, `EXECUTION-BOARD.md` --- @@ -219,8 +251,7 @@ - [x] Committed Phase 8–13 work (ui-redesign branch, 2026-04-21) - [x] Committed UI mockup + Docusign 2024 brand (ui-redesign branch, 2026-04-21) - [x] Committed Phases 14–22 UI implementation (ui-redesign branch, 2026-04-21) -- [ ] Push ui-redesign branch to Gitea -- [ ] Open PR to master +- [x] Pushed ui-redesign branch to Gitea; PR #1 open against master --- @@ -235,3 +266,5 @@ - (2026-04-21) Enterprise UI mockup designed — 8 screens, Docusign 2024 branding, official SVG logo embedded - (2026-04-21) UI Redesign plan written (Phases 14–22) — frontend-only except Phase 16 (readiness data) and Phase 19 (verify API) - (2026-04-21) Phases 14–22 fully implemented — 118/118 tests passing, enterprise UI complete +- (2026-04-21) Post-redesign live testing found 7 bugs — all fixed (routing, polling, branding, verification role names, conditional parent 400s) +- (2026-04-21) Phase 23 complete — structured field issue reporting end-to-end; 119/119 tests passing; cross-recipient conditional now explicitly detected and described rather than silently producing a 400 diff --git a/field-mapping.md b/field-mapping.md index 8c90ca9..e97b946 100644 --- a/field-mapping.md +++ b/field-mapping.md @@ -84,24 +84,39 @@ Tab types that do not merge (only first location used or handled specially): Adobe Sign `conditionalAction` → DocuSign `conditionalParentLabel` + `conditionalParentValue` on the dependent tab. -| Adobe Sign | DocuSign | Notes | -|-----------------------------------|---------------------------------|-------| -| `predicates[].fieldName` | `conditionalParentLabel` | For radio groups, matches the group name | -| `predicates[].value` | `conditionalParentValue` | The value the trigger must equal to reveal the tab | -| `action: SHOW` | Supported | Tab is hidden until condition is met | -| `action: HIDE` | **Not supported** | No DocuSign equivalent — condition skipped, field always shown | -| `operator: EQUALS` | Supported | Only operator DocuSign supports | -| Other operators | **Not supported** | Condition skipped, warning logged | -| Multiple predicates (ANY/ALL) | **Partial** — first EQUALS only | Warning logged; remaining predicates ignored | +| Adobe Sign | DocuSign | Outcome | Notes | +|-----------------------------------|---------------------------------|---------|-------| +| `predicates[].fieldName` | `conditionalParentLabel` | Mapped | For radio groups, matches the group name | +| `predicates[].value` | `conditionalParentValue` | Mapped | The value the trigger must equal to reveal the tab | +| `action: SHOW` | Supported | Mapped | Tab is hidden until condition is met | +| `action: HIDE` | **Not supported** | Dropped | No DocuSign equivalent — field always shown. `HIDE_ACTION` issue emitted. | +| `operator: EQUALS` | Supported | Mapped | Only operator DocuSign supports | +| Other operators (NOT_EQUALS, etc.)| **Not supported** | Dropped | Condition skipped. `UNSUPPORTED_OPERATOR` issue emitted. | +| Multiple predicates (ANY/ALL) | **Partial** — first EQUALS only | Partial | `MULTI_PREDICATE` issue emitted; remaining predicates ignored | +| Trigger field on a different recipient | **Not supported** | Dropped | DocuSign `conditionalParentLabel` only works within the same recipient's tab set. `CROSS_RECIPIENT_CONDITIONAL` issue emitted. | +| Parent is signature/auto-fill tab | **Not supported** | Stripped | DocuSign forbids signature, initial, dateSign, fullName, email, title tabs as conditional parents. `INVALID_PARENT_TAB` issue emitted. | ## Known Gaps - **Conditional HIDE**: Adobe Sign can conditionally hide a field. DocuSign only supports revealing hidden fields — there is no native way to hide a visible field conditionally. Templates with HIDE conditions will have those fields always visible after migration. + Emits a `HIDE_ACTION` field issue. +- **Cross-recipient conditionals**: Adobe Sign allows field B to appear/hide based on + the value of field A even when A and B belong to different recipients. DocuSign's + `conditionalParentLabel` only works within a single recipient's tab set. + Emits a `CROSS_RECIPIENT_CONDITIONAL` field issue; the condition is dropped. +- **Invalid or forbidden conditional parents**: If the trigger field maps to a signature, + initial, dateSign, fullName, email, or title tab — DocuSign forbids these as conditional + parents and returns `CONDITIONALTAB_HAS_INVALID_PARENT` (400). The compose pipeline + strips these conditions in a post-processing pass and emits an `INVALID_PARENT_TAB` + field issue. - **Multi-predicate conditions**: Adobe Sign supports ANY/ALL of multiple predicates. DocuSign only supports a single parent condition per tab. Only the first EQUALS predicate is mapped; complex conditions require manual rework. + Emits a `MULTI_PREDICATE` field issue. +- **Unsupported operators**: NOT_EQUALS, GT, LT etc. have no DocuSign equivalent. + The condition is dropped. Emits an `UNSUPPORTED_OPERATOR` field issue. - **DocuSign formula fields**: No Adobe Sign equivalent — flag for manual rewrite. - **Advanced field validation**: Adobe regex/custom script validation is not mapped; best-effort via standard DocuSign validation types only. @@ -109,8 +124,14 @@ Adobe Sign `conditionalAction` → DocuSign `conditionalParentLabel` + `conditio DocuSign `radioGroupTabs` entry with per-location radio button coordinates. - **Stamp tab account feature**: `stampTabs` requires the stamp/hanko feature to be enabled on the DocuSign account. Verify before migrating templates that contain - Adobe Sign STAMP fields. + Adobe Sign STAMP fields. Emits a `PARTIAL_FIELD_TYPE` field issue. +- **FILE_CHOOSER → signerAttachmentTabs**: Docusign attachment tabs behave differently + from Adobe file upload fields (different UX, no file type restrictions). + Emits a `PARTIAL_FIELD_TYPE` field issue recommending manual review. -## To Do -- Add conditional logic/rule mapping table -- Document field mask and default value transforms +## Field Issue Codes + +All dropped or approximated features are surfaced as structured `FieldIssue` objects +alongside human-readable warning strings. See `src/models/field_issue.py` for the full +list. The UI groups these by code in collapsed sections within migration result rows, +history rows, and the template detail Issues tab.