- Decidir remover este arquivo do .gitignore, ele possui notas que tomo enquanto desenvolvo a aplicação. A ideia é me ajudar com os pontos que não ficaram muito claros da arquitetura hexagonal
Portas são as interfaces, adaptadores são as implementações
- São os casos de uso, o que aciona o app
- São aquilo que o app aciona
Ex.: persistencia
- Objetivo: aprender hexagonal à risca + auth de ponta a ponta. Não é pra "entregar rápido" — a cerimônia é o exercício. (Não reescrever em MVC/Java.)
- Mapeamento ORM: Opção B — model ORM separado + mapper. Domínio nunca herda de
Base. - Banco: SQLite pra v1 (troca pra Postgres depois = mudar URL + driver).
- Sync (não async).
- Sem Unit of Work — decisão revertida.
SqlUserRepository.savecomita direto (commit-on-save), use cases seguem dependendo doUserRepositorydiretamente. - Roles: enum em memória (
UserRole), guardado como coluna JSONlist[str]— sem tabela de roles. Perde query "todos os admins", mas atende o caso atual. - Adapter de entrega deferido até o hexágono fechar (provável FastAPI; Basic Auth usa
VerifyUserCredentials, login JWT usaAuthenticateUser).
User(entidade rica: roles, ativar/desativar, updates,__eq__por id) — documentado.UserRole(StrEnum ADMIN/USER) — documentado.exceptions.py(famíliaDomainException, 11 subclasses) — documentado.
- 9 protocolos: CreateUser, GetUser, UpdateUserFullName, UpdateUserEmail, ChangeUserPassword, ResetUserPassword, RegisterUser, AuthenticateUser, VerifyUserCredentials.
AuthResult(VO: user + access_token).
UserRepository,PasswordHasher,TokenIssuer.
- CreateUser, GetUser, UpdateUserFullName, UpdateUserEmail, ChangeUserPassword, ResetUserPassword, RegisterUser, VerifyUserCredentials, AuthenticateUser.
- Testes unitários com fakes (
FakeUserRepository,FakePasswordHasher,FakeTokenIssuer) +conftest. Todos verdes. - Segurança já pensada:
InvalidCredentialsuniforme (sem enumeração), timing uniforme no verify (hash+verify dummy no ramo de user inexistente).
UserModel(models.py) — pronto e documentado.mapper.py(user_to_user_model/user_model_to_user) — pronto e documentado. Trata roles (set↔list ordenada) e reata UTC na leitura.SqlUserRepository(__init__.py) — implementaUserRepositoryusandosession+ mapper na fronteira;savecomita direto (sem UoW), traduzIntegrityErroremUserAlreadyExists.db.py— engine +sessionmaker+ URL viaSettings.- Testes de integração (
tests/integration/test_orm.py, SQLite) cobrindo save/get/duplicidade — todos verdes.
- Um arquivo por adapter (
password_hasher.py,token_issuer.py), espelhandocore/ports/secondary;__init__.pyvazio. Argon2PasswordHasher— implementaPasswordHasherviaargon2-cffi.JwtTokenIssuer— implementaTokenIssuerviaPyJWT.issue: claimssub/roles/iat/exp, secret/algoritmo/expiração vêm deSettings(JWT_SECRET_KEY,JWT_ALGORITHM,JWT_EXPIRATION_MINUTES).verify(porta ganhou o método): decodifica e valida assinatura/expiração, retorna oUUIDdosub; token inválido/adulterado/expirado viraInvalidCredentials. Reconstrução do actor (UserRepository.get_by_id) fica pro adapter de entrega, não é responsabilidade doTokenIssuer.
- Testes de integração (
tests/integration/test_security.py) — todos verdes.
- FastAPI (ou equivalente): adapter Basic Auth (usa VerifyUserCredentials) e login JWT (usa AuthenticateUser).
- Fluxo "esqueci a senha" (depende de adapter de e-mail).
- Diagramas: ER/relacional (após persistência), sequência do fluxo de auth, diagrama do hexágono.