Repository navigation
RFC VesteAi
Request for Comments — Projeto de Portfólio Católica SC — Engenharia de Software — 8º Semestre
-
Título do Projeto:
VesteAí -
Linha de Projeto (Direction):
Web -
Autor:
Kalebe Fukuda de Oliveira -
Data da Proposta:
08/04/2026 -
Versão:
1.1 — 08/09/2026 (v1.0 em 08/04/2026)
Sincronização com o que foi construído. Nenhuma alteração de escopo, de objetivo ou de requisito: apenas afirmações factuais que deixaram de ser verdade, mais as decisões que a v1.0 não podia conhecer. A Seção 10 não foi tocada.
O que deixou de ser verdade e foi corrigido
| Onde | A v1.0 dizia | Agora |
|---|---|---|
| §5.2 Modelo de Dados | cinco entidades |
seis — entrou password_resets, com esquema e relacionamento descritos |
| §5.4 Infraestrutura | frontend e backend numa instância EC2 t2.micro; RDS db.t3.micro; free tier de 12 meses |
frontend na Vercel; backend em ECS Fargate atrás de ALB; RDS db.t4g.micro em sub-rede privada; operação custeada por crédito finito, pois o free tier de 12 meses foi encerrado para contas novas em julho de 2025 |
| §5.4 Observabilidade | Prometheus e Grafana como containers na instância EC2 | serviços auxiliares no ECS |
| §5.4 Resumo da Stack | uma linha de infraestrutura | cinco linhas, com hospedagem, banco, provisionamento e e-mail, cada uma apontando para o ADR correspondente |
| §7.3 Critérios | "acessível na AWS EC2" | HTTPS em domínio próprio, servido por ECS Fargate atrás de ALB |
| §7.4 Instruções de Deploy | "conecta via SSH na instância EC2 e executa docker compose up -d" |
reescrita: publicação no ECR e deployment ao ECS por role assumida via OIDC. Não há acesso interativo a servidor em nenhum ponto — não porque foi proibido, mas porque não existe instância à qual se conectar. Inclui rollback por revisão de task definition |
| §7.2 Marco M14 | "Deploy na AWS EC2" | Deploy em produção na AWS (ECS Fargate) |
A v1.0 continha, no mesmo trecho, o passo de deploy por SSH e uma nota afirmando que SSH nunca era utilizado. A contradição foi eliminada com a reescrita da seção.
O que a v1.0 não podia conhecer, agora registrado
| Assunto | Onde a decisão vive |
|---|---|
| Hospedagem gerenciada em vez de instância administrada à mão; Railway descartada | ADR-0002 |
JWT sem sessão em banco, e transporte em cookie httpOnly
|
ADR-0004, ADR-0011b |
| Bibliotecas de autenticação sem camadas intermediárias | ADR-0015 |
| Provedor de e-mail transacional (Brevo) | ADR-0005 |
| Task em sub-rede pública sem NAT Gateway | ADR-0017 |
| Armazenamento do contador de limite de requisições | ADR-0018 |
| Limite de requisições nas rotas de autenticação e cabeçalhos de segurança | §6.2 |
Deliberadamente não alterado: objetivo do produto, justificativa das escolhas de negócio, escopo, requisitos funcionais e não funcionais, a meta de 200 usuários simultâneos — que segue sendo alvo e não resultado medido — e a Seção 10.
A moda é um dos maiores mercados de consumo online do Brasil. Plataformas como Instagram, Pinterest e TikTok são amplamente utilizadas para inspiração de moda, gerando alto engajamento com looks e combinações de peças. No entanto, existe uma lacuna estrutural entre o momento de inspiração e o momento de compra — e uma oportunidade de monetização ignorada para quem cria conteúdo de moda de forma amadora.
Quem sofre com esse problema
Dois perfis distintos enfrentam barreiras hoje:
- Consumidores que encontram looks interessantes nas redes sociais mas não conseguem comprar as peças com facilidade — seja o look completo ou cada item individualmente.
- Pessoas com interesse em moda que gostariam de montar e divulgar looks usando peças de diferentes lojas e ganhar uma renda extra através de links de afiliado, mas não têm uma plataforma própria para isso.
Em que contexto ocorre
Ao encontrar um look interessante em qualquer rede social, o fluxo típico do consumidor é:
- Ver o look e se interessar
- Tentar identificar cada peça manualmente (marca, modelo, loja)
- Buscar cada peça em sites diferentes
- Frequentemente não encontrar exatamente o que viu
- Desistir da compra
Um exemplo real desse comportamento pode ser observado abaixo — um post de moda no Instagram onde seguidores pedem nos comentários o preço e o link das peças, sem receber nenhuma resposta centralizada:

Do lado de quem quer criar conteúdo de moda, o problema é diferente: não existe uma plataforma dedicada para montar looks com peças de múltiplas lojas, associar links de afiliado a cada peça e publicar tudo em um único lugar para gerar renda com as vendas que esse conteúdo influencia.
Como é resolvido atualmente
Não existe uma solução centralizada para nenhum dos dois lados. O consumidor depende de buscas manuais em múltiplos e-commerces. Quem quer monetizar curadoria de moda recorre a ferramentas genéricas como o Linktree ou depende de comentários e stories nas redes sociais — sem controle sobre métricas, sem organização por look e sem uma experiência dedicada para o consumidor final.
Plataformas como Pinterest chegam a redirecionar para produtos similares via Amazon, mas a solução é limitada: funciona apenas com o catálogo americano, não suporta lojas brasileiras como Shopee, Shein, Renner ou C&A, e não oferece nenhuma forma de monetização para quem criou o conteúdo:

Limitações das soluções atuais
As redes sociais entregam inspiração mas não oferecem links de compra organizados por look. Os e-commerces oferecem compra mas não curadoria. Ferramentas de link em bio são genéricas e não foram feitas para composição de looks com múltiplas peças. O resultado é uma fricção alta na jornada do consumidor e uma oportunidade de renda desperdiçada para quem tem gosto por moda mas não tem onde canalizar isso.
Foram realizadas conversas informais com 5 pessoas dos dois perfis de usuário da plataforma. Não houve formulário estruturado — as conversas seguiram um roteiro livre com foco em identificar dores no processo de compra de moda online e no uso de links de afiliado.
Perfis entrevistados: consumidores de moda online e pessoas que já utilizam links de afiliado em plataformas como Shopee.
Principais dores identificadas:
| Perfil | Dor relatada |
|---|---|
| Consumidor | Dificuldade em encontrar onde comprar peças de looks vistos nas redes sociais |
| Consumidor | Necessidade de pesquisar em vários sites para montar um look completo |
| Criador | Falta de uma plataforma dedicada para montar e publicar looks com links de afiliado |
| Criador | Dificuldade em organizar links de produtos de lojas diferentes em um só lugar |
Padrão observado: todos os entrevistados demonstraram interesse em uma plataforma unificada para descoberta e compra de looks.
O comportamento de busca por links nos comentários de posts de moda é um padrão recorrente e documentado nas redes sociais. A imagem abaixo ilustra um post no Instagram onde seguidores pedem o preço e o link das peças diretamente nos comentários, sem receber nenhuma resposta centralizada — evidência direta da dor que o VesteAí se propõe a resolver:

