| backup | ||
| endpoint_listener | ||
| logs | ||
| Models | ||
| tecnospeed_queue | ||
| tecnospeed_rpc | ||
| utils | ||
| buildImages.sh | ||
| docker-compose.yml | ||
| pytest.ini | ||
| README.md | ||
Serviço de Integração PlugNotas da Tecnospeed
Serviço especializado e containerizado para gerenciar a emissão, controle e recebimento de informações sobre Notas Fiscais (NFe e NFSe) via API da PlugNotas (Tecnospeed). Com uma arquitetura orientada a eventos e filas (RabbitMQ), o sistema é altamente desacoplado, assíncrono e integrado a um banco de dados PostgreSQL para registro de todas as operações e relatórios de auditoria.
🚀 Principais Tecnologias e Arquitetura
- Python & FastAPI: Base de processamento, recebimento de Webhooks (via
main_listener.py) e tipagem rigorosa utilizando Pydantic. - RabbitMQ (AMQP): Comunicação entre os módulos utilizando as ferramentas especializadas implementadas (como
QueueExchange2eRPCExchange2), promovendo uma arquitetura event-driven livre de bloqueios síncronos. - PostgreSQL: Utilizado com SQLAlchemy para logs, auditorias detalhadas das operações, cache das bases de Serviços, Tomadores, Empresas e relatórios operacionais.
- Redis: Sistema de gerenciamento e armazenamento de persistência de curadoria (como configurações dinâmicas de acesso e credenciais de forma ágil).
- IC2 Logger: Envio centralizado de todos os logs, fluxos de erros, métricas operacionais para um sistema
InfoConnectorusando RabbitMQ Topic.
📦 Estrutura de Módulos (Serviços)
O serviço central funciona consumindo a fila tecnospeed e encaminhando as requisições para os seus respectivos módulos especializados.
1. NFe (Nota Fiscal Eletrônica de Produto)
Módulo que envia e orquestra operações envolvendo notas fiscais de venda (produtos):
- Envio de emissões de NFe em unitário ou em lote.
- Consulta de resumos processados.
- Cancelamentos suportados por justificativas.
- Envio de Cartas de Correção Eletrônica (CCe).
- Download de relatórios, XMLs originais e PDFs de Danfe.
2. NFSe (Nota Fiscal de Serviços Eletrônica)
Voltado a comunicações com prefeituras para emissão de serviços, contém os fluxos de controle essenciais:
- Realiza emissão dos documentos pelo CNPJ do prestador.
- Controle e solicitação formal de cancelamento nas prefeituras.
- Verificação de status e download de histórico de RPS.
- Tomadores: Gerenciamento integrado dos clientes finais (Tomadores da NFSe).
- Serviços: Cadastro de descritivos padrão, itens e alíquotas com base na lei complementar municipal local (LC116).
3. Empresas e Certificados Digitais
Serviço de onboarding das novas contas emissoras junto à PlugNotas:
- Empresas: Vinculação do CNPJ emissor (incluindo endereços, configurações fiscais iniciais e logotipos de impressão).
- Certificados Digitais: Responsável pelo cadastro do certificado físico formato
.pfxcom envios do tipomultipart/form-data, renovação de senhas e update recorrente dos certificados A1.
4. Webhooks (Listeners Internos e Externos)
Gerenciador automatizado orientando o lado da PlugNotas para onde devolver as informações assincronamente:
- Criação, leitura, deleção e envio de testes para registro das URLs via API do Plugnotas.
- Um Listener próprio do lado da integração (
main_listener.py+listenerEndpoint.py) absorve o payload recebido da PlugNotas e encaminha de volta ao fluxo RabbitMQ principal usando RPC — mantendo assim uma auditoria segura com log para todas as frentes (rejeições, aceites contábeis etc).
5. Relatórios
Serviço voltado a buscas gerenciais dentro do portal da Tecnospeed para contabilidades e analistas de sistemas:
- Extratos iterados limitados de NFe e NFSe emitidas ou registradas num dado range de período.
- Recortes centralizados e consolidações por um CNPJ específico.
⚙️ Como Funciona o Ciclo de Eventos (Workflows)
- Ação Disparada: O sistema que integra de fora (ERP etc) publica uma mensagem JSON na fila RabbitMQ com os comandos e a carga de dados de Pydantic Models associada, incluindo as configurações do banco.
- Workers de Fila (
mainQUEUE.py): As mensagens são absorvidas, descriptografadas, instanciam as credenciais adequadas e ativam a Controller/Service (ex: EmpresaController, RegistroNFeService). - Persistência no Postgre (
utils/banco.py): A operação feita junto as rotas do portal salva um rastro de log com ostatus("SUCESSO", "ERRO"). Instalações da NFe e NFSe e Certificados refletem diretamente nesse PostgreSQL. - Listener Asincrono de Retorno (
listenerEndpoint.py): A rota em FastAPI escuta atualizações atrasadas (ex: webservices estaduais demorados) e sinaliza ativamente ao logger e à base da empresa o desfecho da nota.
🗂️ Estrutura de Diretórios
servico_plugnotas/
├── src/
│ ├── main.py # Worker principal (RPCExchange2)
│ ├── mainQUEUE.py # Worker alternativo (QueueExchange2 + IC2 Logger)
│ ├── main_listener.py # Entrypoint do container de Webhook Listener
│ ├── listenerEndpoint.py # Rotas FastAPI que recebem webhooks da PlugNotas
│ ├── test.py # Script de testes manuais
│ │
│ ├── NFe/
│ │ └── registroNFe.py # Service de emissão, cancelamento e download de NFe
│ ├── NFSe/
│ │ ├── nfse.py # Service de emissão e controle de NFSe
│ │ ├── Servico/
│ │ │ └── servico.py # Controller de cadastro de Serviços (LC116)
│ │ └── Tomador/
│ │ └── tomador.py # Controller de cadastro de Tomadores
│ ├── empresas/
│ │ └── empresa.py # Controller de cadastro de Empresas emissoras
│ ├── certificado_digital/
│ │ └── certificado_digital.py # Service de upload e gestão de certificados .pfx
│ ├── webhooks/
│ │ └── webhooks.py # CRUD de URLs de webhook por CNPJ
│ ├── Relatorios/
│ │ └── relatorios.py # Consultas de relatórios em lote
│ │
│ ├── Models/ # Modelos Pydantic que validam os payloads
│ │ ├── config.py # Config (banco) e SystemConfig (AMQP/Redis)
│ │ ├── empresa.py # Modelo de Empresa emissora
│ │ ├── nfe.py # Modelo de NFe (Emitente, Destinatário, Itens, Tributos)
│ │ ├── nfse.py # Modelo de NFSe (Prestador, Tomador, Serviço)
│ │ ├── servico.py # Modelo detalhado de Serviço (ISS, Retenções, IBPT)
│ │ └── tomador.py # Modelo de Tomador (cliente fiscal)
│ │
│ └── utils/ # Classes auxiliares compartilhadas
│ ├── api.py # Wrapper HTTP (requests) para a API PlugNotas
│ ├── banco.py # ORM SQLAlchemy (tabelas + CRUD + logs)
│ ├── redis.py # Cliente Redis para cache de configurações
│ ├── Exchange2.py # QueueExchange2, RPCExchange2, LoggerExchange2
│ ├── exchangeModels.py # Modelos Pydantic do InfoConnector (IC2)
│ └── Logger.py # LogService para logs via mensageria
│
├── Dockerfile # Imagem base Python 3.12-slim
├── docker-compose.yml # Orquestração dos containers
├── buildImages.sh # Script de build com clone de dependências
├── requirements.txt # Dependências Python
├── modelo_system_config.json # Exemplo de configuração do Redis
└── modelo_json_rpc.json # Exemplo de payload RPC
🐳 Infraestrutura Docker
O projeto é composto por 4 containers orquestrados via docker-compose.yml:
| Container | Imagem | Porta | Função |
|---|---|---|---|
redis |
redis |
interna | Armazena system_config (credenciais AMQP, chaves) |
postgres |
postgres:15 |
interna | Banco de dados de auditoria e registros de notas |
tecnospeed |
build local | — | Worker que consome fila RabbitMQ e processa operações |
webhook-listener |
build local | 8000 |
FastAPI que recebe webhooks da PlugNotas via HTTP |
Subindo o ambiente
# Build e execução completa
docker compose up -d --build
# Ou utilizando o script de build (clona dependências externas automaticamente)
bash buildImages.sh clone
Variáveis de ambiente
| Variável | Container | Descrição | Default |
|---|---|---|---|
TZ |
todos | Timezone da aplicação | America/Sao_Paulo |
REDIS_HOST |
tecnospeed, webhook-listener | Host do Redis | localhost |
WEBHOOK_PORT |
webhook-listener | Porta do servidor FastAPI | 8000 |
⚡ Configuração Inicial (Redis)
Antes de subir os workers, é necessário inserir a chave system_config no Redis com as credenciais de acesso ao RabbitMQ:
{
"serviceid": "01234567890123456789012345678901",
"servicekey": "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456",
"origin": "nome-da-maquina",
"amqps": "amqps://usuario:senha@host.rmq.cloudamqp.com/vhost"
}
Esse JSON é lido automaticamente na inicialização dos workers (main.py, mainQUEUE.py, listenerEndpoint.py).
📨 Exemplo de Payload RPC
As mensagens que chegam pela fila RabbitMQ seguem o seguinte formato (já descriptografado):
{
"fila": "nfse",
"cliente": "NomeCliente",
"metodo": "POST",
"dados": { ... },
"config": {
"api_key": "sua-api-key-plugnotas",
"user_postgres": "postgres",
"pass_postgres": "postgres",
"host_postgres": "localhost",
"port_postgres": "5432",
"database_postgres": "tecnospeed"
}
}
fila: Seleciona o módulo de destino (nfe,nfse,empresa,certificado_digital,servico,tomador,webhooks,relatorios,webhook_callback).metodo: Ação a executar (post,get,put,delete,cancelar,download, etc.).dados: Corpo da requisição conforme o Pydantic Model do módulo.config: Credenciais isoladas por cliente para a API e o banco PostgreSQL.
📦 Dependências
sqlalchemy # ORM para PostgreSQL
pydantic # Validação de modelos de dados
requests # Requisições HTTP à API PlugNotas
redis # Cliente Redis
pytz # Timezone São Paulo
pika # Cliente AMQP (RabbitMQ)
cryptography # Criptografia AES-256 dos payloads
psycopg2-binary # Driver PostgreSQL
fastapi # Framework HTTP para o Webhook Listener
uvicorn[standard] # Servidor ASGI
🔖 Versionamento
| Versão | Descrição |
|---|---|
1.0.0 |
Versão inicial do sistema |
1.0.1 |
Implementação do ORM (SQLAlchemy) |
1.0.2 |
Implementação de RPC via RabbitMQ |
1.0.3 |
Configuração dinâmica via Redis |
2.0.0 |
Suporte a NFe e refatoração da Main |
2.0.1 |
Refatoração para RPCExchange2 / QueueExchange2 |
Documento gerado com base no código operacional contido em src/ do serviço (v2.0.1).