Files
EnvelopeGenerator/AGENTS.md
TekH 435be882c9 Complete SF-74 implementation and fix PDF issues
Updated SF-74-PLAN.md to document completed phases (6a–6e), including theme selection, dark mode, grid persistence, and logo placement. Highlighted pending tasks for phase 6f and clarified open questions.

Revised MIGRATION_PLAN.md with deep analysis findings and detailed steps for migrating `EnvelopeGenerator.Service_legacy` to a modern C# Worker Service. Addressed connection string handling, Quartz version mismatch, and TempFiles architecture.

Removed outdated markdown files from EnvelopeGenerator.sln and updated the solution structure for consistency.

Fixed incorrect "Read and confirmed" label in Signature Certificate reports for "Read and Sign" envelopes. Added branching logic in `ReportItem.vb` and updated resource files.

Resolved signature field formatting issues in finalized PDFs based on WISAG feedback. Added truncation logic in `PDFBurner.vb` and updated `PDFBurnerParams.vb` with per-field character limits.
2026-09-25 09:17:50 +02:00

13 KiB
Raw Blame History

EnvelopeGenerator - Agent Guide

Must Read First

  • COPILOT_CONTEXT.md - Architecture, coordinate systems, migration status
  • FORM_APPLICATION_CONTEXT.md - Legacy VB.NET features to migrate

Documentation Catalog

This section explains every markdown file in the repo: what it contains, why it exists, and when you need it. Read this before deciding which file to open.

Core Architecture Docs (Active — Always Relevant)

AGENTS.md ← you are here

What: Authoritative agent/copilot onboarding guide. Covers project structure, route table, render mode rules, coordinate system, API gaps, and common mistakes. Why it exists: Single source of truth for agents so they don't re-derive architecture from code on every session. When you need it: Always. Read first on every session. Maintenance: Update whenever project structure, routes, render modes, or naming conventions change.

COPILOT_CONTEXT.md

What: Deep-dive architecture reference. Covers the full Blazor Auto hybrid setup, authentication flows (JWT + cookies, per-envelope receiver tokens), service registration patterns, coordinate system proof, and an explicit "prefer Server/Server.Client over old WebUI/ReceiverUI" rule. Why it exists: Prevents agents from re-deriving or misinterpreting the hybrid SSR+WASM architecture. Also documents coordinate system evidence to prevent regressions (inches vs. points vs. pixels). When you need it:

  • Implementing any new page or service
  • Debugging auth/cookie issues
  • Any coordinate conversion question
  • Unsure which project a new file should go in Maintenance: Update when render mode assignments change, new auth schemes are added, or the coordinate system is touched.

FORM_APPLICATION_CONTEXT.md

What: Comprehensive reverse-engineering of the legacy VB.NET WinForms app (EnvelopeGenerator.Form). Documents every form (frmMain, frmEnvelopeEditor, frmFieldEditor, etc.), their UI layout, toolbar actions, data models, coordinate system, and a feature-by-feature migration mapping table to EnvelopeGenerator.Server. Why it exists: The WinForms app is the functional specification for the sender-side web UI. It documents the full intended workflow that is being migrated to Blazor — especially the envelope creation, signature field placement, and dashboard features that are not yet implemented. When you need it:

  • Implementing any sender-side feature (/sender, /sender/editor, /sender/envelope/{id})
  • Understanding what a specific toolbar button or form should do
  • Designing API endpoints for sender workflow
  • Checking coordinate system behavior (INCHES proof is here) Maintenance: Update the mapping table as features are implemented (change ❌ Not implemented → ✅ Exists). Do not rename ReceiverUI back — it was the old project name; current target is EnvelopeGenerator.Server.

RECEIVER_PDF_VIEWER_CONTEXT.md

What: Detailed technical reference for the receiver-side PDF viewer (EnvelopeReceiverPage.razor). Documents the PDF.js integration, signature button rendering, JS interop API (window.pdfViewer), signature capture flow, HiDPI/zoom/thumbnail config, and the full component lifecycle. Why it exists: The receiver PDF viewer is the most complex component in the codebase. This doc prevents agents from misunderstanding the JS↔Blazor boundary, re-implementing already-solved problems (HiDPI, zoom, signature caching), or breaking the signing flow. When you need it:

  • Working on EnvelopeReceiverPage.razor or pdf-viewer.js
  • Adding new signature field rendering logic
  • Debugging signature rendering, zoom, or thumbnail issues
  • Implementing sender-side PDF.js overlay (signature field placement) — the receiver side is the reference implementation Maintenance: Update when pdf-viewer.js API changes, new JS interop functions are added, or the signing flow is modified.

Deployment Docs

EnvelopeGenerator.Server/EnvelopeGenerator.Server/README.md

