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
This commit is contained in:
2026-06-18 13:33:21 +02:00
parent 3a2fa77862
commit 88317e40f5

263
AGENTS.md Normal file
View File

@@ -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`