sass-imobiliaria/specs/029-ux-area-do-cliente/spec.md
MatheusAlves96 cf5603243c
Some checks failed
CI/CD → Deploy via SSH / Build & Push Docker Images (push) Successful in 1m0s
CI/CD → Deploy via SSH / Deploy via SSH (push) Successful in 4m35s
CI/CD → Deploy via SSH / Validate HTTPS & Endpoints (push) Failing after 46s
feat: features 025-032 - favoritos, contatos, trabalhe-conosco, area-cliente, navbar, hero-light-dark, performance-homepage
- feat(025): favoritos locais com FavoritesContext, HeartButton, PublicFavoritesPage
- feat(026): central de contatos admin (leads/contatos unificados)
- feat(027): configuração da página de contato via admin
- feat(028): trabalhe conosco - candidaturas com upload e admin
- feat(029): UX área do cliente - visitas, comparação, perfil
- feat(030): navbar UX - menu mobile, ThemeToggle, useFavorites
- feat(031): hero light/dark - imagens separadas por tema, upload, preview, seed
- feat(032): performance homepage - Promise.all parallel fetches, sessionStorage cache,
  preload hero image, loading=lazy nos cards, useInView hook, will-change carrossel,
  keyframes em index.css, AgentsCarousel e HomeScrollScene via props
- fix: light mode HomeScrollScene - gradiente, cores de texto, scroll hint

migrations: g1h2i3j4k5l6 (source em leads), h1i2j3k4l5m6 (contact_config),
            i1j2k3l4m5n6 (job_applications), j2k3l4m5n6o7 (hero theme images)
2026-04-22 22:35:17 -03:00

14 KiB

Feature Specification: Revisão UX/UI — Área do Cliente

Feature Branch: 029-ux-area-do-cliente
Created: 2026-04-22
Status: Draft


User Scenarios & Testing (mandatory)

User Story 1 — Navegar direto para Favoritos ao acessar a Área do Cliente (Priority: P1)

O cliente autenticado digita ou clica no link da Área do Cliente e chega imediatamente à lista de imóveis favoritos, sem passar por uma tela de painel intermediária que não agrega valor.

Why this priority: Elimina um clique desnecessário presente hoje. É a mudança de maior impacto imediato na jornada do usuário e desbloqueio para todo o restante da área.

Independent Test: Acessar /area-do-cliente deve redirecionar para /area-do-cliente/favoritos. A página de Favoritos deve carregar de forma autônoma e ser completamente utilizável.

Acceptance Scenarios:

  1. Given um cliente autenticado, When ele acessa /area-do-cliente, Then é redirecionado automaticamente para /area-do-cliente/favoritos.
  2. Given um cliente autenticado, When ele acessa /area-do-cliente/boletos, Then recebe uma resposta 404 (rota inexistente).
  3. Given um cliente autenticado, When ele visualiza o menu lateral, Then os itens "Painel" e "Boletos" não estão presentes.

User Story 2 — Visualizar favoritos com imagem, preço e localização (Priority: P1)

O cliente vê seus imóveis favoritos exibidos em cards que mostram a thumbnail da propriedade, o preço e a cidade/bairro, permitindo identificar cada imóvel sem precisar clicar para abrir.

Why this priority: É a página mais acessada da área do cliente. Sem imagem e preço, o usuário não consegue distinguir os imóveis e a experiência é frustrante.

Independent Test: Com ao menos um favorito salvo, a página deve exibir cards com imagem (ou placeholder), preço formatado e localização.

Acceptance Scenarios:

  1. Given um cliente com favoritos salvos, When ele acessa /area-do-cliente/favoritos, Then cada card exibe thumbnail da propriedade (ou placeholder se sem foto), título, preço e cidade/bairro.
  2. Given um cliente sem favoritos, When ele acessa a página, Then vê um empty state informativo com link para /imoveis.
  3. Given um cliente visualizando favoritos, When ele clica em "Ver imóvel", Then é levado à página de detalhes do imóvel.
  4. Given um cliente visualizando favoritos, When ele remove um favorito, Then o card some da lista sem recarregar a página.