Os dados do mercado brasileiro reforçam que o problema ocorre em um segmento de alto volume e crescimento acelerado:
- A moda é o segmento líder do e-commerce nacional em volume, com crescimento de 35% nas vendas em 2025, faturando R$ 2,9 bilhões segundo a pesquisa NuvemCommerce (2026).
- 66% dos brasileiros preferem comprar roupas, calçados e acessórios online, segundo pesquisa "Consumo de moda no Brasil" do Opinion Box.
- O mercado brasileiro de social commerce — compras originadas diretamente das redes sociais — projeta crescimento de 16,1% ao ano, atingindo US$ 4,16 bilhões em 2025, segundo dados da Wake.
- O Instagram é utilizado organicamente por 97% das lojas de moda, o maior índice entre todos os setores do e-commerce nacional (NuvemCommerce, 2026).
Esses dados indicam que o comportamento de descoberta de moda pelas redes sociais já é consolidado no Brasil — e que a lacuna entre inspiração e compra ocorre justamente no segmento de maior crescimento do e-commerce nacional.
Link: https://pinterest.com
Público-alvo: Usuários em busca de inspiração visual em geral
Funcionalidades principais:
- Feed de imagens organizadas por interesse
- Redirecionamento automático para produtos similares via Amazon
- Salvar pins em coleções pessoais
Limitações:
- Redirecionamento funciona apenas com catálogo da Amazon (EUA)
- Não suporta lojas brasileiras como Shopee, Shein, Renner ou C&A
- O link de produto é gerado automaticamente por reconhecimento de imagem, não por curadoria intencional de um criador
- Não existe monetização para quem publicou o conteúdo original
- Não há conceito de "look completo" — cada peça é tratada isoladamente
Link: https://shopltk.com
Público-alvo: Influenciadores de moda e consumidores globais
Funcionalidades principais:
- Criadores publicam looks com links de afiliado de múltiplas lojas
- Feed navegável com looks completos e shoppable
- App dedicado com mais de 8 milhões de usuários mensais
- Parceria com mais de 7.000 varejistas globais
Limitações:
- Plataforma americana com foco no mercado norte-americano e europeu
- Não tem integração nativa com as principais lojas brasileiras (Shopee, Mercado Livre, Shein BR, Renner, C&A)
- Exige aprovação para criadores — não é aberto para qualquer pessoa
- Requer audiência prévia nas redes sociais para ser aceito como criador
- Interface e suporte em inglês, sem localização para o Brasil
Link: https://oqvestir.com.br
Público-alvo: Consumidores brasileiros de moda premium
Funcionalidades principais:
- E-commerce multimarcas com mais de 300 marcas nacionais e internacionais
- Curadoria editorial com sugestões de looks prontos
- Seções "Looks da Semana" e "Novidades"
Limitações:
- É um e-commerce: só vende peças do próprio catálogo
- Não permite links de lojas externas (Shopee, Shein, etc.)
- Não existe figura de criador — a curadoria é feita internamente pela equipe editorial
- Não há monetização para usuários externos
- Foco em moda premium, excluindo o público que compra em marketplaces
Links: https://instagram.com / https://tiktok.com
Público-alvo: Criadores de conteúdo e consumidores em geral
Funcionalidades principais:
- Publicação de fotos e vídeos de looks com grande alcance orgânico
- Link na bio para redirecionar seguidores
- Instagram Shopping para marcas parceiras
Limitações:
- Não existe uma forma nativa de organizar múltiplos links de afiliado por look — criadores dependem de ferramentas externas como Linktree
- O consumidor precisa sair da plataforma e buscar cada peça manualmente
- Não há rastreamento de cliques por peça ou por look
- Instagram Shopping só está disponível para marcas, não para criadores independentes com links de afiliado de múltiplas lojas
- O conteúdo se perde no feed com o tempo — não há organização por look
| Solução | Pontos Fortes | Limitações |
|---|---|---|
| Inspiração visual consolidada, grande base de usuários | Só integra Amazon (EUA), sem monetização para criadores, sem suporte a lojas BR | |
| LTK | Modelo mais próximo do VesteAí, links de afiliado por look, app dedicado | Foco no mercado americano, sem lojas BR, exige aprovação e audiência prévia |
| OQVestir | Curadoria editorial brasileira, e-commerce consolidado | Catálogo fechado, sem criadores externos, sem links de lojas parceiras |
| Instagram/TikTok | Alcance massivo, criadores ativos em moda | Sem links organizados por look, sem rastreamento por peça, sem monetização direta |
Por que criar algo novo?
Nenhuma das soluções existentes resolve os dois lados do problema simultaneamente para o mercado brasileiro:
-
O LTK é a referência global mais próxima do VesteAí, mas é construído para o mercado americano e europeu. Não tem integração com as lojas onde o brasileiro de fato compra — Shopee, Mercado Livre, Shein, Renner e C&A — e exige que o criador já tenha uma audiência consolidada para ser aceito na plataforma.
-
O Pinterest entrega inspiração mas não resolve a compra, e o Instagram/TikTok entregam alcance mas não entregam organização nem monetização estruturada.
-
O OQVestir é brasileiro mas é um e-commerce fechado — a curadoria é editorial, não existe criador independente, e o consumidor só pode comprar peças do catálogo da própria plataforma.
Qual lacuna o VesteAí preenche?
O modelo do VesteAí é inspirado no LTK, plataforma americana que valida globalmente que esse modelo funciona. O Brasil é o nono maior mercado de e-commerce do mundo, com moda como categoria líder em volume — e não existe nenhuma plataforma equivalente ao LTK construída para esse mercado.
O VesteAí preenche essa lacuna com dois diferenciais centrais:
- Focado no mercado brasileiro: construído para o consumidor e o criador brasileiro, com compatibilidade com Shopee, Mercado Livre, Shein, Renner e C&A — as plataformas de e-commerce mais consumidas pelo público brasileiro
- Acesso aberto para criadores: qualquer pessoa com gosto por moda pode criar um perfil e começar a monetizar, sem necessidade de audiência prévia ou aprovação editorial
O VesteAí atende dois perfis de usuário distintos:
Perfil: Pessoas entre 18 e 35 anos com interesse em moda, que utilizam redes sociais como Instagram, Pinterest e TikTok para buscar inspiração de looks no dia a dia.
Contexto de uso: Navegam pelo feed em busca de looks completos para ocasiões específicas — trabalho, lazer, eventos — e querem poder comprar as peças sem precisar pesquisar em múltiplos sites.
Nível técnico esperado: Básico. Familiarizados com redes sociais e compras online em marketplaces como Shopee e Mercado Livre.
Perfil: Pessoas com interesse em moda e senso estético desenvolvido, que já montariam looks por prazer mas não têm uma plataforma dedicada para publicar e monetizar essa curadoria. Não necessariamente possuem audiência prévia em outras redes sociais.
Contexto de uso: Montam looks combinando peças de diferentes lojas, associam links de afiliado a cada peça e publicam no feed da plataforma para gerar renda extra com as compras que seus looks influenciam. Incluem pessoas que já utilizam programas de afiliados em plataformas como Shopee.
Nível técnico esperado: Básico a intermediário. Familiarizados com redes sociais e com o conceito de links de afiliado.
Centralizar em uma única plataforma a descoberta e a compra de looks de moda para o mercado brasileiro, eliminando a fricção entre inspiração e compra para o consumidor e criando uma oportunidade de renda para pessoas que têm gosto por moda mas não têm onde monetizar essa curadoria.
- Desenvolver um feed navegável de looks completos com links de compra centralizados, permitindo que o consumidor acesse todas as peças de um look em um único lugar
- Construir um editor de looks que permita ao criador montar composições com peças de múltiplas lojas e associar links de afiliado a cada peça
- Integrar o Google Gemini como ferramenta de apoio ao criador na composição visual dos looks
- Registrar e exibir métricas de cliques por look, dando ao criador visibilidade sobre o desempenho do seu conteúdo
- Disponibilizar a plataforma em produção como um produto funcional, acessível publicamente e validado com usuários reais
- Pelo menos 5 looks publicados no feed por criadores reais até o Demo Day
- Pelo menos 1 clique em link de compra registrado por look publicado
- Suporte a 200 usuários simultâneos sem degradação de performance
- Cobertura mínima de 75% de testes unitários no backend (TDD)
- Cobertura mínima de 25% de testes unitários no frontend
- Integração com Google Gemini funcional com geração de imagem em menos de 30 segundos
- Aplicação acessível publicamente via URL estável em ambiente de produção
- Pipeline CI/CD configurado com execução automática de testes e deploy
- Análise estática de código aprovada no SonarCloud sem issues críticos
Nome: Isabela Rocha, 24 anos Contexto: Estudante de moda em São Paulo, produz conteúdo no Instagram e TikTok há 2 anos. Tem cerca de 8 mil seguidores e recebe frequentemente perguntas como "onde você comprou essa blusa?". Hoje responde nos comentários ou stories, mas os links se perdem rapidamente.
Objetivos:
- Centralizar os links das peças que usa em um único lugar
- Monetizar seu conteúdo através de comissões de afiliados
- Criar looks completos combinando peças de diferentes lojas (Shein, Renner, Shopee)
- Ganhar visibilidade além dos seus seguidores atuais
Principais dificuldades:
- Perde tempo respondendo manualmente onde cada peça foi comprada
- Não tem uma forma organizada de apresentar um look completo com múltiplos links
- Não consegue rastrear quantas pessoas clicaram nos seus links
- Ferramentas como Linktree são genéricas demais — não foram feitas para looks
Nome: Mariana Costa, 27 anos Contexto: Analista de marketing em Florianópolis, acompanha perfis de moda no Instagram e TikTok diariamente. Se inspira em looks que vê nas redes, mas frequentemente desiste da compra porque não consegue identificar onde cada peça foi comprada ou encontra apenas lojas internacionais sem entrega viável no Brasil.
Objetivos:
- Descobrir looks completos já montados, prontos para comprar
- Encontrar peças em lojas brasileiras com frete acessível
- Salvar looks que gostou para consultar depois
- Comprar o visual inteiro sem precisar gastar horas pesquisando cada peça
Principais dificuldades:
- Looks inspiracionais nas redes sociais raramente têm todos os links das peças
- Quando os links existem, muitas vezes apontam para lojas fora do Brasil
- Não há um lugar centralizado só para moda brasileira com curadoria humana
- Processo de "montar o look" é fragmentado e trabalhoso
Os principais fluxos do sistema estão organizados em dois perfis de acesso: Visitante (não autenticado) e Usuário Autenticado. Qualquer usuário autenticado pode tanto consumir looks quanto publicar como creator — não há separação de contas.
Visitante:
- Explorar feed de looks
- Visualizar look completo
- Clicar em link de compra
Usuário Autenticado:
- Criar conta e configurar perfil
- Salvar looks favoritos
- Criar e publicar looks com peças e links de afiliado
- Editar e remover looks próprios
- Visualizar métricas de cliques nos seus looks

