diff --git a/COPILOT_CONTEXT.md b/COPILOT_CONTEXT.md index f145f8d8..995ba9c8 100644 --- a/COPILOT_CONTEXT.md +++ b/COPILOT_CONTEXT.md @@ -1,72 +1,107 @@ # EnvelopeGenerator — AI Context Reference ## Purpose -Digital document signing system with **unified Blazor WASM frontend** for both Senders and Receivers. Senders create envelopes and place signature fields. Receivers view PDFs, sign documents, export stamped PDFs. +Digital document signing system with **unified Blazor Auto (Server+WASM hybrid) frontend** for both Senders and Receivers. Senders create envelopes and place signature fields. Receivers view PDFs, sign documents, export stamped PDFs. **Primary Libraries:** DevExpress + PDF.js (PSPDFKit removed) --- +## Migration Notice + +**EnvelopeGenerator.ReceiverUI ? EnvelopeGenerator.WebUI Migration** + +The project has been migrated from pure Blazor WebAssembly (`ReceiverUI`) to **Blazor Auto (Server+WASM hybrid)** architecture (`WebUI`) to resolve DevExpress `DxPdfViewer` compatibility issues. + +**Reason:** DevExpress `DxPdfViewer` requires backend server-side rendering services that are NOT available in pure WebAssembly projects. + +**New Structure:** +- **WebUI** (Server project): Hosts server-side components, YARP proxy, DevExpress backend services +- **WebUI.Client** (WASM project): Client-side components, business logic, services + +**Migration Details:** See `MIGRATION_CONTEXT.md` + +--- + ## Deployment Architecture **Two Presentation Projects (Both Required):** 1. **EnvelopeGenerator.API** (ASP.NET Core Web API) - Runs independently (development & production) - - **YARP Reverse Proxy** configured via `yarp.json` - - Proxies requests to: - - `EnvelopeGenerator.ReceiverUI` (Blazor WASM) - - External Auth.API service - - Serves as single entry point for all requests + - Backend services for document management, authentication, signature endpoints + - Serves as API endpoint for WebUI -2. **EnvelopeGenerator.ReceiverUI** (Blazor WebAssembly) - - Runs on separate host/port - - Accessed **only through API proxy** (not directly) - - Serves static files (HTML, JS, CSS, WASM) +2. **EnvelopeGenerator.WebUI** (Blazor Auto - Server+WASM Hybrid) + - **Server Project (`EnvelopeGenerator.WebUI`):** + - **YARP Reverse Proxy** configured via `yarp.json` + - Proxies `/api/*` requests to `API:8088` + - Hosts server-side components (`@rendermode InteractiveServer`) + - DevExpress server-side services (DxPdfViewer backend) + - **Client Project (`EnvelopeGenerator.WebUI.Client`):** + - Client-side components (`@rendermode InteractiveWebAssembly`) + - Business logic services (AuthService, DocumentService, etc.) + - WASM runtime **Request Flow:** ``` -Client ? API:8088 (YARP Proxy) ? ReceiverUI:52936 (Blazor WASM) - ? Auth.API:9090 (External Auth Service) +Client ? WebUI:XXXX (Blazor Auto) + ?? Server-side Pages (DxPdfViewer) + ?? Client-side Pages (WASM) + ?? YARP Proxy: /api/* ? API:8088 ``` -**Configuration:** `EnvelopeGenerator.API/yarp.json` +**Configuration:** `EnvelopeGenerator.WebUI/yarp.json` --- -## ReceiverUI Route Structure +## WebUI Route Structure ### Root Route -| Route | File | Purpose | -|---|---|---| -| `/` | `Index.razor` | Application entry point (landing page). | +| Route | File | Location | Render Mode | +|---|---|---|---| +| `/` | `Index.razor` | `WebUI.Client/Pages/` | `@rendermode InteractiveWebAssembly` | ### Sender Routes -| Route | File | Purpose | -|---|---|---| -| `/sender/login` | `LoginSenderPage.razor` | Username/password authentication | -| `/sender` | `EnvelopeSenderPage.razor` | Sender dashboard (envelope list) | +| Route | File | Location | Render Mode | +|---|---|---|---| +| `/sender/login` | `LoginSenderPage.razor` | `WebUI.Client/Pages/` | `@rendermode InteractiveWebAssembly` | +| `/sender` | `EnvelopeSenderPage.razor` | `WebUI.Client/Pages/` | `@rendermode InteractiveWebAssembly` | -### Receiver Routes -| Route | File | Purpose | -|---|---|---| -| `/envelope/login/{EnvelopeKey}` | `LoginReceiverPage.razor` | Access code authentication for specific envelope | -| `/envelope/{EnvelopeKey}` | `EnvelopeReceiverPage.razor` | View & sign envelope (PDF.js viewer) | +### Receiver Routes (PDF Viewers) +| Route | File | Location | Render Mode | +|---|---|---|---| +| `/envelope/login/{EnvelopeKey}` | `LoginReceiverPage.razor` | `WebUI.Client/Pages/` | `@rendermode InteractiveWebAssembly` | +| `/envelope/{EnvelopeKey}` | `EnvelopeReceiverPage.razor` | `WebUI/Components/Pages/` | `@rendermode InteractiveServer` | +| `/envelope/DxPdfViewer` | `EnvelopeReceiverPage_DxPdfViewer.razor` | `WebUI/Components/Pages/` | `@rendermode InteractiveServer` | +| `/envelope/{EnvelopeKey}/DxReportViewer` | `EnvelopeReceiverPage_DxReportViewer.razor` | `WebUI/Components/Pages/` | `@rendermode InteractiveServer` | +| `/envelope/Embed` | `EnvelopeReceiverPage_embed.razor` | `WebUI/Components/Pages/` | `@rendermode InteractiveServer` | **Multi-Envelope Support:** Receivers can login to multiple envelopes simultaneously (per-envelope cookie authentication). +**Render Mode Strategy:** +- **Client-side Pages (WASM):** Login, Sender dashboard, Index (no DevExpress backend required) +- **Server-side Pages (Server):** PDF viewers (DevExpress DxPdfViewer requires backend) + --- ## Architecture Evolution -### Old Architecture (Deprecated) +### Old Architecture (Deprecated v1) - **Sender UI:** `EnvelopeGenerator.Web` (Razor Pages + PSPDFKit) -- **Receiver UI:** `EnvelopeGenerator.ReceiverUI` (Blazor WASM + PDF.js) +- **Receiver UI:** Separate project - **Backend:** `EnvelopeGenerator.API` -### Current Architecture -- **Unified Frontend:** `EnvelopeGenerator.ReceiverUI` (Blazor WASM) — **Both Senders & Receivers** -- **Backend:** `EnvelopeGenerator.API` — **Both Senders & Receivers** +### Intermediate Architecture (Deprecated v2) +- **Unified Frontend:** `EnvelopeGenerator.ReceiverUI` (Pure Blazor WASM) +- **Backend:** `EnvelopeGenerator.API` +- **Issue:** DevExpress `DxPdfViewer` displayed blank screen (no backend services in WASM) + +### Current Architecture (Active) +- **Frontend:** `EnvelopeGenerator.WebUI` (Blazor Auto - Server+WASM Hybrid) + - **WebUI** (Server): Server-side components, YARP proxy, DevExpress backend + - **WebUI.Client** (WASM): Client-side components, services, business logic +- **Backend:** `EnvelopeGenerator.API` - **Libraries:** DevExpress + PDF.js - **PSPDFKit:** **REMOVED** @@ -77,12 +112,14 @@ Client ? API:8088 (YARP Proxy) ? ReceiverUI:52936 (Blazor WASM) | Project | Target | Purpose | |---|---|---| | `EnvelopeGenerator.API` | net8.0 | ASP.NET Core Web API. Backend for **both Senders & Receivers**. Auth, PDF serving, signature endpoints. | -| `EnvelopeGenerator.ReceiverUI` | net8.0 WASM | **Unified Blazor WebAssembly Frontend**. UI for **both Senders & Receivers**. YARP proxy to API. | +| `EnvelopeGenerator.WebUI` | net8.0 | **Blazor Auto Server Project**. YARP proxy, server-side components, DevExpress backend services. | +| `EnvelopeGenerator.WebUI.Client` | net8.0 WASM | **Blazor Auto Client Project**. Client-side components, services, business logic. | +| `EnvelopeGenerator.ReceiverUI` | net8.0 WASM | **DEPRECATED.** Pure Blazor WASM (migrated to WebUI). | | `EnvelopeGenerator.Web` | net7/8/9 | **DEPRECATED.** Legacy Razor Pages (Sender UI). No longer used. | | `EnvelopeGenerator.Application` | multi | MediatR CQRS handlers. Business logic. | | `EnvelopeGenerator.Domain` | multi | Domain models, constants, interfaces. | | `EnvelopeGenerator.Infrastructure` | multi | EF Core repos, DB context. | -| `EnvelopeGenerator.PdfEditor` | multi | iText7 utilities (NOT used in ReceiverUI). | +| `EnvelopeGenerator.PdfEditor` | multi | iText7 utilities (NOT used in WebUI). | | `EnvelopeGenerator.DependencyInjection` | multi | DI registration helpers. | | **VB.NET projects** (Service/Form/BBTests) | net462 | **Legacy. Do NOT touch.** | @@ -90,18 +127,31 @@ Client ? API:8088 (YARP Proxy) ? ReceiverUI:52936 (Blazor WASM) ## Key Files & Routes -| File | Route/Purpose | +### Client-Side Pages (WebUI.Client) +| File | Route | Purpose | +|---|---|---| +| `WebUI.Client/Pages/Index.razor` | `/` | Application entry point (landing page). | +| `WebUI.Client/Pages/EnvelopeSenderPage.razor` | `/sender` | Sender dashboard (envelope list). | +| `WebUI.Client/Pages/LoginSenderPage.razor` | `/sender/login` | Sender username/password auth. | +| `WebUI.Client/Pages/LoginReceiverPage.razor` | `/envelope/login/{EnvelopeKey}` | Receiver access code auth. | + +### Server-Side Pages (WebUI) +| File | Route | Purpose | +|---|---|---| +| `WebUI/Components/Pages/EnvelopeReceiverPage.razor` | `/envelope/{key}` | Receiver PDF viewer & signing (PDF.js). | +| `WebUI/Components/Pages/EnvelopeReceiverPage_DxPdfViewer.razor` | `/envelope/DxPdfViewer` | DevExpress PDF Viewer (test page). | +| `WebUI/Components/Pages/EnvelopeReceiverPage_DxReportViewer.razor` | `/envelope/{key}/DxReportViewer` | DevExpress Report Viewer. | +| `WebUI/Components/Pages/EnvelopeReceiverPage_embed.razor` | `/envelope/Embed` | Embedded PDF viewer (iframe). | + +### Services & Assets +| File | Purpose | |---|---| -| `ReceiverUI/Pages/Index.razor` | `/` — Application entry point (landing page). | -| `ReceiverUI/Pages/EnvelopeSenderPage.razor` | `/sender` — Sender dashboard (envelope list). | -| `ReceiverUI/Pages/EnvelopeReceiverPage.razor` | `/envelope/{key}` — Receiver PDF viewer & signing. | -| `ReceiverUI/Pages/LoginSenderPage.razor` | `/sender/login` — Sender username/password auth. | -| `ReceiverUI/Pages/LoginReceiverPage.razor` | `/envelope/login/{EnvelopeKey}` — Receiver access code auth. | -| `ReceiverUI/wwwroot/js/pdf-viewer.js` | PDF.js wrapper (zoom, pagination, thumbnails). | -| `ReceiverUI/wwwroot/js/receiver-signature.js` | Signature pad (draw/type/image). | -| `ReceiverUI/wwwroot/css/envelope-viewer.css` | EnvelopeViewer styles. | -| `ReceiverUI/Services/AuthService.cs` | Receiver + Sender authentication. | -| `ReceiverUI/Services/SignatureCacheService.cs` | Signature caching (Redis/SQL). | +| `WebUI.Client/Services/AuthService.cs` | Receiver + Sender authentication. | +| `WebUI.Client/Services/SignatureCacheService.cs` | Signature caching (Redis/SQL). | +| `WebUI.Client/Services/DocumentService.cs` | PDF document retrieval. | +| `WebUI/wwwroot/js/pdf-viewer.js` | PDF.js wrapper (zoom, pagination, thumbnails). | +| `WebUI/wwwroot/js/receiver-signature.js` | Signature pad (draw/type/image). | +| `WebUI/wwwroot/css/envelope-viewer.css` | EnvelopeViewer styles. | | `API/Controllers/CacheController.cs` | Signature cache endpoints. | --- @@ -138,8 +188,8 @@ Client ? API:8088 (YARP Proxy) ? ReceiverUI:52936 (Blazor WASM) ## EnvelopeReceiver — PDF.js Viewer & Signing **Route:** `/envelope/{EnvelopeKey}` -**Tech:** PDF.js 3.11.174 + Blazor WASM + configurable quality -**File:** `ReceiverUI/Pages/EnvelopeReceiverPage.razor` +**Tech:** PDF.js 3.11.174 + Blazor Server (`@rendermode InteractiveServer`) + configurable quality +**File:** `WebUI/Components/Pages/EnvelopeReceiverPage.razor` ### Key Features 1. HiDPI/Retina support (4x quality) @@ -150,7 +200,7 @@ Client ? API:8088 (YARP Proxy) ? ReceiverUI:52936 (Blazor WASM) 6. Responsive (desktop/mobile) ### Configuration -**File:** `ReceiverUI/wwwroot/appsettings.json` +**File:** `WebUI/wwwroot/appsettings.json` ```json { @@ -164,7 +214,7 @@ Client ? API:8088 (YARP Proxy) ? ReceiverUI:52936 (Blazor WASM) ``` ### JavaScript API -**File:** `ReceiverUI/wwwroot/js/pdf-viewer.js` +**File:** `WebUI/wwwroot/js/pdf-viewer.js` ```javascript window.pdfViewer = { @@ -211,7 +261,7 @@ window.pdfViewer = { - Session state: `_capturedSignature` (lost on refresh) ### Data Model -**File:** `ReceiverUI/Models/SignatureCaptureDto.cs` +**File:** `WebUI.Client/Models/SignatureCaptureDto.cs` ```csharp public sealed record SignatureCaptureDto { @@ -250,7 +300,7 @@ signature:91751687-8ae6-4777-bf5f-b8846085e62e:{envelopeKey} ``` ### Service -**File:** `ReceiverUI/Services/SignatureCacheService.cs` +**File:** `WebUI.Client/Services/SignatureCacheService.cs` ```csharp public class SignatureCacheService { @@ -267,11 +317,11 @@ public class SignatureCacheService { ## Sender Login **Route:** `/sender/login` -**File:** `ReceiverUI/Pages/LoginSenderPage.razor` +**File:** `WebUI.Client/Pages/LoginSenderPage.razor` **Tech:** Bootstrap 5 + DevExpress Blazing Berry theme ### AuthService Extension -**File:** `ReceiverUI/Services/AuthService.cs` +**File:** `WebUI.Client/Services/AuthService.cs` ```csharp public enum SenderLoginResult { Success, InvalidCredentials, Error } @@ -316,7 +366,7 @@ public async Task LoginSenderAsync(string username, string pa ## Receiver Login **Route:** `/envelope/login/{EnvelopeKey}` -**File:** `ReceiverUI/Pages/LoginReceiverPage.razor` +**File:** `WebUI.Client/Pages/LoginReceiverPage.razor` **Multi-Envelope Support:** Cookies are stored per-envelope (e.g., `AuthTokenSignFLOWReceiver.{envelopeKey}`), allowing simultaneous authentication for multiple envelopes in the same browser session. @@ -344,7 +394,7 @@ public async Task LoginEnvelopeReceiverAsync(string key, st --- -## NuGet Packages (ReceiverUI) +## NuGet Packages (WebUI.Client) | Package | Version | Purpose | |---|---|---| @@ -376,7 +426,8 @@ public async Task LoginEnvelopeReceiverAsync(string key, st ### Deprecated Projects **DO NOT USE:** -- `EnvelopeGenerator.Web` (Razor Pages) — Replaced by unified ReceiverUI +- `EnvelopeGenerator.ReceiverUI` (Pure Blazor WASM) — Migrated to WebUI (DevExpress compatibility issue) +- `EnvelopeGenerator.Web` (Razor Pages) — Replaced by unified WebUI - PSPDFKit — Removed, use PDF.js + DevExpress instead ### Legacy Projects (VB.NET) @@ -411,14 +462,16 @@ Proves database uses INCHES natively. 2. Prefer simplicity over complexity 3. Use `appsettings.json` for configuration 4. Keep consistent with existing design (Bootstrap 5 + Blazing Berry) -5. **Unified frontend:** ReceiverUI serves both Senders and Receivers +5. **Unified frontend:** WebUI serves both Senders and Receivers +6. **Render mode:** Client-side (WASM) for login/dashboard, Server-side for PDF viewers ### When debugging: 1. **Coordinates:** Always check unit system (inches/points/pixels) 2. **Authentication:** Check cookie name/domain/SameSite 3. **Cache:** Check Redis/SQL connection + key format -4. **Frontend confusion:** Only use ReceiverUI (Web is deprecated) +4. **Frontend confusion:** Only use WebUI (ReceiverUI/Web are deprecated) +5. **Blank DxPdfViewer:** Ensure page has `@rendermode InteractiveServer` --- -**Last Updated:** Session 19 (Razor file naming convention + Index route proxy) +**Last Updated:** 2025-01-27 (ReceiverUI ? WebUI migration complete)