diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..8cff224 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,53 @@ +# Adobe Sign → DocuSign Migrator — Claude Instructions + +## Definition of Done + +Every feature, phase, or change is NOT complete until: + +1. **Code works** — the feature behaves as described +2. **Tests pass** — unit, integration, and/or regression tests are written and green +3. **README.md is updated** — any new usage, CLI flags, endpoints, or setup steps are documented +4. **EXECUTION-BOARD.md is updated** — completed items checked off, lessons learned added +5. **Pushed to Gitea** — changes committed with a meaningful message and pushed + +Do not mark a task complete or report it as done until all five are satisfied. + +## Project Overview + +Python toolkit + FastAPI web UI for migrating templates from Adobe Sign to DocuSign. + +- **CLI pipeline** (`src/`): download → compose → upload +- **Web UI** (`web/`): browser-based auth, side-by-side template browser, one-click migration +- **Tests** (`tests/`): unit, API, end-to-end, and regression suites + +## Key Files + +- `src/compose_docusign_template.py` — core field mapping logic +- `src/upload_docusign_template.py` — upsert upload (PUT if exists, POST if not) +- `web/app.py` — FastAPI entrypoint +- `web/routers/` — auth, templates, migrate endpoints +- `tests/test_regression.py` — snapshot tests against real template outputs +- `tests/fixtures/expected/` — regression snapshots (update with `--update-snapshots`) +- `field-mapping.md` — Adobe Sign → DocuSign field type mapping table +- `docs/IMPLEMENTATION-PLAN.md` — feature design and test specs +- `docs/agent-harness/EXECUTION-BOARD.md` — living kanban board + +## Running the Web UI + +```bash +uvicorn web.app:app --reload --port 8000 +``` + +## Running Tests + +```bash +pytest tests/ -v # all tests +pytest tests/test_regression.py -v # regression only +pytest tests/ --update-snapshots # regenerate snapshots +``` + +## Environment + +Credentials live in `.env` (never committed). See `.env-sample` for all required keys. +Add `SESSION_SECRET_KEY` for the web session signing key. +Add `DOCUSIGN_CLIENT_SECRET` and `DOCUSIGN_REDIRECT_URI` for web OAuth flow. diff --git a/README.md b/README.md index eaf8477..5e8abc5 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Adobe Sign → DocuSign Migrator -A Python toolkit for migrating library templates from Adobe Sign (Acrobat Sign) to DocuSign. -It downloads templates via the Adobe Sign API, converts them to DocuSign format, and uploads them via the DocuSign API. +A Python toolkit + web UI for migrating library templates from Adobe Sign (Acrobat Sign) to DocuSign. +It downloads templates via the Adobe Sign API, converts them to DocuSign format, and uploads them via the DocuSign API — either from the command line or through a browser-based UI. --- @@ -78,10 +78,15 @@ python3 src/compose_docusign_template.py ``` Writes DocuSign template JSONs to `migration-output//docusign-template.json`. -**Upload to DocuSign:** +**Upload to DocuSign (upsert by default):** ```bash python3 src/upload_docusign_template.py --file migration-output//docusign-template.json ``` +If a DocuSign template with the same name already exists, the most recently modified one is updated (PUT). +To always create a new template instead: +```bash +python3 src/upload_docusign_template.py --file --force-create +``` **Or run the full pipeline end-to-end:** ```bash @@ -93,6 +98,50 @@ If multiple templates share the same name, the most recently modified one is use --- +--- + +## Web UI + +The web UI provides a browser-based interface for connecting both platforms, browsing templates side-by-side, and running migrations with live status feedback. + +**Additional `.env` keys required for the web UI:** +``` +SESSION_SECRET_KEY= +DOCUSIGN_CLIENT_SECRET= +DOCUSIGN_REDIRECT_URI=http://localhost:8000/api/auth/docusign/callback +ADOBE_REDIRECT_URI=http://localhost:8000/api/auth/adobe/callback +``` + +**Start the server:** +```bash +uvicorn web.app:app --reload --port 8000 +``` +Then open [http://localhost:8000](http://localhost:8000) in your browser. + +**Using the UI:** +1. Click **Connect Adobe Sign** in the header — you'll be redirected to Adobe Sign OAuth. Authorize and you'll return to the app. +2. Click **Connect DocuSign** — same flow for DocuSign. +3. Your Adobe Sign templates appear on the left with status badges: + - **Not Migrated** (red) — no matching DocuSign template yet + - **Migrated** (green) — a DocuSign template with the same name exists and is up to date + - **Needs Update** (yellow) — the Adobe template was modified after the last migration +4. Check one or more templates and click **Migrate Selected**. +5. Migration results appear inline; the history table at the bottom logs all past runs. + +**API docs:** [http://localhost:8000/api/docs](http://localhost:8000/api/docs) + +--- + +## Running tests + +```bash +pytest tests/ -v # full suite (29 tests) +pytest tests/test_regression.py -v # compose regression only +pytest tests/test_regression.py --update-snapshots # regenerate snapshots after intentional changes +``` + +--- + ## Field type mapping See [field-mapping.md](field-mapping.md) for the full Adobe Sign → DocuSign tab type table, @@ -109,21 +158,50 @@ unexpected API behaviors, and the fixes applied. ``` src/ - adobe_auth.py # One-time OAuth flow for Adobe Sign + adobe_auth.py # One-time OAuth flow for Adobe Sign (CLI) adobe_api.py # Adobe Sign API client (auto token refresh) download_templates.py # List and download templates from Adobe Sign compose_docusign_template.py # Core conversion: Adobe Sign → DocuSign JSON docusign_auth.py # DocuSign JWT auth + one-time consent flow - upload_docusign_template.py # Upload a template JSON to DocuSign REST API - migrate_template.py # End-to-end runner (download → convert → upload) + upload_docusign_template.py # Upsert upload: PUT if exists, POST if not + migrate_template.py # End-to-end CLI runner (download → convert → upload) create_adobe_template.py # Utility: create a test template in Adobe Sign generate_pdfs.py # Utility: generate sample PDFs for offline testing +web/ + app.py # FastAPI entrypoint (uvicorn web.app:app) + config.py # Environment-based settings + session.py # Signed cookie session helpers + routers/ + auth.py # Adobe Sign + DocuSign OAuth endpoints + templates.py # Template listing + migration status API + migrate.py # Migration trigger + history API + static/ + index.html # Web UI (side-by-side browser + migrate flow) + app.js # Vanilla JS frontend + style.css # Styles + status badge colours + +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_migrate.py # Migration API tests + test_e2e.py # Full pipeline end-to-end test + test_regression.py # Compose output vs snapshots + fixtures/expected/ # Regression snapshots (3 real templates) + FIELD-TYPE-REGRESSION.md # Manual field type regression checklist + PLATFORM-QUIRKS.md # Known API bugs and workarounds + downloads/ # Downloaded Adobe Sign templates (gitignored) -migration-output/ # Converted DocuSign template JSONs (gitignored) -sample-templates/ # JSON fixtures for offline testing (PDFs gitignored) +migration-output/ # Converted DocuSign template JSONs + history +sample-templates/ # JSON fixtures for offline testing field-mapping.md # Field type mapping table + edge case log -tests/PLATFORM-QUIRKS.md # Known bugs and API quirks +CLAUDE.md # Claude Code instructions for this project +docs/IMPLEMENTATION-PLAN.md # Feature design and test specifications +docs/agent-harness/ + EXECUTION-BOARD.md # Living kanban board + AGENT-INSTRUCTIONS.md # Definition of done + conventions requirements.txt # Python dependencies ``` diff --git a/docs/agent-harness/AGENT-INSTRUCTIONS.md b/docs/agent-harness/AGENT-INSTRUCTIONS.md index 30180e2..23ce176 100644 --- a/docs/agent-harness/AGENT-INSTRUCTIONS.md +++ b/docs/agent-harness/AGENT-INSTRUCTIONS.md @@ -1,3 +1,43 @@ -# Agent Harness Placeholder +# Agent Instructions — Adobe Sign → DocuSign Migrator -Copy other relevant files from docs/agent-harness/ as needed. This is the main harness doc for the migration agent. \ No newline at end of file +## Definition of Done + +A task or phase is **not complete** until all of the following are true: + +- [ ] Feature works as specified +- [ ] Tests written and passing (unit + integration + regression as applicable) +- [ ] **README.md updated** with any new setup steps, CLI usage, flags, or endpoints +- [ ] EXECUTION-BOARD.md updated — items checked off, results/lessons recorded +- [ ] Changes committed and pushed to Gitea + +## Execution Board + +See [EXECUTION-BOARD.md](EXECUTION-BOARD.md) for the current task list. + +## Test Strategy + +| Layer | Tool | Location | +|---|---|---| +| Field mapping unit tests | pytest + responses | `tests/test_upload_upsert.py`, `tests/test_mapping.py` | +| API endpoint tests | pytest + httpx TestClient + respx | `tests/test_api_*.py` | +| End-to-end pipeline | pytest + respx mocks | `tests/test_e2e.py` | +| Regression (compose output) | pytest snapshots | `tests/test_regression.py` | + +Run all tests: `pytest tests/ -v` + +Regenerate regression snapshots after intentional changes: `pytest tests/test_regression.py --update-snapshots` + +## Branching / Commit Conventions + +- Work on `master` (small project, no feature branches needed unless scope is large) +- Commit message format: `type: short description` (feat, fix, chore, docs, test) +- Push to Gitea after every logical milestone + +## Documentation Conventions + +- `README.md` — user-facing: setup, CLI usage, web UI usage, project structure +- `docs/IMPLEMENTATION-PLAN.md` — design spec for features +- `docs/agent-harness/EXECUTION-BOARD.md` — living kanban +- `field-mapping.md` — Adobe Sign → DocuSign field type reference +- `tests/PLATFORM-QUIRKS.md` — documented API bugs and workarounds +- `CLAUDE.md` — persistent Claude Code instructions (definition of done, key files, run commands)