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:
parent
b2bbcac842
commit
15c50f05e3
60
README.md
60
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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue