sass-imobiliaria/.specify/features/001-homepage/spec.md

26 KiB
Raw Blame History

Feature Specification: Homepage (Página Inicial)

Feature Branch: 001-homepage Created: 2026-04-13 Status: Draft


User Scenarios & Testing

User Story 1 — Visitante Experimenta o Hero e a Navegação (Priority: P1)

Um visitante chega ao site da imobiliária e é imediatamente recebido por uma barra de navegação clara e uma seção hero visualmente impactante. O headline comunica a proposta de valor da agência, o subheadline fornece contexto de suporte, e um botão CTA proeminente convida o visitante a explorar os imóveis disponíveis.

Why this priority: O hero é a primeira impressão do site. Sem ele renderizar corretamente com conteúdo atualizado, nenhuma outra seção entrega valor significativo. Ele ancora a identidade visual e orienta o engajamento do visitante.

Independent Test: Pode ser testado de forma independente carregando a URL da homepage em qualquer navegador — a barra de navegação deve exibir o logotipo e os links, o hero deve mostrar o headline e subheadline configurados pelo admin, e o botão CTA deve estar visível e navegável para a listagem de imóveis.

Acceptance Scenarios:

  1. Given o visitante abre a URL da homepage, when a página carrega, then a barra de navegação é visível com o logotipo da agência à esquerda e os links "Imóveis", "Sobre" e "Contato" à direita.
  2. Given a página está carregada, when o visitante visualiza a seção hero, then ela exibe o headline atual, o subheadline (quando configurado), e um botão CTA com o rótulo configurado pelo admin (padrão: "Ver Imóveis").
  3. Given o visitante clica no botão CTA do hero, when o clique é processado, then o navegador redireciona para a página de listagem de imóveis (/imoveis).
  4. Given um admin atualizou o headline via painel administrativo, when o visitante carrega a homepage, then a seção hero exibe o novo headline sem necessidade de redeploy.
  5. Given a homepage é acessada em dispositivo móvel (viewport 320px428px), when a página renderiza a seção hero, then todo o texto é legível, o botão CTA é tocável, e não há overflow horizontal.

User Story 2 — Visitante Explora Imóveis em Destaque (Priority: P1)

Um visitante rola além da seção hero e encontra uma grade de imóveis curados em destaque. Cada card de imóvel fornece informações suficientes (foto, preço, tipo, estatísticas principais) para o visitante avaliar rapidamente o interesse e decidir clicar para ver mais detalhes.

Why this priority: Os imóveis em destaque são o conteúdo comercial primário da homepage. Esta seção conduz diretamente as consultas de imóveis e a conversão de visitante para lead. É a função de negócio central da homepage.

Independent Test: Pode ser testado de forma independente carregando a homepage e verificando que pelo menos um card de imóvel aparece na grade em destaque, com todos os campos obrigatórios visíveis (foto, título, preço, badge de tipo, quartos/banheiros/área). O teste pode ser executado contra um banco de dados com imóveis pré-configurados como destaque.

Acceptance Scenarios:

  1. Given existem imóveis no sistema com o flag "featured" habilitado, when o visitante carrega a homepage, then a seção de imóveis em destaque exibe uma grade mostrando até N imóveis (configurável pelo admin), cada card contendo: foto principal, título do imóvel, preço formatado (R$), badge de tipo (Venda ou Aluguel), contagem de quartos, banheiros e área total em m².
  2. Given nenhum imóvel está configurado como destaque, when o visitante carrega a homepage, then a seção de imóveis em destaque é ocultada ou exibe a mensagem "Nenhum imóvel em destaque no momento" — a grade não é renderizada vazia ou quebrada.
  3. Given um card de imóvel está visível, when o visitante clica no card, then o navegador navega para a URL de detalhe daquele imóvel (/imoveis/{slug}).
  4. Given um imóvel em destaque não possui foto cadastrada, when o card é renderizado, then ele exibe uma imagem placeholder em vez de um elemento de imagem quebrado.
  5. Given a grade de imóveis em destaque é visualizada em tablet (768px1023px), when o layout renderiza, then a grade se adapta para 2 colunas sem overflow ou quebra de alinhamento.

User Story 3 — Visitante Descobre a Agência e Inicia Contato (Priority: P2)

Um visitante que está interessado mas ainda não está pronto para navegar pelos imóveis rola pela seção Sobre para conhecer o background da agência, e em seguida encontra a seção CTA com informações de contato claras ou um convite para entrar em contato.

Why this priority: As seções Sobre e CTA suportam a construção de confiança e a geração de leads para visitantes que precisam de mais contexto antes de engajar com as listagens. São valiosas, mas não bloqueiam a funcionalidade MVP — a homepage funciona sem elas, embora as taxas de conversão se beneficiem significativamente de sua presença.

Independent Test: Pode ser testado de forma independente rolando a homepage além da seção de imóveis em destaque e verificando que (a) uma seção Sobre com nome e descrição da agência aparece, e (b) uma seção CTA com um convite de contato aparece antes do rodapé.

Acceptance Scenarios:

  1. Given o visitante rola além da seção de imóveis em destaque, when a seção Sobre entra na viewport, then ela exibe o nome da agência e pelo menos um parágrafo de descrição.
  2. Given o visitante continua rolando, when a seção CTA entra na viewport, then ela exibe um convite claro para contato com ao menos um elemento acionável (número de telefone, link de e-mail ou botão "Fale Conosco").
  3. Given a página é rolada até o final, when o visitante chega ao rodapé, then o rodapé exibe as informações de contato da agência (ao mínimo: e-mail ou telefone) e links de navegação (Imóveis, Sobre, Contato).

User Story 4 — Admin Configura o Conteúdo da Homepage (Priority: P1)

Um administrador faz login no painel administrativo e atualiza o headline e subheadline do hero da homepage. O admin também seleciona quais imóveis aparecem na grade em destaque habilitando ou desabilitando o flag "featured" nos imóveis individuais.

Why this priority: A capacidade de atualizar o conteúdo da homepage sem alterações de código é um requisito central do painel SaaS. Sem essa capacidade, a homepage é estática e o painel administrativo não entrega valor para o gerenciamento da homepage.

Independent Test: Pode ser testado de forma independente em dois cenários: (1) atualizar o headline via formulário de configurações da homepage no painel e verificar que a mudança aparece na homepage pública; (2) alternar o flag "featured" de um imóvel e verificar que a grade de destaque é atualizada. Ambas as ações podem ser testadas contra o painel com chamadas reais de API.

Acceptance Scenarios:

  1. Given o admin está autenticado e na página de configurações da homepage, when o admin atualiza o headline e o subheadline e salva, then a homepage pública reflete o novo texto no próximo carregamento sem necessidade de redeploy.
  2. Given o admin navega para a lista de imóveis no painel, when o admin habilita ou desabilita o flag "featured" em um imóvel e salva, then aquele imóvel aparece ou é removido da grade em destaque na homepage pública.
  3. Given o admin tenta salvar a configuração da homepage com headline vazio, when o formulário é submetido, then o sistema rejeita o salvamento e exibe uma mensagem de validação — headline vazio não é permitido.
  4. Given o admin seleciona imóveis em destaque, when mais imóveis que o máximo configurável são marcados como destaque, then o sistema exibe apenas até o limite definido na homepage (padrão: 6), priorizando por data de marcação.

Edge Cases

  • Nenhum imóvel em destaque: Se nenhum imóvel está marcado como featured, a seção deve ser oculta ou exibir "Nenhum imóvel em destaque no momento" — a página não deve lançar erro de renderização.
  • Imóvel sem foto: Se um imóvel em destaque não possui foto, um placeholder genérico é exibido — o card não deve renderizar um elemento de imagem quebrado.
  • Headline muito longo: Se o admin inserir um headline muito longo (120+ caracteres), a seção hero deve adaptar-se sem overflow de texto ou quebra de layout.
  • Estado de carregamento / rede lenta: Enquanto a resposta da API de imóveis em destaque está pendente, a seção deve exibir skeleton loaders — sem flash de conteúdo ou espaço em branco.
  • Subheadline vazio: O subheadline é opcional. Um subheadline vazio deve resultar na renderização do hero sem o elemento subheadline — não uma string vazia visível.
  • API indisponível: Se o endpoint de configuração da homepage ou de imóveis falhar, a página deve renderizar uma versão degradada (conteúdo de fallback estático) em vez de uma tela de erro completa.

Requirements

