Sistema completo de gerenciamento de inventário desenvolvido com arquitetura moderna, autenticação via Keycloak e interface responsiva.
- Sobre o Projeto
- Funcionalidades Implementadas
- Tecnologias Utilizadas
- Arquitetura
- Configuração e Instalação
- Dificuldades Encontradas
- Estrutura do Projeto
- API Endpoints
- Autenticação e Autorização
- Testes
Sistema de gerenciamento de produtos desenvolvido como parte de um desafio técnico. O projeto implementa um CRUD completo de produtos e categorias, com sistema de autenticação robusto usando Keycloak, controle de acesso baseado em roles e interface moderna com Next.js.
-
CRUD Completo de Produtos
-
Criação, leitura, atualização e exclusão de produtos
-
Paginação de resultados
-
Busca por nome
-
Filtro por categoria
-
Identificação de produtos com estoque baixo (<10 unidades)
-
CRUD Completo de Categorias
-
Gerenciamento de categorias de produtos
-
Validação de exclusão (não permite excluir categorias com produtos)
-
Listagem ordenada
-
Dashboard com Estatísticas
-
Total de produtos no inventário
-
Valor total do inventário
-
Contagem de itens com estoque baixo
-
Distribuição de produtos por categoria
-
Autenticação e Autorização
-
Integração com Keycloak
-
Autenticação via JWT
-
Controle de acesso baseado em roles (Admin, Manager, User)
-
Refresh token
-
Arquitetura Clean
-
Separação em camadas (API, Application, Domain, Infrastructure)
-
CQRS com MediatR
-
Repository Pattern
-
Dependency Injection
-
Validações
-
FluentValidation para validação de comandos
-
Validações de domínio
-
Middleware de tratamento de exceções global
-
Logging
-
Serilog configurado
-
Logs estruturados em arquivo e console
-
Logs detalhados de autenticação
-
Rate Limiting
-
Proteção contra abuso de API
-
Limitação por IP
-
MongoDB
-
Persistência de dados
-
Índices otimizados
-
Soft delete
-
Health Checks
-
Endpoint de verificação de saúde da aplicação
-
Testes Unitários
-
Testes do Domain Layer
-
Testes do Application Layer
-
Cobertura de validadores
-
Dashboard Interativo
-
Estatísticas em tempo real
-
Gráficos com Recharts
-
Cards informativos
-
Tabela de produtos com estoque baixo
-
Gerenciamento de Produtos
-
Listagem paginada com busca e filtros
-
Formulário de criação/edição
-
Confirmação de exclusão
-
Indicador visual de estoque baixo
-
Validação com Zod
-
Gerenciamento de Categorias
-
Grid responsivo de categorias
-
CRUD completo
-
Validação de dependências
-
Autenticação
-
Login com Keycloak
-
Gestão de tokens (access + refresh)
-
Proteção de rotas
-
Logout seguro
-
Interceptor axios para injeção automática de token
-
UI/UX Moderna
-
Design system com shadcn/ui
-
Tailwind CSS
-
Tema dark/light
-
Componentes reutilizáveis
-
Responsivo (mobile-first)
-
Loading states
-
Toast notifications (sonner)
-
Gestão de Estado
-
React Query para cache e sincronização
-
Zustand para estado global de autenticação
-
Persistência de sessão
-
TypeScript
-
Tipagem forte em todo o código
-
Interfaces compartilhadas
-
Type safety
- .NET 9.0 - Framework principal
- ASP.NET Core - API REST
- MongoDB - Banco de dados NoSQL
- Keycloak - Servidor de autenticação
- MediatR - CQRS pattern
- FluentValidation - Validações
- Serilog - Logging
- xUnit - Testes unitários
- Moq - Mocking para testes
- FluentAssertions - Assertions nos testes
- Swashbuckle - Documentação OpenAPI/Swagger
- Next.js 16 - Framework React
- React 19 - Biblioteca UI
- TypeScript - Tipagem estática
- Tailwind CSS - Estilização
- shadcn/ui - Componentes UI
- React Query (TanStack Query) - Data fetching
- Zustand - State management
- React Hook Form - Gerenciamento de formulários
- Zod - Validação de schemas
- Axios - Cliente HTTP
- Recharts - Gráficos
- Lucide React - Ícones
- Sonner - Toast notifications
- Docker - Containerização
- Docker Compose - Orquestração
- PostgreSQL - Banco do Keycloak
backend/
├── src/
│ ├── Hypesoft.API/ # Controllers, Middlewares
│ ├── Hypesoft.Application/ # Use Cases, DTOs, Validators
│ ├── Hypesoft.Domain/ # Entities, Interfaces
│ └── Hypesoft.Infrastructure/# Repositories, Data Context
└── tests/
├── Hypesoft.Domain.Tests/
├── Hypesoft.Application.Tests/
└── Hypesoft.API.Tests/
Fluxo de Dados:
Request → Controller → MediatR → Handler → Repository → MongoDB
↓
Validator
frontend/
├── app/ # Pages e layouts
│ ├── auth/login/ # Página de login
│ ├── dashboard/ # Dashboard e sub-páginas
│ ├── hooks/ # Custom hooks
│ └── types/ # TypeScript types
├── components/ # Componentes reutilizáveis
│ ├── ui/ # Componentes base (shadcn)
│ ├── dashboard/ # Componentes do dashboard
│ ├── products/ # Componentes de produtos
│ ├── categories/ # Componentes de categorias
│ └── layout/ # Layout components
├── lib/ # Utilitários e configurações
│ ├── api/ # Clientes API
│ ├── auth.ts # Configuração NextAuth
│ ├── keycloak.ts # Integração Keycloak
│ └── utils.ts # Funções auxiliares
└── store/ # Zustand stores
- Docker e Docker Compose
- .NET 9.0 SDK (para desenvolvimento local)
- Node.js 20+ (para desenvolvimento local)
- Git
git clone <repository-url>
cd Desafio-Tecnico-Hypesoft# Inicie todos os serviços
docker-compose up -d
# Aguarde os serviços iniciarem (pode levar 1-2 minutos)
docker-compose psServiços disponíveis:
- API Backend: http://localhost:5000
- Keycloak: http://localhost:8080
- MongoDB: localhost:27017
- MongoDB Express: http://localhost:8081
- PostgreSQL: localhost:5432
Acesse http://localhost:8080 e faça login:
- Usuário: admin
- Senha: admin
O Keycloak deve ser configurado manualmente ou via script. Credenciais de teste:
- Admin: admin / admin123 (roles: Admin, Manager, User)
- Manager: manager / manager123 (roles: Manager, User)
- User: user / user123 (role: User)
Frontend: Acesse http://localhost:3000 (se configurado)
Backend Swagger: http://localhost:5000/swagger
Problema Principal: Durante a implementação da autenticação JWT com Keycloak, enfrentei diversos desafios relacionados à validação do token:
Sintoma: Token rejeitado com erro InvalidAudience
Causa: O Keycloak, por padrão, emite tokens com aud: "account", mas a API esperava aud: "hypesoft-api".
Solução Implementada:
// Program.cs - Configuração inicial (temporária)
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false, // Desabilitado temporariamente
// ... outras configurações
};Solução Recomendada: Configurar um Audience Mapper no Keycloak:
- No cliente
hypesoft-api: Adicionar mapper do tipo "Audience" - Incluir
hypesoft-apicomo audience - Reativar validação:
ValidateAudience = true
Sintoma: Token rejeitado com erro InvalidIssuer
Causa: URL do issuer incorreta ou não incluindo o caminho completo do realm.
Solução:
// Authority deve incluir o realm
Authority = "http://localhost:8080/realms/hypesoft" // ✅ Correto
// NÃO: "http://localhost:8080" // ❌ IncorretoSintoma: Falha na validação por usar HTTP em vez de HTTPS
Solução:
options.RequireHttpsMetadata = !isDevelopment; // false em dev, true em prodSintoma: Tokens expirados rejeitados imediatamente ou aceitos após expiração
Solução:
options.TokenValidationParameters = new TokenValidationParameters
{
ClockSkew = TimeSpan.Zero // Sem margem de tolerância
};Problema: Sincronização entre Zustand, localStorage e o interceptor do Axios
Solução: Implementação de hidratação adequada do store e sincronização manual:
// auth-store.ts
onRehydrateStorage: () => (state) => {
if (state?.accessToken) {
localStorage.setItem('access_token', state.accessToken);
}
state.setHasHydrated(true);
}Para facilitar o debug, implementei logging detalhado:
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
Log.Error("Authentication failed: {ErrorType} - {ErrorMessage}",
context.Exception.GetType().Name,
context.Exception.Message);
return Task.CompletedTask;
},
OnTokenValidated = context =>
{
Log.Information("Token validated successfully. User: {User}",
context.Principal?.Identity?.Name);
return Task.CompletedTask;
}
};Problema: Requisições bloqueadas por CORS em desenvolvimento
Solução:
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});Domain Layer (Hypesoft.Domain)
- Entidades de domínio (
Product,Category) - Interfaces de repositórios
- Exceções de domínio
- Lógica de negócio
Application Layer (Hypesoft.Application)
- Commands e Queries (CQRS)
- Handlers (MediatR)
- DTOs
- Validators (FluentValidation)
- Interfaces de serviços
Infrastructure Layer (Hypesoft.Infrastructure)
- Implementação de repositórios
- Contexto do MongoDB
- Configurações de infraestrutura
- Repositories In-Memory (fallback)
API Layer (Hypesoft.API)
- Controllers
- Middlewares (ExceptionHandling, CorrelationId)
- Configuração de autenticação
- Startup configuration
POST /api/auth/login - Login (Keycloak)
GET /api/products - Listar produtos (paginado)
GET /api/products/{id} - Obter produto por ID
GET /api/products/low-stock - Produtos com estoque baixo
POST /api/products - Criar produto [Admin, Manager]
PUT /api/products/{id} - Atualizar produto [Admin, Manager]
DELETE /api/products/{id} - Excluir produto [Admin]
GET /api/categories - Listar categorias
GET /api/categories/{id} - Obter categoria por ID
POST /api/categories - Criar categoria [Admin, Manager]
PUT /api/categories/{id} - Atualizar categoria [Admin, Manager]
DELETE /api/categories/{id} - Excluir categoria [Admin]
GET /api/dashboard/stats - Estatísticas do dashboard
GET /api/health - Health check
| Role | Permissões |
|---|---|
| Admin | Todas as operações (CRUD completo) |
| Manager | Criar e editar produtos/categorias |
| User | Apenas visualização |
- Login: Frontend envia credenciais para Keycloak
- Token: Keycloak retorna access_token e refresh_token
- Armazenamento: Tokens salvos no Zustand + localStorage
- Requisições: Axios interceptor injeta token no header
- Validação: Backend valida JWT e extrai roles
- Autorização: Atributos
[Authorize(Roles = "...")]protegem endpoints
Este projeto foi desenvolvido como parte de um desafio técnico