FEL Module Architecture
Source-backed architecture reference for apps/backend/src/fel/.
This page replaces earlier design-only analysis and documents current behavior from module wiring, services, providers, and controllers.
Scope and intent
FEL handles Guatemalan electronic tax document workflows in FlowPOS, including:
- certification orchestration (
FelService) - provider routing (
ProviderService) - credit note, debit note, and cancellation flows
- FEL helper lookups (for example taxpayer info through provider shared-info APIs)
- PDF and print surfaces through FEL controller endpoints
- asynchronous certification hooks from sales events (
OnCreateSaleEvent,OnUpdateSaleEvent)
Hexagonal mapping
Domain layer
electronic-certification-provider.interface.ts(provider port)- FEL document/value interfaces in
domain/fel.interface.ts - utility rules in
domain/jwt-token.utils.ts - repository ports for credit note/debit note/cancellation
Domain defines contracts and data shapes, not HTTP or third-party client mechanics.
Application layer
FelService(main orchestration, event listeners for sales certification)ProviderService(provider-name -> adapter resolution)- document helpers (
XmlConversionService,XmlToDteJsonService, validation/document builder services) - dedicated services:
FelCreditNoteServiceFelDebitNoteServiceFelCancellationService
Infrastructure layer
- provider adapters:
provider-digifact.service.tsprovider-infile.service.tsprovider-rpafelapi.service.ts
- Kysely repositories for FEL entities
- external integrations (HTTP calls, crypto token decryption, persistence)
Interfaces layer
fel.controller.tsendpoints under/fel- DTOs and query DTOs for credit/debit/cancellation operations
Provider routing pattern (reference for adapter ports)
ProviderService is the central router:
digifact->ProviderDigifactServiceinfile->ProviderInfileServicerpafelapi->ProviderRpaFelApiService
Contract: ElectronicCertificationProvider
interface ElectronicCertificationProvider {
certifyDocument(params): Promise<CertifierResponse | undefined>;
getSharedInfo(params): Promise<unknown>;
}
This is the reference port-and-adapter pattern reused by other integration modules: application layer requests a provider by name and delegates through a stable domain contract.
Certification orchestration (FelService)
FelService.certifyDocument orchestrates:
- load business + FEL certifier config
- decide routing strategy (
USE_RPA_FEL_APIcontrols direct certifier vs RPA path) - resolve provider and credentials
- transform document payload (XML or DTE JSON path depending on route/type)
- call provider
certifyDocument - return certifier response
Error handling includes:
- network vs HTTP distinction
- enriched response details in thrown exceptions
- structured logging for provider/API failures
Important: this is application orchestration behavior; provider-specific HTTP formatting belongs to infrastructure providers.
Direct certifier path
- provider is resolved from
document.felProviderData.providerName extractFelCertifierConfigvalidates certifier config payload- encrypted certifier token is decrypted through
CryptoService - XML payload is generated with
XmlConversionService
RPA path
- route is selected when
USE_RPA_FEL_API=true - service converts documents into DTE JSON (
XmlToDteJsonService) - provider is explicitly
rpafelapi - token-refresh capability depends on certifier config and provider support
Shared-info lookups (getSharedInfo)
FelService.getSharedInfo:
- resolves business and certifier config
- decrypts certifier token
- resolves provider from certifier name
- delegates to provider
getSharedInfo
This supports NIT and other certifier-backed lookups without exposing provider client details in controllers.
Sales integration events
FelService listens to sales events:
OnCreateSaleEventOnUpdateSaleEvent
When sale status transitions into certifiable states, FEL processing is triggered asynchronously. Errors are logged and do not crash sale processing flow.
After successful certification, OnDocumentCertifiedEvent is emitted for downstream updates.
Sales status gate in FelService:
- certification runs only when sale enters
submittedorreviewed - update flow checks transition from
draftinto a certifiable status
HTTP surface (FelController)
Controller route prefix: /fel
Key endpoint groups:
- generic:
POST /fel/convert-to-xmlPOST /fel/certify-documentPOST /fel/get-shared-info
- credit notes:
- list/create/get/certify/pdf/print variants
- debit notes:
- list/create/get/certify/pdf/print variants
- cancellations:
- list/create/get/certify/pdf/print variants
The controller delegates to application services; it does not contain provider logic.
Operational constraints and pitfalls
- Provider name must map to
ProviderServiceregistry or calls fail with unknown-provider error. - Certifier credentials are sourced from business FEL config and decrypted through
CryptoService. - Network-level provider failures and HTTP-level provider rejections are surfaced differently; this is intentional for troubleshooting quality.
- Environment-driven routing (for RPA path) changes runtime behavior; verify env configuration when diagnosing certifier mismatches.
- Credit/debit note and cancellation operations rely on dedicated services, not generic invoice certification paths.
- Controller-level PDF and print routes are output adapters; document construction and validation still live in application services.
Related docs
- MCP tool exposure for FEL read workflows:
dev/mcp/api-reference - FEL troubleshooting material in this section (
apps/docs/docs/dev/fel/)