Arquitetura
Sistema de Auditoria Centralizado - AgrSis
Data: 2026-02-10
Versão: 1.0
Status: Aprovado para Implementação
Sistema de Auditoria Centralizado - AgrSis
Data: 2026-02-10 Versão: 1.0 Status: Aprovado para Implementação
📋 Visão Geral
Centralizar todo o histórico de eventos de Orders e Proposals em uma única tabela audit_logs, substituindo a abordagem descentralizada atual (order_status_history).
Benefícios
- Uma única fonte de verdade para todo histórico
- Componentes reutilizáveis entre Producer, Supplier e Admin
- Admin com visão global e atualização em tempo real
- Facilidade de manutenção - um único código para histórico
- Extensível - fácil adicionar novas entidades no futuro
🏗️ Arquitetura
┌─────────────────────────────────────────────────────────────────────────┐
│ AUDIT_LOGS (centralizado) │
├─────────────────────────────────────────────────────────────────────────┤
│ auditable_type: "App\Models\Order" | "App\Models\Proposal" │
│ auditable_id: ID da entidade │
│ event: código do evento (ex: "order.created", "proposal.submitted") │
│ description: texto descritivo em português │
│ old_values / new_values: JSON com mudanças │
│ metadata: { reason_type, reason_notes, extra_data } │
│ user_id: quem fez a ação │
│ user_type: 'producer' | 'supplier' | 'admin' | 'system' │
│ ip_address, user_agent: rastreabilidade │
│ show_in_activity_feed: boolean (para feed de atividades) │
└─────────────────────────────────────────────────────────────────────────┘
│
┌─────────────────────────┼─────────────────────────┐
▼ ▼ ▼
Producer Portal Supplier Portal Admin Portal
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Order │ │ Proposal │ │ Logs │
│ Timeline │ │ Timeline │ │ (tempo real)│
│ │ │ │ │ │
│ - Filtra │ │ - Filtra │ │ - Vê TUDO │
│ por Order │ │ por │ │ - Filtros │
│ - Eventos │ │ Proposal │ │ - Busca │
│ do prod. │ │ - Eventos │ │ │
│ │ │ do suppl. │ │ + Order e │
│ ANÔNIMO: │ │ │ │ Proposal │
│ não mostra │ │ ANÔNIMO: │ │ views │
│ supplier │ │ não mostra │ │ (anônimo) │
└─────────────┘ │ producer │ └─────────────┘
└─────────────┘
📊 Mapeamento de Eventos
Eventos de ORDER (Licitação)
| Evento | Código | Descrição (Producer) | Descrição (Supplier) | Visível |
|---|---|---|---|---|
| Criada | order.created | Licitação criada | - | Producer, Admin |
| Atualizada | order.updated | Licitação atualizada | - | Producer, Admin |
| Publicada | order.published | Licitação publicada | Nova licitação disponível | Todos |
| Proposta recebida | order.proposal_received | Nova proposta recebida | - | Producer, Admin |
| Proposta cancelada | order.proposal_cancelled | Proposta cancelada pelo fornecedor | - | Producer, Admin |
| Em análise | order.in_analysis | Prazo encerrado, em análise | Licitação em análise | Todos |
| Expirada | order.expired | Licitação expirada | Licitação expirada | Todos |
| Cancelada | order.cancelled | Licitação cancelada | Licitação cancelada | Todos |
| Revogada | order.revoked | Licitação revogada | Licitação revogada | Todos |
| Vencedor selecionado | order.awarded | Proposta vencedora selecionada | - | Producer, Admin |
| Finalizada | order.finished | Licitação finalizada | Licitação finalizada | Todos |
Eventos de PROPOSAL (Proposta)
| Evento | Código | Descrição (Supplier) | Descrição (Producer) | Visível |
|---|---|---|---|---|
| Criada | proposal.created | Proposta criada | - | Supplier, Admin |
| Atualizada | proposal.updated | Proposta atualizada | - | Supplier, Admin |
| Enviada | proposal.submitted | Proposta enviada | Nova proposta recebida | Todos |
| Cancelada | proposal.cancelled | Proposta cancelada | Proposta cancelada | Todos |
| Em análise | proposal.in_analysis | Sua proposta está em análise | - | Supplier, Admin |
| Aprovada | proposal.accepted | Parabéns! Proposta aprovada | Proposta selecionada | Todos |
| Rejeitada | proposal.rejected | Proposta não selecionada | - | Supplier, Admin |
| Perdida | proposal.lost | Outra proposta foi selecionada | - | Supplier, Admin |
| Expirada | proposal.expired | Proposta expirada | - | Supplier, Admin |
| Visualizada | proposal.viewed | - | Proposta visualizada | Producer, Admin |
| Favoritada | proposal.favorited | - | Proposta marcada como favorita | Producer, Admin |
🔒 Regras de Anonimidade
Producer vendo Orders:
- Não vê nome do supplier em eventos de proposta
- Propostas identificadas como "Proposta A", "Proposta B", etc.
- Apenas após adjudicação vê dados do vencedor
Supplier vendo Proposals:
- Não vê nome do producer
- Order identificada pelo número (ex: "Licitação #2026-001")
- Não vê outras propostas ou seus dados
Admin:
- Vê tudo, mas respeita anonimidade nas views de Order e Proposal
- Na view geral de Logs pode ver todos os dados para debug
🗄️ Estrutura do Banco de Dados
Tabela: audit_logs
CREATE TABLE audit_logs (
id BIGSERIAL PRIMARY KEY,
-- Entidade auditada (polimórfico)
auditable_type VARCHAR(255) NOT NULL, -- 'App\Models\Order', 'App\Models\Proposal'
auditable_id BIGINT NOT NULL,
-- Evento
event VARCHAR(100) NOT NULL, -- 'order.created', 'proposal.submitted'
description TEXT, -- Descrição em português
-- Valores (JSON)
old_values JSONB, -- Estado anterior
new_values JSONB, -- Estado novo
metadata JSONB, -- Dados extras (reason_type, reason_notes, etc)
-- Usuário que fez a ação
user_id BIGINT, -- Pode ser NULL (sistema)
user_type VARCHAR(50), -- 'producer', 'supplier', 'admin', 'system'
-- Rastreabilidade
ip_address VARCHAR(45),
user_agent TEXT,
-- Controle de exibição
show_in_activity_feed BOOLEAN DEFAULT TRUE,
-- Timestamp
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
-- Índices
CONSTRAINT fk_audit_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL
);
-- Índices para performance
CREATE INDEX idx_audit_auditable ON audit_logs(auditable_type, auditable_id);
CREATE INDEX idx_audit_event ON audit_logs(event);
CREATE INDEX idx_audit_user ON audit_logs(user_id);
CREATE INDEX idx_audit_created ON audit_logs(created_at DESC);
CREATE INDEX idx_audit_activity_feed ON audit_logs(show_in_activity_feed, created_at DESC);
📁 Estrutura de Arquivos (Backend)
apps/api/
├── app/
│ ├── Enums/
│ │ └── AuditEvent.php # Enum com todos os eventos
│ │
│ ├── Models/
│ │ └── AuditLog.php # Model (já existe, atualizar)
│ │
│ ├── Traits/
│ │ └── Auditable.php # Trait para models
│ │
│ ├── Services/
│ │ └── AuditService.php # Service para registrar eventos
│ │
│ ├── Http/
│ │ ├── Controllers/Api/
│ │ │ └── AuditController.php # Endpoints de histórico
│ │ │
│ │ └── Resources/
│ │ └── AuditLogResource.php # Resource para API
│ │
│ └── Observers/
│ ├── OrderObserver.php # Observer para Order (atualizar)
│ └── ProposalObserver.php # Observer para Proposal (criar)
│
└── database/
└── migrations/
└── 2026_02_10_create_audit_logs_table.php
📁 Estrutura de Arquivos (Frontend)
apps/shared/ # Componentes compartilhados
└── components/
└── audit/
├── AuditTimeline.vue # Timeline genérica reutilizável
├── AuditTimelineItem.vue # Item individual da timeline
└── AuditEventBadge.vue # Badge de evento
apps/producer/
└── components/
└── order/
└── OrderHistory.vue # Usa AuditTimeline filtrado por Order
apps/supplier/
└── components/
└── proposal/
└── ProposalHistory.vue # Usa AuditTimeline filtrado por Proposal
apps/admin/
└── pages/
└── logs/
└── index.vue # View geral de logs (tempo real)
└── components/
└── audit/
└── AdminAuditTimeline.vue # Timeline com mais detalhes
⏱️ Estimativa de Tempo
| Fase | Tarefa | Tempo |
|---|---|---|
| 1. Backend - Base | Migration + Model + Enum | 30 min |
| 2. Backend - Trait | Auditable trait | 30 min |
| 3. Backend - Service | AuditService | 30 min |
| 4. Backend - Observers | Order + Proposal observers | 45 min |
| 5. Backend - API | Endpoints + Resource | 30 min |
| 6. Frontend - Shared | Componentes base | 45 min |
| 7. Frontend - Producer | OrderHistory | 30 min |
| 8. Frontend - Supplier | ProposalHistory | 30 min |
| 9. Frontend - Admin | Logs page + timeline | 1h |
| 10. Testes | Testar fluxos | 30 min |
| 11. Deploy | Deploy produção | 15 min |
| TOTAL | ~6h |
🔄 Migração de Dados
Estratégia:
- Criar nova tabela
audit_logs - Migrar dados de
order_status_historyparaaudit_logs - Manter compatibilidade -
order_status_historycontinua funcionando - Deprecar gradualmente - após validação, remover uso antigo
Script de Migração:
// Migrar order_status_history para audit_logs
OrderStatusHistory::chunk(100, function ($histories) {
foreach ($histories as $history) {
AuditLog::create([
'auditable_type' => Order::class,
'auditable_id' => $history->order_id,
'event' => 'order.status_changed',
'description' => $history->getChangeDescription(),
'old_values' => ['status' => $history->from_status?->value],
'new_values' => ['status' => $history->to_status->value],
'metadata' => [
'reason_type' => $history->reason_type?->value,
'reason_notes' => $history->reason_notes,
],
'user_id' => $history->changed_by,
'user_type' => 'producer',
'ip_address' => $history->ip_address,
'user_agent' => $history->user_agent,
'created_at' => $history->created_at,
]);
}
});
📋 Tasks Linear
Epic: Sistema de Auditoria Centralizado
- Backend Criar migration e model AuditLog - 30min
- Labels: Backed-API, Feature
- Criar tabela audit_logs com todos os campos
- Atualizar model AuditLog
- Backend Criar enum AuditEvent - 15min
- Labels: Backed-API, Feature
- Enum com todos os eventos de Order e Proposal
- Métodos para label, cor, ícone
- Backend Criar trait Auditable - 30min
- Labels: Backed-API, Feature
- Trait para registrar eventos automaticamente
- Hooks para created, updated, deleted
- Backend Criar AuditService - 30min
- Labels: Backed-API, Feature
- Service para registrar eventos customizados
- Métodos específicos para cada tipo de evento
- Backend Criar/atualizar Observers - 45min
- Labels: Backed-API, Feature
- OrderObserver: eventos de status, propostas
- ProposalObserver: eventos de ciclo de vida
- Backend Criar endpoints de histórico - 30min
- Labels: Backed-API, Feature
- GET /orders/{uuid}/history
- GET /proposals/{uuid}/history
- GET /admin/audit-logs (com filtros)
- Frontend Criar componentes compartilhados - 45min
- Labels: Front-Produtor, Front-Fornecedor, Feature
- AuditTimeline.vue
- AuditTimelineItem.vue
- AuditEventBadge.vue
- Frontend Atualizar OrderHistory no Producer - 30min
- Labels: Front-Produtor, Improvement
- Usar novo componente AuditTimeline
- Respeitar anonimidade
- Frontend Criar ProposalHistory no Supplier - 30min
- Labels: Front-Fornecedor, Feature
- Timeline de histórico da proposta
- Respeitar anonimidade
- Frontend Criar página de Logs no Admin - 1h
- Labels: Backed-API, Feature
- View geral com todos os logs
- Filtros por tipo, entidade, período
- Atualização em tempo real (polling/websocket)
- Deploy Migrar dados e deploy - 30min
- Labels: Backed-API, Improvement
- Migrar order_status_history
- Deploy para produção
✅ Checklist de Implementação
- Migration criada e executada
- Model AuditLog atualizado
- Enum AuditEvent criado
- Trait Auditable implementado
- AuditService funcionando
- Observers configurados
- Endpoints de histórico criados
- Componentes Vue compartilhados
- Producer OrderHistory atualizado
- Supplier ProposalHistory criado
- Admin Logs page funcionando
- Dados migrados de order_status_history
- Testes executados
- Deploy realizado
Última atualização: 2026-02-10 Autor: Sistema