- replace outdated draft/update/send endpoint list with current POST /api/Envelope workflow contract
317 lines
13 KiB
Markdown
317 lines
13 KiB
Markdown
# 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.
|
||
|
||
---
|
||
|
||
### 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.
|
||
|
||
---
|
||
|
||
## 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 + API Host:** `EnvelopeGenerator.Server` (ASP.NET Core 8.0, merged Blazor + Web API host)
|
||
|
||
**Proxy:** YARP in `EnvelopeGenerator.Server` is used for external integrations (for example AuthHub forwarding), not for routing app APIs to `EnvelopeGenerator.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 Active Host
|
||
```powershell
|
||
# Terminal - Blazor + Web API host
|
||
cd EnvelopeGenerator.Server\EnvelopeGenerator.Server
|
||
dotnet run
|
||
```
|
||
|
||
**Critical:** `EnvelopeGenerator.Server` is the active runtime host for both UI and API controllers.
|
||
|
||
### 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.Server/
|
||
EnvelopeGenerator.Server/ # Server-side Blazor + API controllers
|
||
├─ Components/Pages/ # @rendermode InteractiveServer
|
||
├─ Controllers/ # Active Web API endpoints
|
||
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)
|
||
|
||
### Sender Workflow Endpoint
|
||
```
|
||
POST /api/Envelope # Create/update/save/send envelope workflow payload
|
||
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
|
||
```
|
||
|
||
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
|
||
}
|
||
}
|
||
```
|
||
|
||
### Server Host Config (`EnvelopeGenerator.Server/EnvelopeGenerator.Server/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 EnvelopeGenerator.Server (`dotnet run` in `EnvelopeGenerator.Server\EnvelopeGenerator.Server`)
|
||
2. Navigate to `https://localhost:5131` (or check console output for port)
|
||
3. Test sender login at `/sender/login`
|
||
4. Test receiver flow at `/envelope/login/{envelopeKey}`
|
||
|
||
## Database
|
||
|
||
**SQL Server** (DD_ECM)
|
||
- Connection string in `EnvelopeGenerator.Server/EnvelopeGenerator.Server/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:**
|
||
- App host (UI + API): `https://localhost:5131` or `http://localhost:7192`
|