Commit Graph

26 Commits

Author SHA1 Message Date
Paul Huliganga 7912eaf252 Show DocuSign user initials in avatar 2026-04-21 23:22:10 -04:00
Paul Huliganga 2681d7d5ba Show template load errors 2026-04-21 23:18:16 -04:00
Paul Huliganga 90113a6514 Add DocuSign account picker 2026-04-21 23:06:48 -04:00
Paul Huliganga af92aa6c47 Improve account switching controls 2026-04-21 21:48:07 -04:00
Paul Huliganga eb9ce84001 Add multi-user web auth sessions 2026-04-21 21:05:15 -04:00
Paul Huliganga 3be3903986 Switch DocuSign auth to authorization code flow 2026-04-21 16:25:56 -04:00
Paul Huliganga b2bbcac842 feat(issues): structured field-issue reporting throughout migration pipeline
Replaces flat warning strings with machine-readable FieldIssue objects
(code, field_name, message, severity) emitted during compose and surfaced
in all migration result paths via a new field_issues[] key.

Codes: CROSS_RECIPIENT_CONDITIONAL, UNSUPPORTED_OPERATOR, HIDE_ACTION,
MULTI_PREDICATE, INVALID_PARENT_TAB, FIELD_TYPE_SKIPPED, PARTIAL_FIELD_TYPE

Cross-recipient conditional detection: compose now builds a field→assignee
map and flags conditions where the trigger field belongs to a different
recipient — the main cause of the CONDITIONALTAB_HAS_INVALID_PARENT 400.

UI changes:
- Success rows with field_issues show ⚠️ icon + amber "partial" badge
- Results, History & Audit, and Template Detail history tab all show
  field issues grouped by code in collapsible sections within expanded rows

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 15:25:23 -04:00
Paul Huliganga 4f9cb43ac8 feat(templates): expandable failure details in detail history tab
Rows with errors, blockers, or warnings now show a '▶ click for details'
hint and expand inline on click, matching the behaviour in History & Audit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 15:03:18 -04:00
Paul Huliganga 1c5b131f19 feat(migration): show error detail under failed rows and summary hint
Failed/blocked rows now show the error message or first blocker in small
red text below the template name. On completion, if any templates failed
a count + "select View Results for details" hint appears above the footer.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 14:53:50 -04:00
Paul Huliganga 5eee7e0ab4 fix(verify): poll every 30s, timeout at 5 min, show Timed Out badge
DocuSign rate-limit guidance discourages polling more than once per 15 min
in production. For this manual quick-test flow, 30s intervals with a 5-min
ceiling is a reasonable middle ground. Production should migrate to DS Connect
(webhooks). Timed-out envelopes show an amber badge with Send Again action.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 14:51:37 -04:00
Paul Huliganga 5cf415d38a fix(migration): stop polling when job status is 'completed'
Backend returns "completed" but pollJob only checked "done"/"complete",
causing infinite polling and oscillating UI state.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 14:26:28 -04:00
Paul Huliganga e521fd8e58 fix(router): correct parseHash slice indices for detail routes
parts.slice(0,3) was returning the full path as base; should be slice(0,2)
so '#/templates/abc123' yields base='#/templates', param='abc123'.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 14:21:50 -04:00
Paul Huliganga 6f684f330f fix(ui): rebrand DocuSign → Docusign throughout frontend (2024 brand)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 14:19:15 -04:00
Paul Huliganga e9f21b6c6d fix(ui): correct HTTP method for auth connect/disconnect endpoints
GET /api/auth/{adobe,docusign}/connect and /disconnect — not POST.
api.js was calling them with POST, causing 405 Method Not Allowed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 13:59:16 -04:00
Paul Huliganga 17e478e996 feat(ui-phase-21): settings view — verification defaults, migration defaults
Three sections: Verification (test recipient name/email, auto-void timer),
Migration Defaults (overwrite toggle, include documents toggle), Connections
(read-only auth status + account IDs from /api/auth/status). Save writes to
localStorage key 'migrator_settings'. Values pre-read by migration options
modal and verification send dialog.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 11:41:45 -04:00
Paul Huliganga 5bf2cc756a feat(ui-phase-20): history & audit view — filters, pagination, CSV export
Filterable by template name, status (success/error/dry_run/skipped), and
date range. Sortable by all columns. Expandable rows show blockers/warnings.
Checksum displayed as first 8 chars with full hash on hover tooltip.
Client-side CSV export. 50 records per page with prev/next pagination.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 11:41:05 -04:00
Paul Huliganga 11b646d3b7 feat(ui-phase-19): verification — send/status/void API + frontend polling
Backend (web/routers/verify.py): POST /send (creates envelope from template),
GET /status/{id} (polls envelope state), POST /void/{id} (voids test envelope).
Registered in app.py. 7 tests passing.

