2.8 KiB
Research: Vídeo de Apresentação do Imóvel (033)
Gerado por: /speckit.plan
Data: 2026-04-22
Decisão 1 — Estratégia de embed de vídeo
Decision: Utilitário puro getEmbedUrl no frontend (sem lógica no backend) que faz parse client-side.
Rationale: O backend não precisa transformar URLs — salva o valor bruto e devolve sem alteração. O parse pode falhar silenciosamente no cliente sem impactar dados. Reduz complexidade no servidor.
Alternatives considered: Validar domínio no backend via Pydantic @field_validator — rejeitado porque geraria 422 em URLs válidas de domínios futuros; validação de formato basta no backend.
Decisão 2 — Posição do vídeo: VARCHAR(20) vs ENUM SQL
Decision: VARCHAR(20) NOT NULL DEFAULT 'section' — sem ENUM SQL.
Rationale: O projeto já usa db.Enum apenas para property_type onde os valores são críticos para queries. Para posição de vídeo, a validação é feita no Pydantic (Literal['carousel', 'section']); usar ENUM SQL adicionaria complexidade em migrations sem benefício mensurável.
Alternatives considered: db.Enum('carousel', 'section', name='video_position') — rejeitado por custo de migration mais alto.
Decisão 3 — Integração do vídeo no carrossel vs componente separado
Decision: Modificar PhotoCarousel para aceitar videoUrl?: string | null e renderizar o VideoPlayer como slide virtual no índice 0 quando a posição for carousel. Para posição section, renderizar <VideoPlayer> fora do carrossel em PropertyDetailPage.
Rationale: Reuso do sistema de navegação (setas, dots, touch swipe) já testado no carrossel. Não cria um segundo carrossel, não duplica lógica de gestos.
Alternatives considered: Criar carrossel separado MediaCarousel — rejeitado por YAGNI (sobrecomplexidade para suportar um único slide de vídeo).
Decisão 4 — Sanitização de URL no backend
Decision: Aplicar str.strip() antes de persistir e tratar string vazia como None.
Rationale: Previne persistência de URLs com espaços acidentais (edge case da spec). Simples de implementar no update handler existente, sem dependência externa.
Alternatives considered: Pydantic AnyUrl — rejeitado porque URLs de arquivos diretos (ex.: CDN sem https://) precisam ser aceitas; AnyUrl restringiria demais.
Decisão 5 — Preview no admin (debounce)
Decision: Debounce de 600ms no campo de URL; o preview re-renderiza apenas quando getEmbedUrl retorna tipo != 'unknown'.
Rationale: Evita re-renders a cada keystroke enquanto o administrador digita. Valor de 600ms é suficiente para não parecer lento.
Alternatives considered: Preview apenas on-blur — rejeitado porque a spec exige "em tempo real" (FR-011).