RF01 — O sistema deve permitir que o visitante crie uma conta. RF02 — O sistema deve permitir que o usuário faça login com e-mail e senha. RF03 — O sistema deve permitir que o usuário recupere sua senha via e-mail. RF04 — O sistema deve permitir que o usuário configure seu perfil (nome, foto e bio).
RF05 — O sistema deve permitir que o visitante explore o feed de looks publicados. RF06 — O sistema deve permitir que o visitante visualize um look completo com todas as peças e links. RF07 — O sistema deve permitir que o visitante clique em um link de compra e seja redirecionado para a loja externa.
RF08 — O sistema deve permitir que o usuário salve looks favoritos. RF09 — O sistema deve permitir que o usuário acesse sua lista de looks salvos.
RF10 — O sistema deve permitir que o usuário crie um look com título, descrição e foto de referência. RF11 — O sistema deve permitir que o usuário adicione peças ao look com nome, link de afiliado e imagem. RF12 — O sistema deve permitir que o usuário publique o look tornando-o visível no feed. RF13 — O sistema deve permitir que o usuário edite um look já publicado. RF14 — O sistema deve permitir que o usuário remova um look publicado. RF15 — O sistema deve validar se o link de compra cadastrado está acessível e não redireciona para domínios sinalizados como maliciosos.
RF16 — O sistema deve registrar cada clique em links de compra e exibir o total por look ao usuário criador.
RF17 — O sistema deve permitir que o usuário faça upload de uma foto de referência ao criar um look.
RNF01 — O feed de looks deve carregar em menos de 2 segundos em condições normais de rede. RNF02 — O redirecionamento para links de compra deve ocorrer em menos de 500ms. RNF03 — A API deve responder às requisições em menos de 300ms para operações de leitura.
RNF04 — O sistema deve utilizar autenticação segura com tokens JWT. RNF05 — As senhas dos usuários devem ser armazenadas com hash utilizando bcrypt. RNF06 — A comunicação entre cliente e servidor deve ser realizada exclusivamente via HTTPS. RNF07 — O sistema deve proteger endpoints sensíveis contra acesso não autenticado.
RNF08 — O sistema deve ter disponibilidade mínima de 99% ao mês.
RNF09 — A arquitetura deve suportar o crescimento do volume de looks e usuários sem necessidade de refatoração estrutural. RNF10 — O banco de dados deve ser estruturado para suportar paginação eficiente no feed de looks.
RNF11 — A interface deve ser responsiva e funcionar adequadamente em dispositivos móveis e desktop. RNF12 — O fluxo de criação de um look deve ser concluído em no máximo 5 etapas.
RN01 — Apenas usuários autenticados podem criar, editar e remover looks. RN02 — Apenas usuários autenticados podem salvar looks favoritos. RN03 — O feed de looks e os links de compra são acessíveis sem autenticação.
RN04 — Um look só pode ser publicado se tiver ao menos uma peça com link de compra cadastrado. RN05 — Cada peça de um look deve conter obrigatoriamente nome e link de compra. RN06 — O creator é o único responsável pela validade dos links de compra — o VesteAí não valida nem garante os links externos. RN07 — Um creator só pode editar ou remover looks criados por ele mesmo.
RN08 — O registro de clique é contabilizado apenas quando o usuário é redirecionado para a loja externa. RN09 — As métricas de cliques são visíveis apenas para o creator do look.
- O sistema não processará pagamentos diretamente — as transações ocorrem nas lojas externas
- O sistema não realizará integração direta com programas de afiliados — a gestão dos links é responsabilidade do creator
- O sistema não oferecerá funcionalidade de chat ou mensagens entre usuários
- O sistema não permitirá a venda de produtos diretamente na plataforma
- O sistema não realizará curadoria ou moderação automática de looks publicados
Esta seção demonstra como o sistema funciona na prática, descrevendo os caminhos percorridos pelos dois perfis de usuário da plataforma — consumer e creator — e os desvios mais relevantes que o sistema deve tratar.
O VesteAí possui dois fluxos principais distintos, um para cada perfil de usuário. Ambos são independentes e refletem jornadas fundamentalmente diferentes: o consumer descobre e compra, o creator monta e publica.
O consumer acessa a plataforma sem necessidade de autenticação. A jornada começa pela exploração do feed de looks publicados, onde pode abrir qualquer look completo e visualizar todas as peças com seus respectivos links de compra. O clique em um link redireciona o consumer diretamente para a loja externa, que é o ponto de conversão central da plataforma.
Caso o consumer queira salvar um look nos favoritos, o sistema verifica se está autenticado. Se não estiver, é direcionado para login ou cadastro antes de concluir a ação. Se já estiver autenticado, o look é salvo imediatamente. Essa é a única ação do consumer que exige autenticação — explorar o feed e clicar em links de compra são acessíveis a qualquer visitante.

O creator precisa estar autenticado para publicar looks. Ao acessar a plataforma, o sistema verifica se possui conta — caso contrário, passa pelo cadastro e login antes de acessar o painel. A partir do painel, inicia a criação do look adicionando título, descrição e as peças com seus respectivos links de compra.
A etapa seguinte exige que o creator forneça uma imagem para o look, que é obrigatória para publicação. Se já tiver uma foto do look, faz o upload diretamente. Caso contrário, utiliza o assistente Gemini para gerar uma imagem de referência. Sem imagem — seja por upload ou gerada pelo Gemini — o look não pode ser publicado.
Antes de publicar, o sistema verifica se o creator está dentro do limite de publicações do seu plano. Se tiver atingido o limite, é apresentada a opção de upgrade para o plano Pro. Caso opte por não fazer o upgrade, o fluxo é encerrado sem publicação. Caso faça o upgrade ou já esteja dentro do limite, o look é revisado e publicado, tornando-se visível no feed da plataforma. Após a publicação, o creator pode acompanhar as métricas de cliques no seu painel.

Esta seção descreve os principais desvios do caminho feliz — situações de erro, cancelamento ou exceção que o sistema deve tratar de forma explícita.
Contexto: O visitante clica em "salvar look" sem estar autenticado.
Comportamento esperado: O sistema interrompe a ação e exibe um prompt de login ou cadastro. Após autenticação bem-sucedida, o sistema retoma a ação e salva o look nos favoritos automaticamente, sem exigir que o usuário repita o gesto.
Contexto: O creator conclui o preenchimento das peças e tenta publicar sem ter fornecido uma imagem — nem por upload nem via Gemini.
Comportamento esperado: O sistema bloqueia a publicação e exibe uma mensagem informando que a imagem é obrigatória. O creator permanece na tela de criação e pode escolher entre fazer upload ou gerar via Gemini antes de tentar publicar novamente.
Contexto: O creator tenta publicar um look sem ter adicionado nenhuma peça com link de compra cadastrado.
Comportamento esperado: O sistema bloqueia a publicação e exibe uma mensagem informando que ao menos uma peça com link de compra é obrigatória (RN04). O creator permanece na tela de criação para completar o look antes de tentar novamente.
Contexto: O creator cadastra um link de compra que está inacessível ou aponta para um domínio sinalizado como malicioso.
Comportamento esperado: O sistema executa a validação do link (RF15) e, ao detectar o problema, exibe uma mensagem de erro indicando qual link falhou na validação. O creator pode corrigir ou substituir o link antes de prosseguir. Links que passam na validação técnica mas são inválidos comercialmente permanecem sob responsabilidade do creator (RN06).
Contexto: O creator opta por gerar a imagem via Gemini, mas a requisição falha por erro da API ou timeout.
Comportamento esperado: O sistema exibe uma mensagem de erro informando que a geração não foi concluída e oferece duas opções: tentar novamente ou fazer upload manual de uma imagem. O look em criação não é perdido — as peças e links já cadastrados são preservados.
Contexto: O creator tenta publicar um look mas já atingiu o limite de publicações do plano gratuito e, ao ser apresentado ao upgrade Pro, decide não prosseguir.
Comportamento esperado: O sistema encerra o fluxo de publicação sem descartar o look. O rascunho é preservado no painel do creator, permitindo que retome e publique quando decidir fazer o upgrade ou quando um slot de publicação estiver disponível.
Observação: Os mockups apresentados nesta seção são a base para construção da aplicação. Eles representam a estrutura, os fluxos e a intenção de design da plataforma, mas não constituem o design final da interface. Elementos visuais como tipografia, espaçamento, paleta de cores e componentes estão sujeitos a revisão durante o desenvolvimento.
Esta seção apresenta a visualização inicial do produto antes da implementação. Os mockups foram utilizados para validar o fluxo de navegação, a organização da interface, as interações dos dois perfis de usuário e a clareza da experiência como um todo.
O VesteAí possui dois fluxos de navegação distintos, refletindo as jornadas documentadas na Seção 3. Ambos partem do feed de looks como tela central e divergem conforme o perfil e a intenção do usuário.
Jornada do Consumer:

