NodeJS + TypeScript
NextJS
NestJS
PostgreSQL
S3
Docker
Docker compose
Github Actions
Scss
AWS S3
AWS ECR
DDD (Domain Driven Design): Abordagem de design que coloca o domínio de negócio no centro do desenvolvimento. O código reflete a linguagem e as regras do negócio por meio de Entidades, Agregados, Value Objects e Repositórios. Promove alinhamento entre times técnicos e especialistas de domínio através de uma Linguagem Ubíqua compartilhada.
Clean Architecture: Organiza o sistema em camadas concêntricas — Entidades, Casos de Uso, Interface Adapters e Frameworks — garantindo que dependências apontem sempre para dentro. O core da aplicação permanece independente de frameworks, banco de dados e interfaces externas, facilitando testes e evolução.
TDD (Test Driven Development): Metodologia em que os testes são escritos antes do código de produção. O ciclo Red-Green-Refactor guia o desenvolvimento: escrever um teste que falha, implementar o mínimo para passá-lo e então refatorar. Resulta em código mais simples, bem testado e com design emergente de alta qualidade.
CQRS (Command and Query Responsibility Segregation): Separa as operações de leitura (Queries) das operações de escrita (Commands) em modelos distintos. Permite otimizar cada lado de forma independente — leituras podem usar projeções desnormalizadas enquanto escritas mantêm consistência via modelo de domínio rico. Combina naturalmente com Event Sourcing.
SOLID: Conjunto de cinco princípios para código orientado a objetos coeso e manutenível: responsabilidade única (SRP), aberto/fechado (OCP), substituição de Liskov (LSP), segregação de interfaces (ISP) e inversão de dependência (DIP). Guiam decisões de design para reduzir acoplamento e aumentar coesão.
Modularização: Estratégia de organizar o sistema em módulos com alta coesão interna e baixo acoplamento externo. Cada módulo encapsula um conjunto coerente de responsabilidades, expondo apenas interfaces públicas bem definidas. Facilita o trabalho paralelo de times, manutenção isolada e eventual extração de serviços.
RBAC (Role Based Access Control): Modelo de controle de acesso que vincula permissões a papéis (roles) e atribui papéis a usuários, em vez de gerenciar permissões individualmente. Simplifica a gestão de autorização em sistemas com múltiplos perfis, tornando políticas de acesso auditáveis, reutilizáveis e fáceis de modificar.
SDD (Spec Driven Development): Abordagem em que especificações formais — contratos de API, schemas, user stories estruturadas ou BDD scenarios — dirigem o desenvolvimento. O código é gerado ou validado contra a spec, garantindo alinhamento entre o que foi especificado e o que foi implementado. Reduz ambiguidade e retrabalho.
O fluxo adota três níveis de branches com pipelines automatizados em cada transição:
Branches
feature/* — branches de tópico onde o desenvolvimento acontece. Commits locais sem automação.
develop — branch de integração. Recebe merges das features via PR.
main — branch de produção. Recebe merges do develop via PR após validação completa.
Pipelines
PR → develop: acionado ao abrir PR de feature para develop. Executa build, lint, testes de unidade e testes de integração com Docker. Portão de entrada na integração.
PR → main: mesmas verificações do PR anterior. Garante que nada quebrou na consolidação para produção.
Commit em main (deploy): acionado após o merge em main. Executa build, Docker build e push da imagem para o ECR — entregando o artefato pronto para deploy.
Fluxo resumido
feature/* → PR → develop → PR → main → deploy automático para ECR
É um Gitflow simplificado — sem branches de release ou hotfix explícitas — com CI progressivo que aumenta a confiança a cada promoção de branch, e CD acionado apenas no merge final em main.
A arquitetura segue um modelo em camadas com separação clara entre frontend, backend e integrações externas.
Camada de apresentação — o usuário acessa via navegador ou mobile através de HTTPS. O frontend é construído em Next.js com React, usando SSR/SSG e App Router, servido na porta 3000.
Camada de aplicação — o Next.js se comunica com o backend via REST/JSON usando fetch e server actions. O NestJS (porta 3001) concentra toda a lógica de negócio em Controllers e Services, expondo uma API REST em TypeScript.
Camada de dados — o NestJS acessa o PostgreSQL (porta 5432) via queries SQL através do TypeORM, responsável pela persistência relacional.
Integrações externas — o backend se conecta a dois serviços externos:
AWS S3 via HTTPS/S3 API usando o AWS SDK, para armazenamento de uploads, assets e documentos.
Google SMTP via SMTP/TLS na porta 587, para envio transacional de e-mails de notificação e recuperação de conta.
É uma arquitetura web clássica de três camadas — cliente, servidor, banco — complementada por serviços gerenciados de cloud para storage e comunicação, mantendo o backend como único ponto de integração com recursos externos.
ADRs são documentos curtos que registram decisões arquiteturais relevantes tomadas ao longo do projeto — capturando não apenas o que foi decidido, mas o contexto que motivou a decisão e as consequências esperadas. Cada registro funciona como um histórico auditável da evolução arquitetural do sistema, facilitando o onboarding de novos membros, a revisão de decisões passadas e a rastreabilidade técnica do projeto.
No TutorVest, as ADRs são utilizadas para documentar escolhas estruturais como definição de stack, padrões arquiteturais adotados e estratégias de infraestrutura — garantindo que o raciocínio por trás de cada decisão permaneça acessível ao time.
Abaixo está o drive com as ADRs registradas do projeto:
A infraestrutura do TutorVest é provisionada integralmente na AWS, organizada dentro de uma VPC dedicada na região us-east-1.
A VPC é dividida em duas subnets com responsabilidades distintas, seguindo boas práticas de segurança e separação de camadas. A subnet pública hospeda a instância EC2 do frontend — exposta à internet via Internet Gateway e protegida por um Security Group que libera exclusivamente a porta 80 para qualquer origem (0.0.0.0/0). É nessa instância que roda o contêiner Docker do frontend Next.js, acessível diretamente pelos usuários. A subnet privada hospeda a instância EC2 do backend e do banco de dados — completamente isolada da internet, sem exposição pública. Nela rodam os contêineres do backend NestJS (porta 3000) e do PostgreSQL (porta 5432), ambos acessíveis apenas por tráfego originado dentro da própria VPC (10.0.0.0/0). Essa separação garante que nenhuma requisição externa alcance diretamente a camada de dados ou de negócio — o frontend é o único ponto de entrada público, e toda comunicação com o backend ocorre pela rede interna da VPC.
Fora da VPC, dois serviços gerenciados complementam a infraestrutura. O AWS S3 armazena arquivos da aplicação, uploads de usuários e assets estáticos. O AWS ECR atua como registro privado de imagens Docker: a cada merge na branch main, o pipeline de CD gera uma nova imagem e a publica no ECR, de onde ela é puxada para as instâncias EC2 no momento do deploy.
É uma arquitetura enxuta e segura — adequada ao contexto acadêmico, com custo operacional próximo de zero dentro do AWS Free Tier — com separação clara entre camadas pública e privada e caminho evolutivo definido para escala futura.