Adobe Sign uses a non-standard separate endpoint for refresh:
/oauth/v2/refresh (not /oauth/v2/token). Using the wrong endpoint
returned a misleading "Invalid grant_type refresh_token" error.
Also:
- Remove redirect_uri from refresh requests (not required)
- Add clear RuntimeError message directing user to re-authenticate
- Validate access_token is non-empty before saving in adobe_auth.py
- Log token lengths and exchange response keys on successful auth
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Matches the naming convention of docusign_auth.py. Update all
references in README.md and the error message in adobe_api.py.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
README:
- Remove Node.js prerequisite (upload now handled by Python script)
- Complete .env template with all DocuSign JWT auth keys
- Add DocuSign consent step to setup instructions
- Update all script examples: download_templates subcommands, Python upload,
migrate_template.py replacing migrate_paul_template.py
- Update project structure to include all current src files
field-mapping.md:
- Replace incorrect coordinate translation note with confirmed behaviour:
both platforms use top-left origin, direct pass-through with MIN_TEXT_WIDTH floor
- Add dedicated Multi-location (Cloned) Fields section documenting tab merging
and which tab types support it
- Replace vague To Do items with accurate known gaps (conditional logic,
formula fields, advanced validation)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
README.md — rewritten to reflect actual usage: setup, auth flows, CLI
commands for all three scripts, and links to field-mapping and quirks docs.
tests/PLATFORM-QUIRKS.md — documents confirmed bugs and API quirks found
during development: numberTabs rendering as text+validation (DocuSign API
bug), multi-location field fix, zero-width tab fix, Company/Title contentType
SIGNER_ prefix variant from Adobe Sign API.
tests/ — SCENARIOS, EDGE-CASES, FIELD-TYPE-REGRESSION test planning docs.
validation/ — research notes: field eval, mapping ambiguity log, decision
log, conditional logic analysis, round-trip eval, DocuSign ingest eval.
docs/architecture.md — system architecture overview.
api-samples.md — annotated Adobe Sign API response examples.
PRODUCT-SPEC.md — product requirements and migration scope definition.
sample-templates/ — JSON fixtures (NDA, onboarding, sales contract) for
offline testing; PDFs excluded from version control.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
migrate_template.py — generic end-to-end CLI replacing the earlier
migrate_paul_template.py:
--list list available Adobe Sign templates
--template "Name" download → convert → upload a named template
--template "Name" --skip-upload convert only, write JSON to migration-output/
Picks most recently modified when multiple templates share a name.
create_adobe_template.py — utility for creating a test template in Adobe Sign
that exercises all 15+ field types. Uses the David Tag Demo Form PDF as the
base document and positions extra fields (Number, Email, Company, Title) in
the gaps of the original layout.
generate_pdfs.py — generates realistic sample PDFs with labelled form areas
matching the *-formfields.json fixtures in sample-templates/, for use in
offline testing without a live Adobe Sign account.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
docusign_auth.py — authentication helper supporting two flows:
- JWT Grant: service-to-service token generation using an RSA private key;
caches token + expiry in .env to avoid redundant round-trips
- Auth Code Grant (--consent): one-time browser flow to grant the app the
'impersonation' scope required for JWT; must be run once per user/app before
JWT will work
upload_docusign_template.py — posts a docusign-template.json to the DocuSign
Templates REST API (v2.1). No Node.js dependency. Retries once on 401.
requirements.txt — adds PyJWT>=2.0 and cryptography for RSA key handling.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
compose_docusign_template.py — converts a downloaded template folder into a
DocuSign envelopeTemplate JSON ready for the Templates API. Key behaviours:
- Full field type mapping: TEXT_FIELD, SIGNATURE, CHECKBOX, RADIO, DROP_DOWN,
BLOCK, FILE_CHOOSER (with warning), INLINE_IMAGE (skipped with warning)
- contentType dispatch: SIGNER_NAME → fullNameTabs, SIGNER_EMAIL →
emailAddressTabs, SIGNATURE_DATE → dateSignedTabs, COMPANY/SIGNER_COMPANY →
companyTabs, TITLE/SIGNER_TITLE → titleTabs, DATA+NUMBER → numberTabs,
DATA+DATE → dateTabs, SIGNER_INITIALS → initialHereTabs
- Multi-location (cloned) fields: emits one tab per location with the same
tabLabel so DocuSign tab merging replicates Adobe Sign's sync behaviour
- Width/height passed through from Adobe Sign locations; MIN_TEXT_WIDTH=120pt
ensures text fields render as visible boxes rather than vertical lines
- Coordinate system: both platforms use top-left origin — no inversion needed
test_mapping.py — unit test harness validating tab grouping and field mapping.
field-mapping.md — full Adobe Sign → DocuSign tab type reference table with
edge cases, known gaps, and decision log.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
download_templates.py — subcommand CLI for listing and downloading library
templates from Adobe Sign.
list — print all templates with name, modified date, ID
download — download all templates (default)
download --all — explicit download all
download "Name" — download a single named template; picks the most
recently modified if duplicates exist
Each template is saved to downloads/<name>__<id8>/ containing metadata.json,
form_fields.json, documents.json, and the source PDF.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
auth_adobe.py — one-time browser Auth Code Grant flow; saves access and
refresh tokens to .env. Targets the EU2 shard.
adobe_api.py — thin API client with auto token refresh on 401. Supports
GET, POST (JSON and multipart), PUT, and binary download.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>