Jornada do Creator:

Os diagramas completos, incluindo desvios e fluxos alternativos, estão na Seção 3.
A tela de autenticação adota um layout dividido em dois painéis. O painel esquerdo é visual e exibe o card de look característico da plataforma com os floating badges de engajamento, reforçando a proposta de valor do produto no momento de entrada do usuário. O painel direito contém o formulário de autenticação com campos de e-mail e senha, opção de login via Google e link para cadastro.
A mesma tela serve tanto para login quanto para o redirecionamento descrito no FA01 — quando um visitante tenta salvar um look sem autenticação, é encaminhado para esta tela e, após autenticar, retorna automaticamente à ação interrompida.
Requisitos cobertos: RF01, RF02, RF03, RF04

O feed é a tela central da plataforma e o ponto de entrada para o consumidor. A navegação superior apresenta os filtros de categoria em pills horizontais, permitindo que o usuário refine o conteúdo sem sair da tela.
O conteúdo é organizado em um grid uniforme de quatro colunas, com cards de proporção padronizada seguindo a convenção de marketplaces de moda. Cada card exibe a foto do look, o handle do creator, o título, o ícone da ocasião, a contagem de curtidas e um link direto para o look completo. O visitante não precisa estar autenticado para navegar no feed — a exploração é aberta a qualquer usuário (RN03).
Requisitos cobertos: RF05, RF06

A tela de detalhes é o ponto de conversão da jornada do consumer. O layout é dividido em duas colunas: à esquerda, a imagem do look em proporção destacada com badges de "IA Gerado" e contagem de curtidas; à direita, o painel com título, tags, descrição e a lista de peças.
Cada peça exibe nome, loja, preço indicativo e um botão de acesso ao link de compra externo. O botão principal "Ver todos os links de compra" ao final da lista direciona o usuário para o carrinho, onde os links ficam agregados antes do redirecionamento. Um aviso explícito informa que o VesteAí não realiza cobranças — as transações ocorrem nas lojas externas (RN06, seção 2.6).
Requisitos cobertos: RF06, RF07, RF08

O carrinho do VesteAí não é um checkout — não processa pagamentos nem armazena dados financeiros. Sua função é agregar os itens salvos de múltiplos looks e centralizar os links de compra externos em um único lugar, eliminando a necessidade de o usuário abrir cada look separadamente para acessar cada link.
Os itens são agrupados pelo look de origem, com o handle do creator identificado em cada grupo. Cada item exibe nome, loja, preço indicativo e um botão individual "Ir para compra →" que abre o link externo em nova aba. O botão "Ir para todas as compras" no painel de resumo dispara todos os links simultaneamente. Um aviso abaixo do botão reforça que o VesteAí não realiza cobranças e que o usuário será redirecionado para os sites das lojas.
Requisitos cobertos: RF07, RF08, RF09

O editor é a tela central do fluxo do creator. O layout de duas colunas separa responsabilidades visuais das informacionais: à esquerda, a área de upload da imagem do look com o toggle de geração via IA; à direita, os campos de nome, tags de estilo e a lista de peças com links.
Uma barra de progresso no topo da tela indica o avanço no processo de criação. A lista de peças permite adicionar, visualizar e remover itens individualmente, com o link de compra visível para cada peça cadastrada. O botão "Publicar" na barra de navegação permanece desabilitado até que os requisitos mínimos de publicação sejam atendidos — ao menos uma peça com link e uma imagem (RN04, RN08).
Requisitos cobertos: RF10, RF11, RF12, RF13, RF14, RF15, RF17

O painel centraliza as métricas de desempenho dos looks publicados pelo creator. A tela é dividida em sidebar à esquerda — com seletor de período e atalhos de navegação — e área principal à direita com os indicadores e a tabela de performance.
Os dois cards de métrica exibem cliques totais e visualizações de looks, ambas as métricas coletadas pela própria plataforma. A tabela "Performance by Look" lista cada look publicado com data, volume de cliques representado por uma barra proporcional e status de publicação. Não há dados financeiros ou de comissão no painel — a monetização ocorre fora da plataforma, nos programas de afiliados de cada loja, e é de responsabilidade do creator (seção 2.6).
Requisitos cobertos: RF16

- Usuário acessa a plataforma e visualiza o Feed de Looks sem necessidade de autenticação
- Aplica filtro de categoria (ex: "Minimalista") para refinar o conteúdo
- Clica em um card de look para abrir os Detalhes do Look
- Visualiza as peças, loja e preço indicativo de cada item
- Clica em "Ver todos os links de compra" e é direcionado ao Carrinho
- No carrinho, revisa os itens agrupados por look de origem
- Clica em "Ir para todas as compras" e é redirecionado para as lojas externas em novas abas — a transação ocorre fora da plataforma
Desvio (FA01): se o usuário tentar salvar um look sem estar autenticado, o sistema redireciona para a tela de Login e, após autenticação, retorna automaticamente ao look.
- Creator acessa a tela de Login e autentica com e-mail/senha ou via Google
- É direcionado ao Feed de Looks como tela inicial da sessão
- Clica em "Create Look" na barra de navegação para abrir o Editor
- Faz upload da foto do look ou aciona o toggle "Gerar modelo com IA"
- Preenche o nome do look e seleciona as tags de estilo
- Adiciona peças com nome, loja e link de compra externo
- Clica em "Publicar" — o look passa a ser visível no feed publicamente
- Acessa o Painel do Creator para acompanhar cliques e visualizações
Desvio (FA02/FA03): se tentar publicar sem imagem ou sem peças com link, o sistema bloqueia e exibe mensagem orientando a completar os campos obrigatórios antes de prosseguir.
Os mockups foram apresentados informalmente aos mesmos 5 participantes das conversas descritas na seção 1.2. As reações foram coletadas sem formulário estruturado, com foco em identificar pontos de confusão ou expectativas não atendidas na interface.
| Tela | Observação coletada |
|---|---|
| Feed de Looks | Filtros de categoria foram considerados intuitivos; expectativa de busca por texto também foi mencionada |
| Detalhes do Look | A separação entre "ver o look" e "comprar as peças" ficou clara para todos os participantes |
| Carrinho | O aviso "VesteAí não realiza cobranças" foi considerado necessário e aumentou a confiança no fluxo |
| Editor de Looks | O toggle de geração por IA gerou curiosidade positiva; participantes demonstraram interesse em visualizar o resultado antes de publicar |
| Painel do Creator | A ausência de dados financeiros foi compreendida após explicação do modelo de negócio |
Esta seção descreve as decisões arquiteturais que estruturam o VesteAí como sistema de software, organizando os componentes, suas responsabilidades e as relações entre eles.
O modelo C4 organiza a arquitetura em níveis progressivos de detalhe: do contexto geral do sistema até os componentes internos de cada serviço.
No nível de contexto, o objetivo é identificar quem interage com o sistema e quais sistemas externos ele depende, sem detalhar como o sistema funciona internamente.
Dois atores humanos interagem diretamente com a plataforma. O Visitante é qualquer pessoa que acessa o VesteAí sem autenticação — pode explorar o feed, visualizar looks completos e clicar em links de compra. O Usuário Autenticado representa o perfil unificado da plataforma: a mesma conta que salva looks como consumidor também pode criar e publicar looks como creator. Não existe separação de contas entre os dois comportamentos.
O VesteAí depende de três sistemas externos. A Google Gemini API é utilizada pelo módulo de geração de imagem — quando o creator opta por não fazer upload de uma foto e aciona o assistente de IA para gerar uma imagem de referência do look. O Stripe processa exclusivamente a assinatura Pro do creator, que libera publicações ilimitadas de looks; a plataforma não processa pagamentos de produtos nem armazena dados financeiros dos consumidores. As Lojas Externas de E-commerce (Shopee, Mercado Livre, Shein, Renner, C&A e demais) não integram com o VesteAí via API — o sistema apenas redireciona o usuário para a URL cadastrada pelo creator, e a transação ocorre inteiramente fora da plataforma.