Functional Requirements

  • FR-001: O sistema DEVE renderizar uma barra de navegação contendo o logotipo da agência e links para as seções/páginas Imóveis, Sobre e Contato.
  • FR-002: A barra de navegação DEVE ser sticky (visível durante a rolagem) em viewports desktop (≥768px).
  • FR-003: A barra de navegação DEVE colapsar para um menu hamburger em viewports abaixo de 768px.
  • FR-004: O sistema DEVE renderizar uma seção hero exibindo um headline, um subheadline opcional, e um botão CTA que navega para a listagem de imóveis.
  • FR-005: O headline e o subheadline do hero DEVEM ser configuráveis por um admin autenticado via painel administrativo sem alterações de código ou redeploy.
  • FR-006: O sistema DEVE renderizar uma seção de Imóveis em Destaque exibindo uma grade de imóveis marcados como "featured" por um admin.
  • FR-007: Cada card de imóvel na grade DEVE exibir: uma foto principal, título do imóvel, preço formatado em R$ (pt-BR), badge de tipo (Venda ou Aluguel), contagem de quartos, contagem de banheiros e área total em m².
  • FR-008: A grade de imóveis em destaque DEVE ser populada dinamicamente via API de backend — a lista NÃO DEVE exigir redeploy para ser atualizada.
  • FR-009: O sistema DEVE limitar a grade em destaque a um número máximo configurável de entradas (padrão: 6, máximo suportado: 12).
  • FR-010: Se nenhum imóvel estiver configurado como destaque, o sistema DEVE tratar esse estado graciosamente sem erros de renderização, ocultando a seção ou exibindo uma mensagem adequada.
  • FR-011: Cards de imóvel DEVEM exibir uma imagem placeholder quando nenhuma foto estiver disponível.
  • FR-012: O sistema DEVE renderizar uma seção Sobre/Empresa contendo ao mínimo o nome da agência e uma descrição breve.
  • FR-013: O sistema DEVE renderizar uma seção Call-to-Action contendo um convite para contato com ao mínimo um elemento acionável.
  • FR-014: O sistema DEVE renderizar um rodapé contendo informações de contato e links de navegação.
  • FR-015: O painel administrativo DEVE fornecer uma interface para selecionar quais imóveis são exibidos na grade em destaque.
  • FR-016: O painel administrativo DEVE rejeitar salvamentos de configuração de homepage com headline vazio, exibindo mensagem de validação ao admin.

Non-Functional Requirements

Performance

  • NFR-001: A homepage DEVE atingir um Largest Contentful Paint (LCP) abaixo de 2,5 segundos em conexão banda larga padrão (>10 Mbps).
  • NFR-002: Os endpoints de API que suprem dados da homepage DEVEM responder em até 500ms sob carga normal (até 100 requisições concorrentes).
  • NFR-003: Imagens de imóveis em destaque DEVEM ser servidas em formato web-otimizado — nenhuma imagem de thumbnail de card deve exceder 300 KB.

Responsiveness

  • NFR-004: A homepage DEVE ser completamente funcional e visualmente íntegra nos seguintes breakpoints: 320px (mobile S), 375px (mobile M), 768px (tablet), 1024px (laptop), 1280px (desktop), 1440px (wide).
  • NFR-005: A grade de imóveis em destaque DEVE se adaptar de 1 coluna em mobile para 2 colunas em tablet e 3 colunas em desktop (≥1024px).
  • NFR-006: A tipografia do hero DEVE escalar responsivamente: 72px em desktop, 48px em tablet, 40px em mobile.

Accessibility

  • NFR-007: Todas as imagens DEVEM ter texto alt descritivo (título do imóvel para fotos de imóveis; descrição para o logotipo).
  • NFR-008: Todos os elementos interativos (links, botões) DEVEM ser navegáveis por teclado e ter estados de foco visíveis.
  • NFR-009: Relações de contraste de cor DEVEM atender aos padrões WCAG 2.1 AA: mínimo 4,5:1 para texto de corpo, 3:1 para texto grande e componentes de UI.
  • NFR-010: A página DEVE usar elementos HTML5 semânticos apropriados e papéis ARIA landmark (<nav>, <main>, <footer>, <header>) em toda a estrutura.

