Revised COPILOT_CONTEXT.md to align with the active EnvelopeGenerator architecture and workflows. Key updates: - Updated title and purpose for clarity. - Replaced migration notice with active app structure details. - Documented hosting model, including `Program.cs` setup. - Removed outdated deployment architecture section. - Reorganized route structure for WebAssembly and server pages. - Expanded authentication model for sender/receiver flows. - Added details on server-side data loading and caching. - Updated receiver PDF viewer and signature workflow sections. - Clarified coordinate system conversions and usage. - Marked deprecated projects and legacy files as "Do Not Touch." - Replaced mistakes history with workspace rules. - Updated last modified date to 2026-06-29.
352 lines
13 KiB
Markdown
352 lines
13 KiB
Markdown
# EnvelopeGenerator — Current Workspace Context
|
|
|
|
## Purpose
|
|
Digital document signing system for senders and receivers.
|
|
|
|
- Senders authenticate, view envelope lists, and manage envelope workflows.
|
|
- Receivers authenticate per envelope, open PDFs, create signatures, and apply them in the viewer.
|
|
- The active UI stack is `Blazor Auto` with server-side and WebAssembly render modes.
|
|
- Primary UI/PDF libraries are `DevExpress` and `PDF.js`.
|
|
|
|
---
|
|
|
|
## Active Application Structure
|
|
|
|
### Main Host
|
|
**Primary active application:** `EnvelopeGenerator.Server`
|
|
|
|
`EnvelopeGenerator.Server` is the current runtime host and contains:
|
|
- Blazor server host
|
|
- WebAssembly host integration
|
|
- API controllers
|
|
- authentication/authorization setup
|
|
- Swagger/Scalar setup
|
|
- YARP reverse proxy configuration
|
|
- DevExpress server-side services
|
|
- SQL Server distributed cache setup
|
|
|
|
### Client Project
|
|
**Client UI project:** `EnvelopeGenerator.Server.Client`
|
|
|
|
This project contains:
|
|
- WebAssembly-rendered pages
|
|
- client-side services
|
|
- client models and options
|
|
- sender and receiver login flows
|
|
|
|
### Other Projects
|
|
- `EnvelopeGenerator.Application` — MediatR/CQRS handlers and business logic
|
|
- `EnvelopeGenerator.Domain` — domain models, constants, shared abstractions
|
|
- `EnvelopeGenerator.Infrastructure` — EF Core and infrastructure services
|
|
- `EnvelopeGenerator.PdfEditor` — PDF-related backend utilities
|
|
- `EnvelopeGenerator.API` — still exists in the solution, but the current merged app host is `EnvelopeGenerator.Server`
|
|
|
|
### Legacy / Do Not Touch
|
|
- `EnvelopeGenerator.Service`
|
|
- `EnvelopeGenerator.Form`
|
|
- `EnvelopeGenerator.BBTests`
|
|
- `EnvelopeGenerator.CommonServices`
|
|
|
|
---
|
|
|
|
## Current Hosting Model
|
|
|
|
`EnvelopeGenerator.Server/Program.cs` currently configures:
|
|
- `AddRazorComponents()` with both interactive server and interactive WebAssembly components
|
|
- `AddControllers()` and `MapControllers()`
|
|
- JWT authentication for sender and receiver flows
|
|
- cookie authentication
|
|
- authorization policies using `AuthScheme.Sender`, `AuthScheme.Receiver`, `AuthPolicy.Sender`, `AuthPolicy.Receiver`
|
|
- `AddReverseProxy()` with `yarp.json`
|
|
- Swagger / OpenAPI / Scalar
|
|
- distributed SQL Server cache
|
|
- DevExpress Blazor and DevExpress PDF Viewer server-side services
|
|
- request localization middleware
|
|
|
|
This means the active app is a **merged UI + API host**.
|
|
|
|
---
|
|
|
|
## Reverse Proxy
|
|
|
|
**Config file:** `EnvelopeGenerator.Server/EnvelopeGenerator.Server/yarp.json`
|
|
|
|
Current YARP usage is focused on **AuthHub forwarding**, not a general `/api/* -> EnvelopeGenerator.API` proxy.
|
|
|
|
Configured routes forward:
|
|
- `POST /api/auth` -> AuthHub `/api/auth/sign-flow`
|
|
- `POST /api/Auth/envelope-receiver/{key}` -> AuthHub `/api/auth/envelope-receiver/{key}?cookie=true`
|
|
|
|
---
|
|
|
|
## Active Routes and Files
|
|
|
|
### WebAssembly Pages (`EnvelopeGenerator.Server.Client`)
|
|
| Route | File | Render Mode | Purpose |
|
|
|---|---|---|---|
|
|
| `/` | `EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Pages/IndexPage.razor` | WebAssembly | Landing page |
|
|
| `/sender/login` | `EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Pages/LoginSenderPage.razor` | WebAssembly | Sender login |
|
|
| `/sender` | `EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Pages/EnvelopeSenderPage.razor` | WebAssembly (`prerender: false`) | Sender dashboard |
|
|
| `/envelope/login/{EnvelopeKey}` | `EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Pages/LoginReceiverPage.razor` | WebAssembly | Receiver login |
|
|
|
|
### Server Pages (`EnvelopeGenerator.Server`)
|
|
| Route | File | Render Mode | Purpose |
|
|
|---|---|---|---|
|
|
| `/envelope/{EnvelopeKey}` | `EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverPage.razor` | InteractiveServer | Main receiver PDF viewer and signing page |
|
|
| `/envelope/DxPdfViewer` | `EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverPage_DxPdfViewer.razor` | InteractiveServer | DevExpress PDF Viewer test page |
|
|
| `/envelope/{EnvelopeKey}/DxReportViewer` | `EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverPage_DxReportViewer.razor` | InteractiveServer | DevExpress report-based PDF rendering |
|
|
| `/envelope/Embed` | `EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverPage_embed.razor` | InteractiveServer | Embedded browser PDF view test page |
|
|
|
|
---
|
|
|
|
## Current API Location
|
|
|
|
The active application exposes controllers from:
|
|
`EnvelopeGenerator.Server/EnvelopeGenerator.Server/Controllers`
|
|
|
|
Current controller set includes:
|
|
- `AnnotationController`
|
|
- `AuthController`
|
|
- `CacheController`
|
|
- `ConfigController`
|
|
- `DocumentController`
|
|
- `EmailTemplateController`
|
|
- `EnvelopeController`
|
|
- `EnvelopeReceiverController`
|
|
- `EnvelopeTypeController`
|
|
- `HistoryController`
|
|
- `LocalizationController`
|
|
- `ReadOnlyController`
|
|
- `ReceiverController`
|
|
- `SignatureController`
|
|
- `TfaRegistrationController`
|
|
|
|
Do not assume API behavior lives only in `EnvelopeGenerator.API`; the active merged host contains controller endpoints directly.
|
|
|
|
---
|
|
|
|
## Authentication Model
|
|
|
|
### Sender
|
|
Client login page uses `EnvelopeGenerator.Server.Client/Services/AuthService.cs`.
|
|
|
|
Key sender endpoints:
|
|
- `POST /api/auth?cookie=true` — login
|
|
- `GET /api/auth/check` — current sender access check
|
|
- `POST /api/auth/logout` — logout
|
|
|
|
### Receiver
|
|
Receiver authentication is **per envelope**.
|
|
|
|
Key receiver endpoints used by client services:
|
|
- `POST /api/Auth/envelope-receiver/{envelopeKey}` — submit access code
|
|
- `GET /api/auth/check/envelope/{envelopeKey}` — check access
|
|
- `POST /api/auth/logout/envelope/{envelopeKey}` — logout receiver for one envelope
|
|
|
|
Receiver cookie resolution in server auth uses an envelope-specific cookie name derived from:
|
|
- `AuthTokenSignFLOWReceiver.{envelopeKey}` pattern
|
|
|
|
### Receiver Server-Side Authorization
|
|
`EnvelopeReceiverPage.razor` does **not** rely on its own API access-check call for page authorization.
|
|
|
|
It uses:
|
|
- `EnvelopeGenerator.Server/EnvelopeGenerator.Server/Services/EnvelopeReceiverAuthorizationService.cs`
|
|
|
|
Behavior:
|
|
- tries the current `HttpContext.User`
|
|
- if needed, reads the per-envelope receiver cookie directly
|
|
- validates the JWT with the receiver auth scheme
|
|
- verifies the token subject matches the route envelope key
|
|
|
|
---
|
|
|
|
## Receiver Page Data Loading
|
|
|
|
Main server-side page data service:
|
|
- `EnvelopeGenerator.Server/EnvelopeGenerator.Server/Services/EnvelopeReceiverPageDataService.cs`
|
|
|
|
This service loads directly via MediatR and distributed cache:
|
|
- document bytes
|
|
- receiver envelope data
|
|
- signature placeholders
|
|
- cached signature data
|
|
|
|
For signature placeholders, the service:
|
|
- reads document receiver elements
|
|
- filters them for the authenticated receiver
|
|
- converts coordinates to `UnitOfLength.Point` before UI use
|
|
|
|
---
|
|
|
|
## Receiver PDF Viewer
|
|
|
|
**Main file:** `EnvelopeGenerator.Server/EnvelopeGenerator.Server/Components/Pages/EnvelopeReceiverPage.razor`
|
|
|
|
Current receiver viewer characteristics:
|
|
- route: `/envelope/{EnvelopeKey}`
|
|
- render mode: `InteractiveServer`
|
|
- PDF rendering: `PDF.js`
|
|
- toolbar: page navigation, zoom, thumbnail toggle, signature navigation, signature reset
|
|
- signature popup: `DxPopup`
|
|
- thumbnail sidebar: resizable and stored in `localStorage`
|
|
|
|
### JS Assets
|
|
- `EnvelopeGenerator.Server/EnvelopeGenerator.Server/wwwroot/js/pdf-viewer.js`
|
|
- `EnvelopeGenerator.Server/EnvelopeGenerator.Server/wwwroot/js/receiver-signature.js`
|
|
|
|
### CSS
|
|
- `EnvelopeGenerator.Server/EnvelopeGenerator.Server/wwwroot/css/envelope-viewer.css`
|
|
|
|
### PDF.js CDN
|
|
- `https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js`
|
|
- `https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf_viewer.min.css`
|
|
|
|
---
|
|
|
|
## Signature Workflow
|
|
|
|
Receiver signatures are handled as a **viewer overlay workflow**.
|
|
|
|
### Current behavior
|
|
1. Server-side authorization validates receiver access.
|
|
2. The page loads document bytes, receiver data, signature placeholders, and cached signature state.
|
|
3. If no cached signature exists, the signature popup opens automatically.
|
|
4. Receiver creates signature using one of three tabs:
|
|
- draw
|
|
- text
|
|
- image
|
|
5. Required metadata:
|
|
- full name
|
|
- place
|
|
6. Optional metadata:
|
|
- position
|
|
7. Clicking a signature placeholder applies the signature as a client-side overlay in the PDF viewer.
|
|
|
|
### Important note
|
|
Although `itext` is referenced by the server project, the current receiver page signing flow is **not PDF stamping-based**. The active receiver UI uses client-side overlay behavior in the viewer.
|
|
|
|
### Signature DTO
|
|
`EnvelopeGenerator.Server.Client/Models/SignatureCaptureDto.cs`
|
|
|
|
```csharp
|
|
public sealed record SignatureCaptureDto {
|
|
public required string DataUrl { get; init; }
|
|
public required string FullName { get; init; }
|
|
public string Position { get; init; } = "";
|
|
public required string Place { get; init; }
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Signature Cache
|
|
|
|
### Active cache model
|
|
The current receiver page cache flow is handled directly in the server project through:
|
|
- `EnvelopeReceiverPageDataService`
|
|
- `IDistributedCache`
|
|
- SQL Server distributed cache configuration from `Program.cs`
|
|
|
|
### Cache key format
|
|
Current server-side key prefix:
|
|
- `envelope-generator.receiver-ui.signature:{receiverSignature}`
|
|
|
|
This is different from an envelope-key-only cache convention.
|
|
|
|
### Config
|
|
`EnvelopeGenerator.Server/EnvelopeGenerator.Server/Options/CacheOptions.cs`
|
|
- section name: `Cache`
|
|
- option: `SignatureCacheExpiration`
|
|
|
|
### Related controller
|
|
A cache API controller also exists in:
|
|
- `EnvelopeGenerator.Server/EnvelopeGenerator.Server/Controllers/CacheController.cs`
|
|
|
|
---
|
|
|
|
## Sender Dashboard
|
|
|
|
**Main file:** `EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Pages/EnvelopeSenderPage.razor`
|
|
|
|
Current behavior:
|
|
- checks sender access through `AuthService.CheckSenderAccessAsync()`
|
|
- redirects to `/sender/login` when unauthorized
|
|
- loads envelope list through client `EnvelopeService`
|
|
- separates envelopes into active/completed tabs
|
|
- uses `DevExpress DxGrid`
|
|
|
|
The sender page is active, but create/edit/delete actions are still marked with TODO behavior in the UI page.
|
|
|
|
---
|
|
|
|
## Localization
|
|
|
|
Current server host localization setup in `Program.cs`:
|
|
- supported cultures: `de-DE`, `en-US`
|
|
- request localization middleware is enabled
|
|
- `QueryStringRequestCultureProvider` is added
|
|
- cookie-based localization services are registered via `AddCookieBasedLocalizer()`
|
|
|
|
Do not assume the old ReceiverUI-only `localStorage` culture approach is the current source of truth for the active host.
|
|
|
|
---
|
|
|
|
## Coordinate System
|
|
|
|
### Source data
|
|
Database signature coordinates are still based on:
|
|
- **unit:** inches
|
|
- **origin:** top-left
|
|
- **axes:** X right, Y down
|
|
|
|
### Relevant conversions
|
|
- inches -> PDF points: `x_pt = x_inches * 72`
|
|
- inches -> DevExpress DX units: `x_dx = x_inches * 100`
|
|
|
|
### Current receiver page behavior
|
|
The server page data service converts signature placeholders to **points** before sending them into the viewer workflow.
|
|
|
|
### Unit systems to keep in mind
|
|
| System | Unit | Origin | Y-axis |
|
|
|---|---|---|---|
|
|
| Database | Inches | Top-left | Down |
|
|
| PDF.js display | Pixels | Top-left | Down |
|
|
| PDF points | Points | Depends on PDF model | Depends on consumer |
|
|
| DevExpress DX | 1/100 inch style coordinates | Top-left-oriented usage in this app | Down-oriented usage |
|
|
|
|
---
|
|
|
|
## Key Services and Files
|
|
|
|
### Client services
|
|
- `EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Services/AuthService.cs`
|
|
- `EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Services/EnvelopeService.cs`
|
|
- `EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Services/DocumentService.cs`
|
|
- `EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Services/SignatureCacheService.cs`
|
|
|
|
### Server services
|
|
- `EnvelopeGenerator.Server/EnvelopeGenerator.Server/Services/EnvelopeAuthService.cs`
|
|
- `EnvelopeGenerator.Server/EnvelopeGenerator.Server/Services/IEnvelopeAuthService.cs`
|
|
- `EnvelopeGenerator.Server/EnvelopeGenerator.Server/Services/EnvelopeReceiverAuthorizationService.cs`
|
|
- `EnvelopeGenerator.Server/EnvelopeGenerator.Server/Services/EnvelopeReceiverPageDataService.cs`
|
|
|
|
### Server config and host files
|
|
- `EnvelopeGenerator.Server/EnvelopeGenerator.Server/Program.cs`
|
|
- `EnvelopeGenerator.Server/EnvelopeGenerator.Server/yarp.json`
|
|
|
|
---
|
|
|
|
## Working Rules for This Workspace
|
|
|
|
- Treat `EnvelopeGenerator.Server` as the active main application host.
|
|
- Treat `EnvelopeGenerator.Server.Client` as the active client UI project.
|
|
- Prefer current `Server` / `Server.Client` paths over old `WebUI` / `ReceiverUI` references.
|
|
- Do not use `EnvelopeGenerator.Web` or `EnvelopeGenerator.ReceiverUI` as the primary implementation target unless explicitly asked.
|
|
- Do not modify the legacy VB.NET projects unless explicitly requested.
|
|
- For receiver PDF/signature work, prefer the current `PDF.js`-based flow in `EnvelopeReceiverPage.razor`.
|
|
- For DevExpress PDF viewer issues, remember server-side services are registered in `EnvelopeGenerator.Server`.
|
|
|
|
---
|
|
|
|
**Last Updated:** 2026-06-29
|