No nível de containers, o interior do sistema é explicitado. O VesteAí é composto por dois containers principais que se comunicam via HTTPS com troca de dados em formato JSON.
O Frontend é construído com Next.js e combina renderização no lado do servidor (SSR) para as páginas públicas — feed e detalhes de look — com interatividade no lado do cliente para o editor de looks e o painel do creator. O SSR é especialmente relevante para o feed, pois garante que o conteúdo seja indexável por mecanismos de busca e carregue com baixa latência para o visitante não autenticado. Toda a comunicação do frontend com o backend ocorre por meio de chamadas HTTPS à API.
O Backend é uma API construída com FastAPI em Python. É responsável por toda a lógica de negócio: autenticação de usuários, criação e publicação de looks, registro de cliques em links, validação de URLs, orquestração da requisição à Gemini e processamento de eventos do Stripe. O backend persiste os dados no PostgreSQL, o banco de dados relacional central da aplicação.
A Google Gemini API e o Stripe são acessados exclusivamente pelo backend — o frontend nunca se comunica diretamente com esses serviços. Esse isolamento centraliza o controle de chaves de API e evita que credenciais sensíveis sejam expostas no cliente.

No nível de componentes, o interior do container FastAPI é detalhado. A API segue uma arquitetura em camadas que separa responsabilidades de forma clara: routers recebem as requisições HTTP e delegam para os serviços; services concentram as regras de negócio; repositories encapsulam o acesso ao banco de dados; e clients abstraem a comunicação com serviços externos.
Os principais componentes da API são:
AuthService — gerencia o ciclo de vida de autenticação: criação de conta com senha armazenada como hash bcrypt, login com geração de token JWT e validação do token nas rotas protegidas.
LookService — coordena as operações de criação, edição, publicação e remoção de looks. Verifica as pré-condições de publicação (imagem obrigatória, ao menos uma peça com link) e aplica a regra de limite de publicações por plano antes de persistir o look como público.
PieceService — gerencia as peças associadas a cada look. Recebe nome, loja, preço, imagem e link de compra de cada item. Aciona a validação de URL para cada link cadastrado antes de confirmar o cadastro da peça.
ClickTracker — registra cada clique em link de compra externo. Ao receber
uma requisição de redirecionamento, persiste o evento na tabela clicks com o
identificador da peça e do look, e então redireciona o usuário para a URL
externa. Esse componente é o responsável direto pela north star metric da
plataforma: contagem de cliques em links de compra.
ImageService — encapsula a integração com a Google Gemini API. Recebe uma descrição textual do look, monta o prompt e envia a requisição para a API de geração de imagem. Em caso de falha ou timeout, retorna um erro estruturado para o LookService, que aciona o fluxo alternativo FA05 descrito na Seção 3.
StripeClient — abstrai a integração com o Stripe. Processa a criação da
assinatura Pro do creator e responde a webhooks de confirmação e cancelamento
de pagamento, atualizando o campo plan na entidade users.
LinkValidator — valida os links de compra cadastrados pelos creators. Verifica se a URL está acessível (resposta HTTP válida) e se o domínio de destino não consta em listas de domínios sinalizados como maliciosos. Não garante a validade comercial do link — apenas a acessibilidade e a segurança técnica (RF15, RN06).

O modelo relacional do VesteAí é composto por seis entidades principais. O diagrama a seguir representa as relações entre elas, seguido pelo esquema relacional com os tipos de dados adotados no PostgreSQL.