Key Entities

  • HomepageConfig: Representa o conteúdo configurável pelo admin para a homepage. Atributos principais: hero_headline (obrigatório, máx. 120 caracteres), hero_subheadline (opcional, máx. 240 caracteres), hero_cta_label (opcional, máx. 40 caracteres, padrão: "Ver Imóveis"), hero_cta_url (opcional, caminho relativo, padrão: "/imoveis"), featured_properties_limit (inteiro, padrão: 6, máximo: 12).
  • Property: Representa um anúncio imobiliário. Atributos relevantes para a homepage: id (UUID), title (string), type (enum: venda | aluguel), price (decimal), area_m2 (inteiro), bedrooms (inteiro), bathrooms (inteiro), is_featured (boolean), slug (string única). A entidade Property é compartilhada com a feature de listagem de imóveis.
  • PropertyPhoto: Representa uma foto associada a um imóvel. A homepage usa apenas a foto principal (primeira por ordem de display). Atributos: url (string), alt_text (string), display_order (inteiro).

Design Specifications

Toda a especificação visual segue o tema dark inspirado no Linear documentado em DESIGN.md.

Color Application

Element Token Value
Page background Marketing Black #08090a
Navigation background (sticky) Marketing Black semi-transparente rgba(8,9,10,0.85) + backdrop-blur
Hero background (gradiente padrão) Radial brand indigo fade radial-gradient(ellipse at center, rgba(94,106,210,0.08) 0%, #08090a 70%)
Card/container background Level 2 Surface rgba(255,255,255,0.03)
Card border Border Standard 1px solid rgba(255,255,255,0.08)
Card border hover Border Standard brightened 1px solid rgba(255,255,255,0.12)
Primary text Near-white #f7f8f8
Secondary text Silver-gray #d0d6e0
Tertiary text / metadata Muted gray #8a8f98
CTA button background Brand Indigo #5e6ad2
CTA button hover Accent Hover #828fff
Badge tipo Venda Brand Indigo pill rgba(94,106,210,0.15) + borda rgba(94,106,210,0.3)
Badge tipo Aluguel Neutral pill rgba(255,255,255,0.05) + borda rgba(255,255,255,0.1)
Section dividers Line Tint sem divisor visível — espaçamento separa as seções
Footer background Panel Dark #0f1011

Typography Application

Element Style from DESIGN.md Size Weight Letter Spacing
Hero headline (desktop) Display XL 72px 510 -1.584px
Hero headline (tablet) Display 48px 510 -1.056px
Hero headline (mobile) Heading 1 40px 510 -0.704px
Hero subheadline Body Large 18px 400 -0.165px
CTA button label Label 14px 590 normal
Section headings (ex: "Imóveis em Destaque") Display 48px (desktop) / 32px (mobile) 510 -1.056px / -0.704px
Property card title Heading 3 20px 590 -0.24px
Property price Body Semibold 16px 590 normal
Property stats (quartos, banheiros, área) Caption Large 14px 510 -0.182px
Navigation links Link Small 14px 510 -0.182px
Footer links Link Caption 13px 510 -0.13px
About / CTA body text Body 16px 400 normal

Toda a tipografia usa Inter Variable com OpenType features "cv01", "ss03" habilitadas globalmente via font-feature-settings: "cv01", "ss03".

Layout

  • Largura máxima do conteúdo: 1200px, centralizado horizontalmente com margens auto.
  • Hero section: mínimo 100vh de altura, layout de coluna única centralizado, padding: 120px superior / 80px inferior em desktop; 80px / 60px em mobile.
  • Grade de Imóveis em Destaque: 3 colunas em desktop (≥1024px), 2 colunas em tablet (768px1023px), 1 coluna em mobile (<768px). Gap: 24px.
  • Espaçamento vertical entre seções: 80px padding-top e padding-bottom em desktop; 60px em mobile.
  • Border radius dos cards: 12px (Panel radius conforme DESIGN.md).
  • Fotos dos cards: border-radius 12px 12px 0 0 (arredondado só no topo), aspect-ratio 16:9.

Component Notes

  • Navigation bar: fundo rgba(8,9,10,0.85) com backdrop-filter: blur(12px), border-bottom: 1px solid rgba(255,255,255,0.05). Posição: sticky, z-index elevado.
  • Property card: fundo rgba(255,255,255,0.03), borda 1px solid rgba(255,255,255,0.08), radius 12px, com transição de hover aumentando levemente a opacidade do fundo e a borda.
  • CTA button (Primary): Background #5e6ad2, padding 10px 20px, radius 6px, texto branco weight 590. Hover: #828fff.
  • Type badges: pills com radius 9999px, padding 2px 10px, fonte 12px weight 510.

API Contract

Os seguintes endpoints devem ser implementados pelo backend Flask para suportar a homepage.

GET /api/v1/homepage-config

Retorna o conteúdo configurável pelo admin para a seção hero da homepage.

Autenticação: Nenhuma (endpoint público) Cache: As respostas podem ser cacheadas por até 60 segundos (header Cache-Control: public, max-age=60).

Response 200 OK:

{
  "hero": {
    "headline": "Encontre o imóvel dos seus sonhos",
    "subheadline": "Imóveis para comprar e alugar com a melhor assessoria da região.",
    "cta_label": "Ver Imóveis",
    "cta_url": "/imoveis"
  },
  "featured_properties_limit": 6
}

Response 500 Internal Server Error:

{
  "error": "internal_server_error",
  "message": "An unexpected error occurred."
}

Retorna a lista de imóveis marcados como destaque, ordenados por prioridade de exibição.

Autenticação: Nenhuma (endpoint público)

Query Parameters:

Parâmetro Tipo Obrigatório Descrição
featured boolean sim (para este use case) true filtra apenas imóveis em destaque
limit integer não Máximo de resultados. Padrão: valor de featured_properties_limit da config. Máximo: 12.

Response 200 OK:

{
  "properties": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "title": "Apartamento Moderno no Centro",
      "type": "venda",
      "price": 450000.00,
      "price_formatted": "R$ 450.000,00",
      "area_m2": 85,
      "bedrooms": 3,
      "bathrooms": 2,
      "primary_photo_url": "https://cdn.example.com/properties/abc123/main.jpg",
      "primary_photo_alt": "Apartamento Moderno no Centro — foto principal",
      "slug": "apartamento-moderno-no-centro",
      "detail_url": "/imoveis/apartamento-moderno-no-centro"
    }
  ],
  "total": 4
}