User Story 3 — Cancelar visita agendada (Priority: P2)

O cliente pode solicitar o cancelamento de uma visita com status pendente diretamente pela Área do Cliente, sem precisar entrar em contato por outro canal.

Why this priority: Resolve um ponto de atrito real: hoje o usuário não tem como cancelar uma visita pelo sistema, o que gera contato desnecessário via WhatsApp ou telefone.

Independent Test: Com uma visita no status "pendente", o botão "Cancelar" deve ser exibido e, ao clicar, alterar o status para "cancelado".

Acceptance Scenarios:

  1. Given uma visita com status=pending, When o cliente acessa /area-do-cliente/visitas, Then o card exibe o botão "Cancelar".
  2. Given o cliente clica em "Cancelar", When a ação é confirmada, Then o status do card muda para "cancelado" e o botão desaparece.
  3. Given uma visita com status diferente de pending (ex: confirmada, cancelada), When o cliente visualiza o card, Then o botão "Cancelar" não está disponível.
  4. Given uma falha de rede ao cancelar, When a requisição retorna erro, Then o cliente vê uma mensagem de erro e o status não muda.

User Story 4 — Editar perfil e trocar senha (Priority: P2)

O cliente pode acessar /area-do-cliente/conta, visualizar seus dados cadastrais, atualizar o nome e alterar a senha, tudo dentro da Área do Cliente.

Why this priority: Hoje não existe nenhuma forma do cliente atualizar seus dados pelo sistema. É uma funcionalidade básica esperada em qualquer área logada.

Independent Test: A página /area-do-cliente/conta deve existir com formulário funcional de atualização de nome e de troca de senha.

Acceptance Scenarios:

  1. Given o cliente acessa /area-do-cliente/conta, When a página carrega, Then exibe o nome atual preenchido e o e-mail em campo somente leitura.
  2. Given o cliente altera o nome e clica em "Salvar", When o nome é válido (não vazio), Then vê confirmação de sucesso e o nome atualizado no menu lateral.
  3. Given o cliente preenche "Senha atual", "Nova senha" e "Confirmar nova senha", When as senhas coincidem e têm pelo menos 8 caracteres, Then a senha é alterada e uma mensagem de sucesso é exibida.
  4. Given o cliente informa uma senha atual incorreta, When submete o form, Then vê mensagem de erro "Senha atual incorreta" sem alterar nada.
  5. Given "Nova senha" e "Confirmar nova senha" divergem, When o cliente tenta salvar, Then vê validação inline "As senhas não coincidem" antes de enviar ao servidor.

User Story 5 — Navegação com ícones consistentes e item "Minha conta" (Priority: P3)

O cliente vê o menu lateral (desktop) e a barra de navegação (mobile) com ícones vetoriais consistentes em qualquer sistema operacional, e um link "Minha conta" que leva à nova página de perfil.

Why this priority: Melhoria visual e de consistência; não bloqueia funcionalidades principais, mas impacta a percepção de qualidade do produto.

Independent Test: O menu deve renderizar 4 itens (Favoritos, Comparar, Visitas, Minha conta) com ícones SVG visíveis e corretos em temas claro e escuro.

Acceptance Scenarios:

  1. Given o cliente está na Área do Cliente, When visualiza o menu lateral ou a barra mobile, Then os 4 itens (Favoritos, Comparar, Visitas, Minha conta) estão presentes com ícones SVG.
  2. Given o cliente está em qualquer página da área do cliente, When observa o item de menu correspondente à página atual, Then o item está visualmente destacado (ativo).
  3. Given o cliente está em mobile, When acessa a barra de navegação, Then os 4 itens estão centralizados sem scroll horizontal desnecessário.
  4. Given o cliente clica em "Sair", When a ação é executada, Then o ícone do botão é o ícone de logout (seta saindo de uma porta), não uma seta genérica.

User Story 6 — Empty state explicativo no Comparar (Priority: P3)

