Swagger UI openapi.json openapi.yaml

Platform components

A small set of microservices behind a single API gateway, connected by RabbitMQ, sharing one PostgreSQL database, with the fiscal work delegated to government and NFS-e providers and the back-office steps automated in n8n.

Component map

Every client talks HTTPS to one API gateway; the gateway forwards each request over RabbitMQ to the owning service. business-contabeleza (Rails) owns businesses, professionals, contracts, business requests and professional invoices; accounting (Go) owns fiscal entities, credentials, NFS-e, MEI diagnosis, DAS and revenue, and talks to the government and fiscal providers. Both share the Contabeleza PostgreSQL database; workflow automation runs in n8n.

🧭How to use
  • Click a box to open its card below the map: technology, responsibilities, how it is organized inside and every connection. Click it again (or ✕ Close) to reset.
  • Hover a box to preview its connections; hover an arrow for its label.
  • Show filters highlight the components of one flow (request path, fiscal setup, NFS-e, MEI data, business requests, login).
  • In the card, click any connection to jump to that component. Arrows point from caller to callee; dashed = asynchronous (RabbitMQ message, webhook or event).

Play the flows step by step in Architecture — information flows.

Principles

🚪One door

Only the gateway is exposed. It owns authentication, tenant resolution, the route registry and response caching.

✉️Messages, not HTTP

Services never expose HTTP: every call (gateway→service and service→service) is a RabbitMQ RPC controller#action with a context.

🧾Fiscal work in one place

Everything that touches the government or an NFS-e provider lives in accounting. The tenant service only checks ownership and forwards.

⏳Async by default

Emission, credential validation, DAS and diagnosis data come from slow external systems: the API answers with a pending state and the final result arrives by callback, webhook or worker.

🤖Humans in the loop via n8n

