O Vortex é um sistema web de cadastro de usuários com programa de indicações e pontuação. O projeto permite que usuários se cadastrem, recebam um link único de indicação e ganhem pontos sempre que alguém se cadastrar através do seu link.
- Cadastro de Usuários: Sistema completo de registro com validação de dados
- Sistema de Indicações: Cada usuário recebe um link único de indicação
- Pontuação Automática: Usuários ganham pontos quando alguém se cadastra através do seu link
- Perfil Personalizado: Página de perfil mostrando nome, pontos e link de indicação
- Copiar Link: Funcionalidade para copiar o link de indicação com um clique
- Atualização em Tempo Real: Botão para atualizar a pontuação sem recarregar a página
- Validação de Senha: Requisitos de segurança (mínimo 8 caracteres, letras e números)
- Persistência de Dados: Dados salvos em arquivo JSON no servidor
Por quê? Node.js foi escolhido por ser uma plataforma JavaScript amplamente utilizada no mercado, permitindo usar a mesma linguagem no frontend e backend. Além disso, é ideal para aplicações que precisam lidar com múltiplas requisições simultâneas (como um sistema de cadastros). Sua natureza assíncrona e event-driven torna o servidor eficiente e escalável.
Por quê? Express é o framework web mais popular para Node.js, oferecendo uma API simples e minimalista para criar servidores HTTP. Foi escolhido por:
- Facilidade de criar rotas REST de forma organizada
- Grande comunidade e documentação extensa
- Sistema de middleware flexível e poderoso
- Perfeito para construir APIs RESTful
- Reduz significativamente o boilerplate code
Por quê? Biblioteca para geração de IDs únicos universais. Foi escolhida para:
- Garantir IDs únicos para cada usuário sem colisões
- Segurança (IDs não são sequenciais/previsíveis)
- Padrão amplamente aceito na indústria (RFC 4122)
- Facilitar integração futura com bancos de dados
- Independência de contador centralizado
Por quê? Middleware para habilitar CORS (Cross-Origin Resource Sharing). Essencial porque:
- Frontend e backend rodam em portas diferentes (8080 e 8000)
- Permite que o navegador faça requisições entre origens diferentes
- Necessário para a arquitetura cliente-servidor separada
- Protege contra requisições não autorizadas de outras origens
Por quê? Middleware para processar o corpo das requisições HTTP. Escolhido para:
- Parsear automaticamente JSON enviado pelo frontend
- Simplificar o acesso aos dados enviados via POST
- Validar e tratar erros de formato automaticamente
- Suporte a diferentes formatos (JSON, URL-encoded)
Por quê? Estruturação semântica das páginas web. Escolhido por:
- Padrão universal para estruturação web
- Suporte nativo a validação de formulários
- Acessibilidade e SEO aprimorados
- Compatibilidade cross-browser
Por quê? Estilização das páginas com design responsivo. Escolhido por:
- Separação clara entre estrutura (HTML) e apresentação (CSS)
- Flexbox para layouts responsivos
- Media queries para adaptação mobile
- Pseudo-classes para interações (hover, focus)
- Performance superior a bibliotecas CSS pesadas
Justificativa de não usar frameworks CSS: Para este projeto, optou-se por CSS puro para manter o bundle pequeno, ter controle total sobre o estilo e demonstrar conhecimento fundamental de CSS sem dependências externas.
Por quê? Linguagem de programação para lógica e interatividade. Escolhido por:
- Sem dependências de frameworks pesados (React, Vue, Angular)
- Performance superior para projetos pequenos/médios
- Fetch API nativa para requisições HTTP
- Async/await para código assíncrono limpo
- Manipulação de DOM eficiente
- URLSearchParams para parsing de query strings
Justificativa de não usar frameworks JavaScript: Para este projeto, frameworks como React seriam overhead desnecessário. JavaScript puro oferece tudo que precisamos: manipulação de DOM, requisições HTTP e gerenciamento de estado simples.
Por quê? Arquivo JSON para persistência de dados. Escolhido por:
- Simplicidade para projetos pequenos/protótipos
- Não requer configuração de banco de dados
- Fácil visualização e debug dos dados
- Formato legível por humanos
- Zero dependências externas
Observação: Para produção, seria recomendado migrar para um banco de dados (PostgreSQL, MongoDB) para melhor performance, segurança e escalabilidade.
vortex/
├── backend/
│ ├── server.js # Servidor Express com rotas da API
│ ├── data.json # Armazenamento de dados dos usuários
│ ├── package.json # Dependências do backend
│ └── package-lock.json # Lock file das dependências
│
└── frontend/
├── index.html # Página de cadastro
├── profile.html # Página de perfil do usuário
├── styles.css # Estilos globais
└── script.js # Lógica JavaScript do frontend
-
Cadastro:
- Usuário acessa
index.html(com ou sem parâmetroref) - Preenche formulário e clica em "Cadastrar"
- JavaScript envia POST para
/registerno backend - Backend cria usuário, gera ID único (UUID), salva em
data.json - Se houver
ref, adiciona 1 ponto ao usuário que indicou - Backend retorna dados do usuário + link de indicação
- Frontend redireciona para
profile.html?id={userId}
- Usuário acessa
-
Perfil:
- Usuário acessa
profile.html?id={userId} - JavaScript extrai
idda URL - Envia GET para
/users/:idno backend - Backend busca usuário em
data.jsone retorna dados - Frontend exibe nome, pontos e link de indicação
- Usuário pode copiar link ou atualizar pontos
- Usuário acessa
-
Indicação:
- Usuário compartilha link
index.html?ref={seuId} - Novo usuário se cadastra através desse link
- Backend identifica
ref, adiciona ponto ao indicador - Dados são salvos em
data.json
- Usuário compartilha link
- Node.js (versão 14 ou superior)
- NPM (geralmente vem com Node.js)
- Python 3 (para servir o frontend - já vem instalado no Mac/Linux)
git clone https://github.com/seu-usuario/vortex.git
cd vortex# Navegar até a pasta do backend
cd backend
# Instalar dependências
npm install
# Iniciar o servidor
node server.jsO backend estará rodando em http://localhost:8000
Saída esperada:
Servidor rodando em http://localhost:8000
Abra um novo terminal (mantendo o backend rodando) e execute:
# Navegar até a pasta do frontend
cd frontend
# Iniciar servidor HTTP com Python
python3 -m http.server 8080O frontend estará rodando em http://localhost:8080
Saída esperada:
Serving HTTP on :: port 8080 (http://[::]:8080/) ...
Abra seu navegador e acesse:
http://localhost:8080/index.html
- Faça um cadastro inicial
- Na página de perfil, copie seu link de indicação
- Abra uma aba anônima (Cmd+Shift+N no Chrome)
- Cole o link de indicação e faça outro cadastro
- Volte ao perfil do primeiro usuário e clique em "Atualizar Pontos"
- Você verá que ganhou 1 ponto!
# Parar os servidores
# Pressione Ctrl+C em cada terminal
# Limpar dados (apagar todos os usuários)
cd backend
rm data.json
# Um novo data.json será criado automaticamente no próximo cadastroCadastra um novo usuário.
Request Body:
{
"nome": "João Silva",
"email": "joao@email.com",
"senha": "senha12345",
"ref": "uuid-do-indicador" // opcional
}Response (200):
{
"id": "uuid-gerado",
"nome": "João Silva",
"email": "joao@email.com",
"senha": "senha12345",
"pontos": 0,
"referralLink": "http://localhost:8080/index.html?ref=uuid-gerado"
}Response (400):
{
"error": "Campos obrigatórios"
}Busca informações de um usuário pelo ID.
Response (200):
{
"id": "uuid-do-usuario",
"nome": "João Silva",
"email": "joao@email.com",
"senha": "senha12345",
"pontos": 5
}Response (404):
{
"error": "Usuário não encontrado"
}Vantagens:
- Separação de responsabilidades: Frontend cuida da UI, backend cuida da lógica de negócio
- Escalabilidade: Backend pode servir múltiplos clientes (web, mobile, desktop)
- Manutenibilidade: Código mais organizado e fácil de manter
- Deploy independente: Pode atualizar frontend sem tocar no backend e vice-versa
- Segurança: Lógica sensível fica no servidor, não exposta no cliente
Para este projeto específico:
- Simplicidade: Não requer instalação ou configuração de BD
- Portabilidade: Fácil de compartilhar e executar em qualquer máquina
- Prototipagem rápida: Ideal para MVP e demonstrações
- Zero custo: Não precisa de serviços de banco de dados
Limitações reconhecidas:
- Não escalável para muitos usuários simultâneos
- Sem transações ACID
- Performance degradada com grandes volumes
- Sem queries complexas
- Risco de corrupção de dados em escritas simultâneas
Para produção, recomenda-se migrar para:
- PostgreSQL: Para dados relacionais estruturados
- MongoDB: Para flexibilidade de schema
- Redis: Para cache de sessões e dados temporários
Benefícios:
- UX melhor: Feedback imediato ao usuário
- Reduz requisições: Não envia dados inválidos ao servidor
- Performance: Valida localmente antes de fazer requisição HTTP
Observação: Em produção, sempre fazer validação também no backend (never trust the client).
Decisão consciente de não usar localStorage porque:
- Dados devem persistir entre dispositivos
- Sistema de indicações requer dados centralizados
- Múltiplos usuários precisam acessar os mesmos dados
- localStorage é client-side only, não serve para este caso de uso
- CORS configurado: Apenas origens específicas podem acessar a API
- Validação de senha: Mínimo 8 caracteres, letras e números
- UUID não sequencial: IDs imprevisíveis previnem enumeração
- Validação de campos obrigatórios: Previne dados incompletos
- Hashing de senhas: Usar bcrypt para armazenar senhas
- HTTPS: Criptografar comunicação cliente-servidor
- Rate limiting: Prevenir brute force attacks
- JWT: Autenticação stateless com tokens
- Sanitização de inputs: Prevenir SQL/NoSQL injection
- Headers de segurança: Helmet.js para proteção adicional
- Validação no backend: Nunca confiar apenas no frontend
- CSRF tokens: Proteção contra Cross-Site Request Forgery
Sou aluno do primeiro semestre e, ao iniciar este desafio, não tinha experiência prática com desenvolvimento full-stack — tive que aprender grande parte do fluxo do zero. Para acelerar o aprendizado e superar bloqueios, utilizei assistentes de IA (Claude da Anthropic e ChatGPT) como ferramentas de apoio técnico e pedagógico. A seguir descrevo, de forma objetiva e profissional, como a IA foi empregada, em quais etapas contribuiu e o que aprendi com essa interação.
A IA ajudou a definir a separação frontend/backend, as rotas REST necessárias e os trade-offs entre servir arquivos estáticos pelo Express ou usar um servidor separado para o front.
O que aprendi: Fundamentos de arquitetura cliente-servidor e critérios para separar responsabilidades. Compreendi que a separação permite escalabilidade, manutenibilidade e deploy independente de cada camada.
Recebi orientações sobre estruturação do servidor Express, criação das rotas POST /register e GET /users/:id, tratamento de erros, uso de middlewares (CORS, body-parser) e geração de UUIDs.
O que aprendi: Fluxo de requisições HTTP, uso de middleware e boas práticas básicas em Express. Entendi que middleware são funções que interceptam requisições e podem modificar request/response ou encerrar o ciclo. A lógica de buscar o usuário indicador pelo ref e incrementar seus pontos me ensinou manipulação eficiente de arrays e objetos em JavaScript.
A IA explicou opções de leitura/escrita com fs, diferenças entre operações síncronas e assíncronas e padrões simples para armazenar usuários em data.json.
O que aprendi: Trade-offs entre simplicidade (JSON) e soluções de produção (bancos de dados), e quando operações síncronas são aceitáveis em protótipos. Compreendi conceitos de I/O de arquivos em Node.js e que, para este caso de uso (escrita não frequente, dados pequenos), síncrono é aceitável, mas para produção seria necessário migrar para banco de dados real com operações assíncronas.
Recebi ajuda para implementar validações de formulário, uso de URLSearchParams, Fetch API com async/await, redirecionamento entre páginas e a funcionalidade de copiar para a área de transferência.
O que aprendi: Manipulação do DOM, requisições assíncronas e boas práticas para UX inicial. Entendi o event loop do JavaScript e como async/await torna o código assíncrono mais legível que callbacks ou promises encadeadas. A API URLSearchParams facilitou o trabalho com query strings de forma nativa. A funcionalidade de copiar para clipboard me introduziu à Clipboard API moderna do navegador.
A IA foi útil para identificar causas comuns de falha na integração (ex.: portas diferentes entre front e back, requisições para porta errada) e propor correções práticas.
O que aprendi: Como rastrear problemas entre cliente e servidor e a importância de logs claros. Um momento crucial foi entender o erro "Cannot GET /" ao tentar acessar o backend diretamente — aprendi que o Express, por padrão, não serve arquivos estáticos automaticamente (a menos que configurado com express.static). Compreendi que APIs REST geralmente retornam JSON, não HTML, e que é comum ter servidores separados para frontend e backend em desenvolvimento.
Auxílio na definição das regras de senha e no fluxo de feedback para o usuário (mensagens de erro claras).
O que aprendi: Balancear validação client-side para UX com a necessidade de validação server-side por segurança. Entendi a importância da validação no frontend para feedback imediato ao usuário, mas também que ela nunca deve ser a única linha de defesa. Aprendi sobre regex em JavaScript para validar padrões (verificar se senha tem letras e números).
A IA contribuiu para estruturar este README, descrever endpoints, comandos de execução e justificar escolhas técnicas.
O que aprendi: Formatar uma documentação que comunique decisões e facilite a reprodução do projeto. Documentação é tão importante quanto o código — aprendi a estruturar um README profissional, justificar decisões técnicas e fornecer instruções claras de instalação. Entendi que boa documentação facilita onboarding de novos desenvolvedores e demonstra profissionalismo.
-
Iteração incremental: Pedir ajuda por etapas (arquitetura → rotas → front) facilitou a validação contínua. Construir o projeto passo a passo, testando cada parte antes de avançar, permitiu identificar e corrigir problemas precocemente.
-
Perguntas específicas: Consultas bem formuladas geraram respostas práticas e aplicáveis. Em vez de perguntas vagas como "faça o projeto", optei por questões direcionadas como "como implementar a rota POST /register com validação de campos?".
-
Debug colaborativo: Compartilhar trechos de erro/console permitiu soluções direcionadas. Ao encontrar erros, compartilhar logs e trechos de código específicos acelerou significativamente a resolução.
-
Exigência do "porquê": Pedir justificativas ajudou a transformar sugestões em conhecimento técnico. Sempre que recebia uma solução, perguntava "por que essa abordagem?" ou "quais são as alternativas?", o que aprofundou minha compreensão.
-
Conhecimento prévio assumido: Em algumas interações a IA assumiu conhecimento prévio que eu ainda não tinha; precisei pedir explicações mais básicas. Por exemplo, conceitos como "middleware" ou "CORS" requereram explicações adicionais mais fundamentais.
-
Contexto de ambiente: Em poucas ocasiões, foram fornecidas alternativas sem considerar o contexto exato do meu ambiente (por exemplo, sistema operacional), exigindo que eu adaptasse as instruções. Precisei especificar que estava no Mac para receber comandos adequados (ex.:
python3em vez depython). -
Código incompleto: Em uma iteração específica, o código JavaScript foi fornecido de forma incompleta (terminou abruptamente com
const data = await), exigindo uma nova solicitação para completar a implementação.
A IA funcionou como um "pair programmer" e mentor técnico, mas não substituiu o aprendizado ativo. Foi necessário:
- Entender cada linha do código gerado
- Fazer perguntas quando algo não estava claro
- Testar e validar todas as soluções propostas
- Adaptar sugestões ao contexto específico do projeto
- Tomar decisões finais sobre implementação
O maior valor da IA não foi escrever código por mim, mas sim:
- Acelerar o aprendizado através de explicações contextualizadas
- Fornecer best practices e padrões da indústria
- Ajudar a debugar problemas rapidamente
- Documentar e justificar decisões técnicas
- Reduzir o tempo gasto em bloqueios técnicos, permitindo focar no aprendizado conceitual
Principais aprendizados técnicos:
- Arquitetura de Software: Compreendi na prática a separação frontend/backend e suas vantagens
- APIs REST: Entendi os verbos HTTP (GET, POST) e como estruturar endpoints
- JavaScript Assíncrono: Domínio de Promises, async/await e Fetch API
- Node.js Ecosystem: Compreensão de NPM, packages e como funciona o ecossistema
- Debugging: Aprendi a ler mensagens de erro e identificar problemas sistematicamente
- Pensamento Crítico: Nem toda sugestão da IA é perfeita; aprendi a questionar, validar e adaptar
Esta experiência demonstrou que IA é uma ferramenta poderosa quando usada corretamente: não para evitar aprender, mas para aprender mais eficientemente, com mais contexto e de forma mais estruturada. Como aluno iniciante, a IA me permitiu construir um projeto full-stack funcional enquanto absorvia conceitos fundamentais que normalmente levariam muito mais tempo para dominar sozinho.
- Migrar para banco de dados (PostgreSQL ou MongoDB)
- Implementar hash de senhas com bcrypt
- Adicionar autenticação JWT
- Criar página de login
- Implementar logout
- Dashboard com estatísticas de indicações
- Sistema de níveis baseado em pontos
- Notificações quando ganhar pontos
- Histórico de indicações
- Edição de perfil
- Sistema de recompensas por pontos
- API pública para integrações
- Aplicativo mobile (React Native)
- Gamificação avançada
- Analytics e relatórios
Contribuições são bem-vindas! Para contribuir:
- Fork o projeto
- Crie uma branch para sua feature (
git checkout -b feature/MinhaFeature) - Commit suas mudanças (
git commit -m 'Adiciona MinhaFeature') - Push para a branch (
git push origin feature/MinhaFeature) - Abra um Pull Request
Este projeto está sob a licença MIT. Veja o arquivo LICENSE para mais detalhes.
Desenvolvido como projeto de aprendizado sobre desenvolvimento full-stack com Node.js e JavaScript vanilla.
Contato: ianpereira31@gmail.com GitHub: https://github.com/GitDoIan
- Anthropic (Claude) pela assistência no desenvolvimento e aprendizado
- Comunidade Node.js pela excelente documentação
- MDN Web Docs pelas referências de JavaScript e Web APIs