-
users1:Nlooks— um usuário pode criar múltiplos looks; cada look pertence a exatamente um usuário. -
looks1:Npieces— um look é composto por múltiplas peças; cada peça pertence a exatamente um look. -
pieces1:Nclicks— um clique é sempre associado a uma peça específica e ao look ao qual essa peça pertence; cada registro de clique pertence a exatamente uma peça. -
usersN:Mlooksviasaved_looks— um usuário pode salvar múltiplos looks e um mesmo look pode ser salvo por múltiplos usuários. -
users1:Npassword_resets— cada pedido de recuperação de senha gera um registro próprio, de uso único e com prazo de validade; um usuário pode ter vários ao longo do tempo, mas apenas o mais recente permanece válido.
users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(100) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
password TEXT NOT NULL,
plan VARCHAR(20) NOT NULL DEFAULT 'free', -- 'free' | 'pro'
avatar TEXT,
bio TEXT,
created_at TIMESTAMP NOT NULL DEFAULT now()
)
looks (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
title VARCHAR(200) NOT NULL,
description TEXT,
image_url TEXT, -- ver ADR-0019
category VARCHAR(20), -- ocasião; ver ADR-0021
ai_generated BOOLEAN NOT NULL DEFAULT false,
status VARCHAR(20) NOT NULL DEFAULT 'draft', -- 'draft' | 'published'
created_at TIMESTAMP NOT NULL DEFAULT now()
)
pieces (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
look_id UUID NOT NULL REFERENCES looks(id) ON DELETE CASCADE,
name VARCHAR(200) NOT NULL,
store VARCHAR(100),
price NUMERIC(10,2),
purchase_url TEXT NOT NULL,
image_url TEXT,
created_at TIMESTAMP NOT NULL DEFAULT now()
)
clicks (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
piece_id UUID REFERENCES pieces(id) ON DELETE SET NULL, -- ver ADR-0022
look_id UUID NOT NULL REFERENCES looks(id) ON DELETE CASCADE,
created_at TIMESTAMP NOT NULL DEFAULT now()
)
saved_looks (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
look_id UUID NOT NULL REFERENCES looks(id) ON DELETE CASCADE,
created_at TIMESTAMP NOT NULL DEFAULT now(),
UNIQUE (user_id, look_id)
)
password_resets (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
token_hash TEXT NOT NULL UNIQUE,
expires_at TIMESTAMP NOT NULL,
used_at TIMESTAMP,
created_at TIMESTAMP NOT NULL DEFAULT now()
)Na entidade password_resets persiste-se apenas o hash do token, nunca o token em
si: um vazamento do banco não permitiria redefinir senha alguma. O campo used_at
garante o uso único, e o consumo é feito em operação atômica para que duas requisições
simultâneas não possam aproveitar o mesmo token.
O campo look_id é mantido diretamente na entidade clicks — ainda que derivável via pieces — para permitir consultas de métricas agregadas por look sem a necessidade de junções adicionais, o que favorece o desempenho das consultas do painel do creator.
Esta seção descreve os módulos que compõem o sistema, sua responsabilidade funcional e os requisitos que cada um atende.
O módulo de autenticação gerencia o cadastro e o login de usuários. Ao criar uma conta, a senha é processada com bcrypt antes de ser persistida — nenhuma senha em texto claro é armazenada no banco. No login, as credenciais são verificadas e um token JWT é gerado com prazo de expiração configurável. Esse token é enviado pelo frontend em todas as requisições que exigem autenticação e validado pelo middleware da API antes de acionar qualquer serviço protegido. A recuperação de senha (RF03) gera um token de uso único, com prazo de validade e persistido apenas como hash, entregue por e-mail transacional através da Brevo — provedor escolhido em ADR-0005 por não exigir liberação de sandbox nem consumir o crédito da AWS. O módulo cobre os requisitos RF01, RF02, RF03 e os requisitos não funcionais RNF04, RNF05 e RNF07.
O módulo de looks concentra as operações de criação, edição, publicação e
remoção de looks. É o módulo central da plataforma em termos de lógica de
negócio: verifica se as pré-condições de publicação estão satisfeitas (RN04,
RN08), aplica o limite de publicações conforme o plano do usuário (RN07) e
persiste o estado do look como draft ou published. O feed público
retorna apenas looks com status published, paginados para atender ao
requisito de desempenho RNF10. O módulo cobre os requisitos RF05, RF10, RF11,
RF12, RF13 e RF14.
O módulo de peças gerencia os itens que compõem um look. Cada peça é associada a um look específico e deve conter obrigatoriamente nome e link de compra (RN05). O módulo aciona o LinkValidator antes de confirmar o cadastro de cada peça, garantindo que links tecnicamente inválidos ou maliciosos sejam bloqueados na entrada (RF15). Links que passam na validação técnica mas são comercialmente inválidos permanecem sob responsabilidade do creator, conforme estabelecido pela regra de negócio RN06.
O rastreamento de cliques é o mecanismo central de medição da north star metric
da plataforma. Toda vez que um usuário acessa um link de compra, a requisição
passa pelo ClickTracker antes do redirecionamento: o evento é registrado na
tabela clicks com o identificador da peça e do look, e o usuário é redirecionado para a
URL externa. Esse fluxo garante que cada clique seja contabilizado de forma
atômica — sem depender de JavaScript no cliente — e que as métricas do painel
do creator reflitam a realidade com precisão. O módulo cobre os requisitos RF07
e RF16, além da regra de negócio RN09.
O ImageService encapsula toda a comunicação com a Google Gemini API. Ao ser
acionado, recebe os dados do look em criação — título, tags de estilo e
descrição das peças — e constrói um prompt estruturado para a geração de uma
imagem de modelo virtual vestindo o look. A resposta da API é processada e a
URL da imagem gerada é associada ao look com o campo ai_generated marcado como
true, permitindo que o frontend exiba o badge "IA Gerado" na tela de
detalhes do look. Em caso de falha, o serviço retorna um erro estruturado que
aciona o fluxo alternativo FA05. O módulo cobre o requisito RF17.
O StripeClient gerencia exclusivamente o ciclo de vida da assinatura Pro do
creator. O fluxo de upgrade cria uma sessão de checkout no Stripe; após o
pagamento confirmado via webhook, o campo plan do usuário é atualizado de
free para pro no banco de dados. Cancelamentos e inadimplências são
processados pelo mesmo mecanismo de webhook, revertendo o plano para free
quando necessário. O VesteAí não armazena dados de cartão nem processa
pagamentos de produtos em nenhuma circunstância — toda a transação financeira
ocorre no ambiente seguro do Stripe.
O LinkValidator é um componente utilitário acionado pelo módulo de peças durante o cadastro de links de compra. Realiza duas verificações sequenciais: primeiro, testa a acessibilidade da URL com uma requisição HTTP e verifica se a resposta indica um destino válido; segundo, consulta o domínio de destino contra uma lista de domínios sinalizados como maliciosos. Links que falham em qualquer uma das verificações são rejeitados com uma mensagem de erro identificando qual link causou o problema (FA04). O componente cobre o requisito RF15 e operacionaliza a regra de negócio RN06.
As escolhas tecnológicas do VesteAí foram orientadas por três critérios principais: adequação técnica aos requisitos do projeto, produtividade no contexto de um time reduzido e um único desenvolvedor, e maturidade do ecossistema para um produto web em produção. Esta seção justifica cada escolha em relação às alternativas disponíveis.
O Next.js foi escolhido como framework de frontend por combinar, em uma única solução, renderização no lado do servidor (SSR), geração estática (SSG) e interatividade no cliente via React. Essa flexibilidade é especialmente relevante para o VesteAí: o feed público e as páginas de look individual se beneficiam do SSR para indexação por mecanismos de busca e carregamento rápido sem autenticação, enquanto o editor de looks e o painel do creator operam com estado dinâmico no cliente.
O FastAPI foi escolhido como framework de backend pela combinação de alta performance, tipagem estática nativa via Pydantic e geração automática de documentação OpenAPI. A tipagem forte no contrato da API reduz erros de integração com o frontend e facilita a validação dos dados de entrada sem código boilerplate adicional.
O PostgreSQL foi escolhido como banco de dados relacional pela robustez, pelo suporte nativo a UUIDs como chave primária e pela maturidade do ecossistema de ferramentas e bibliotecas de acesso em Python. O modelo relacional é adequado ao domínio do VesteAí: as entidades possuem relacionamentos bem definidos (Look → Piece → Click) e as consultas de métricas do painel do creator se beneficiam da expressividade do SQL para agregações.
A Google Gemini API foi escolhida para a funcionalidade de geração de imagem de look com modelo virtual por oferecer capacidade multimodal — geração de imagem a partir de texto descritivo — com SDK Python oficial e documentação ampla. A integração se encaixa no fluxo do creator como uma funcionalidade auxiliar: o creator que não tem uma foto do look pode gerar uma imagem de referência sem precisar sair da plataforma.
O Stripe foi escolhido para processar a assinatura Pro do creator por ser a plataforma de pagamentos recorrentes com melhor suporte a webhooks, documentação mais completa e SDK oficial para Python. O modelo de assinatura recorrente é exatamente o caso de uso central do Stripe — o que simplifica a implementação em comparação com soluções alternativas como PagSeguro ou Mercado Pago, que têm suporte menos maduro a cobranças recorrentes programáticas.
É importante reiterar que o Stripe é utilizado exclusivamente para a assinatura da plataforma. A monetização dos creators — as comissões de afiliado — ocorre fora do VesteAí, nos programas de afiliados das próprias lojas, e não envolve nenhum fluxo financeiro dentro do sistema.
A autenticação por tokens JWT foi escolhida por ser stateless — o servidor não precisa manter sessões em memória ou banco — o que simplifica a arquitetura ao eliminar a necessidade de um serviço de sessões. O token carrega os dados necessários para identificar o usuário e é validado pelo middleware da API a cada requisição protegida.
O bcrypt foi escolhido para o hash de senhas por ser o algoritmo recomendado para armazenamento seguro de credenciais: é adaptativo (o fator de custo pode ser aumentado conforme o hardware evolui), resistente a ataques de força bruta por ser computacionalmente custoso por design, e amplamente suportado nas bibliotecas Python de segurança. Essa combinação atende diretamente aos requisitos não funcionais RNF04 e RNF05.
O repositório do VesteAí é organizado como monorepo no GitHub, com o frontend Next.js e o backend FastAPI no mesmo repositório. Essa organização facilita a consistência entre as versões dos dois serviços, simplifica o gerenciamento de dependências compartilhadas e permite que um único pull request abranja alterações que afetam tanto o frontend quanto o backend — o que é especialmente relevante em um projeto desenvolvido por um único desenvolvedor.
O pipeline de integração e entrega contínua é implementado com GitHub
Actions. A cada push na branch main, o pipeline executa
automaticamente: instalação de dependências, lint, testes unitários
(backend e frontend), análise estática via SonarCloud e, em caso de
sucesso, build das imagens Docker e deploy no ambiente de produção.
Pull requests bloqueiam merge se qualquer etapa falhar.
O SonarCloud é integrado ao pipeline CI/CD para análise estática automática do código a cada pull request. Monitora cobertura de testes, code smells, bugs potenciais e vulnerabilidades de segurança. O projeto mantém o Quality Gate configurado para rejeitar código com cobertura abaixo dos limites definidos nos KPIs (75% backend, 25% frontend) ou com issues de severidade crítica.
O monitoramento de infraestrutura é realizado com Prometheus para coleta de métricas e Grafana para visualização, executados como serviços auxiliares ao lado da API no ECS. São monitorados: latência das rotas da API, taxa de erros HTTP, uso de CPU e memória dos serviços e disponibilidade da aplicação. Alertas são configurados para disponibilidade abaixo de 99% (RNF08) e latência acima dos limites definidos em RNF01–RNF03.
O frontend Next.js é hospedado na Vercel, e o backend FastAPI na Amazon Web Services. Essa separação foi autorizada em orientação: a Vercel entrega SSR e Preview Deployments por pull request sem infraestrutura a manter, e a AWS concentra o que exige controle de arquitetura.
O backend roda em ECS Fargate (sa-east-1), atrás de um Application Load Balancer com certificado do ACM. O banco PostgreSQL é provisionado no Amazon RDS (db.t4g.micro), em sub-rede privada e sem endereço público, acessível apenas pelo security group da aplicação. As imagens de look ficam em um bucket S3 privado, servidas por URL pré-assinada. Segredos vivem no AWS Secrets Manager e são resolvidos em tempo de execução pela task definition — nunca em variável de ambiente em texto plano.
Toda essa infraestrutura é descrita em Terraform, versionada no repositório em infra/: mudança de infraestrutura é mudança de código e entra por pull request, com terraform validate no pipeline. O apply é sempre manual e com aval, porque cria recurso que gera custo.
A escolha por serviços gerenciados em vez de uma instância administrada à mão está registrada em ADR-0002, e a decisão de manter a task em sub-rede pública sem NAT Gateway em ADR-0017. O free tier de 12 meses da AWS foi encerrado para contas novas em julho de 2025 e não se aplica a este projeto: a operação é custeada por crédito promocional finito, o que torna o dimensionamento uma restrição de projeto e não um detalhe operacional.
| Camada | Tecnologia | Alternativa Considerada | Razão da Escolha |
|---|---|---|---|
| Frontend | Next.js (React) | React + Vite (SPA) | SSR para feed público e indexabilidade |
| Backend | FastAPI (Python) | Flask (Python) | Tipagem nativa, async, validação integrada |
| Banco de dados | PostgreSQL (Amazon RDS) | MongoDB | Esquema relacional estável, integridade referencial |
| IA | Google Gemini API | DALL-E (OpenAI) | Ecossistema Python, custo operacional do MVP |
| Pagamentos | Stripe | PagSeguro / Mercado Pago | Suporte maduro a assinaturas recorrentes |
| Autenticação | JWT + bcrypt | Sessões em banco | Stateless, sem necessidade de serviço de sessão |
| Repositório | GitHub (monorepo) | Polyrepo | Time único, sincronização simplificada |
| CI/CD | GitHub Actions | Jenkins | Integrado ao repositório, sem infraestrutura adicional |
| Qualidade | SonarCloud | SonarQube (self-hosted) | Análise automática integrada ao PR sem setup de servidor |
| Product Analytics | ClickTracker customizado | Rastreamento de eventos sem construir infraestrutura própria | |
| Monitoramento | Prometheus + Grafana | Google Cloud Monitoring | Open-source, sem custo adicional, demonstra domínio técnico |
| Hospedagem do frontend | Vercel | Servir pelo backend | SSR e Preview por PR sem infraestrutura a manter |
| Hospedagem do backend | AWS ECS Fargate + ALB | EC2 administrada à mão · Railway | Sem servidor para administrar, e controle de arquitetura preservado (ADR-0002) |
| Banco em produção | AWS RDS db.t4g.micro
|
Postgres em container na própria instância | Backup e recuperação gerenciados, em sub-rede privada |
| Provisionamento | Terraform versionado | Console da AWS à mão | Infraestrutura revisável por PR e reproduzível |
| E-mail transacional | Brevo | AWS SES · servidor próprio | Sem sandbox a liberar e sem consumir o crédito AWS (ADR-0005) |
Esta seção descreve as medidas de segurança adotadas no VesteAí e o tratamento dos dados pessoais dos usuários em conformidade com a Lei Geral de Proteção de Dados (LGPD).
O VesteAí utiliza autenticação baseada em tokens JWT. Após o login com
e-mail e senha, o servidor emite um token assinado com prazo de expiração
configurável. Esse token é enviado pelo frontend no header Authorization
em todas as requisições que exigem autenticação.
As senhas dos usuários são armazenadas exclusivamente como hash bcrypt — nenhuma senha em texto claro é persistida ou trafegada pelo sistema. O bcrypt é resistente a ataques de força bruta por ser computacionalmente custoso por design.
O controle de autorização é aplicado por middleware na API: endpoints protegidos verificam a validade do token antes de acionar qualquer serviço. Um usuário autenticado só pode editar ou remover looks criados por ele mesmo (RN07) — requisições que tentam acessar recursos de outro usuário são rejeitadas com erro 403.
As principais ameaças do OWASP Top 10 relevantes para o VesteAí e as medidas adotadas para mitigá-las:
| Ameaça | Medida adotada |
|---|---|
| Broken Access Control | Middleware de autenticação JWT em todos os endpoints protegidos; verificação de propriedade antes de editar ou remover recursos |
| Cryptographic Failures | Senhas armazenadas com bcrypt; comunicação exclusivamente via HTTPS |
| Injection | Queries executadas via SQLAlchemy com parâmetros — sem concatenação de SQL; validação de entrada via Pydantic no FastAPI |
| Insecure Design | Separação entre frontend e backend; credenciais de API externas (Gemini, Stripe) acessadas exclusivamente pelo backend |
| Security Misconfiguration | Segredos no AWS Secrets Manager, resolvidos em tempo de execução e nunca em código nem em variável de ambiente em texto plano; RDS em sub-rede privada sem endereço público; bucket S3 privado; CORS restrito a uma única origem; cabeçalhos de resposta descritos abaixo |
| Vulnerable Components | Dependências com versões fixas em requirements.txt e package-lock.json, com atualizações propostas automaticamente e análise estática bloqueante no pipeline |
| Server-Side Request Forgery (SSRF) | LinkValidator recusa esquema não-HTTP, localhost, endereços de metadados de nuvem e faixas de IP privadas antes de qualquer requisição a link de compra |
| Identification and Authentication Failures | Limite de requisições nas rotas de autenticação (ver abaixo); token de recuperação de senha de uso único, com prazo e persistido apenas como hash; mensagem de erro idêntica para e-mail inexistente e senha incorreta, evitando enumeração de usuários; tokens anteriores invalidados quando a senha muda |
| Security Logging and Monitoring Failures | Log estruturado em JSON com identificador de requisição propagável, sem senha, token, endereço IP ou e-mail completo |
As rotas de autenticação são as únicas expostas sem credencial, e por isso recebem um
limite de requisições por endereço de origem. Os limites são calibrados pelo recurso que
cada rota consome: login e reset-password aceitam 10 requisições por minuto, pois
consomem processamento; register aceita 10 por hora; e forgot-password aceita apenas
3 por hora, por ser a única que consome uma cota diária e finita de envio de e-mail —
sem esse limite, um laço automatizado esgotaria a cota do dia e deixaria usuários
legítimos sem recuperação de conta.
O contador é mantido em memória do processo, decisão registrada em ADR-0018 junto com a condição que a invalidaria. A identificação da origem considera que o balanceador acrescenta o endereço observado ao cabeçalho de encaminhamento, e não o substitui — por isso o valor lido é o último da lista, o único que o balanceador escreveu. Ler o primeiro permitiria ao cliente escolher a própria identidade e anular o limite.
Toda resposta da API carrega X-Content-Type-Options: nosniff, X-Frame-Options: DENY,
Referrer-Policy: strict-origin-when-cross-origin e uma política de conteúdo
default-src 'none' — a mais restritiva possível, adequada a uma API que devolve apenas
JSON e da qual nada deve poder ser carregado ou embutido. O Strict-Transport-Security
é enviado somente em produção, determinado pelo ambiente da aplicação e não por cabeçalho
recebido na requisição, que seria falsificável.
Toda a comunicação entre cliente e servidor ocorre exclusivamente via HTTPS — requisito não funcional RNF06. Isso garante que tokens JWT, credenciais de login e dados do usuário não trafeguem em texto claro na rede.
O banco de dados PostgreSQL é acessado exclusivamente pelo backend via conexão autenticada. Nenhum dado do banco é exposto diretamente ao frontend ou a sistemas externos.
O VesteAí coleta apenas os dados necessários para o funcionamento da plataforma:
| Dado | Finalidade | Base legal (LGPD) |
|---|---|---|
| Nome e e-mail | Identificação e autenticação do usuário | Execução de contrato (Art. 7°, V) |
| Senha (hash bcrypt) | Autenticação segura | Execução de contrato (Art. 7°, V) |
| Avatar e bio | Personalização do perfil público | Consentimento (Art. 7°, I) |
| Looks e peças publicados | Conteúdo da plataforma | Execução de contrato (Art. 7°, V) |
| Cliques em links (com IP hash) | Métricas de desempenho para o creator | Legítimo interesse (Art. 7°, IX) |
O VesteAí não coleta dados de cartão de crédito, dados bancários nem informações de compra — todas as transações financeiras ocorrem nas lojas externas ou no ambiente seguro do Stripe.
Os dados são armazenados no PostgreSQL hospedado em ambiente de produção com acesso restrito. O endereço IP dos visitantes que clicam em links de compra é armazenado exclusivamente como hash SHA-256 — o IP bruto nunca é persistido, minimizando a retenção de dado pessoal identificável.
O usuário pode, a qualquer momento:
- Acessar seus dados exportando o conteúdo do seu perfil
- Corrigir nome, e-mail, avatar e bio nas configurações de perfil
-
Excluir sua conta, o que remove permanentemente todos os seus dados
pessoais e looks publicados do banco de dados (exclusão em cascata via
ON DELETE CASCADEno esquema relacional)
Solicitações de direitos do titular podem ser feitas diretamente pelo e-mail de contato da plataforma. O prazo de resposta é de até 15 dias corridos, conforme previsto na LGPD.
Os dados do usuário são mantidos enquanto a conta estiver ativa. Após a exclusão da conta, todos os dados pessoais são removidos imediatamente. Registros de cliques anonimizados (sem vínculo com usuário identificável) podem ser mantidos para fins estatísticos agregados.
O desenvolvimento do VesteAí está dividido em duas fases distintas, separadas por semestre letivo. O primeiro semestre de 2026 é dedicado à documentação, definição arquitetural e aprovação pelos professores orientadores. O desenvolvimento da aplicação ocorre integralmente no segundo semestre de 2026, com entrega e apresentação no Demo Day.
| Marco | Descrição | Período |
|---|---|---|
| M1 | Definição do produto, pesquisa de usuários e benchmark | Março 2026 |
| M2 | Engenharia de requisitos (RFs, RNFs, regras de negócio, personas) | Abril 2026 |
| M3 | Fluxos do sistema, wireframes e mockups de UX | Abril 2026 |
| M4 | Arquitetura do sistema (C4, modelo de dados, stack tecnológica) | Maio 2026 |
| M5 | Segurança, privacidade e planejamento do projeto | Maio 2026 |
| M6 | Entrega da RFC e aprovação pelos professores orientadores | Junho 2026 |
| Marco | Descrição | Período |
|---|---|---|
| M7 | Setup do monorepo, pipeline CI/CD (GitHub Actions), SonarCloud e ambientes AWS | Agosto 2026 |
| M8 | Backend: autenticação, modelo de dados e CRUD de looks (TDD) | Agosto 2026 |
| M9 | Backend: rastreamento de cliques, validação de links e integração Gemini (TDD) | Setembro 2026 |
| M10 | Frontend: feed de looks, tela de detalhes e carrinho | Setembro 2026 |
| M11 | Frontend: editor de looks, painel do creator e autenticação | Outubro 2026 |
| M12 | Integração Stripe (assinatura Pro) e testes de integração | Outubro 2026 |
| M13 | Testes unitários (75% backend, 25% frontend), Prometheus + Grafana | Novembro 2026 |
| M14 | Deploy em produção na AWS (ECS Fargate), validação com usuários reais e ajustes finais | Novembro 2026 |
| M15 | Demo Day — apresentação do produto funcional | Dezembro 2026 |
O projeto será considerado concluído quando os seguintes critérios forem atendidos simultaneamente:
- RFC aprovada pelos professores orientadores até o fim do 1º semestre
- Todos os requisitos funcionais RF01–RF17 implementados e verificados
- Cobertura mínima de 75% de testes unitários no backend (TDD)
- Cobertura mínima de 25% de testes unitários no frontend
- Pipeline CI/CD ativo com execução automática de testes a cada push
- SonarCloud sem issues críticos de segurança ou qualidade
- Monitoramento configurado (Prometheus + Grafana) em produção
- Aplicação acessível publicamente por HTTPS em domínio próprio, servida por ECS Fargate atrás de ALB
- Pelo menos 5 looks publicados por criadores reais antes do Demo Day
- Pelo menos 1 clique em link de compra registrado por look publicado
O deploy é realizado exclusivamente pelo pipeline de CI/CD. Não há acesso interativo a servidor em nenhum ponto do processo — nem por SSH, nem por FTP, nem por console: o pipeline não possui credencial de sessão, e a aplicação roda em contêiner gerenciado, sem instância a administrar.
Pré-requisitos, todos provisionados por Terraform (infra/):
- Repositório no Amazon ECR para a imagem da API
- Cluster ECS e task definition apontando para essa imagem
- ALB com certificado do ACM e redirecionamento de HTTP para HTTPS
-
RDS PostgreSQL (
db.t4g.micro) em sub-rede privada - Segredos no AWS Secrets Manager (
DATABASE_URL,JWT_SECRET,BREVO_API_KEY), referenciados no camposecretsda task definition e resolvidos em tempo de execução - Role de IAM assumida por OIDC, que autoriza o GitHub Actions a publicar no ECR e a solicitar deployment ao ECS. Nenhuma chave estática da AWS existe no repositório: a credencial é temporária e expira em minutos
Pipeline do backend (GitHub Actions, a cada merge na branch de produção):
- Executa lint e a suíte de testes contra um PostgreSQL real, com limiar de cobertura
- Executa análise estática no SonarCloud, com Quality Gate bloqueante
- Valida a infraestrutura (
terraform fmteterraform validate) - Constrói a imagem Docker da API e a publica no ECR, marcada com o SHA do commit
- Registra uma nova revisão da task definition e solicita um novo deployment ao ECS, que substitui as tarefas de forma gradual
- Executa smoke test na URL pública
Pipeline do frontend: o deploy automático da Vercel para produção está desativado de
forma versionada em frontend/vercel.json — a decisão fica no repositório e aparece no
diff, em vez de num interruptor de painel. Cada pull request recebe um Preview
Deployment, que já funciona e serve como ambiente de validação do frontend. A promoção
para produção passará a partir do pipeline quando o job de deploy existir.
Rollback: como cada imagem é marcada com o SHA do commit e cada deployment gera uma revisão da task definition, voltar atrás é solicitar deployment da revisão anterior — sem rebuild e sem acesso a servidor.
Migrações de banco são executadas como passo do pipeline, nunca à mão.
Nenhuma etapa deste processo envolve conectar-se a uma máquina. Essa é uma característica do desenho, não uma recomendação: não existe instância à qual se conectar.
Estado de implementação em 08/09/2026. Os passos 1 a 3 estão implementados e rodam a
cada pull request. Os passos 4 a 6 — publicação da imagem no ECR, deployment ao ECS e
smoke test — ainda não existem: dependem da role de OIDC, que por sua vez depende
do primeiro provisionamento da infraestrutura. Toda a infraestrutura está descrita em
Terraform e validada no pipeline, mas nada foi aplicado, porque apply cria recurso que
gera custo sobre um crédito finito. Até que esses passos existam, não há ambiente de
produção — e este parágrafo é o registro disso, para que o documento não afirme uma
automação que ainda não roda.
-
NuvemCommerce 2026 — Relatório anual do e-commerce brasileiro. Dados de crescimento do segmento de moda (35%, R$ 2,9 bilhões). Disponível em: https://nuvemshop.com.br/nuvemcommerce
-
Opinion Box — Pesquisa "Consumo de moda no Brasil". Dado: 66% dos brasileiros preferem comprar roupas online. Disponível em: https://opinionbox.com
-
Wake — Dados de social commerce brasileiro. Projeção de crescimento de 16,1% ao ano, US$ 4,16 bilhões em 2025. Disponível em: https://wake.tech
-
Lei Geral de Proteção de Dados — LGPD Lei nº 13.709, de 14 de agosto de 2018. Disponível em: https://www.planalto.gov.br/ccivil_03/_ato2015-2018/2018/lei/l13709.htm
-
OWASP Top 10 — Os dez riscos de segurança mais críticos em aplicações web. Open Web Application Security Project, 2021. Disponível em: https://owasp.org/www-project-top-ten
-
BROWN, Simon — The C4 model for visualising software architecture. Disponível em: https://c4model.com
-
RFC 7519 — JSON Web Token (JWT). Internet Engineering Task Force (IETF), 2015. Disponível em: https://datatracker.ietf.org/doc/html/rfc7519
-
Next.js — The React Framework for the Web. Disponível em: https://nextjs.org/docs
-
FastAPI — Modern, fast web framework for building APIs with Python. Disponível em: https://fastapi.tiangolo.com
-
PostgreSQL — The World's Most Advanced Open Source Relational Database. Disponível em: https://www.postgresql.org/docs
-
SQLAlchemy — The Python SQL Toolkit and Object Relational Mapper. Disponível em: https://docs.sqlalchemy.org
-
Google Gemini API — Documentação oficial da API de geração de imagem. Disponível em: https://ai.google.dev/docs
-
Stripe — Documentação de assinaturas recorrentes e webhooks. Disponível em: https://stripe.com/docs/billing/subscriptions/overview
-
bcrypt — Adaptive password hashing for Python (passlib). Disponível em: https://passlib.readthedocs.io
- LTK (LikeToKnowIt) — https://shopltk.com
- Pinterest — https://pinterest.com
- OQVestir — https://oqvestir.com.br
- Instagram — https://instagram.com
- TikTok — https://tiktok.com
-
Structurizr — Geração dos diagramas C4 (Nível 1, 2 e 3). Disponível em: https://structurizr.com/dsl
-
dbdiagram.io — Geração do Diagrama Entidade-Relacionamento (DER). Disponível em: https://dbdiagram.io
-
Excalidraw — Diagramas de fluxo de usuário (consumer e creator). Disponível em: https://excalidraw.com
-
Google Stitch — Geração dos mockups de interface. Disponível em: https://stitch.withgoogle.com
O código-fonte, a documentação e todos os assets da RFC estão disponíveis no repositório oficial do projeto:
- Repositório: https://github.com/kalebefukuda/veste-ai
-
Branch da RFC:
docs/rfc -
Pasta de assets:
docs/assets/
Foi desenvolvida uma landing page do VesteAí como referência de identidade visual da plataforma. Ela estabelece a paleta de cores, tipografia e tom de comunicação que guiarão o desenvolvimento da interface final.
Stack: Next.js + Tailwind CSS
Paleta: #8B5CF6 (purple), #C4A8FF (purple-light), #F472B6 (rose), #1E1B4B (navy)

