# Diseño: fechas aproximadas de subida vía discovery (approximate_date) Fecha: 2026-08-22 Estado: aprobado en conversación ## Problema La tabla de vídeos no muestra fecha de subida para la mayoría de filas: el discovery flat de yt-dlp no trae `upload_date` (verificado en el proyecto), y la fecha exacta solo se aprende al extraer cada vídeo (2 peticiones/vídeo). Hoy la UI muestra `~fecha-inferida` derivada del rank del canal. Hallazgo verificado con yt-dlp 2026.07.04 instalado: `extractor_args: {"youtubetab": {"approximate_date": ["true"]}}` hace que los entries flat traigan `timestamp` parseado del texto relativo que YouTube ya incluye en el listado ("hace 3 semanas"). **Costo: cero peticiones extra**; viaja en las mismas respuestas del discovery. Precisión: día para recientes, más gruesa para antiguos. ## Alcance elegido Solo el flag gratis. Sin RSS, sin extracción masiva (descartadas por costo o valor marginal). El backlog se llena con un **Full rescan** por canal usando los mismos requests de siempre. ## Decisiones ### Datos: misma columna + bandera Nueva columna `videos.upload_date_approx INTEGER DEFAULT 0` vía `_VIDEO_COLUMNS`. La fecha aproximada vive en `upload_date` normal: `SORT_DATE_SQL`, orden y consumidores existentes la aprovechan sin cambios. La bandera preserva la distinción aprox/real. Matriz de `upsert_videos` (reemplaza el `COALESCE` simple en `upload_date`): | En DB \ Entra | Aproximada | Real | |---|---|---| | NULL | escribe, flag=1 | escribe, flag=0 | | Aproximada | re-escribe estimación fresca, flag=1 | escribe real, flag=0 | | Real | conserva real, flag=0 | conserva | Upgrade approx→real: `set_upload_date()` hoy solo escribe si `upload_date IS NULL`; pasa a escribir también cuando `upload_date_approx = 1` (y apaga la bandera). Ahí entra la fecha real de la extracción. ### Discovery: timestamp → YYYYMMDD Los entries flat traen `timestamp` (epoch), no `upload_date`. Nuevo helper puro `_entry_upload_date(entry) -> tuple[str | None, int]` en `discover.py`: prefiere `upload_date` crudo (flag 0); si no, deriva de `timestamp` UTC a `YYYYMMDD` (flag 1). Los dos constructores de `VideoRef` lo usan. `deep_channel_avatar` no lo necesita (limit=1, solo avatar). Extractor arg siempre activo en `discover_channel`; sin knob de config. ### UI - API: `_video_dict` expone `upload_date_approx` y `date_estimated` pasa a ser `inferida-por-rank OR bandera-aprox`. - Tabla: fecha con `~` cuando `upload_date` viene aproximada; tooltip explica el origen ("YouTube lo muestra relativo"); tooltip previo de rank-inference queda para el caso sin fecha alguna. ### No afectado `.md` filenames (se renderizan tras extracción, con fecha real), `channel_seq`/maquinaria de inferencia (queda como red), economía de peticiones (0 extra). ## Testing Tests nuevos sobre `Store(tmp_path)` sintético: matriz de upsert (4 casos) + upgrade approx→real vía `set_upload_date`; unit del helper de conversión con entries fake. Migración idempotente queda cubierta por los tests existentes del Store. Suite completa debe seguir verde.