Repository navigation
PetMatch ponta a ponta: contrato unificado, matches/chat, auth, mobile, uploads, CI e segurança - #4
Merged
Merged
Conversation
…artilhado
O schema/DTO do Pet divergiam do modelo usado pelo seed, pelo motor de
recomendação e pelo frontend (purpose/birthDate/energyLevel/Macho-Fêmea/isActive
vs. seeking/ageMonths/macho-femea/active), o que quebrava a integração
ponta a ponta.
- Schema e DTOs passam ao contrato compartilhado: gender (macho|femea),
size (pequeno|medio|grande), seeking (socializacao|cruzamento|ambos),
ageMonths, temperament, compatibility, city, active. toJSON expõe `id`
(sem _id/__v). Índice composto passa a {location, seeking, status}.
- Rotas: adiciona GET /pets (lista) e GET /pets/feed?petId= (declarada antes
de :id). O feed delega a ordenação ao recommendation-engine e cai para um
modo degradado no Mongo se o motor estiver indisponível.
- POST /pets resolve o dono pelo header X-Owner-Id (@OwnerId) e deriva a
location da cidade.
- Corrige imports duplicados em pets.module.ts (quebravam o build).
- Atualiza os specs ao novo modelo e comportamento.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VcgjQctU9a6AkRXuXKh2CM
…pm run seed O seed falhava a validação do Mongoose (faltavam birthDate/energyLevel/purpose e gender/size estavam fora do enum) e não havia script para executá-lo. Agora os 26 pets de exemplo validam contra o schema unificado, com `city` no topo do documento, e `npm run seed` executa src/seed.ts via ts-node. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VcgjQctU9a6AkRXuXKh2CM
…no front Ao registrar um like, o backend verifica se o alvo já havia curtido a origem e devolve `matched` de verdade. O frontend passa a usar esse resultado em vez de um match aleatório (Math.random). A persistência do documento Match e o chat seguem como Etapa 2. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VcgjQctU9a6AkRXuXKh2CM
Campos extras espelhados de Pet para o frontend montar o card sem uma segunda consulta. Compatível com o contrato existente (campos opcionais, com default). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VcgjQctU9a6AkRXuXKh2CM
…viços README reflete o app funcionando ponta a ponta (passo de seed, variáveis, status e próximos passos). Adiciona .github/workflows/ci.yml com build/testes do backend, build do web e pytest do motor de recomendação. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VcgjQctU9a6AkRXuXKh2CM
- Match: corrige o índice (pairKey única no lugar do multikey {petIds} único) e
expõe `id` no toJSON. MatchesService.ensureFromReciprocalLike faz upsert
idempotente do par e monta o resumo a partir dos pets.
- SwipesService passa a criar o Match no like recíproco e devolve `matchId`.
- MatchesController: GET /matches (do dono, via X-Owner-Id).
- Chat: MessagesService + MessagesController (GET/POST /matches/:matchId/messages),
com autorização pelo dono e atualização de lastMessageAt.
- Testes: matches, messages e swipes (32 no total).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VcgjQctU9a6AkRXuXKh2CM
- AuthModule: POST /auth/register e /auth/login devolvem { accessToken, user };
senha com bcryptjs, JWT via @nestjs/jwt + passport-jwt.
- UsersModule: UsersService (create/findByEmail/findById) e GET /users/me
protegido por JwtAuthGuard. toJSON do User esconde o passwordHash e expõe id.
- OptionalJwtAuthGuard global: popula req.user quando há JWT válido sem bloquear
o fluxo anônimo. @OwnerId passa a preferir o usuário autenticado e cai para o
X-Owner-Id/DEMO_OWNER_ID quando não há login.
- backend-api/.env.example com MONGO_URI/PORT/AI_ENGINE_URL/JWT_*.
- Testes de AuthService e UsersService (38 no total).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VcgjQctU9a6AkRXuXKh2CM
Lista os pets do dono autenticado (ou identificado por X-Owner-Id), usado pela tela de perfil do web. Declarado antes de :id para não colidir com a rota. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VcgjQctU9a6AkRXuXKh2CM
- react-router-dom: rotas para feed, /matches, /matches/:id (chat), /perfil, /login, /cadastro e /pets/novo. - Auth: telas de login e criação de conta; sessão (JWT + conta) no localStorage; cliente HTTP envia Bearer quando logado (e X-Owner-Id no anônimo). - Matches: lista por dono; o match no swipe agora abre o chat real (matchId). - Chat: lista e envio de mensagens. - Perfil: conta (entrar/sair) e "meus pets" (listar/excluir) via GET /pets/mine. - SwipePage: navegação no header e onboarding preservado. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VcgjQctU9a6AkRXuXKh2CM
- ConfigModule.forRoot({ isGlobal: true }) carrega variáveis de .env.
- Swagger (plugin do nest-cli + DocumentBuilder) publica a doc interativa da API
em /docs, com bearer auth.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VcgjQctU9a6AkRXuXKh2CM
Botão "usar minha localização" captura coordenadas do dispositivo (GeoJSON [lng, lat]) e as envia em `location`; sem isso, o backend deriva da cidade. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VcgjQctU9a6AkRXuXKh2CM
…at, perfil) Sai do andaime para um app navegável (react-navigation: tabs + stack): - Sessão em AsyncStorage (token + conta + ownerId anônimo) hidratada no boot. - Cliente HTTP espelhando o web (Bearer/X-Owner-Id). - Telas: descoberta (curtir/passar + match abre o chat), matches, chat, perfil (entrar/sair, meus pets, excluir), login, criar conta e cadastrar pet. Validado com tsc --noEmit (build/execução exigem Expo + dispositivo). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VcgjQctU9a6AkRXuXKh2CM
- backend-api: build multi-stage (node) -> roda dist/main.js. - recommendation-engine: imagem python + uvicorn. - web-app: build Vite -> nginx (com fallback SPA para o react-router). - docker-compose: serviços de app sob o profile "full" (o padrão segue só com o Mongo, para combinar com `npm run dev`). `docker compose --profile full up` sobe tudo. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VcgjQctU9a6AkRXuXKh2CM
- ESLint flat config no backend e no web (typescript-eslint + regras de hooks no web); scripts `lint`. Remove diretivas eslint-disable obsoletas. - Engine: aplica o formato do Black (test_ranking). Ruff e Black já configurados no pyproject e nas deps de dev. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VcgjQctU9a6AkRXuXKh2CM
- Vitest (jsdom) com testes dos helpers de display e do MatchModal. - CI: lint no backend/web, build, testes (jest/vitest), typecheck do mobile e ruff/black/pytest no motor de recomendação. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VcgjQctU9a6AkRXuXKh2CM
- Backend: POST /uploads (multipart, campo "file") grava a imagem em disco e
devolve { url }; arquivos servidos estaticamente em /uploads. Valida tipo
(imagens) e tamanho (5 MB).
- Web: campo de arquivo no cadastro de pet que envia a foto e usa a URL retornada
(a URL manual continua funcionando).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VcgjQctU9a6AkRXuXKh2CM
…s/uploads) O padrão `uploads/` ignorava também `src/modules/uploads`, deixando o módulo de fora do commit anterior (o build quebraria). Padrão corrigido para `/uploads/` (apenas a pasta de runtime na raiz do serviço) e os fontes adicionados. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VcgjQctU9a6AkRXuXKh2CM
Reflete matches/chat, auth JWT, uploads, Swagger, geolocalização, app mobile, testes/lint/CI e a stack via docker compose --profile full. Próximos passos revisados (tempo real, storage externo, etc.). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VcgjQctU9a6AkRXuXKh2CM
- PATCH/DELETE /pets/:id agora exigem que o solicitante seja o dono (@OwnerId + verificação no service), fechando o IDOR que permitia editar/excluir o pet de qualquer um. Lança 403 quando não é o dono. - POST /uploads passa a exigir JWT (JwtAuthGuard); evita upload anônimo. No web, o seletor de arquivo só aparece logado — anônimo continua podendo colar URL. - Testes cobrindo os casos de "Forbidden" (41 no backend). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VcgjQctU9a6AkRXuXKh2CM
Passo a passo de uso (onboarding, swipe, match, chat, conta/perfil), nota sobre reciprocidade para gerar match, instruções do mobile e rotas principais da API (Swagger em /docs). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VcgjQctU9a6AkRXuXKh2CM
O main trouxe `fix: importacao correta do module`, que removeu as linhas de import duplicadas em pets.module.ts de forma diferente da deste branch. O merge 3-way juntou as duas remoções e apagou TODOS os imports de PetsController/ PetsService (TS2304 no CI do PR). Imports restaurados; backend volta a compilar. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VcgjQctU9a6AkRXuXKh2CM
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Contexto
Uma revisão da base apontou que o merge anterior (PR #3) deixou dois modelos de dados de Pet conflitantes (
purpose/birthDate/Machono NestJS vs.seeking/ageMonths/machono seed/engine/web), o que quebrava o seed, o feed e a integração web↔API. Este PR corrige a causa-raiz e leva o produto a um MVP funcional ponta a ponta (web + mobile).Principais mudanças
Correções de base
Petno contrato compartilhado (seeking,ageMonths,macho/femea,pequeno/medio/grande,locationGeoJSON,active);toJSONexpõeid.npm run seed.GET /pets,GET /pets/feed?petId=(delega ao motor, com fallback no Mongo),POST /pets(dono viaX-Owner-Id,locationderivada da cidade).pets.module.tsque quebrava o build.Novas funcionalidades
Match(índicepairKeyno lugar do multikeypetIds); lista de matches e chat (REST)./auth/register|login,/users/me, bcrypt) convivendo com a identidade anônima porX-Owner-Id.POST /uploads), Swagger em/docseConfigModule.Segurança
PATCH/DELETE /pets/:idagora exigem ser o dono (403 caso contrário).POST /uploadsexige login.Qualidade
.github/workflows/ci.yml) e Dockerfiles +docker compose --profile full.Como testar
docker compose --profile full up -d --build(ounpm run dev+npm run seed), abrahttp://localhost:5173. Detalhes em Como usar o app no README.Ressalvas
validateSync+ build/typecheck. O CI deste PR executa lint/build/testes dos quatro serviços.tsc --noEmit; rodeexpo startnum device para o teste real.npm audit: 1 item moderado transitivo (js-yamlvia@nestjs/swagger), sem correção não-quebrante.🤖 Generated with Claude Code
https://claude.ai/code/session_01VcgjQctU9a6AkRXuXKh2CM
Generated by Claude Code