O cliente que acessa a página de comparação sem imóveis selecionados recebe uma instrução clara sobre como adicionar imóveis à comparação.

Why this priority: Melhoria de usabilidade pontual; sem ela o usuário fica confuso, mas o impacto é menor que os itens anteriores.

Independent Test: Acessar /area-do-cliente/comparar sem imóveis selecionados deve exibir o empty state com a instrução de uso.

Acceptance Scenarios:

  1. Given o cliente não tem imóveis na comparação, When acessa /area-do-cliente/comparar, Then vê uma mensagem explicando como adicionar imóveis (ex: "Acesse um imóvel e clique em 'Comparar' para adicioná-lo aqui").
  2. Given o cliente tem imóveis na comparação, When acessa a página, Then a tabela de comparação é exibida normalmente.

Edge Cases

  • O que acontece se a foto de um imóvel favorito for removida após ser salvo? → O card exibe um placeholder de imagem.
  • O que acontece se o cliente tentar cancelar uma visita já cancelada por outra aba? → O servidor retorna erro e o frontend exibe mensagem informativa.
  • O que acontece se o cliente enviar o form de perfil com nome vazio? → Validação inline impede o envio antes de chegar ao servidor.
  • O que acontece se o cliente sem favoritos tentar acessar diretamente /area-do-cliente? → Redireciona para /area-do-cliente/favoritos e exibe o empty state de favoritos.
  • O que acontece se a sessão expirar durante uso da área do cliente? → O cliente é redirecionado para a tela de login com mensagem de sessão expirada.

Requirements (mandatory)

Functional Requirements

Roteamento e Estrutura

  • FR-001: O sistema DEVE redirecionar /area-do-cliente para /area-do-cliente/favoritos de forma automática.
  • FR-002: A rota /area-do-cliente/boletos DEVE ser removida; acessá-la DEVE retornar 404.
  • FR-003: O menu de navegação da Área do Cliente DEVE conter exatamente 4 itens: Favoritos, Comparar, Visitas e Minha conta.
  • FR-004: Os ícones do menu DEVE ser SVG vetoriais (Heroicons 2.0 outline), sem uso de emoji ou caracteres Unicode.

Favoritos

  • FR-005: Cada card de favorito DEVE exibir: thumbnail da propriedade (ou placeholder padronizado), título, preço formatado em reais e cidade/bairro.
  • FR-006: A thumbnail DEVE ser obtida a partir dos dados da propriedade (campo cover_photo ou primeira foto da galeria).
  • FR-007: O card DEVE oferecer as ações "Ver imóvel" (navega para detalhe) e "Remover dos favoritos" (remove sem recarregar a página).

Visitas

  • FR-008: O card de visita DEVE exibir: título do imóvel em destaque, data agendada/solicitada em destaque, badge de status alinhado à direita e mensagem como texto secundário.
  • FR-009: Visitas com status=pending DEVE exibir botão "Cancelar".
  • FR-010: Ao confirmar o cancelamento, o sistema DEVE chamar PATCH /me/visits/:id/cancel e atualizar o status do card para "cancelado" sem recarregar a página.
  • FR-011: Visitas com status diferente de pending NÃO DEVEM exibir o botão "Cancelar".

Comparar

  • FR-012: Quando não há imóveis selecionados para comparação, a página DEVE exibir um empty state com instrução clara de como adicionar imóveis à comparação.

Perfil / Minha conta

  • FR-013: A rota /area-do-cliente/conta DEVE ser criada e acessível pelo menu "Minha conta".
  • FR-014: A página de conta DEVE exibir o nome atual do cliente em campo editável e o e-mail em campo somente leitura.
  • FR-015: O cliente DEVE poder atualizar o nome via PATCH /me/profile; o campo nome é obrigatório.
  • FR-016: O cliente DEVE poder trocar a senha informando senha atual, nova senha e confirmação via PATCH /me/password.
  • FR-017: A nova senha DEVE ter no mínimo 8 caracteres; a confirmação DEVE ser idêntica à nova senha; validações DEVEM ocorrer no frontend antes do envio.
  • FR-018: Se a senha atual informada estiver incorreta, o servidor DEVE retornar erro e o frontend DEVE exibir "Senha atual incorreta".