Frontend (verification.js): table of migrated templates, Send Test button opens
dialog with pre-filled name/email from settings, polling every 5s, per-row
status updates (Sent → Delivered → Verified), Void button for cleanup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 11:40:19 -04:00
Paul Huliganga 329edc39d2 feat(ui-phase-18): issues & warnings view with nav badge
Dedicated view surfacing all templates with blockers (migration will fail)
and warnings (migration with caveats). Each blocker item shows all error
messages; each warning item has a Migrate Anyway button and View Detail link.
Nav badge count driven by state.issueCount (updated when templates load).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 11:38:33 -04:00
Paul Huliganga 587104d520 feat(ui-phase-17): migration workflow — options modal, progress polling, results view
Options modal: dry_run, overwrite_if_exists, include_documents toggles, target
folder input. Launches POST /api/migrate/batch and polls GET /api/migrate/batch/{id}
every 2s with per-template status icons. Results view: 5-stat summary grid,
expandable per-template result rows, CSV export, Verify Templates button.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 11:38:04 -04:00
Paul Huliganga 023c3928f3 feat(ui-phase-16): templates view — readiness badges, filter bar, detail tabs
Backend: add blockers[] and warnings[] to GET /api/templates/status. Calls
validate_template() on downloaded templates; returns empty lists if not
downloaded. 3 new tests (10 total, all passing).

Frontend (templates.js): filterable/sortable table with readiness badges
(Blocked/Caveats/Ready/Migrated/Needs Update), bulk-select toolbar,
per-row migrate/detail buttons, and template detail view with 3 tabs
(Overview, Issues, Migration History).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 11:26:49 -04:00
Paul Huliganga 85f82eaabf feat(ui-phase-15): project switcher — localStorage CRUD, first-run modal
Projects stored in localStorage (key: migrator_projects). CRUD: create,
list, setActive, delete. Switcher modal opens automatically on first run
when no projects exist. Active project name displayed in nav footer and
project button. Deleting a project requires confirmation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 11:24:40 -04:00
Paul Huliganga 516af313a1 feat(ui-phase-14): app shell — Docusign nav, router, state, brand tokens
Replace monolithic app.js/style.css with a modular CSS+JS architecture:

CSS: tokens.css (Docusign 2024 brand tokens), base.css (reset, typography,
buttons, badges, cards, toggles), nav.css (Inkwell sidebar, topbar, auth
chips), cards.css (readiness badges, filter bar, bulk toolbar, issue/result
rows), modals.css (modal shell, options panel, project switcher), tables.css
(sortable headers, pagination, checksum display), forms.css (inputs, setting
rows, connection info).

JS: utils.js (escHtml, formatDate, downloadCsv, uuid), state.js (global
reactive state with pub/sub), api.js (fetch wrappers for all endpoints),
router.js (hash-based SPA router), auth.js (connect/disconnect chips,
Adobe OAuth dialog, toast notifications), app.js (entry point — wires
router, auth, nav badges, project display).

index.html: full app shell with official docusign SVG logo, 7 nav links,
top bar with auth chips, router outlet.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 11:24:06 -04:00
Paul Huliganga c63d49e208 fix: Adobe Sign connects via .env refresh token; restore DocuSign OAuth
- GET /api/auth/adobe/connect: reads ADOBE_REFRESH_TOKEN from .env,
  refreshes the access token, stores in session — no login required
- Falls back to OAuth dialog only if no .env credentials exist
- Restores DocuSign OAuth start/callback endpoints alongside JWT connect
- 33/33 tests passing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 15:27:42 -04:00
Paul Huliganga aa88ba363d fix: DocuSign connects via JWT grant from .env, no browser sign-in
Replaces the DocuSign OAuth redirect flow with a direct JWT grant call
using credentials already in .env (same as the CLI). Clicking
"Connect DocuSign" now calls GET /api/auth/docusign/connect which calls
get_access_token() and stores the result in the session cookie.

No email sign-in required.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 15:24:50 -04:00
Paul Huliganga 1383586d91 fix: use existing Adobe Sign redirect URI (localhost:8080) in web UI
The Adobe Sign OAuth app has https://localhost:8080/callback registered
(same as CLI). The web UI now uses the same manual paste flow:
- GET /api/auth/adobe/url returns the auth URL for the frontend to open
- POST /api/auth/adobe/exchange accepts the full redirect URL the user
  copies after authorizing, extracts the code, exchanges for tokens
- Dialog UI guides user through the 3-step process

DocuSign keeps its standard redirect callback flow unchanged.
31/31 tests passing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 15:20:10 -04:00
Paul Huliganga 51f532f452 feat: idempotent upload + FastAPI web UI with full test coverage
Phase 1 — Idempotent upload:
- upload_docusign_template.py now upserts: PUT if template with same name
  exists (most recently modified), POST otherwise
- --force-create flag to bypass upsert

Phase 2-6 — FastAPI web UI:
- web/app.py: FastAPI app with /health, static file serving
- web/routers/auth.py: Adobe Sign + DocuSign OAuth start/callback/disconnect
- web/routers/templates.py: template listing + migration status badges
  (not_migrated / migrated / needs_update)
- web/routers/migrate.py: POST /api/migrate pipeline + GET /api/migrate/history
- web/static/: vanilla HTML/CSS/JS side-by-side template browser UI

Phase 7 — Tests (29/29 passing):
- test_upload_upsert.py: 4 upsert unit tests
- test_api_health/auth/templates/migrate.py: full API coverage
- test_e2e.py: 7-step full pipeline end-to-end test
- test_regression.py: compose output vs snapshots for 3 real templates
- conftest.py: --update-snapshots CLI option

Docs: IMPLEMENTATION-PLAN.md, updated EXECUTION-BOARD.md + architecture.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 14:47:27 -04:00