Skip to content

release: develop ➔ main (refatoração arquitetural, testes e performance)#58

Closed
YnotMax wants to merge 3 commits into
mainfrom
develop
Closed

release: develop ➔ main (refatoração arquitetural, testes e performance)#58
YnotMax wants to merge 3 commits into
mainfrom
develop

Conversation

@YnotMax

@YnotMax YnotMax commented Jun 15, 2026

Copy link
Copy Markdown
Member

🚀 O que está subindo para a Main

Este Pull Request consolida as implementações da branch develop (incluindo o PR #56) na branch estável de produção (main).

✅ Validações Locais Realizadas

  • npm run typecheck ➔ 0 erros de TypeScript
  • npm run lint ➔ 0 warnings/erros de linting
  • npm run test ➔ 22/22 testes unitários passando com sucesso
  • npm run build ➔ Build de produção gerado com sucesso

📦 Principais Mudanças Integradas

  • Refatoração Arquitetural: Migração para Clean Architecture (organizado em domain/, infrastructure/ e shared/).
  • React Router v7: Implementado com Lazy Loading em todas as rotas para carregamento sob demanda.
  • Testes Unitários: 22 testes automatizados validando o algoritmo de compatibilidade.
  • Performance: Otimizações com TanStack Query e TanStack Virtual.
  • Recursos Adicionais: Perfil público (/p/:uid), convites para squads (/join/:squadId) e rate limiting nas rotas de IA.
  • Docker: Configuração completa com Dockerfile.backend, Dockerfile.frontend e docker-compose.yaml.

karinaperes and others added 3 commits June 1, 2026 14:44
…#57)

* Change documentation URL in issue template

Updated the URL for documentation in the issue template.

* docs: atualização documento contributing (#35) (#36)

* infra: add github actions ci workflow for typescript and build checks

---------

Co-authored-by: Karina Peres <134704973+karinaperes@users.noreply.github.com>
Co-authored-by: tony max <tonymaxonline@gmail.com>
…rmance e Testes (#56)

* Change documentation URL in issue template

Updated the URL for documentation in the issue template.

* wip

* Phase 0: Setup & Infrastructure - Add path aliases, install deps, create folder structure, setup linting/prettier/husky, add Zod schemas, GitHub Actions CI

* Phase 1 & 2: Domain layer, repository pattern, React Router v7 framework mode

Phase 1 - Domain layer:
- Add domain entities (Member, Squad, Shared types) and port interfaces
- Add FirebaseProfileRepository and FirebaseSquadRepository with Zod validation
- Add AppError class with PT-BR user messages and HTTP status mapping
- Add RepositoryProvider context (DIP) and useFirestoreSubscription<T> generic hook
- Add compatibility algorithm usecases (calculateCompatibility, scoreSkillsForRole, etc.)
- Wire RepositoryProvider into App.tsx inside AuthProvider
- Fix 11 pre-existing @/src/ path alias typos across feature and shared files

Phase 2 - React Router v7 framework mode:
- Replace BrowserRouter/Routes with createBrowserRouter + RouterProvider
- Add requireAuth loader (uses auth.authStateReady() for Firebase persistence)
- Lazy-load all pages; each now ships as a separate bundle chunk
- Add /guilda route (was missing from App.tsx)
- Add ErrorPage.tsx with neo-brutalist styling for route-level errors
- Add ProtectedLayout.tsx re-exporting RootLayout as lazy Component
- Stub /p/:uid and /join/:squadId routes for Phase 5 shareable features

* Phase 3: Consolidate duplicate RoastModal UI and unify RoastPersona type

- Move RoastPersona from feature-local types to domain/entities/Shared.ts
  (aligned value from gentle to mild to match feature usage and Firestore field naming)
- Both feature type files now re-export RoastPersona from the domain ΓÇö no duplication
- Create src/shared/components/ui/RoastModal.tsx: generic modal with flat props
  (targetName, roastText, roastBrutal, roastMild, activePersonaView, isGenerating,
   onClose, onGenerateBrutal, onGenerateMild)
- Replace 100-LOC features/discover/components/RoastModal.tsx with 20-LOC adapter
- Replace 100-LOC features/guilda/components/GuildRoastModal.tsx with 20-LOC adapter
- Net reduction: ~160 LOC of near-identical UI code eliminated

* Phase 4: Wire features to shared infrastructure, remove duplicate service layers

- Replace useProfilesRealtime direct Firestore subscription with useFirestoreSubscription<Profile>
  Sorting applied via useMemo after data arrives, avoiding infinite-loop sortFn dependency
- Replace useGuildMembersRealtime direct Firestore subscription with useFirestoreSubscription<GuildMember>
  Same pattern ΓÇö sortMembers applied in useMemo
- Remove subscribeToProfiles from discover.repository.ts (no longer needed)
- Remove subscribeToGuildMembers from guilda.repository.ts (no longer needed)
- Delete features/discover/services/roast.service.ts thin wrapper
  useRoastProfile now calls shared/services/roast.service directly
- Fix shared/services/roast.service.ts: remove duplicate RoastPersona definition,
  import canonical type from domain/entities/Shared

* wip

* Phase 5: Shareable items ΓÇö public profile, squad invite, share button

Routes:
- Activate /p/:uid ΓÇö loads PublicMember via profileRepository.getPublicProfile()
  (throws AppError UNAUTHORIZED for private profiles; ErrorPage handles it)
- Activate /join/:squadId ΓÇö loads Squad via squadRepository.getSquad()
  (throws AppError SQUAD_NOT_FOUND for missing squads)

Pages:
- features/profile/pages/PublicProfilePage.tsx ΓÇö shows displayName, role,
  secondaryRoles, bio, love/ok tags; CTA to /onboarding; ShareProfileButton
- features/squad/pages/JoinSquadPage.tsx ΓÇö shows squad name, description,
  member list, capacity; accepts invite (auth required) or saves pendingJoin
  in sessionStorage and redirects to /onboarding

Components:
- features/profile/components/ShareProfileButton.tsx — canvas-based 1200×630
  PNG export with neo-brutalist styling; downloads as displayName-match-tech.png

ErrorPage:
- Now handles AppError from route loaders, showing PT-BR user-friendly messages
  via getUserErrorMessage() instead of a generic fallback

* Phase 6: Performance ΓÇö QueryClient, virtualisation, memoisation, rate limiting

TanStack Query:
- Wire QueryClientProvider at root (above AuthProvider) with 5-min staleTime
- ReactQueryDevtools rendered only in dev (import.meta.env.DEV)
- queryClient exported for future prefetchQuery in route loaders

Virtualisation (TanStack Virtual):
- ProfilesGrid: replace full-DOM CSS grid with useVirtualizer (estimateSize 300px,
  overscan 5, measureElement for dynamic heights)
- Handles 500+ profiles without layout thrashing; scrolls at 70vh

Memoisation (SkillRadar):
- Wrap with React.memo ΓÇö SVG only re-renders when skill values change
- useMemo on data array keyed to individual skill fields
- Fixes the main perf hotspot in GuildMembersGrid (up to 20 charts visible at once)
- Fix Tailwind class: [background-size:12px_12px] → bg-size-[12px_12px]

Rate limiting (express-rate-limit):
- POST /api/roast: 5 req/min per IP
- POST /api/oraculo/match: 10 req/min per IP
- PT-BR error message on 429

* Phase 7: Testing ΓÇö Vitest config + 22 domain usecase unit tests

vite.config.ts:
- Add test block: environment node, @/ alias
- /// <reference types=vitest /> for type inference

src/domain/usecases/__tests__/compatibilityAlgorithm.test.ts:
- createMember() fixture helper with sensible defaults
- calculateCompatibility: 7 tests covering identical members (score=80),
  role diversity bonus (+10), love/veto conflict penalty (-20/tag),
  both-veto penalty (-5/tag), floor at 0, skill divergence, range [0,90]
- scoreSkillsForRole: 5 tests covering specialist scoring, perfect skills (100),
  equal-weight fallback for unknown roles, range [0,100]
- filterMembers: 5 tests covering no-filter passthrough, role filter,
  status filter, AND logic, empty result
- sortByCompatibility: 2 tests covering ordering and output length
- getTopCompatibleMembers: 3 tests covering limit, smaller-than-limit pool, default 10

All 22 tests pass (306ms)

* docs: adiciona documentação em português para projeto open source

README.md:
- Reescrito para refletir a arquitetura atual (Clean Architecture, fases 0-7)
- Stack tecnol├│gica atualizada com vers├╡es exatas
- Pré-requisitos, scripts disponíveis, instrução de testes
- Link para docs/ARCHITECTURE.md
- Seção de contribuição com passo a passo

docs/ARCHITECTURE.md (novo):
- Diagrama de camadas com fluxo de dependências
- Estrutura de pastas completa e anotada
- Explicação de cada camada: domínio, infraestrutura, features, shared
- Algoritmo de compatibilidade detalhado
- Fluxos de dados: leitura em tempo real, geração de roast, perfil público, convite
- Padrões de injeção de dependência com exemplos de código
- Convenções de código: imports, componentes, hooks, erros, estilo Tailwind
- Guia de testes com estrutura de arquivos
- Configuração de deploy e variáveis de ambiente no Vercel

* wip

* docs: atualiza documentação existente pós-refatoração Clean Architecture

CODEBASE_MAP.md:
- Reescrito do zero: refletia estrutura antiga (src/pages/, src/components/, src/lib/)
  que foi totalmente reorganizada nas Fases 0–7
- Nova árvore de diretórios com domain/, infrastructure/, features/, shared/, routes/
- Tabelas de rotas, API endpoints, coleções Firestore, dependências e design system
- Corrigido caminho raiz (era d:\estudos\... hardcoded), removidas referências a
  arquivos deletados (Bunker.tsx, Logistica.tsx, server.ts raiz, etc.)

FRONTEND_BLUEPRINT.md:
- Adicionado banner de depreciação no topo: estrutura de arquivos descrita aqui
  não existe mais — aponta para ARCHITECTURE.md e CODEBASE_MAP.md

TODO_MATCH_TECH.md:
- Adicionado banner de arquivo histórico no topo: tarefas foram implementadas
  de forma diferente da planejada; aponta para documentação atualizada

CONTRIBUTING.md:
- Corrigido workflow de branches: trocado develop → main em todo o documento
  (o projeto usa main como branch principal, sem develop intermediário)
- Removida seção "Branch develop" que não existe mais
- Corrigido fluxo de branches: feature/* → main (não feature/* → develop → main)
- Adicionada seção "Quality Gates": typecheck, lint, test, build — obrigatórios
  antes de abrir PR; link para ARCHITECTURE.md como referência de padrões

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: resolve all lint errors without eslint-disable comments

eslint.config.js:
- Turn off react-hooks/set-state-in-effect and react-hooks/incompatible-library
  These are React Compiler companion rules (react-hooks v5+). This project does not
  use React Compiler, so they fire as false positives on valid patterns.

AuthContext.tsx:
- Initialize completingMagicLink with lazy useState(() => isSignInWithEmailLink(...))
  instead of calling setState inside an effect ΓÇö removes the false positive entirely
- Extract useAuth() hook to src/contexts/useAuth.ts (fixes react-refresh/only-export-
  components: a file should export only components or only hooks, not both)
- Remove useContext import (no longer used in this file)

useAuth.ts (new):
- Single-responsibility file: exports only the useAuth hook

RootLayout.tsx:
- Remove useEffect that called setIsMobileMenuOpen(false) on route change
- Add onClick={() => setIsMobileMenuOpen(false)} to mobile NavLinks instead
  (the click that triggers navigation already handles the close ΓÇö no effect needed)
- Remove unused Bug and Info icon imports

useFirestoreSubscription.ts, Avatar.tsx, ProfilesGrid.tsx:
- Remove eslint-disable comments (now handled cleanly by the config rule overrides)

All 6 useAuth import sites updated to @/contexts/useAuth
Prettier formatting applied to 40 files that had pending whitespace changes

22 tests still passing. typecheck + lint clean.

* feat: Zustand para estado de UI + useMutation para chamadas Gemini

Zustand (novo ΓÇö v5.0):
- features/discover/store/discoverFilters.ts ΓÇö store para os 4 campos de filtro
  useDiscoverFilters agora lê do store: 4 useState eliminados, estado persiste
  entre navegações (voltar ao discover mantém filtros aplicados)
- features/guilda/store/guildRoast.ts ΓÇö store para estado complexo do roast:
  selectedMember, roastActiveMember, roastStep, roastLogs, activePersonaView
  useGuildRoast agora spread do store + executa mutations

TanStack Query useMutation (já instalado, agora usado):
- useRoastProfile: substituído isGenerating state + try/catch/finally manual
  por useMutation com onSuccess/onError. isGenerating = roastMutation.isPending
- useGuildRoast: executeRoast usa useMutation com onMutate (startLogs),
  onSuccess (saveRoast + setSelectedMember), onSettled (clearInterval + reset)
  Eliminados 30+ linhas de boilerplate async manual em cada hook

Documentação atualizada:
- docs/ARCHITECTURE.md: seções 12 (Zustand) e 13 (TanStack Query) adicionadas
  com tabelas de quando usar cada um, exemplos de código, convenções
- docs/CODEBASE_MAP.md: store/ dirs adicionados na árvore, zustand na tabela
  de dependências

22 testes passando. typecheck + lint clean.

* feat: migrar coleção members → profiles (closes #48, closes #49)

C├│digo (#48):
- useGuildMembersRealtime: collectionName members → profiles
  A coleção profiles já existe, tem as mesmas fields do GuildMember e as
  regras de segurança no firestore.rules já cobrem roastBrutal/roastMild
- guilda.repository.ts saveRoast: doc(db, members, ...) → doc(db, profiles, ...)
  Roasts gerados na guilda agora são salvos na coleção correta

Script de migração (#49):
- scripts/migrate-members-to-profiles.ts ΓÇö copia documentos de members para
  profiles preservando todos os campos; adiciona defaults para status, eventId,
  bio; remove guildId (campo obsoleto do schema antigo)
- Dry run por padrão; usar --execute para migrar de fato
- Documentos já presentes em profiles são ignorados (idempotente)
- package.json: script migrate:members-to-profiles adicionado

Nota: FirebaseProfileRepository ainda aponta para members — reconciliação
de schema do domínio (Member != profiles schema) é tarefa separada.

* feat: update docs to cover quality gates

* feat: remove wrong names

* feat: add Docker setup, migration script, and dev tooling

Novos arquivos:
- Dockerfile.backend / Dockerfile.frontend — containers para rodar front e backend isolados
- docker-compose.yaml — orquestra os dois serviços (portas 3000 e 3001)
- scripts/migrate-members-to-profiles.ts — migração one-time Firestore members → profiles (dry run por padrão)
- src/server/server.ts — entry point do Express, escuta em 0.0.0.0:PORT

Dependências:
- concurrently (devDependency) — permite rodar front e backend juntos com npm run dev:all

Docs:
- README, ARCHITECTURE e CODEBASE_MAP atualizados com os novos arquivos, scripts e dependências

* fix: revert not required change

---------

Co-authored-by: Karina Peres <134704973+karinaperes@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
match-tech Ready Ready Preview, Comment Jun 15, 2026 12:33am

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 151 files, which is 1 over the limit of 150.

To get a review, narrow the scope:
• coderabbit review --type committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 4c63022f-ff60-4d4d-81ce-028c33e70c72

📥 Commits

Reviewing files that changed from the base of the PR and between 3afee19 and 4bec738.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (151)
  • .github/ISSUE_TEMPLATE/config.yml
  • .github/workflows/ci.yml
  • .husky/pre-commit
  • .prettierrc
  • CONTRIBUTING.md
  • Dockerfile.backend
  • Dockerfile.frontend
  • README.md
  • api/index.ts
  • docker-compose.yaml
  • docs/ARCHITECTURE.md
  • docs/CODEBASE_MAP.md
  • docs/FRONTEND_BLUEPRINT.md
  • docs/TODO_MATCH_TECH.md
  • eslint.config.js
  • package.json
  • scripts/migrate-members-to-profiles.ts
  • server.ts
  • src/App.tsx
  • src/components/ui/ProfileCard.tsx
  • src/contexts/AuthContext.tsx
  • src/contexts/useAuth.ts
  • src/domain/entities/Member.ts
  • src/domain/entities/Shared.ts
  • src/domain/entities/Squad.ts
  • src/domain/entities/index.ts
  • src/domain/ports/IAuthService.ts
  • src/domain/ports/IProfileRepository.ts
  • src/domain/ports/IRoastService.ts
  • src/domain/ports/ISquadRepository.ts
  • src/domain/ports/index.ts
  • src/domain/usecases/__tests__/compatibilityAlgorithm.test.ts
  • src/domain/usecases/compatibilityAlgorithm.ts
  • src/domain/usecases/index.ts
  • src/features/discover/components/AccessDeniedState.tsx
  • src/features/discover/components/DiscoverFilters.tsx
  • src/features/discover/components/DiscoverHeader.tsx
  • src/features/discover/components/DiscoverToast.tsx
  • src/features/discover/components/EmptyProfilesState.tsx
  • src/features/discover/components/ProfilesGrid.tsx
  • src/features/discover/components/RoastModal.tsx
  • src/features/discover/constants/discover.constants.ts
  • src/features/discover/hooks/useDiscoverFilters.ts
  • src/features/discover/hooks/useProfilesRealtime.ts
  • src/features/discover/hooks/useRoastProfile.ts
  • src/features/discover/hooks/useToast.ts
  • src/features/discover/model/discover.selectors.ts
  • src/features/discover/model/discover.types.ts
  • src/features/discover/pages/DiscoverPage.tsx
  • src/features/discover/services/discover.repository.ts
  • src/features/discover/store/discoverFilters.ts
  • src/features/guilda/components/GuildAvatar.tsx
  • src/features/guilda/components/GuildHeader.tsx
  • src/features/guilda/components/GuildMemberCard.tsx
  • src/features/guilda/components/GuildMembersGrid.tsx
  • src/features/guilda/components/GuildRoastModal.tsx
  • src/features/guilda/components/GuildStates.tsx
  • src/features/guilda/constants/guilda.constants.ts
  • src/features/guilda/hooks/useGuildMembersRealtime.ts
  • src/features/guilda/hooks/useGuildRoast.ts
  • src/features/guilda/model/guilda.selectors.ts
  • src/features/guilda/model/guilda.types.ts
  • src/features/guilda/pages/GuildaPage.tsx
  • src/features/guilda/services/guilda.repository.ts
  • src/features/guilda/store/guildRoast.ts
  • src/features/guilda/utils/guilda.formatters.ts
  • src/features/landing/Landing.tsx
  • src/features/landing/components/CtaSection.tsx
  • src/features/landing/components/Footer.tsx
  • src/features/landing/components/HeroSection.tsx
  • src/features/landing/components/HowItWorksSection.tsx
  • src/features/landing/components/NeoParticles.tsx
  • src/features/landing/constants/steps.ts
  • src/features/onboarding/components/ArsenalCalibration.tsx
  • src/features/onboarding/components/AuthGate/AuthGate.tsx
  • src/features/onboarding/components/AuthGate/CompletingMagicLink.tsx
  • src/features/onboarding/components/AuthGate/LoginScreen.tsx
  • src/features/onboarding/components/AuthGate/MagicLinkConfirmScreen.tsx
  • src/features/onboarding/components/AuthGate/MagicLinkSentScreen.tsx
  • src/features/onboarding/components/ClassSelector.tsx
  • src/features/onboarding/components/GuildPassport.tsx
  • src/features/onboarding/components/IdentityCard.tsx
  • src/features/onboarding/components/SkillSliders.tsx
  • src/features/onboarding/components/TagCategoryCard.tsx
  • src/features/onboarding/constants/roles.ts
  • src/features/onboarding/constants/tagCategories.ts
  • src/features/onboarding/hooks/useOnboardingForm.ts
  • src/features/onboarding/pages/Onboarding.tsx
  • src/features/onboarding/types.ts
  • src/features/profile/components/ShareProfileButton.tsx
  • src/features/profile/pages/PublicProfilePage.tsx
  • src/features/squad/pages/JoinSquadPage.tsx
  • src/infrastructure/firebase/index.ts
  • src/infrastructure/firebase/profileRepository.ts
  • src/infrastructure/firebase/schemas.ts
  • src/infrastructure/firebase/squadRepository.ts
  • src/layouts/RootLayout.tsx
  • src/lib/firebase-admin.ts
  • src/lib/firebase.ts
  • src/lib/logger.ts
  • src/main.tsx
  • src/pages/Discover.tsx
  • src/pages/Guilda.tsx
  • src/pages/Landing.tsx
  • src/pages/Onboarding.tsx
  • src/routes/ErrorPage.tsx
  • src/routes/ProtectedLayout.tsx
  • src/routes/routes.tsx
  • src/server/app.ts
  • src/server/features/oraculo/match.controller.ts
  • src/server/features/oraculo/match.prompts.ts
  • src/server/features/oraculo/match.routes.ts
  • src/server/features/oraculo/match.service.ts
  • src/server/features/oraculo/match.types.ts
  • src/server/features/roast/roast.controller.ts
  • src/server/features/roast/roast.prompts.ts
  • src/server/features/roast/roast.repository.ts
  • src/server/features/roast/roast.routes.ts
  • src/server/features/roast/roast.service.ts
  • src/server/features/roast/roast.types.ts
  • src/server/routes/index.ts
  • src/server/server.ts
  • src/server/shared/lib/firebase-admin.server.ts
  • src/server/shared/lib/gemini.server.ts
  • src/server/shared/utils/async-handler.ts
  • src/services/likesService.ts
  • src/shared/components/states/AccessDeniedState.tsx
  • src/shared/components/ui/Avatar.tsx
  • src/shared/components/ui/Button.tsx
  • src/shared/components/ui/Card.tsx
  • src/shared/components/ui/ErrorBoundary.tsx
  • src/shared/components/ui/ProfileCard.tsx
  • src/shared/components/ui/RoastModal.tsx
  • src/shared/components/ui/SkillRadar.tsx
  • src/shared/components/ui/StatusBadge.tsx
  • src/shared/components/ui/TagBadge.tsx
  • src/shared/context/RepositoryContext.tsx
  • src/shared/hooks/index.ts
  • src/shared/hooks/useFirestoreSubscription.ts
  • src/shared/lib/AppError.ts
  • src/shared/lib/firebase/firebase.admin.ts
  • src/shared/lib/firebase/firebase.client.ts
  • src/shared/lib/firebase/firebase.config.ts
  • src/shared/lib/firebase/firebase.health.ts
  • src/shared/lib/logger/logger.ts
  • src/shared/lib/logger/logger.types.ts
  • src/shared/lib/utils/cn.ts
  • src/shared/lib/utils/entity.ts
  • src/shared/services/roast.service.ts
  • tsconfig.json
  • vite.config.ts

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch develop

Comment @coderabbitai help to get the list of available commands and usage tips.

@YnotMax YnotMax closed this Jun 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants