feat(services): atualizar pessoa atendida e contatos vinculados (#156, backend) - #165
evertonschuster wants to merge 2 commits into
Conversation
… backend)
PUT /api/v1/clients/{id}: o corpo traz os dados atuais da pessoa e a lista
final de contatos. Contato com id é alterado no lugar, sem id é novo e
omitido é removido (exclusão lógica), tudo em uma única transação.
- Client.Update valida tudo antes de atribuir (limites, responsável de
menor sobre a lista final, ids do próprio cliente, ids repetidos, dados de
cada contato) e depois sincroniza as duas listas; uma falha não deixa a
pessoa pela metade.
- Id de contato que não é da pessoa (outra pessoa, outro tenant,
inexistente, removido ou na lista errada): 404 Client.ContactNotFound,
sem gravar nada.
- CPF e e-mail seguem as regras da criação (ADR 0044) excluindo a própria
pessoa; e-mail só é checado se a pessoa está ativa. Tenant e situação do
corpo são ignorados.
- Regras de entrada compartilhadas e mapeamento de contatos movidos para a
raiz de Clients, para criar e editar não divergirem; os lookups do
repositório ganharam excludeClientId.
- Ids dos contatos passam a ValueGeneratedNever: com a chave já preenchida
pela raiz, o EF tratava o contato novo como Modified e a gravação falhava.
Sem mudança de schema, sem migração.
- Tipos do OpenAPI do frontend regenerados.
- ADR 0053, ARCHITECTURE §5/§10 e skills de slice atualizadas.
Verificado à mão em PostgreSQL descartável (78 verificações, incluindo 12
rodadas de edições concorrentes pelo mesmo CPF sem gravação parcial).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 4 minutes. View limit detailsLimit details: You’ve used the included review currently available. Review configuration: ⚙️ Run configuration
⛔ Files ignored due to path filters (1)
📒 Files selected for processing (29)
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
⛔ Files ignored due to path filters (1)
📒 Files selected for processing (29)
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe change adds a client update endpoint and command flow. The domain validates and synchronizes guardian and reference-contact lists by ID. Repository lookups can exclude the edited client, and persistence configuration and tests cover contact updates. ChangesClient profile editing
Priority: ➖ Normal Estimated code review effort: 4 (Complex) | ~45 minutes Change: Feature Sequence Diagram(s)sequenceDiagram
participant ClientsController
participant UpdateClientCommandHandler
participant ClientRepository
participant UpdateClientCommandExtensions
participant Client
participant UnitOfWork
ClientsController->>UpdateClientCommandHandler: Dispatch UpdateClientCommand
UpdateClientCommandHandler->>ClientRepository: Load client and contacts
UpdateClientCommandHandler->>UpdateClientCommandExtensions: ApplyTo(command, client, today)
UpdateClientCommandExtensions->>Client: Update profile and contact collections
UpdateClientCommandHandler->>ClientRepository: Check CPF and active email, excluding client
UpdateClientCommandHandler->>UnitOfWork: Save changes
Merge Risk: ⚪ Minimal · up to The client update endpoint follows the existing tenant access policy. No issue requiring resolution before merge was established. Security Architecture ReviewSecurity architecture risk: 🟡 Moderate · up to Authentication, tenant isolation and contact ownership checks are preserved. However, concurrent edits can defeat the required-guardian rule and persist a minor with no remaining guardian. The exposure is limited to authorized edits within the caller’s tenant. Retained concerns
Security review detailsSecurity Blast Radius
Security Findings and Attack Paths
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 0.63% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 158 functions across 24 files. (5 skipped: 5 unsupported.) ✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…te-backend # Conflicts: # docs/adr/README.md
O que muda
Backend de #156 (a tela de edição fica em outro PR, cortado da
maindepois deste). Não fecha a issue.PUT /api/v1/clients/{id}: o corpo traz os dados atuais da pessoa e a lista final de contatos.ido contato é alterado no lugar; semidé novo; omitido é removido. Tudo em uma única transação.idde contato que não é da pessoa (outra pessoa, outro tenant, inexistente, já removido, lista trocada):404 Client.ContactNotFound, sem gravar nada e sem revelar existência.ClientResponseigual ao da criação;[RequestSizeLimit]de 64 KB como noPOST.generate:api-types:checkok).Decisões (detalhes na ADR 0053)
Client.Updateúnico, em duas fases: valida tudo (limites, menor, ids do próprio cliente, ids repetidos, dados de cada contato) e só então atribui e sincroniza, para uma falha não deixar a pessoa pela metade.DeletedAt), como todo registro do serviço; não há política de retenção ainda.nullno corpo = sem contatos daquele tipo (igual à criação).UpdateGuardianInput,UpdateReferenceContactInput) em vez de reaproveitar as da criação comidopcional.Para o revisor
Guid.CreateVersion7()), um contato novo adicionado a um cliente carregado era rastreado comoModifiede a gravação falhava (DbUpdateConcurrencyException). Os ids dos dois contatos agora sãoValueGeneratedNever(). O schema não muda (has-pending-model-changeslimpo), então não há migração. Há teste de modelo que trava a configuração.ClientRuleBuilderExtensionse o mapeamento de contatos paraClientContactMapping, para os dois validators não divergirem;FindByCpfAsync/FindActiveByEmailAsyncganharamexcludeClientId. Os testes de criação foram ajustados e seguem verdes.docs/adr/README.mdvai conflitar de forma trivial com o PR feat(services): manter os serviços oferecidos (#141, backend) #164 (ele edita as mesmas linhas, ADR 0052).Verificação
dotnet build backend/AdminBackend.slnx -c Release: 0 avisos.dotnet test: 476 (unidade) + 38 (persistência) verdes; cobertura de Domain + Application 94,8%.DeletedAt; regra de menor; ids alheios (mesmo tenant, outro tenant, inexistente, lista trocada) → 404 sem gravar; pessoa de outro tenant/excluída → 404 e linha intacta; CPF/e-mail por situação;tenantIdestatusdo corpo ignorados; corpo > 64 KB → 413; e 12 rodadas de duas edições disputando o mesmo CPF, cada uma com exatamente um200e um409cujo perdedor ficou intacto (nome, CPF e contatos). 11 delas foram barradas pelo índice único (Client.SaveFailed).🤖 Generated with Claude Code
Summary by CodeRabbit