Response 400 Bad Request (parâmetros inválidos):

{
  "error": "invalid_parameter",
  "message": "Parameter 'limit' must be an integer between 1 and 12."
}

Response 500 Internal Server Error:

{
  "error": "internal_server_error",
  "message": "An unexpected error occurred."
}

PUT /api/v1/admin/homepage-config

Atualiza a configuração da homepage. Reservado para o painel administrativo (autenticação de admin obrigatória).

Autenticação: Bearer token (JWT), role admin obrigatória. Nota: Este endpoint é referenciado para completude do contrato; sua especificação completa (autenticação, sessões, permissões) é definida na feature spec do Admin Panel.

Request Body:

{
  "hero": {
    "headline": "string (obrigatório, máx. 120 caracteres)",
    "subheadline": "string (opcional, máx. 240 caracteres)",
    "cta_label": "string (opcional, máx. 40 caracteres)",
    "cta_url": "string (opcional, caminho relativo válido)"
  },
  "featured_properties_limit": "integer (opcional, 112)"
}

Response 200 OK: Retorna o objeto HomepageConfig atualizado com o mesmo schema de GET /api/v1/homepage-config.

Response 400 Bad Request (validação falhou):

{
  "error": "validation_error",
  "fields": {
    "hero.headline": "This field is required and cannot be empty."
  }
}

Response 401 Unauthorized / 403 Forbidden: Retornado quando o token está ausente, expirado ou sem a role admin.


Habilita ou desabilita o flag de destaque de um imóvel específico.

Autenticação: Bearer token (JWT), role admin obrigatória. Nota: Endpoint referenciado para completude. Especificação completa na feature spec de gerenciamento de imóveis do Admin Panel.

Request Body:

{
  "is_featured": true
}

Response 200 OK:

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "is_featured": true
}

Out of Scope