A landing page não representa o design final da aplicação — é uma referência de identidade visual e proposta de valor do produto.
As conversas informais descritas na Seção 3 foram realizadas com 5 participantes divididos entre os dois perfis de usuário da plataforma. Nenhuma gravação foi realizada — os registros abaixo são sínteses das observações coletadas.
| Participante | Perfil | Principal observação |
|---|---|---|
| P1 | Mulher, 24 anos, estudante | "Fico horas tentando achar onde comprar um look que vi no Instagram" |
| P2 | Mulher, 27 anos, analista | "Quando acho o link, às vezes é loja americana sem entrega aqui" |
| P3 | Homem, 29 anos, designer | "Nunca consigo montar o look completo, sempre falta alguma peça" |
| Participante | Perfil | Principal observação |
|---|---|---|
| P4 | Mulher, 22 anos, influenciadora | "Respondo nos comentários onde comprei mas os links somem no stories" |
| P5 | Mulher, 31 anos, usa afiliados Shopee | "Queria um lugar só para moda, o Linktree é genérico demais" |
Padrão identificado: todos os 5 participantes demonstraram interesse imediato na proposta e perguntaram quando a plataforma estaria disponível.
Avaliador 1: Nome: JANAINA FONTANA BIFFI DUARTE
Assinatura: _____________________
Avaliador 2: Nome: EDICARSIA BARBIERO PILLON
Assinatura: _____________________