Backend — Novos Endpoints

  • FR-019: PATCH /me/profile — atualiza o nome do cliente autenticado. Requer autenticação JWT. Retorna os dados atualizados.
  • FR-020: PATCH /me/password — altera a senha do cliente autenticado. Valida senha atual antes de persistir. Requer autenticação JWT.
  • FR-021: PATCH /me/visits/:id/cancel — cancela uma visita com status=pending pertencente ao cliente autenticado. Retorna a visita atualizada. Requer autenticação JWT.
  • FR-022: Tentativa de cancelar visita com status diferente de pending DEVE retornar erro com mensagem descritiva.
  • FR-023: Tentativa de cancelar visita de outro cliente DEVE retornar 403 Forbidden.

Layout e Mobile

  • FR-024: O botão "Sair" DEVE usar o ícone ArrowRightOnRectangle (Heroicons) no lugar do caractere .
  • FR-025: Em viewport mobile, a barra de navegação DEVE centralizar os 4 itens e indicar visualmente o item ativo.

Key Entities

  • ClientUser: Usuário da área do cliente. Atributos relevantes: id, name, email, password_hash. Possui coleções de favoritos e visitas.
  • SavedProperty (Favorito): Associação entre ClientUser e Property. Atributos relevantes: id, client_user_id, property_id, created_at.
  • VisitRequest (Visita): Solicitação de visita feita por um ClientUser para uma Property. Atributos relevantes: id, client_user_id, property_id, scheduled_date, status (pending | confirmed | cancelled), message.
  • Property (Imóvel): Imóvel do catálogo. Atributos consumidos nesta feature: id, title, price, city, neighborhood, cover_photo (ou galeria de fotos).

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: O cliente chega ao conteúdo real (Favoritos) com um clique a menos do que hoje — a página de painel não existe mais como etapa intermediária.
  • SC-002: O cliente consegue identificar visualmente seus imóveis favoritos sem precisar abrir nenhum deles — cada card mostra imagem, preço e localização.
  • SC-003: O cliente consegue cancelar uma visita pendente em menos de 3 cliques a partir da página de Visitas, sem sair da Área do Cliente.
  • SC-004: O cliente consegue atualizar nome ou senha em uma única interação com o formulário de conta, sem precisar entrar em contato com suporte.
  • SC-005: Os ícones do menu são renderizados de forma idêntica em Windows, macOS e Linux, tanto em tema claro quanto escuro.
  • SC-006: A taxa de abandono da Área do Cliente (saída imediata) deve ser reduzida, dado que o primeiro conteúdo exibido passa a ser imediatamente útil.
  • SC-007: Todos os 3 novos endpoints do backend respondem corretamente com autenticação válida e retornam erros descritivos para entradas inválidas.

Assumptions

  • A tabela client_users já existe no banco com as colunas id, name, email e password_hash; nenhuma migration de schema é necessária para os endpoints de perfil e senha.
  • A tabela visit_requests já possui a coluna status com os valores pending, confirmed e cancelled; o endpoint de cancelamento apenas atualiza este campo.
  • O backend de favoritos já expõe o property_id; a foto do imóvel será obtida do campo cover_photo da tabela de propriedades ou do primeiro item retornado pela API de fotos já existente.
  • O sistema de autenticação JWT para clientes já está operacional; os novos endpoints reutilizarão o mesmo middleware de autenticação.
  • A remoção de BoletosPage é apenas frontend e de rota; o model e os dados de boletos no banco são mantidos intactos para uso futuro pelo admin.
  • O componente de comparação já armazena os imóveis selecionados em estado local ou contexto; esta feature não altera o mecanismo de seleção, apenas o empty state.
  • Não há requisito de confirmação por e-mail para troca de senha nesta fase (fluxo simplificado: validar senha atual → salvar nova senha).
  • A feature não inclui upload de foto de perfil do cliente.