Os itens a seguir estão explicitamente excluídos desta especificação de feature e serão tratados em specs separadas:

  • Página de detalhe do imóvel: Clicar em um card de imóvel navega para a URL de detalhe, mas o layout, conteúdo e API da página de detalhe são uma feature separada.
  • Busca e filtros de imóveis: A funcionalidade de busca (filtrar por faixa de preço, localização, tipo, quartos, etc.) é uma feature separada. O botão CTA do hero linka para a listagem; qualquer interface de busca na homepage está fora de escopo.
  • Autenticação e UI do Painel Administrativo: O fluxo de login do admin, layout do painel, navegação e gerenciamento de sessão são features separadas. Esta spec define apenas a view pública da homepage e o contrato de API que o painel consumirá.
  • Página de Listagem de Imóveis: A listagem completa em /imoveis com paginação, filtros e ordenação é uma feature separada.
  • Backend de Formulário de Contato: O processamento de submissão de formulário de contato, entrega de e-mail e armazenamento de leads são features separadas. O CTA da homepage pode linkar para uma página de contato ou fornecer e-mail/telefone estático.
  • Suporte multi-idioma (i18n): Português (pt-BR) é o único idioma suportado. Internacionalização está fora de escopo.
  • SEO / Meta Tags avançadas: Open Graph tags, dados estruturados (JSON-LD para RealEstateListing) e geração de sitemap são concerns separados.
  • Integração de Analytics: Eventos de rastreamento (GA4, Hotjar, etc.) estão fora de escopo para esta feature.
  • Conteúdo editável via admin das seções Sobre e Rodapé: Na versão inicial, o conteúdo das seções Sobre, CTA e Rodapé é estático. Uma spec futura pode adicionar gerenciamento dessas seções pelo admin.

Success Criteria

Measurable Outcomes

  • SC-001: Um visitante pode chegar à homepage e clicar para ver um imóvel em destaque em menos de 30 segundos sem nenhuma orientação — taxa de conclusão da tarefa primária ≥ 90% em testes de usabilidade.
  • SC-002: A homepage carrega e exibe o conteúdo acima da dobra (hero + navegação) em até 2,5 segundos em conexão banda larga padrão.
  • SC-003: Um admin pode atualizar o headline do hero e vê-lo refletido na homepage pública em até 60 segundos, sem intervenção de desenvolvedor.
  • SC-004: Um admin pode alterar quais imóveis estão em destaque e ver a grade da homepage ser atualizada em até 60 segundos, sem redeploy.
  • SC-005: A homepage renderiza sem regressões visuais em todos os 6 breakpoints definidos (320px, 375px, 768px, 1024px, 1280px, 1440px).
  • SC-006: Todos os requisitos de contraste de cor WCAG 2.1 AA são atendidos em toda a homepage — verificado por auditoria de acessibilidade automatizada com zero violações críticas.
  • SC-007: A seção de imóveis em destaque renderiza corretamente com 0, 1 ou 6 imóveis marcados como featured — sem erros de JavaScript ou layouts quebrados em nenhum desses estados.

Assumptions

  • A agência opera exclusivamente no Brasil; toda formatação de moeda usa o locale pt-BR (prefixo R$, ponto como separador de milhar, vírgula como separador decimal).
  • A homepage é renderizada como React SPA com client-side data fetching; esta spec não prescreve a estratégia de renderização (CSR/SSR/SSG).
  • O sistema de autenticação do painel admin (login, sessão, JWT) é implementado como feature separada e é um pré-requisito para a User Story 4 (Admin Configura Conteúdo).
  • Fotos de imóveis são armazenadas externamente (object storage / CDN) e referenciadas por URL na resposta da API. A homepage não realiza upload de arquivos.
  • O conteúdo das seções Sobre e CTA (descrição da agência, informações de contato) é considerado estático para a versão inicial e não requer configurabilidade via admin nesta spec.
  • O conteúdo do rodapé (links e informações de contato) é HTML estático para a versão inicial.
  • O número máximo de imóveis em destaque exibidos na homepage tem padrão 6, configurável pelo admin até no máximo 12.
  • Links de cards de imóveis apontam para /imoveis/{slug} mesmo que a página de detalhe ainda não esteja implementada. Links temporariamente quebrados são aceitáveis durante o desenvolvimento em fases.
  • A fonte Inter Variable é carregada via fonte auto-hospedada ou CDN com OpenType features "cv01", "ss03" habilitadas globalmente via font-feature-settings.
  • O painel admin está hospedado na mesma origem ou com CORS configurado adequadamente para os endpoints /api/v1/admin/*.