docs: update SKILLS.md with complete ANCPI ePay documentation

This commit is contained in:
AI Assistant
2026-03-23 04:20:37 +02:00
parent c9ecd284c7
commit b7302d274a
+84 -1
View File
@@ -214,6 +214,89 @@ siruta, layerId, status, totalRemote, totalLocal, newFeatures, removedFeatures,
---
## ANCPI ePay — CF Extract Ordering
### Overview
Orders CF extracts (Carte Funciară) from ANCPI ePay (epay.ancpi.ro).
Separate auth system from eTerra. Uses credits (prepaid, 1 per extract).
### Critical Discovery: ID Mapping
- **ePay internal county IDs = eTerra WORKSPACE_IDs** (CLUJ=127, ALBA=10, etc.)
- **ePay UAT IDs = SIRUTA codes** (Cluj-Napoca=54975, Florești=57706)
- This means ZERO discovery calls needed — use GisUat.workspacePk + siruta directly
### Auth Flow (OpenAM)
1. GET login page with `module=SelfRegistration&goto=http://epay.ancpi.ro:80/epay/LogIn.action`
2. POST credentials (`IDToken1`, `IDToken2`) → gets `AMAuthCookie` (NOT `iPlanetDirectoryPro`)
3. Navigate to `http://epay.ancpi.ro:80/epay/LogIn.action` (HTTP, not HTTPS!) for JSESSIONID
4. Session TTL: ~1 hour
### Order Flow (4 requests per batch)
1. `POST AddToCartOrWishListFromPost.action` × N → basketRowIds
2. `POST EpayJsonInterceptor.action` (multipart) × N → `reqType=saveProductMetadataForBasketItem` + `productMetadataJSON`
3. `POST EditCartSubmit.action``goToCheckout=true` (ONE submit for ALL items)
4. `GET CheckoutConfirmationSubmit.action` → confirms order
5. Poll `ShowOrderDetails.action?orderId=...` → parse documents from HTML-encoded JSON (`"``"`)
6. `POST DownloadFile.action?typeD=4&id=...` with `Content-Type: application/pdf` in REQUEST header
### ePay Endpoint Gotchas
1. **EpayJsonInterceptor uses form-urlencoded** (NOT JSON): `reqType=nomenclatorUAT&countyId=127`
2. **saveProductMetadataForBasketItem uses multipart/form-data** (form-data npm package)
3. **CF/CAD use `stringValues[0]`** (array!), not `stringValue`
4. **Document IDs are HTML-encoded** in ShowOrderDetails: `"idDocument":47301767` → decode first
5. **DownloadFile sends Content-Type: application/pdf in the REQUEST** (not response)
6. **EditCartSubmit returns 200** (not redirect) — Angular does client-side redirect to CheckoutConfirmation
7. **SearchEstate needs `identificator`/`judet`/`uat`** (not `identifier`/`countyId`/`uatId`), plus requires internal IDs
8. **MinIO metadata must be ASCII** — strip diacritics from values (`Florești``Floresti`)
### Dedup Protection
- **Queue level**: batch key = sorted cadastral numbers, 60s dedup window
- **API level**: optional `nonce` field, 60s idempotency cache
- **Test endpoint**: 30s dedup on hardcoded test parcels
### Key Files
| File | Purpose |
|------|---------|
| `services/epay-client.ts` | HTTP client (login, cart, metadata, submit, poll, download) |
| `services/epay-queue.ts` | Batch queue with dedup |
| `services/epay-storage.ts` | MinIO storage helpers |
| `services/epay-counties.ts` | County index mapping (legacy, not needed for ordering) |
| `services/epay-session-store.ts` | Session singleton |
| `services/epay-types.ts` | TypeScript types |
| `components/epay-connect.tsx` | Connection widget |
| `components/epay-order-button.tsx` | Per-parcel order button |
| `components/epay-tab.tsx` | Full "Extrase CF" tab |
| `api/ancpi/session/` | Connect/disconnect |
| `api/ancpi/order/` | Create batch orders |
| `api/ancpi/orders/` | List all extracts |
| `api/ancpi/credits/` | Credit balance |
| `api/ancpi/download/` | Stream PDF from MinIO |
| `api/ancpi/test/` | Diagnostic/test endpoint (temporary) |
### DB Model: CfExtract
- `orderId` — shared across batch items (NOT unique)
- `nrCadastral`, `siruta`, `judetName`, `uatName` — parcel identity
- `status` — pending|queued|cart|ordering|polling|downloading|completed|failed|cancelled
- `minioPath``parcele/{nrCadastral}/{idx}_Extras CF_{nrCadastral} - {DD-MM-YYYY}.pdf`
- `expiresAt` — 30 days after documentDate
- `version` — increments on re-order for same cadastral number
### Credentials
- Env vars: `ANCPI_USERNAME`, `ANCPI_PASSWORD` (hardcoded in docker-compose for Portainer CE)
- Default solicitant: ID `14452` (Beletage persoană juridică)
- MinIO bucket: `ancpi-documente`
---
## Last Updated
2026-03-22 — Added county population via nomenclature API, local feature count in UAT dropdown.
2026-03-23 — ANCPI ePay CF extract ordering: full backend + UI + dedup protection.