From 88317e40f5062aeafa202b8794cead85fcf6a938 Mon Sep 17 00:00:00 2001 From: TekH Date: Thu, 18 Jun 2026 13:33:21 +0200 Subject: [PATCH] Add AGENTS.md - Quick-start guide for AI agents - Architecture overview (Blazor Auto Server+WASM hybrid) - Critical development commands (both API and WebUI must run) - Route structure with render mode requirements - Coordinate system conversions (INCHES in DB) - API architecture quirks and missing endpoints - Status color coding from legacy VB.NET app - Common mistakes to avoid - Configuration locations and migration status --- AGENTS.md | 263 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..8f57e84a --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,263 @@ +# EnvelopeGenerator - Agent Guide + +## Must Read First +- **`COPILOT_CONTEXT.md`** - Architecture, coordinate systems, migration status +- **`FORM_APPLICATION_CONTEXT.md`** - Legacy VB.NET features to migrate + +## Active Architecture (Post-Migration) + +**Frontend:** Blazor Auto (Server+WASM hybrid) +- **WebUI** (Server): `@rendermode InteractiveServer` - PDF viewers requiring DevExpress backend +- **WebUI.Client** (WASM): `@rendermode InteractiveWebAssembly` - Login, dashboards, business logic + +**Backend:** EnvelopeGenerator.API (ASP.NET Core 8.0) + +**Proxy:** YARP in WebUI routes `/api/*` → `localhost:8088` (API) + +### Deprecated Projects - DO NOT USE +- `EnvelopeGenerator.ReceiverUI` - Pure WASM (migrated to WebUI) +- `EnvelopeGenerator.Web` - Razor Pages (replaced by WebUI) +- **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.WebUI\EnvelopeGenerator.WebUI +dotnet run +``` + +**Critical:** Both must run simultaneously. WebUI 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.WebUI/ # Server-side Blazor components + ├─ Components/Pages/ # @rendermode InteractiveServer +EnvelopeGenerator.WebUI.Client/ # Client-side WASM components + ├─ Pages/ # @rendermode InteractiveWebAssembly + ├─ Services/ # HTTP API clients + ├─ Models/ # DTOs +``` + +## Route Structure (Critical) + +| Route | File Location | Render Mode | Purpose | +|-------|--------------|-------------|---------| +| `/` | `WebUI.Client/Pages/Index.razor` | WASM | Landing page | +| `/sender/login` | `WebUI.Client/Pages/LoginSenderPage.razor` | WASM | Sender auth | +| `/sender` | `WebUI.Client/Pages/EnvelopeSenderPage.razor` | WASM | Sender dashboard | +| `/envelope/login/{key}` | `WebUI.Client/Pages/LoginReceiverPage.razor` | WASM | Receiver auth | +| `/envelope/{key}` | `WebUI/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`. WebUI 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 (`WebUI/yarp.json`) +Routes `/api/*`, `/swagger/*`, `/openapi/*`, `/scalar/*` → `https://localhost:8088` + +### PDF.js Settings (`WebUI/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 WebUI (`dotnet run` in `EnvelopeGenerator.WebUI\EnvelopeGenerator.WebUI`) +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 (WebUI.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`