Merge branch 'master' into bugfix/devexpress-pdf-not-displaying

This commit is contained in:
2026-06-24 16:17:40 +02:00
53 changed files with 2283 additions and 210 deletions

View File

@@ -1,4 +1,4 @@
# EnvelopeGenerator — AI Context Reference
# EnvelopeGenerator — AI Context Reference
## Purpose
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.
@@ -125,6 +125,71 @@ Client ? WebUI:XXXX (Blazor Auto)
---
## Localization & Culture Management
**Current Architecture:** Blazor WebAssembly (client-side culture management)
### Implementation Details
**Culture Storage:**
- Culture preference stored in browser's `localStorage` (key: `AppCulture`)
- Managed by `CultureService.cs` (ReceiverUI/Services)
- Supported cultures: `de-DE`, `en-US`, `fr-FR`
**Culture Initialization:**
- **Location:** `Program.cs` (lines 53-57)
- Sets `CultureInfo.DefaultThreadCurrentCulture/UICulture` **before** app runs
- **WASM-Safe:** Each user has isolated browser instance
**Language Selector:**
- **Component:** `LanguageSelector.razor` (ReceiverUI/Shared)
- Displays flag icon + language name
- Changes culture via `CultureService.SetCultureAsync()`
- Navigates with `forceLoad: false` (smooth transition, no page reload)
### ⚠️ MIGRATION WARNING: Blazor Server/Auto
**Current approach is WASM-specific and will break in Server/Auto render modes!**
**Why it breaks:**
- `Program.cs:53-57` sets **global** `DefaultThreadCurrentCulture`
- In Server/Auto, one app instance serves **all users**
- User A selects German → User B sees German too (shared state)
- Thread-safety issues and culture conflicts
**Migration Checklist (when moving to Server/Auto):**
1. **Remove global culture initialization** from `Program.cs` (lines 53-57)
- See detailed warning comment in the code
2. **Add RequestLocalizationMiddleware** (Server-side approach):
```csharp
app.UseRequestLocalization(options => {
options.SupportedCultures = new[] { "de-DE", "en-US", "fr-FR" };
options.SupportedUICultures = options.SupportedCultures;
options.RequestCultureProviders.Insert(0, new CookieRequestCultureProvider());
});
```
3. **OR** Use **per-circuit culture** (Blazor Server approach):
- Store culture in circuit-scoped service
- Use `CascadingParameter` to distribute to components
- See: https://learn.microsoft.com/aspnet/core/blazor/globalization-localization
4. **Update `LanguageSelector.razor`:**
- Remove manual `CultureInfo.DefaultThreadCurrentCulture` assignment
- Use middleware/circuit culture provider instead
5. **Update `CultureService.cs`:**
- Integrate with Server-side culture provider
- May need to store in cookies instead of localStorage
**References:**
- Microsoft Docs: [Blazor Globalization/Localization](https://learn.microsoft.com/aspnet/core/blazor/globalization-localization)
- Current implementation: `Program.cs`, `CultureService.cs`, `LanguageSelector.razor`
---
## Key Files & Routes
### Client-Side Pages (WebUI.Client)
@@ -156,7 +221,7 @@ Client ? WebUI:XXXX (Blazor Auto)
---
## Coordinate System — CRITICAL
## Coordinate System — CRITICAL
**Database Format:** INCHES (GdPicture14 native)
**Origin:** Top-left corner
@@ -185,7 +250,7 @@ Client ? WebUI:XXXX (Blazor Auto)
---
## EnvelopeReceiver — PDF.js Viewer & Signing
## EnvelopeReceiver — PDF.js Viewer & Signing
**Route:** `/envelope/{EnvelopeKey}`
**Tech:** PDF.js 3.11.174 + Blazor Server (`@rendermode InteractiveServer`) + configurable quality
@@ -228,7 +293,7 @@ window.pdfViewer = {
---
## Signature Workflow — EnvelopeReceiver
## Signature Workflow — EnvelopeReceiver
**IMPORTANT:** iText7 NOT used (GPL license issue). Client-side overlay system only.
@@ -281,9 +346,9 @@ public sealed record SignatureCaptureDto {
### API Endpoints
**Controller:** `API/Controllers/CacheController.cs`
- `POST /api/Cache/SignatureCapture/{envelopeKey}` — Save
- `GET /api/Cache/SignatureCapture/{envelopeKey}` — Load
- `DELETE /api/Cache/SignatureCapture/{envelopeKey}` — Delete
- `POST /api/Cache/SignatureCapture/{envelopeKey}` — Save
- `GET /api/Cache/SignatureCapture/{envelopeKey}` — Load
- `DELETE /api/Cache/SignatureCapture/{envelopeKey}` — Delete
**Cache Key Format:**
```
@@ -349,7 +414,7 @@ public async Task<SenderLoginResult> LoginSenderAsync(string username, string pa
**Response:**
- `200 OK` ? Cookie set, redirect to `/sender`
- `401 Unauthorized` ? Show error: "Ungültige Anmeldedaten"
- `401 Unauthorized` ? Show error: "Ungültige Anmeldedaten"
- Other ? Show error: "Serverfehler"
**Cookie:** HTTP-only, Secure (HTTPS), SameSite=Strict
@@ -407,7 +472,7 @@ public async Task<EnvelopeLoginResult> LoginEnvelopeReceiverAsync(string key, st
---
## Mistakes History — Do NOT Repeat
## Mistakes History — Do NOT Repeat
| Mistake | Why Wrong |
|---|---|
@@ -426,9 +491,9 @@ public async Task<EnvelopeLoginResult> LoginEnvelopeReceiverAsync(string key, st
### Deprecated Projects
**DO NOT USE:**
- `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
- `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)
**DO NOT TOUCH:** `EnvelopeGenerator.Service`, `EnvelopeGenerator.Form`, `EnvelopeGenerator.BBTests`
@@ -453,8 +518,8 @@ Proves database uses INCHES natively.
## Quick Reference
### When working with coordinates:
1. **Database ? UI:** INCHES × 72 = PDF Points
2. **UI ? Display:** Points × scale = Pixels
1. **Database ? UI:** INCHES × 72 = PDF Points
2. **UI ? Display:** Points × scale = Pixels
3. **iText7 stamping:** Flip Y-axis (top-down ? bottom-up)
### When adding features: