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 <noreply@anthropic.com>
This commit is contained in:
Paul Huliganga 2026-04-21 15:34:06 -04:00
parent b2bbcac842
commit 15c50f05e3
3 changed files with 122 additions and 28 deletions

View File

@ -133,7 +133,7 @@ Then open [http://localhost:8000](http://localhost:8000) in your browser.
### Workflow ### Workflow
1. **Create a project** — the switcher modal opens on first run; name it after the customer. 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: 3. **Review templates** — the Templates view shows readiness badges:
- **Ready** (green) — no issues, safe to migrate - **Ready** (green) — no issues, safe to migrate
- **Caveats** (amber) — warnings exist; migration will proceed but check Issues view - **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 - **Migrated** (cobalt) — successfully migrated and up to date
- **Needs Update** (amber) — Adobe template modified after last migration - **Needs Update** (amber) — Adobe template modified after last migration
4. **Resolve issues** — check Issues & Warnings before migrating blocked templates. 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. 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. **Verify** — on the Verification screen, send test envelopes and confirm receipt. 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. **Audit** — History & Audit logs every migration with checksums and export. 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 ### Project / customer context
@ -157,7 +158,7 @@ Create one project per customer to keep history and settings separate.
## Running tests ## Running tests
```bash ```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 -v # compose regression only
pytest tests/test_regression.py --update-snapshots # regenerate snapshots after intentional changes 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. 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 ## Security
@ -244,6 +261,7 @@ Unsupported features flagged for manual review: conditional HIDE actions, JavaSc
src/ src/
models/ models/
normalized_template.py # Platform-agnostic intermediate schema normalized_template.py # Platform-agnostic intermediate schema
field_issue.py # Structured field-issue model + issue codes
services/ services/
mapping_service.py # Adobe Sign → NormalizedTemplate converter mapping_service.py # Adobe Sign → NormalizedTemplate converter
validation_service.py # Pre/post migration checks (blockers + warnings) validation_service.py # Pre/post migration checks (blockers + warnings)
@ -265,13 +283,34 @@ web/
config.py # Environment-based settings config.py # Environment-based settings
session.py # Signed cookie session helpers session.py # Signed cookie session helpers
routers/ routers/
auth.py # Adobe Sign + DocuSign OAuth endpoints auth.py # Adobe Sign + Docusign OAuth endpoints
templates.py # Template listing + migration status API templates.py # Template listing + migration status API
migrate.py # Migration trigger, batch, + history API migrate.py # Migration trigger, batch, + history API
verify.py # Verification envelope send / status / void
static/ static/
index.html # Web UI (side-by-side browser + migrate flow) index.html # SPA shell (left nav, router outlet, top bar)
app.js # Vanilla JS frontend css/
style.css # Styles + status badge colours 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/ tests/
test_normalized_schema.py # Normalized model + mapping service tests test_normalized_schema.py # Normalized model + mapping service tests
@ -283,8 +322,9 @@ tests/
test_upload_upsert.py # Upsert logic unit tests test_upload_upsert.py # Upsert logic unit tests
test_api_health.py # Health endpoint test_api_health.py # Health endpoint
test_api_auth.py # OAuth endpoint tests 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_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_e2e.py # Full pipeline end-to-end test
test_regression.py # Compose output vs snapshots test_regression.py # Compose output vs snapshots
fixtures/expected/ # Regression snapshots (3 real templates) fixtures/expected/ # Regression snapshots (3 real templates)

View File

@ -1,6 +1,6 @@
# Execution Board (Living Kanban) # 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] Full backend test suite: **118/118 tests passing**
- [x] Update `README.md` — new UI navigation guide, workflow, project context - [x] Update `README.md` — new UI navigation guide, workflow, project context
- [x] Update EXECUTION-BOARD.md — all phases complete - [x] Update EXECUTION-BOARD.md — all phases complete
- [ ] Push `ui-redesign` branch to Gitea - [x] Push `ui-redesign` branch to Gitea
- [ ] Open PR to `master` - [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 813 work (ui-redesign branch, 2026-04-21) - [x] Committed Phase 813 work (ui-redesign branch, 2026-04-21)
- [x] Committed UI mockup + Docusign 2024 brand (ui-redesign branch, 2026-04-21) - [x] Committed UI mockup + Docusign 2024 brand (ui-redesign branch, 2026-04-21)
- [x] Committed Phases 1422 UI implementation (ui-redesign branch, 2026-04-21) - [x] Committed Phases 1422 UI implementation (ui-redesign branch, 2026-04-21)
- [ ] Push ui-redesign branch to Gitea - [x] Pushed ui-redesign branch to Gitea; PR #1 open against master
- [ ] Open PR to master
--- ---
@ -235,3 +266,5 @@
- (2026-04-21) Enterprise UI mockup designed — 8 screens, Docusign 2024 branding, official SVG logo embedded - (2026-04-21) Enterprise UI mockup designed — 8 screens, Docusign 2024 branding, official SVG logo embedded
- (2026-04-21) UI Redesign plan written (Phases 1422) — frontend-only except Phase 16 (readiness data) and Phase 19 (verify API) - (2026-04-21) UI Redesign plan written (Phases 1422) — frontend-only except Phase 16 (readiness data) and Phase 19 (verify API)
- (2026-04-21) Phases 1422 fully implemented — 118/118 tests passing, enterprise UI complete - (2026-04-21) Phases 1422 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

View File

@ -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 `conditionalAction` → DocuSign `conditionalParentLabel` + `conditionalParentValue` on the dependent tab.
| Adobe Sign | DocuSign | Notes | | Adobe Sign | DocuSign | Outcome | Notes |
|-----------------------------------|---------------------------------|-------| |-----------------------------------|---------------------------------|---------|-------|
| `predicates[].fieldName` | `conditionalParentLabel` | For radio groups, matches the group name | | `predicates[].fieldName` | `conditionalParentLabel` | Mapped | For radio groups, matches the group name |
| `predicates[].value` | `conditionalParentValue` | The value the trigger must equal to reveal the tab | | `predicates[].value` | `conditionalParentValue` | Mapped | The value the trigger must equal to reveal the tab |
| `action: SHOW` | Supported | Tab is hidden until condition is met | | `action: SHOW` | Supported | Mapped | Tab is hidden until condition is met |
| `action: HIDE` | **Not supported** | No DocuSign equivalent — condition skipped, field always shown | | `action: HIDE` | **Not supported** | Dropped | No DocuSign equivalent — field always shown. `HIDE_ACTION` issue emitted. |
| `operator: EQUALS` | Supported | Only operator DocuSign supports | | `operator: EQUALS` | Supported | Mapped | Only operator DocuSign supports |
| Other operators | **Not supported** | Condition skipped, warning logged | | Other operators (NOT_EQUALS, etc.)| **Not supported** | Dropped | Condition skipped. `UNSUPPORTED_OPERATOR` issue emitted. |
| Multiple predicates (ANY/ALL) | **Partial** — first EQUALS only | Warning logged; remaining predicates ignored | | 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 ## Known Gaps
- **Conditional HIDE**: Adobe Sign can conditionally hide a field. DocuSign only supports - **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. 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. 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. - **Multi-predicate conditions**: Adobe Sign supports ANY/ALL of multiple predicates.
DocuSign only supports a single parent condition per tab. Only the first EQUALS DocuSign only supports a single parent condition per tab. Only the first EQUALS
predicate is mapped; complex conditions require manual rework. 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. - **DocuSign formula fields**: No Adobe Sign equivalent — flag for manual rewrite.
- **Advanced field validation**: Adobe regex/custom script validation is not mapped; - **Advanced field validation**: Adobe regex/custom script validation is not mapped;
best-effort via standard DocuSign validation types only. 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. DocuSign `radioGroupTabs` entry with per-location radio button coordinates.
- **Stamp tab account feature**: `stampTabs` requires the stamp/hanko feature to be - **Stamp tab account feature**: `stampTabs` requires the stamp/hanko feature to be
enabled on the DocuSign account. Verify before migrating templates that contain 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 ## Field Issue Codes
- Add conditional logic/rule mapping table
- Document field mask and default value transforms 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.