Backend do Kim em .NET 8, PostgreSQL, EF Core, JWT e xUnit.
- .NET SDK 8
- Docker Desktop
dotnet-efdisponível no terminal
src/Kim.Domain: entidades e regras centrais.src/Kim.Application: casos de uso e interfaces.src/Kim.Infrastructure: EF Core, PostgreSQL e repositories.src/Kim.Api: controllers, JWT, Swagger e middlewares.tests/Kim.Tests: testes automatizados com xUnit.mobile: app React Native/Expo.
Suba o PostgreSQL:
docker compose up -dRestaure dependências:
dotnet restore Kim.slnAplique migrations:
dotnet ef database update --project src/Kim.Infrastructure --startup-project src/Kim.ApiRode a API:
dotnet run --project src/Kim.Api/Kim.Api.csprojAbra o Swagger:
https://localhost:7028/swagger
Desenvolvimento usa src/Kim.Api/appsettings.Development.json.
{
"ConnectionStrings": {
"KimDb": "Host=localhost;Port=55432;Database=kim;Username=kim_app;Password=kim_dev_password"
},
"Jwt": {
"Issuer": "Kim.Api",
"Audience": "Kim.Mobile",
"SecretKey": "kim-development-secret-key-change-before-production-123456",
"ExpirationMinutes": 60
},
"SafetyAlert": {
"GracePeriodMinutes": 10,
"JobIntervalMinutes": 1
}
}Para sobrescrever por ambiente:
$env:ConnectionStrings__KimDb="Host=localhost;Port=55432;Database=kim;Username=kim_app;Password=sua_senha"
$env:Jwt__SecretKey="uma-chave-secreta-segura-e-bem-longa"O Docker publica PostgreSQL em localhost:55432.
docker compose ps
docker compose logs postgres
docker compose downCriar migration:
dotnet ef migrations add NomeDaMigration --project src/Kim.Infrastructure --startup-project src/Kim.Api --output-dir Persistence/MigrationsAplicar migration:
dotnet ef database update --project src/Kim.Infrastructure --startup-project src/Kim.ApiListar migrations:
dotnet ef migrations list --project src/Kim.Infrastructure --startup-project src/Kim.ApiBuild:
dotnet build Kim.slnTestes:
dotnet test Kim.slnTodas as respostas seguem:
{
"success": true,
"message": "Mensagem amigavel.",
"data": {},
"errors": []
}POST /api/auth/register
Request:
{
"name": "Julia",
"email": "julia@email.com",
"password": "Senha@123"
}Response 201:
{
"success": true,
"message": "Conta criada com sucesso.",
"data": {
"id": "guid",
"name": "Julia",
"email": "julia@email.com"
},
"errors": []
}POST /api/auth/login
Request:
{
"email": "julia@email.com",
"password": "Senha@123"
}Response 200:
{
"success": true,
"message": "Login realizado com sucesso.",
"data": {
"accessToken": "jwt-token",
"expiresAt": "2026-05-22T23:59:00Z",
"user": {
"id": "guid",
"name": "Julia",
"email": "julia@email.com"
}
},
"errors": []
}Credenciais inválidas retornam 401 com mensagem genérica.
GET /api/me
Header:
Authorization: Bearer seu_token
No Swagger, execute register, depois login, copie data.accessToken, clique em Authorize e informe:
Bearer seu_token
register e login não exigem autenticação. /api/me exige Bearer válido.
A API usa Hangfire para processar sessões vencidas. Em desenvolvimento, o dashboard fica em:
https://localhost:7028/hangfire
Configuração:
{
"SafetyAlert": {
"GracePeriodMinutes": 10,
"JobIntervalMinutes": 1
}
}Fluxo do MVP:
- sessões
ActivecomCheckInDeadlinevencido viramAlertPending; - um
EmergencyAlertPendingé criado com snapshot emAlertPayloadJson; - depois da tolerância, a sessão vira
AlertSente o alerta viraSent; - a regra é idempotente e não cria alerta duplicado para a mesma sessão.
- quando o alerta é enviado, o backend monta uma mensagem textual contextual;
- o envio MVP usa
FakeEmergencyNotificationService; - cada tentativa de envio por contato é registrada em
EmergencyAlertDeliveries; - o índice único evita duplicidade por alerta, contato e canal.
A mensagem fake inclui:
- nome da usuária;
- horário limite de confirmação;
- pessoa informada no encontro;
- app de origem, quando existir;
- local planejado;
- link do Google Maps da última localização, quando existir;
- mensagem personalizada da usuária;
- contatos que serão avisados.
Endpoints:
GET /emergency-alerts/{id}: consulta um alerta da usuária autenticada.GET /emergency-alerts: lista o historico de alertas da usuária autenticada.POST /safety-sessions/{id}/trigger-emergency: aciona emergência manualmente e marca o alerta comoSent.GET /safety-sessions/{id}/emergency-protocol/preview: mostra o preview da mensagem, contatos e ultima localização sem disparar alerta.POST /emergency-alerts/{id}/send: dispara o envio fake manualmente para testes no Swagger.
Durante a tolerância, a usuária ainda pode usar POST /safety-sessions/{id}/confirm-safe.
Nesse caso, a sessão vira SafeConfirmed e o alerta pendente vira Cancelled.
Para aplicar as tabelas novas:
dotnet ef database update --project src/Kim.Infrastructure --startup-project src/Kim.Api