# 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. --- ### Ticket / Feature Plans (Active Work Items) #### `EnvelopeGenerator.Server/SF-74-PLAN.md` **What:** Implementation plan for SF-74 ticket — Theme selection, Dark Mode, Grid Layout Persistence, signFLOW logo, and customer logo area on the sender dashboard. Includes the original ticket requirements, component breakdown, and implementation steps. **Why it exists:** Captures the agreed scope and implementation decisions for SF-74 so work can be resumed or reviewed without re-reading the ticket system. **When you need it:** - Resuming work on theme, dark mode, or grid persistence features - Checking what was agreed for logo positioning and size - Verifying which features of SF-74 are complete vs. pending **Maintenance:** Mark items as complete as they are implemented. Archive when the ticket is closed. --- ### 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. --- ### Fix Reports (Historical — Read-Only) These files document completed bug fixes. They exist as audit trails and as references if a similar issue resurfaces. Do not modify them. #### `fix-report-label-read-and-confirmed.md` **What:** Documents the fix for an incorrect label in the Signature Certificate report (`Signierungszertifikat`). For "Read and Sign" envelope type (`EnvelopeTypeId = 2`), the history event showed "Document signed" instead of "Read and confirmed" / "Gelesen und bestätigt". **Branch:** `fix/report-label-read-and-confirmed` — **COMPLETED** **When you need it:** If a similar report label regression appears, or when adding new envelope type-specific label logic to the certificate report. #### `fix-signature-field-formatting.md` **What:** Documents a signature stamp layout fix triggered by WISAG customer feedback (email 3/7/2026). The finalized PDF's signature stamp had incorrect spacing: certificate hash too close to name, position text wrapping, no spacing before date. Fix was applied in the GdPicture14 PDF burning pipeline — not in the Blazor UI. **When you need it:** If signature stamp formatting regresses, or when modifying the PDF stamping/burning pipeline in the API or infrastructure layer. --- ### Service Migration Docs #### `EnvelopeGenerator.Service/MIGRATION_PLAN.md` **What:** Migration plan (v3) for porting `EnvelopeGenerator.Service_legacy` (VB.NET Windows Service) to `EnvelopeGenerator.Service` (C# Worker Service, .NET Framework 4.6.2). Documents connection string handling, job scheduling (Quartz → IHostedService), and deep analysis of legacy code. **Why it exists:** The Windows Service handles background jobs (email dispatch, envelope finalization). This plan ensures the port is complete and no job logic is silently dropped. **When you need it:** - Modifying background jobs (email sending, PDF finalization, access code dispatch) - Debugging service startup or job execution issues - Checking if a specific legacy VB.NET job has been ported --- ## 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) ```powershell # 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 ```powershell 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 ```csharp // 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: ```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`) ```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` ```javascript 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` ```javascript 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`