Business requests, contracts and manual invoices are worked by the Contabeleza team in n8n: status webhooks out, /postbacks/n8n/* back in.

⬡Hexagonal services

Inside each service: inbound adapters (message controllers, postbacks, workers) → use cases (actions) → domain → outbound adapters (persistence, other services, providers).

Two routes to accounting

The fiscal features are reachable two ways. Both end in the same accounting actions; they differ in who checks the tenant.

RoutePath patternPath through the platformWho uses it
Tenant wrapper/businesses/{id}/fiscal-entity/*
/professionals/{id}/fiscal-entity/*
/professional-fiscal-entities…
gateway → business-contabeleza (ownership of the business/professional) → accountingMEI Pro and other tenant apps
Direct/fiscal-entities/*, /buyer-fiscal-entities/*
/accounting/search/*, /accounting/callbacks/*, /accounting/diagnosis/*
gateway → accounting (routes registered by accounting itself)Admin/accounting tools, n8n, provider webhooks — see Internal endpoints ★

Inside a service

Every service follows the same ports-and-adapters layout. The dashed rings are the outside world (adapters); the solid ring is the application core. Dependencies point inwards: adapters call actions, actions call domain services, domain uses models; persistence, other services and providers are reached through outbound adapters.

🧭How to use
  • Pick the Rails or Go tab, then click a layer to see its responsibility, rules, where it lives in the code and an example.
Inbound adapters (driving side)
RabbitMQ consumerrabbiter
n8n postbackslocal_config/routes/postbacks.rb
Controllersapp/controllers
▼
Application core
Actions (use cases)app/services/actions
▼
Domain servicesapp/services/domain
▼
Modelsapp/models · AASM · JSON schemas
▼
Outbound adapters (driven side)
Operationsrails_common
External domainaccounting · access · sheets
Serializersjsonapier
n8n webhooksN8nWebhookable

Services built this way

business-contabeleza core-contabelezaaccesszeus back-office

Select a layer.

Request lifecycle — click a step to open its layer

1Gateway messagequeue <ns>.web.business
2Controllerfilter/data params · business_id
3ActionActions::ProfessionalInvoices::Emit
4Domainrules · AASM · transaction
5OperationsFetch · ilm_scope
6External domainaccounting invoices#create
7n8n webhookafter commit
8Serializerjsonapier
9Reply queueback to the gateway
gateway / brokeradapterapplication coredata / provider
main.go + initializerscomposition root
Inbound adapters
Dispatcher + routes.yamlgo-messenger
Controllersjsonapi · internal RPC
Workersgocron
▼
Application core
Actions / Applicationapp/services/actions
▼
Domain servicesapp/services/domain
▼
Modelsapp/models · go-database
▼
Outbound adapters
Providerslib/providers
External domaingo-messenger
Serializersgo-jsonapi

Services built this way

accounting

Select a layer.

Request lifecycle — click a step to open its layer

1Gateway messageroutes.yaml match
2Controllerjsonapi_controllers
3Actionapp/services/actions
4Domain servicego-errors on failure
5Modelsgo-database
6ProvidereNotas · Serpro…
7Serializergo-jsonapi
8Reply queueback to the gateway
gateway / brokeradapterapplication coredata / provider

Shared Go libraries (olympus.ilove.me/ilovelibs): go-common, go-database, go-jsonapi, go-messenger, go-errors, go-redis, go-logging, provider clients (go-enotas, go-serpro, go-infosimples, go-pagarme).

Multi-tenancy

1

Gateway

The ilm-business header must be one of the session businesses; it becomes ctx.business_id plus the acting professional and permissions.

2

business-contabeleza

Controllers force business_id into filters and writes, and check that the professional or business in the path belongs to the tenant before forwarding fiscal calls.

3

accounting

Fiscal entities carry their owners (business, professional, account); tenant wrappers pass the resolved fiscal entity id. Direct routes are reserved for admin, accounting and external-app tokens.

4

Data

Every tenant table has business_id; the gateway cache keys are per business.

Deployment

Environments

okteto · developmentdev2-contabelezaapi.dev2.contabeleza.com.br
QA · reset oftenqa-contabelezaapi.qa.contabeleza.com.br
final testsstaging-contabelezaapi.staging.contabeleza.com.br
customersproduction (mei)api.contabeleza.com.br

Kubernetes

Namespace ilm-brasil · one Helm chart per service (k8s/chart/values/<group>) · same images as iLoveMe for the shared services (gateway, access), Contabeleza values per environment

gateway

public edge — HTTPS
api (gateway)

web

RPC consumers that answer the gateway
business-contabelezaaccountingaccesszeus

notifications

email workflows
notifier-novu-express

From commit to cluster

GitLab CIBuilds the image; Rails services clone rails_common, Go services pull ilovelibs modules.
RegistryImages pushed to registry.olympus.ilove.me (…/business-contabeleza/, …).
HelmChart per service (k8s/chart) with per-environment values (values.staging-contabeleza.yaml, values.mei.yaml…).
KubernetesNamespace ilm-brasil of each Contabeleza cluster; database migrations from migrations-contabeleza.
Route registryEach service publishes its routes on boot; the gateway stores them in Redis and rebuilds its router by weight.

Technology catalog

🖥️Frontend

MEI Pro, mobile and admin

  • React 19 + ViteMEI Pro web
  • React Nativemobile shell
  • Refine + MUIadmin panel
  • Netlifymarketing site

🚪Gateway

the only public entry point

  • Node.js + ExpressHTTP server
  • express-jwtHS256 JWT
  • ioredissessions · cache · routes
  • formidableuploads

💎Rails services

business-contabeleza, access

  • Rails 7.2API-only
  • rails_commonbase library
  • jsonapierJSON:API
  • rabbiterRabbitMQ RPC
  • AASM · PaperTrailstates · audit
  • JSON schemasrequest payloads

🐹Go service

accounting

  • Golanguage
  • go-messengerRabbitMQ RPC
  • go-jsonapiJSON:API
  • go-database · go-redispersistence
  • go-enotas · go-serpro · go-infosimplesproviders
  • gocronworkers

🗄️Data & messaging

shared infrastructure

  • PostgreSQLcblz database
  • Redissessions · cache
  • RabbitMQRPC · callbacks
  • S3documents · PDFs

🔗Integrations

external providers

  • eNotasNFS-e
  • Serprogovernment APIs
  • InfoSimplesfiscal lookups
  • Revenue APImunicipal revenue
  • n8nautomation
  • Novuemail

⚙️Ops

build, run, observe

  • Kubernetes + Helmruntime
  • Oktetodev environments
  • GitLab CIpipelines
  • Sentryerrors