What: IIS publish and deployment guide for EnvelopeGenerator.Server. Covers why self-contained publish is required (WASM assembly version strictness), the exact dotnet publish command, IIS Application Pool settings (No Managed Code), directory structure after publish, and common deployment errors. Why it exists: Blazor Auto (Server + WASM hybrid) has non-obvious deployment requirements that differ from a standard ASP.NET Core app. Forgetting self-contained publish or using the wrong app pool will break WASM loading in production. When you need it:

  • Deploying to IIS for the first time
  • Troubleshooting 500 errors on production after deploy
  • Setting up a new deployment environment Maintenance: Update if the publish target, IIS config, or runtime version changes.

Active Architecture (Post-Migration)

Frontend: Blazor Auto (Server+WASM hybrid)

  • EnvelopeGenerator.Server (Server): @rendermode InteractiveServer - PDF viewers requiring DevExpress backend
  • EnvelopeGenerator.Server.Client (WASM): @rendermode InteractiveWebAssembly - Login, dashboards, business logic

Backend: EnvelopeGenerator.API (ASP.NET Core 8.0)

Proxy: YARP in EnvelopeGenerator.Server routes /api/* → localhost:8088 (API)

Deprecated Projects - DO NOT USE

  • EnvelopeGenerator.ReceiverUI - Pure WASM (migrated to Server)
  • EnvelopeGenerator.Web - Razor Pages (replaced by Server)
  • VB.NET projects (Form, Service, BBTests) - Legacy, read-only for reference

Development Commands

Run Both Projects (Required)

# Terminal 1 - API Backend
cd EnvelopeGenerator.API
dotnet run

# Terminal 2 - Blazor Frontend
cd EnvelopeGenerator.Server\EnvelopeGenerator.Server
dotnet run

Critical: Both must run simultaneously. EnvelopeGenerator.Server proxy forwards /api/* to API.

Build

dotnet build EnvelopeGenerator.sln

Project Boundaries

EnvelopeGenerator.Domain/          # Entities (Envelope, Receiver, Document, etc.)
EnvelopeGenerator.Application/     # MediatR CQRS (Commands, Queries, Handlers)
EnvelopeGenerator.Infrastructure/  # EF Core, SQL executors, repositories
EnvelopeGenerator.API/             # Controllers, endpoints
EnvelopeGenerator.Server/
  EnvelopeGenerator.Server/        # Server-side Blazor components
    ├─ Components/Pages/           # @rendermode InteractiveServer
  EnvelopeGenerator.Server.Client/ # Client-side WASM components
    ├─ Pages/                      # @rendermode InteractiveWebAssembly
    ├─ Services/                   # HTTP API clients
    ├─ Models/                     # DTOs

Route Structure (Critical)

Route File Location Render Mode Purpose
/ Server.Client/Pages/Index.razor WASM Landing page
/sender/login Server.Client/Pages/LoginSenderPage.razor WASM Sender auth
/sender Server/Components/Pages/EnvelopeSenderPage.razor Server Sender dashboard
/sender/editor Server/Components/Pages/EnvelopeSenderEditorPage.razor Server Envelope editor + PDF viewer
/envelope/login/{key} Server.Client/Pages/LoginReceiverPage.razor WASM Receiver auth
/envelope/{key} Server/Components/Pages/EnvelopeReceiverPage.razor Server PDF viewer + signing

Rule: PDF viewers MUST use @rendermode InteractiveServer (DevExpress backend requirement). Everything else uses WASM.

Coordinate System (CRITICAL)

Database stores INCHES (GdPicture14 native). Origin: top-left, Y-axis down.

Conversions

// Database (INCHES) → PDF Points
float points = inches * 72;

// Database (INCHES) → DevExpress DX
float dx = inches * 100;

// PDF.js Pixels → Database (INCHES)
float inches = (pixelX / canvasWidth) * pageWidthInches;

A4 Page: 8.27" wide × 11.69" tall = 595pt × 842pt

Signature Field Size: 1.77" × 1.96" (FIXED, do not change)

Evidence: See COPILOT_CONTEXT.md lines 158-185, EnvelopeGenerator.Form/frmFieldEditor.vb

API Architecture Quirks

Monolithic Endpoint (Avoid for UI)

POST /api/EnvelopeReceiver - Creates envelope+document+receivers+fields atomically.

  • Use case: External API consumers
  • Not suitable for: Step-by-step UI workflow (no draft support, no partial updates)

Missing Granular Endpoints (Need to Create)

POST /api/Envelope/draft          # Create draft envelope
PUT /api/Envelope/{id}            # Update metadata
DELETE /api/Envelope/{id}         # Delete with reason
POST /api/Envelope/{id}/document  # Upload PDF
POST /api/Envelope/{id}/receivers # Add receiver
POST /api/Envelope/{id}/signature-fields  # Place signature field
POST /api/Envelope/{id}/send      # Send to receivers

See FORM_APPLICATION_CONTEXT.md for detailed workflow requirements.

Status Color Coding

Form app uses DevExpress CustomDrawCell. EnvelopeGenerator.Server needs CSS:

.envelope-row.status-partly-signed { background-color: #81C784; } /* GREEN_300 */
.envelope-row.status-queued,
.envelope-row.status-sent { background-color: #FFB74D; } /* ORANGE_300 */
.envelope-row.status-completed { background-color: #81C784; }
.envelope-row.status-deleted,
.envelope-row.status-rejected { background-color: #E57373; } /* RED_300 */

Configuration

YARP Proxy (EnvelopeGenerator.Server/yarp.json)

Routes /api/*, /swagger/*, /openapi/*, /scalar/* → https://localhost:8088

PDF.js Settings (EnvelopeGenerator.Server/wwwroot/appsettings.json)

{
  "PdfViewerOptions": {
    "ThumbnailBaseScale": 0.75,
    "ThumbnailEnableHiDPI": true,
    "MainCanvasEnableHiDPI": true,
    "ZoomStepPercentage": 5
  }
}

API Config (API/appsettings.json)

  • ConnectionStrings:Default - SQL Server DB
  • AllowedOrigins - CORS (includes http://localhost:5131, http://localhost:7192)
  • Cache:SignatureCacheExpiration - Signature persistence timeout
  • PSPDFKitLicenseKey - DEPRECATED (use PDF.js instead)

Migration Status

Complete ✅

  • Receiver login/authentication
  • PDF viewing with PDF.js (HiDPI, zoom, thumbnails)
  • Signature capture (draw/type/image)
  • Signature caching (Redis/SQL)
  • Sender login

Missing (High Priority) ❌

  • Sender dashboard (/sender) - Empty stub
  • Envelope editor (/sender/envelope/{id})
  • Signature field placement tool (PDF.js + draggable overlays)
  • Granular API endpoints (draft, receivers, fields)
  • Master-detail grids for receivers/history

Common Mistakes (DO NOT REPEAT)

Mistake Why Wrong
Using iText7 in receiver pages GPL license issue. Use PDF.js overlays.
Using PSPDFKit Removed from architecture. Use PDF.js + DevExpress.
@rendermode InteractiveWebAssembly on PDF viewers DevExpress DxPdfViewer requires server-side rendering.
Hardcoded quality in PDF.js Use appsettings.json PdfViewerOptions.
Coordinates in points/pixels for DB Database uses INCHES. Convert before save.
BottomMarginBand for signatures Repeats on every page. Use DetailBand.

Testing

No automated tests exist yet.

Manual testing workflow:

  1. Start API (dotnet run in EnvelopeGenerator.API)
  2. Start EnvelopeGenerator.Server (dotnet run in EnvelopeGenerator.Server\EnvelopeGenerator.Server)
  3. Navigate to https://localhost:5131 (or check console output for port)
  4. Test sender login at /sender/login
  5. Test receiver flow at /envelope/login/{envelopeKey}

Database

SQL Server (DD_ECM)

  • Connection string in API/appsettings.json
  • EF Core migrations NOT used (manual SQL scripts)
  • Stored procedures: PRSIG_* prefix

Key Tables:

  • TBSIG_ENVELOPE - Envelope metadata
  • TBSIG_ENVELOPE_RECEIVER - Receiver assignments
  • TBSIG_DOC_RECEIVER_ELEMENT - Signature fields (X, Y in INCHES)
  • TBSIG_RECEIVER - Receiver registry
  • TBSIG_DOCUMENT - PDF binary data
  • TBSIG_ENVELOPE_HISTORY - Audit trail

DevExpress

License: Commercial (v25.2.3) Components Used:

  • DxGrid - Master-detail grids
  • DxPdfViewer - Server-side PDF rendering
  • DxPopup - Modal dialogs
  • DxToolbar - Action bars
  • DxFormLayout - Forms

Theme: Blazing Berry (default)

JavaScript Interop

PDF Viewer: wwwroot/js/pdf-viewer.js

window.pdfViewer = {
    initialize(canvasId, pdfDataUrl, dotNetRef),
    renderPage(num),
    renderSignatureButtons(signatures, pageNum, dotNetRef),
    applySignature(signatureId, dataUrl, fullName, position, place),
    zoomIn(), zoomOut(), dispose()
}

Signature Pad: wwwroot/js/receiver-signature.js

window.receiverSignature = {
    initializeDrawPad(canvasId, dotNetRef),
    getSignatureDataUrl(canvasId),
    clearPad(canvasId)
}

Multi-Envelope Support

Receivers can login to multiple envelopes simultaneously via per-envelope cookies:

AuthTokenSignFLOWReceiver.{envelopeKey}

Each envelope maintains independent authentication state.

External Dependencies

CDN:

  • PDF.js 3.11.174: https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js

NuGet (Server.Client):

  • DevExpress.Blazor.* 25.2.3
  • SkiaSharp.* 3.119.1 (WASM rendering)

External Services:

  • LDAP/AD authentication (optional)
  • GTX Messaging (SMS 2FA)
  • Email dispatcher (signFlow)

Environment Variables

None required. All config in appsettings.json.

Local dev ports:

  • API: https://localhost:8088
  • WebUI: https://localhost:5131 or http://localhost:7192