44 lines
2.8 KiB
Markdown
44 lines
2.8 KiB
Markdown
# 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).
|