# Acbr Components

> ---

- Skill: `delphicleancode/acbr-components` (Agent Skill)
- Install (CLI): `npx skillmds@latest add delphicleancode/acbr-components`
- Raw SKILL.md: https://api.skillmd.com/api/skills/delphicleancode/acbr-components/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: delphicleancode (https://skillmd.com/u/delphicleancode)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/delphicleancode/acbr-components

---

﻿---
name: ACBr Project Patterns
description: Architectural, dependency injection and UI patterns for the ACBr Project (Commercial Automation Brazil) ecosystem in Delphi.
---

# Standards for ACBr Project

The **ACBr Project** is vital for issuing NFe, CTe, NFCe, SAT, TEF and controlling fiscal/non-fiscal scales/printers in Brazil. It contains fantastic components, but due to its background and history of strong VCL coupling that accompanies older developers, the best practices below ensure maintainability in modernizations.

## 1. Rule of Thumb: No Strong Visual Coupling

Do not instantiate components `TACBrNFe`, `TACBrCTe`, `TACBrPosPrinter`, etc., directly in the View Forms of the interface (`.dfm`/`.fmx`). This breaks the clean architecture, MVC and makes unit testing immensely difficult.

### O Que Fazer?

Create Service "Wrapper" classes or Infrasctructure Repositories that inject (via constructor or Service Locator) the system configurations to the Fiscal Engine.

```pascal
type
  INFeEmissor = interface
    ['{GUID}']
    function EmitirNota(ANota: TBaseNFeModel): TEmissionResult;
  end;

  TNFeEmissorACBr = class(TInterfacedObject, INFeEmissor)
  private
    FAcbrNFe: TACBrNFe;
    FConfig: IAppConfig;
    procedure ConfigureComponent;
  public
    constructor Create(AConfig: IAppConfig);
    destructor Destroy; override;
    function EmitirNota(ANota: TBaseNFeModel): TEmissionResult;
  end;
```

## 2. Abstracting Signing and Cryptography Libraries (OpenSSL vs WinCrypt)

It is a documented good practice to also isolate the libraries for each OS version if the project is cross-platform or supports VMs (e.g. Linux Docker vs Windows).
Configure this *Always via code* dynamically within the wrapper referenced in Session 1, never at fixed design-time, using `LAcbrNFe.Configuracoes.Geral.SSLLib := libWinCrypt;` (or OpenSSL).

## 3. Handle Callbacks and Events (ex: TEF)

ACBrTEFD works heavily based on VCL events (OnExibeMensagem, OnAguardaDigitacao). Implement them by sending native bus events or defining a generic UI "Handler" injected into the class so that the component code remains in the Business/Gateway Layer, delegating only the "Draw to Screen" to specific interfaces that can be overridden in Headless/REST API scenarios.

```pascal
  ITefPresentationHandler = interface
    procedure ShowTefMessage(const Msg: string);
    procedure ClearTefMessage;
  end;
```

## 4. Dynamic Memory Management

If you instantiate sub-function components (e.g. ACBrCEP) dynamically, avoid memory leaks.

```pascal
function RetrieveAddress(const AZipCode: string): TAddressResponse;
var
  LCepComponent: TACBrCEP;
begin
  LCepComponent := TACBrCEP.Create(nil);
  try
    LCepComponent.WebService := wsViaCep;
    //Perform the logic
    LCepComponent.BuscarPorCEP(AZipCode);
    Result := MapToResponse(LCepComponent.Enderecos[0]);
  finally
    LCepComponent.Free;
  end;
end;
```

## 5. Component Prefixes

When dealing with design-time components in `DataModules` created to facilitate events, use these mappings:

| ACBr component | Description | Typical Prefix |
|-----------------|-----------|----------------|
| `TACBrNFe` | Electronic Invoice | `acbrNfe` |
| `TACBrNFCe`| Consumer Note | `acbrNfce` |
| `TACBrCTe` | Knowledge of Transp. | `acbrCte` |
| `TACBrBoleto`| Bills | `acbrBoleto` |
| `TACBrTEFD`| TEF | `acbrTef` |
| `TACBrPosPrinter`| Printers (EscPOS) | `acbrPosPrinter`|
| `TACBrSAT` | SAT CF-e equipment | `acbrSat` |


