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:
263
AGENTS.md
Normal file
263
AGENTS.md
Normal 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`
|
||||
Reference in New Issue
Block a user