From 89382537b1e846d6e7afa6fabe9d4aa4991f5eac Mon Sep 17 00:00:00 2001 From: Paul Huliganga Date: Tue, 21 Apr 2026 10:37:46 -0400 Subject: [PATCH] =?UTF-8?q?docs(ui-redesign):=20implementation=20plan=20fo?= =?UTF-8?q?r=20Phases=2014=E2=80=9322=20+=20execution=20board=20update?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Full UI redesign plan covering 9 phases: app shell, project/customer context, templates view with readiness badges, migration workflow, issues view, verification (with new verify API), history/audit, settings, and smoke test checklist. Only backend additions are Phase 16 (blockers/warnings in status endpoint) and Phase 19 (verify router). All other phases are frontend-only. Co-Authored-By: Claude Sonnet 4.6 --- docs/UI-REDESIGN-PLAN.md | 573 ++++++++++++++++++++++++++ docs/agent-harness/EXECUTION-BOARD.md | 68 ++- 2 files changed, 640 insertions(+), 1 deletion(-) create mode 100644 docs/UI-REDESIGN-PLAN.md diff --git a/docs/UI-REDESIGN-PLAN.md b/docs/UI-REDESIGN-PLAN.md new file mode 100644 index 0000000..a34ad00 --- /dev/null +++ b/docs/UI-REDESIGN-PLAN.md @@ -0,0 +1,573 @@ +# UI Redesign — Implementation Plan + +*Branch: `ui-redesign` | Last updated: 2026-04-21* + +--- + +## Overview + +Replace the basic Phase 6 single-page app (`web/static/`) with the enterprise-grade +migration console designed in `docs/ui-mockup/mockup.html`. + +The backend is complete (Phases 8–13, 108/108 tests passing). All new UI phases are +**frontend-only** unless noted. Existing FastAPI routes do not change except where +noted under Phase 16 (readiness data) and Phase 19 (Verification API). + +### Design reference + +Open `docs/ui-mockup/mockup.html` in a browser to see all 8 screens before starting. + +### Docusign 2024 brand tokens + +| Token | Value | Usage | +|---|---|---| +| Cobalt | `#4C00FF` | Primary CTA, active nav highlight | +| Inkwell | `#130032` | Left nav background | +| Ecru | `#F8F3F0` | Page background | +| Poppy | `#FF5252` | Error / Blocked badge | +| Slate | `#6B6B9A` | Secondary text, muted labels | +| White | `#FFFFFF` | Card surfaces | + +Typography: `Inter` (Google Fonts), fallback `-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`. + +--- + +## Current state + +`web/static/` — three files, ~600 lines total: +- `index.html` — 79 lines, single-page layout (header, two panels, history table) +- `app.js` — 343 lines, vanilla JS (auth, template list, migrate, history) +- `style.css` — 186 lines, basic styles, non-Docusign colours + +--- + +## File structure after redesign + +Keep no-build-step approach (vanilla JS ES modules, no bundler). Split monolith into +logical files served statically by FastAPI. + +``` +web/static/ + index.html # app shell (nav, router outlet, modals) + css/ + tokens.css # CSS custom properties (brand colours, spacing) + base.css # reset, typography, utility classes + nav.css # left sidebar nav + top bar + cards.css # template cards, readiness badges + modals.css # dialog / modal styles + tables.css # history and audit tables + forms.css # settings form inputs + js/ + state.js # global app state (project, auth, templates) + router.js # hash-based client-side router + api.js # thin fetch wrappers for all backend endpoints + auth.js # auth status, connect/disconnect, Adobe dialog + project.js # project switcher modal, project CRUD (localStorage) + templates.js # template list view, readiness badges, filters + migration.js # options modal, progress polling, results view + verification.js # send test envelope, poll status + history.js # history & audit view + settings.js # settings screen + utils.js # escHtml, formatDate, debounce, etc. +``` + +`app.js` and `style.css` are **deleted** (replaced by the above). +`index.html` is **rewritten** as the app shell. + +--- + +## Phase 14 — App Shell & Navigation + +**Goal:** Branded shell that all other views live inside. No functional logic yet — +just the frame, router, and state container. + +### index.html structure + +```html + + +
+
+
+
+ + + +``` + +### css/tokens.css + +```css +:root { + --cobalt: #4C00FF; + --inkwell: #130032; + --ecru: #F8F3F0; + --poppy: #FF5252; + --slate: #6B6B9A; + --white: #FFFFFF; + --success: #28A745; + --warning: #F0A500; + --border: #E0DCF8; + --radius-sm: 4px; + --radius-md: 8px; + --shadow-sm: 0 1px 4px rgba(0,0,0,0.08); + --shadow-md: 0 4px 16px rgba(0,0,0,0.12); +} +``` + +### js/router.js + +```js +const ROUTES = { + '#/dashboard': () => import('./templates.js').then(m => m.renderDashboard()), + '#/templates': () => import('./templates.js').then(m => m.renderTemplates()), + '#/results': () => import('./migration.js').then(m => m.renderResults()), + '#/issues': () => import('./issues.js').then(m => m.renderIssues()), + '#/verify': () => import('./verification.js').then(m => m.renderVerification()), + '#/history': () => import('./history.js').then(m => m.renderHistory()), + '#/settings': () => import('./settings.js').then(m => m.renderSettings()), +}; +// Default route: #/templates +``` + +### js/state.js + +```js +export const state = { + project: null, // { id, name } — loaded from localStorage + auth: { adobe: false, docusign: false }, + templates: [], // array from /api/templates/status + selectedIds: new Set(), + lastMigrationResults: null, // results from most recent batch job +}; +// Simple pub/sub: subscribe(key, fn) / publish(key) +``` + +### js/api.js — endpoint wrappers + +All existing endpoints wrapped: +```js +export const api = { + auth: { + status: () => GET('/api/auth/status'), + connectAdobe: () => POST('/api/auth/adobe/connect'), + connectDocusign: () => POST('/api/auth/docusign/connect'), + exchangeAdobe: (url) => POST('/api/auth/adobe/exchange', { redirect_url: url }), + disconnect: (p) => POST(`/api/auth/${p}/disconnect`), + }, + templates: { + status: () => GET('/api/templates/status'), + adobe: () => GET('/api/templates/adobe'), + docusign: () => GET('/api/templates/docusign'), + }, + migrate: { + run: (body) => POST('/api/migrate', body), + batch: (body) => POST('/api/migrate/batch', body), + batchStatus: (id) => GET(`/api/migrate/batch/${id}`), + history: () => GET('/api/migrate/history'), + }, +}; +``` + +### js/utils.js + +```js +export const escHtml = str => String(str).replace(/[&<>"]/g, c => …); +export const formatDate = iso => new Date(iso).toLocaleDateString(…); +export const formatRelative = iso => …; +export const debounce = (fn, ms) => { … }; +export const uuid = () => crypto.randomUUID(); +``` + +### Commit + +`feat(ui-phase-14): app shell — nav, router, state, brand tokens` + +--- + +## Phase 15 — Project / Customer Context + +**Goal:** Project switcher so the same installation can manage migrations for +multiple customers without mixing history or credentials. + +### Data model (localStorage only — no backend) + +```js +// Stored in localStorage key: 'migrator_projects' +{ + active: "uuid-1", + projects: [ + { id: "uuid-1", name: "Acme Corp", createdAt: "2026-04-21T…" }, + { id: "uuid-2", name: "Globex Inc", createdAt: "2026-04-22T…" }, + ] +} +``` + +Credentials remain in the server-side signed cookie session. Switching projects +triggers a fresh `/api/auth/status` check (session may still be valid if the user +didn't disconnect). + +### js/project.js + +```js +export function listProjects() { … } // returns projects array +export function createProject(name) { … } // generates uuid, saves, returns project +export function deleteProject(id) { … } +export function getActive() { … } // returns active project or null +export function setActive(id) { … } // updates localStorage + triggers nav refresh +``` + +### Project switcher modal + +- Opened by clicking project name in nav footer +- Lists projects: name + creation date + "Activate" button +- "New Project" inline form (name field + Create button) +- Deleting a project requires confirmation ("Delete Acme Corp? This cannot be undone.") +- First run: modal opens automatically with welcome copy + +### Nav footer display + +Shows `▸ Acme Corp` (truncated to 18 chars). Clicking opens switcher modal. +No project → shows `▸ New Project` in amber. + +### Commit + +`feat(ui-phase-15): project switcher — localStorage CRUD, switcher modal` + +--- + +## Phase 16 — Templates View with Readiness Badges + +**Goal:** Replace the two-panel list with a filterable, sortable single table. +Each row shows a readiness badge computed from validation results. + +### Readiness badge system + +| Badge | Colour | Condition | +|---|---|---| +| Ready | `--success` green | `blockers=[]`, `warnings=[]` | +| Caveats | `--warning` amber | `blockers=[]`, `warnings.length > 0` | +| Blocked | `--poppy` red | `blockers.length > 0` | +| Migrated | `--cobalt` | `status=migrated` and no blockers | +| Needs Update | `--warning` amber | `status=needs_update` | +| Verified | green + ✓ | post-migration verification passed (Phase 19) | + +### Backend update required: `web/routers/templates.py` + +Add `blockers: list[str]` and `warnings: list[str]` to each template object in +`GET /api/templates/status`. Run `validate_template()` on the normalized form if the +template has been downloaded; otherwise return empty lists. + +```python +# In templates.py status endpoint, for each adobe template: +normalized_dir = Path(settings.downloads_dir) / f"{template['name']}__{template['id']}" +if normalized_dir.exists(): + normalized = adobe_folder_to_normalized(str(normalized_dir)) + result = validate_template(normalized) + blockers = result.blockers + warnings = result.warnings +else: + blockers, warnings = [], [] +``` + +Add 3 backend tests to `tests/test_api_templates.py`: +- `test_status_includes_blockers_and_warnings_fields` +- `test_status_blockers_populated_when_template_downloaded` +- `test_status_empty_when_not_downloaded` + +### js/templates.js + +```js +export function renderTemplates() { + // Fetches state.templates (or refreshes via api.templates.status()) + // Renders filterable table into #router-outlet + // Columns: ☐ | Name | Readiness | Fields | Last Modified | DS Status | Actions + // Filter bar: search input + status dropdown + readiness dropdown + // Bulk toolbar (hidden until ≥1 selected): "Migrate X selected" button +} + +export function renderTemplateDetail(adobeId) { + // 4-tab layout: Overview | Fields | Issues | Migration History +} +``` + +### Template detail view (`#/templates/:id`) + +- **Overview tab:** name, description, roles, document count, last modified date +- **Fields tab:** table of fields — type, label, page, role, required, conditional +- **Issues tab:** blockers (red cards) + warnings (amber cards) from validation +- **Migration History tab:** records from `/api/migrate/history` filtered to this template + +### Commit + +`feat(ui-phase-16): templates view — readiness badges, filters, detail tabs, backend blockers/warnings` + +--- + +## Phase 17 — Migration Workflow UI + +**Goal:** Options modal → progress view → results view as a cohesive flow. + +### Flow + +``` +Templates view → select ≥1 template → "Migrate Selected" button → + Options modal → "Run Migration" → + Progress view (replaces modal) → + Results view (#/results) +``` + +### js/migration.js + +```js +export function showOptionsModal(selectedIds) { + // Renders modal with: + // - Dry run toggle (default: off) + // - Overwrite existing toggle (default: off, from settings) + // - Include documents toggle (default: on, from settings) + // - Target folder text input (optional) + // - Selected count display + // - "Run Migration" button +} + +export async function runMigration(ids, options) { + // Calls POST /api/migrate/batch + // Returns job_id +} + +export async function pollJob(jobId, onProgress, onComplete) { + // Polls GET /api/migrate/batch/{jobId} every 2s + // Calls onProgress({ completed, total, results }) + // Calls onComplete(finalResults) when status === 'done' +} + +export function renderResults(jobResults) { + // Navigates to #/results and renders: + // - Summary row: X Created | Y Updated | Z Skipped | W Blocked | V Errors + // - Per-template result table + // - "Verify Templates" button (pre-loads migrated IDs) + // - "Back to Templates" button + // - "Export CSV" button (client-side Blob download) +} +``` + +### Progress view (inline, inside modal) + +After "Run Migration" is clicked: +- Modal content replaces with: progress bar + per-template status list +- Each template row: name → ⏳ spinning → ✅ success or ❌ error +- "View Results" button appears when job status === 'done' + +### Commit + +`feat(ui-phase-17): migration workflow — options modal, progress polling, results view` + +--- + +## Phase 18 — Issues & Warnings View + +**Goal:** A dedicated screen to review all validation problems before migrating. + +### js/issues.js + +```js +export function renderIssues() { + // Reads state.templates (already has blockers/warnings from Phase 16) + // Renders two sections: + // BLOCKERS — templates that will fail migration + // WARNINGS — templates that will migrate with caveats + // Each item: template name | issue message | suggested action link + // "Migrate Anyway" button on warning items → showOptionsModal([id]) + // "View Template" link → #/templates/:id +} +``` + +### Nav badge + +Left nav Issues link shows a red badge with count of blocked templates. +Updates whenever `state.templates` changes. + +### Commit + +`feat(ui-phase-18): issues view — blocked and warning templates, nav badge` + +--- + +## Phase 19 — Verification View + +**Goal:** Send test envelopes to confirm migrated templates work end-to-end. + +### New backend: `web/routers/verify.py` + +```python +POST /api/verify/send + body: { template_id: str, recipient_name: str, recipient_email: str } + action: GET /v2.1/accounts/{id}/envelopes (create via template) + returns: { envelope_id: str } + +GET /api/verify/status/{envelope_id} + action: GET /v2.1/accounts/{id}/envelopes/{envelopeId} + returns: { status: str, completed_at: str | null } + +POST /api/verify/void/{envelope_id} + body: { reason: str } + action: PUT envelope status to "voided" + returns: { voided: true } +``` + +Register router in `web/app.py`: `app.include_router(verify_router, prefix="/api/verify")`. + +### tests/test_api_verify.py + +Four tests (all mock DocuSign calls with respx): +- `test_send_requires_auth` +- `test_send_returns_envelope_id` +- `test_status_returns_envelope_state` +- `test_void_calls_docusign` + +### js/verification.js + +```js +export function renderVerification(preloadedTemplateIds = []) { + // Shows list of migrated templates (from history or passed-in IDs) + // Per-template row: + // - Template name + DS template ID + // - "Send Test Envelope" button → opens send dialog + // - Status chip (Not Tested | Sent | Delivered | Completed = Verified | Voided) + // Send dialog: recipient name + email (pre-filled from settings), "Send" button + // After send: row updates with status, "Void" button, polling every 5s +} +``` + +### Commit + +`feat(ui-phase-19): verification view + verify API endpoints (send/status/void)` + +--- + +## Phase 20 — History & Audit View + +**Goal:** Filterable, exportable migration history. + +### js/history.js + +```js +export function renderHistory() { + // Calls GET /api/migrate/history + // Renders: + // - Filter bar: date range, template name search, status filter + // - Table: timestamp | template | action | status | DS ID | warnings | checksum + // - Expandable row: full blockers/warnings list, field count diff + // - "Export CSV" button (client-side) +} +``` + +SHA-256 checksum: first 8 chars displayed, full value in title attribute (tooltip). + +### Commit + +`feat(ui-phase-20): history & audit view — filters, export, checksum display` + +--- + +## Phase 21 — Settings View + +**Goal:** Central config screen for verification defaults and migration defaults. + +### Settings (localStorage key: `migrator_settings`) + +| Key | Default | UI control | +|---|---|---| +| `testRecipientName` | `""` | Text input | +| `testRecipientEmail` | `""` | Email input | +| `autoVoidHours` | `24` | Number input | +| `defaultOverwrite` | `false` | Toggle | +| `defaultIncludeDocs` | `true` | Toggle | + +### js/settings.js + +```js +export function renderSettings() { + // 3 sections: + // 1. Verification defaults (name, email, auto-void timer) + // 2. Migration defaults (overwrite, include documents) + // 3. Connection info (read-only: connected accounts, base URLs) + // Save button writes to localStorage + // Values pre-loaded into options modal (Phase 17) and send dialog (Phase 19) +} +``` + +### Commit + +`feat(ui-phase-21): settings view — verification defaults, migration defaults` + +--- + +## Phase 22 — Smoke Test Checklist & Cleanup + +**Goal:** Validate the full redesigned UI works end-to-end, update docs. + +### tests/UI-SMOKE-TEST.md + +Manual checklist: +- [ ] First run: project switcher opens automatically +- [ ] Create project "Test Customer", verify it appears in nav footer +- [ ] Connect Adobe Sign via `.env` path → badge turns green +- [ ] Connect DocuSign via JWT path → badge turns green +- [ ] Templates view loads ≥1 template with correct readiness badge +- [ ] Select 2 templates → options modal opens → dry run → results show `dry_run` status +- [ ] Select 2 templates → real migration → progress bar counts up → results view +- [ ] Navigate to Verification → Send Test → status updates to Completed +- [ ] History view shows all migrations with correct counts and checksums +- [ ] Issues view shows blocked templates (use a fixture template with no recipients) +- [ ] Settings: save test recipient → reopen Settings → values persist + +### Final tasks + +- Run `pytest tests/ -v` — confirm all tests still pass (≥108 + new verify tests) +- Update `README.md` — new UI navigation guide section +- Update `docs/agent-harness/EXECUTION-BOARD.md` — Phases 14–22 complete +- Push `ui-redesign` branch to Gitea +- Open PR to `master` + +### Commit + +`feat(ui-phase-22): smoke test checklist, README update, final cleanup` + +--- + +## Dependency order + +``` +Phase 14 (Shell) + └── Phase 15 (Project) + └── Phase 16 (Templates + backend readiness data) + ├── Phase 17 (Migration workflow) + │ └── Phase 18 (Issues view) + └── Phase 19 (Verification + verify API) + +Phase 20 (History) ← depends on Phase 14 only, can run after Phase 14 +Phase 21 (Settings) ← depends on Phase 14 only, can run after Phase 14 + +Phase 22 (Cleanup) ← depends on all phases complete +``` + +Phases 20 and 21 can be implemented in parallel with Phases 17–19. + +--- + +## What does NOT change + +- All existing FastAPI routes (`auth.py`, `templates.py`, `migrate.py`) +- All backend Python source (`src/`) +- All 108 existing tests +- `.env` / credential handling +- The CLI pipeline (`src/migrate_template.py`) + +Only backend additions: +1. **Phase 16:** `blockers` + `warnings` fields added to `GET /api/templates/status` +2. **Phase 19:** New `web/routers/verify.py` with 3 envelope endpoints diff --git a/docs/agent-harness/EXECUTION-BOARD.md b/docs/agent-harness/EXECUTION-BOARD.md index 851fbbc..0281f00 100644 --- a/docs/agent-harness/EXECUTION-BOARD.md +++ b/docs/agent-harness/EXECUTION-BOARD.md @@ -149,10 +149,74 @@ --- +## UI Redesign — Phases 14–22 (in progress) + +*Full plan: `docs/UI-REDESIGN-PLAN.md`* + +### Phase 14 — App Shell & Navigation +- [ ] Rewrite `index.html` as app shell (left nav, router outlet, top bar) +- [ ] `css/tokens.css` — Docusign 2024 brand custom properties +- [ ] `css/base.css` — reset, Inter font, utility classes +- [ ] `css/nav.css` — Inkwell sidebar, logo, nav links, project footer +- [ ] `js/utils.js` — escHtml, formatDate, debounce, uuid +- [ ] `js/router.js` — hash-based router (#/templates default) +- [ ] `js/state.js` — global state with pub/sub +- [ ] `js/api.js` — fetch wrappers for all existing endpoints + +### Phase 15 — Project / Customer Context +- [ ] `js/project.js` — project CRUD (localStorage) +- [ ] Project switcher modal (list, create, delete, activate) +- [ ] First-run experience (auto-open modal if no projects) +- [ ] Active project name in nav footer + +### Phase 16 — Templates View with Readiness Badges +- [ ] Backend: add `blockers[]` + `warnings[]` to `GET /api/templates/status` +- [ ] Add 3 backend tests to `tests/test_api_templates.py` +- [ ] `js/templates.js` — filterable/sortable table with readiness badges +- [ ] Template detail view (4 tabs: Overview, Fields, Issues, Migration History) +- [ ] `css/cards.css` — badge styles, table hover, bulk toolbar + +### Phase 17 — Migration Workflow UI +- [ ] Options modal (dry_run, overwrite, include_documents, target folder) +- [ ] Progress view with batch job polling (every 2s) +- [ ] `js/migration.js` — showOptionsModal, runMigration, pollJob, renderResults +- [ ] Results view (#/results) with summary + export CSV +- [ ] `css/modals.css` + +### Phase 18 — Issues & Warnings View +- [ ] `js/issues.js` — issues view (Blockers + Warnings sections) +- [ ] Nav badge showing blocked template count + +### Phase 19 — Verification View + API +- [ ] `web/routers/verify.py` — POST /send, GET /status/{id}, POST /void/{id} +- [ ] Register verify router in `web/app.py` +- [ ] `tests/test_api_verify.py` — 4 tests +- [ ] `js/verification.js` — send test envelope, poll status, void + +### Phase 20 — History & Audit View +- [ ] `js/history.js` — filterable history table, expand row, export CSV +- [ ] Checksum display (first 8 chars, full on hover) + +### Phase 21 — Settings View +- [ ] `js/settings.js` — 3 sections (verification defaults, migration defaults, connection info) +- [ ] `css/forms.css` + +### Phase 22 — Smoke Test Checklist & Cleanup +- [ ] `tests/UI-SMOKE-TEST.md` — manual test checklist (11 steps) +- [ ] Full backend test suite passes (≥108 + verify tests) +- [ ] Update `README.md` — new UI navigation guide +- [ ] Update EXECUTION-BOARD.md — all phases complete +- [ ] Push `ui-redesign` branch to Gitea +- [ ] Open PR to `master` + +--- + ## Gitea - [x] Committed and pushed all changes (2026-04-17) -- [ ] Commit and push Phase 8–13 work (ui-redesign branch) +- [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) +- [ ] Push Phases 14–22 UI implementation (ui-redesign branch) --- @@ -164,3 +228,5 @@ - (2026-04-17) v2 planning complete — idempotent upload + web UI implementation begins - (2026-04-21) Blueprint comparison complete — added normalized schema, validation service, migration options, rate-limit/retry, security hardening, and batch migration phases (Phases 8–13) - (2026-04-21) Phases 8–13 fully implemented — 108/108 tests passing on ui-redesign branch +- (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)