chore(issues): auto-commit
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
---
|
||||
id: 0079
|
||||
title: tables playground — drill-through extendido (fase 10)
|
||||
status: pending
|
||||
priority: medium
|
||||
created: 2026-05-12
|
||||
related_components: [cpp/apps/primitives_gallery/playground/tables]
|
||||
---
|
||||
|
||||
## Contexto
|
||||
|
||||
Fase 10 del roadmap del tables playground. Drill-down basico ya implementado
|
||||
(`make_drill_filter` + chip de filtro en stage previo). Falta granularidad de
|
||||
zoom, presets rapidos, click sobre elementos del chart, historial de drill y
|
||||
row inspector.
|
||||
|
||||
## Cambios
|
||||
|
||||
### 1. Zoom granularity sobre cols Date
|
||||
|
||||
- Detectar col tipo `Date` en breakout.
|
||||
- Combo en chip de breakout: "year / month / week / day / hour".
|
||||
- Pure fn `truncate_date_cpp_core(date_str, granularity) -> string`.
|
||||
- Stage 1 con breakout `<col>:month` agrega valores formateados al granular.
|
||||
- TQL: `breakout = {"col:month"}` (sufijo despues de `:`).
|
||||
- Auto-detect granularity inicial: si rango > 2 anios -> year; > 60 dias -> month; > 14 dias -> week; resto -> day.
|
||||
|
||||
### 2. Quick filter presets
|
||||
|
||||
- Boton "Presets" en chip row de filtros.
|
||||
- Menu con:
|
||||
- "Top 10 by <col>" (auto-sugiere col numerica)
|
||||
- "Last 7 / 30 / 90 dias" (si hay col Date)
|
||||
- "Exclude nulls in <col>"
|
||||
- "Non-zero only"
|
||||
- Aplica como filtros al stage activo.
|
||||
|
||||
### 3. Click-to-drill sobre chart elements
|
||||
|
||||
- Bar/Column/Pie/Funnel: click en elemento -> `make_drill_filter(col_idx, value)` -> push filter en stage previo, `active_stage--`.
|
||||
- Scatter/Bubble: click en punto -> filter por X y Y rangos cercanos (snap to nearest data point) o muestra row inspector.
|
||||
- Heatmap: click en celda -> filtro por par (row, col).
|
||||
- ImPlot api: `ImPlot::IsPlotHovered() + GetPlotMousePos()`. Hit-test propio para barras.
|
||||
|
||||
### 4. Drill history (back/forward)
|
||||
|
||||
- Pila de `DrillStep { stage_idx, filter_added }` en `UiState.drill_history`.
|
||||
- Botones `<` `>` en breadcrumb para back/forward.
|
||||
- TQL preserva el stage agrupado pero no la history (es UI state efimero).
|
||||
|
||||
### 5. Row inspector
|
||||
|
||||
- Click derecho sobre row de tabla o punto de chart -> popup modal con todas las cols + valores de la fila.
|
||||
- Incluye cols ocultas.
|
||||
- Solo lectura. Boton "Copy as TSV" + "Filter by this row".
|
||||
|
||||
### 6. Drill-up: vuelve un stage atras sin perder filtros nuevos
|
||||
|
||||
- Boton `<` en breadcrumb del stage previo: pushdown del filter actual al stage anterior + active--.
|
||||
- Inverso de drill-down. Usuario navega la jerarquia sin perder camino.
|
||||
|
||||
## Tests
|
||||
|
||||
- `truncate_date_cpp_core` para granularities (round-trip por fecha conocida).
|
||||
- Pure fn de quick filter presets (build `vector<Filter>` desde preset id).
|
||||
- Round-trip TQL con breakout sufijo `:month`.
|
||||
|
||||
## No-objetivos
|
||||
|
||||
- Map drill (lat/lng -> region) — fuera de scope.
|
||||
- Cross-filter entre paneles (click en panel A filtra panel B) — fase futura.
|
||||
@@ -0,0 +1,77 @@
|
||||
---
|
||||
id: 0080
|
||||
title: tables playground — LLM API "Ask AI" (fase 11)
|
||||
status: pending
|
||||
priority: medium
|
||||
created: 2026-05-12
|
||||
related_components: [cpp/apps/primitives_gallery/playground/tables]
|
||||
---
|
||||
|
||||
## Contexto
|
||||
|
||||
Fase 11 del roadmap del tables playground. El user escribe en lenguaje natural
|
||||
una pregunta sobre los datos ("show me top 10 langs by total size"). El LLM
|
||||
recibe el TQL actual + schema + pregunta, devuelve nuevo TQL. App aplica via
|
||||
`tql::apply` y renderiza.
|
||||
|
||||
## Cambios
|
||||
|
||||
### 1. UI
|
||||
|
||||
- Boton "Ask AI" en toolbar (al lado de "+ Viz").
|
||||
- Modal con:
|
||||
- InputText multiline para la pregunta.
|
||||
- Boton "Send" + spinner durante la llamada.
|
||||
- Diff side-by-side: TQL actual vs TQL propuesto (texto con highlight).
|
||||
- Botones "Apply" / "Reject" / "Edit before apply".
|
||||
|
||||
### 2. Backend LLM
|
||||
|
||||
- Provider: Anthropic Claude (API key desde `pass anthropic/api-key`).
|
||||
- Endpoint: `https://api.anthropic.com/v1/messages`.
|
||||
- Model: `claude-sonnet-4-6` por defecto. Configurable via env `FN_LLM_MODEL`.
|
||||
- Cliente HTTP: cURL via popen (sin deps nuevas) o libcurl si ya esta linkada.
|
||||
- Prompt template incluye:
|
||||
- Esquema TQL (de `docs/TQL.md`).
|
||||
- Cols disponibles del stage 0 (name, type) + cols joinables.
|
||||
- Funciones Lua disponibles (de `lua_engine`).
|
||||
- TQL actual.
|
||||
- Pregunta del user.
|
||||
- Response: extraer ```lua``` block del markdown, strip prose.
|
||||
|
||||
### 3. Validacion + safety
|
||||
|
||||
- Antes de aplicar: `tql::apply` con dry-run (parsea sin mutar State). Si fail, mostrar error + boton "Ask AI again with this error".
|
||||
- Lua sandbox ya cubre side effects en formulas — el TQL en si es declarativo, no ejecuta nada peligroso.
|
||||
|
||||
### 4. Streaming
|
||||
|
||||
- Stream tokens via SSE (`stream=true` en Anthropic API).
|
||||
- Mostrar texto en vivo en el modal.
|
||||
- Cuando termina, parsear lua block final.
|
||||
|
||||
### 5. Persistencia conversation
|
||||
|
||||
- UiState guarda lista de turns (pregunta + TQL propuesto + resultado apply).
|
||||
- "Ask AI" siguiente turn incluye history previa.
|
||||
- Boton "Reset chat" limpia.
|
||||
- NO persistido en TQL (es UI state).
|
||||
|
||||
### 6. Coste / rate limit
|
||||
|
||||
- Mostrar tokens estimados antes de enviar (rough char count / 4).
|
||||
- Cap input a 8000 tokens.
|
||||
- Error handling: 429 / 5xx -> mensaje + reintentar.
|
||||
|
||||
## Tests
|
||||
|
||||
- Mockear HTTP response con cURL stub.
|
||||
- Test: prompt build incluye schema + TQL + pregunta en formato esperado.
|
||||
- Test: response parse extrae lua block correctamente.
|
||||
- Test: tql::apply sobre output del LLM funciona end-to-end con dataset sintetico.
|
||||
|
||||
## No-objetivos
|
||||
|
||||
- Generacion de visualizaciones nuevas via LLM (la viz la elige TQL `display`, suficiente).
|
||||
- Acciones del LLM mas alla de modificar TQL (sin acceso a I/O del sistema).
|
||||
- Multi-provider (OpenAI / local) — fase futura. Hardcode Anthropic primero.
|
||||
@@ -0,0 +1,118 @@
|
||||
---
|
||||
id: 0081
|
||||
title: tables playground — promote a registry + migrar apps C++ (fase 12)
|
||||
status: pending
|
||||
priority: high
|
||||
created: 2026-05-12
|
||||
related_components: [cpp/apps/primitives_gallery/playground/tables, cpp/functions, fn_framework]
|
||||
---
|
||||
|
||||
## Contexto
|
||||
|
||||
Fase 12 final del roadmap. Extraer el playground completo al registry como
|
||||
funciones reutilizables. Migrar todas las apps C++ que renderizan tablas para
|
||||
que usen `data_table_cpp_viz` en vez de codigo propio.
|
||||
|
||||
## Extraccion al registry
|
||||
|
||||
### Funciones a crear
|
||||
|
||||
| ID | Lang | Domain | Purity | Que hace |
|
||||
|-------------------------------|------|----------|--------|----------|
|
||||
| `data_table_cpp_viz` | cpp | viz | impure | UI completa: chips + tabla + viz + extras + joins + TQL |
|
||||
| `compute_stage_cpp_core` | cpp | core | pure | Ejecuta un Stage (filter+breakout+agg+sort) |
|
||||
| `compute_pipeline_cpp_core` | cpp | core | pure | Chain de stages 0..N -> StageOutput final |
|
||||
| `tql_emit_cpp_core` | cpp | core | pure | State -> Lua text |
|
||||
| `tql_apply_cpp_core` | cpp | core | pure | Lua text -> State (+ warnings) |
|
||||
| `viz_render_cpp_viz` | cpp | viz | impure | Dispatcher ImPlot sobre StageOutput |
|
||||
| `lua_engine_cpp_core` | cpp | core | impure | Eval de formulas Lua sandboxed |
|
||||
| `join_tables_cpp_core` | cpp | core | pure | Hash join multi-key, 4 estrategias |
|
||||
| `auto_detect_type_cpp_core` | cpp | core | pure | Auto-detect ColumnType desde sample (ya existe en logic) |
|
||||
| `compute_column_stats_cpp_core` | cpp | core | pure | Stats por col (mean/p25/p50/p75/uniq/missing/hist) |
|
||||
|
||||
### Tipos
|
||||
|
||||
| ID | Algebraic |
|
||||
|-----------------------------|-----------|
|
||||
| `ColumnType_cpp_core` | sum |
|
||||
| `Op_cpp_core` | sum |
|
||||
| `Filter_cpp_core` | product |
|
||||
| `Stage_cpp_core` | product |
|
||||
| `StageOutput_cpp_core` | product |
|
||||
| `Aggregation_cpp_core` | product |
|
||||
| `Join_cpp_core` | product |
|
||||
| `TableInput_cpp_core` | product |
|
||||
| `ViewMode_cpp_viz` | sum |
|
||||
| `ViewConfig_cpp_viz` | product |
|
||||
| `VizPanel_cpp_viz` | product |
|
||||
| `State_cpp_viz` | product |
|
||||
| `ColStats_cpp_core` | product |
|
||||
|
||||
### Estructura en el registry
|
||||
|
||||
```
|
||||
cpp/functions/core/
|
||||
compute_stage.{h,cpp,md}
|
||||
compute_pipeline.{h,cpp,md}
|
||||
tql_emit.{h,cpp,md}
|
||||
tql_apply.{h,cpp,md}
|
||||
lua_engine.{h,cpp,md}
|
||||
join_tables.{h,cpp,md}
|
||||
data_table_logic.h # tipos compartidos (Stage, ColumnType, etc.)
|
||||
...
|
||||
cpp/functions/viz/
|
||||
data_table.{h,cpp,md} # UI principal
|
||||
viz_render.{h,cpp,md} # dispatcher ImPlot
|
||||
```
|
||||
|
||||
Dominio nuevo `viz` para funciones de visualizacion. Alternativa: usar `tui`
|
||||
si encaja, pero `viz` es mas explicito.
|
||||
|
||||
### Bundle en `fn_framework`
|
||||
|
||||
`fn_framework` ya bundle a `lua54`, `implot`. Añadir las funciones core/viz
|
||||
como parte del lib estatico opcional `fn_table_viz` que las apps linkan via
|
||||
`target_link_libraries(<app> PRIVATE fn_table_viz)`.
|
||||
|
||||
## Migracion de apps existentes
|
||||
|
||||
Apps con tabla custom hoy:
|
||||
|
||||
| App | Cambios |
|
||||
|----------------------------------------------|---------|
|
||||
| `cpp/apps/chart_demo` | Sustituir tabla por `data_table::render({tables}, state)`. Persistir State en SQLite local. |
|
||||
| `projects/osint_graph/apps/graph_explorer` | Reemplaza panels que listan entities/relations con render(). Pasa multiples TableInput (entities, relations, jobs). |
|
||||
| `projects/fn_monitoring/apps/registry_dashboard` | Tablas de funciones/types/apps via render. Joinables: cross-references entre tablas. |
|
||||
| `projects/fn_monitoring/apps/sqlite_api` | Resultado de query como TableInput. |
|
||||
| `apps/kanban` | NO migrar — kanban no es tabla, es board. |
|
||||
| `apps/deploy_server` | Tabla de deploys + targets. |
|
||||
|
||||
Cada migracion en su rama TBD propia (ver `apps_tbd.md`).
|
||||
|
||||
## TQL como contrato textual
|
||||
|
||||
Documento `docs/TQL.md` ya existe pero hay que actualizar:
|
||||
- Anadir `joins`, `views`, `main_source` (faltan)
|
||||
- Listado completo de viz tokens
|
||||
- Funciones Lua disponibles + sandbox
|
||||
|
||||
## Tests
|
||||
|
||||
- `compute_stage/pipeline` ya tienen tests en playground self_test. Mover a `cpp/functions/core/*_test.cpp`.
|
||||
- Smoke test: app fake con TableInput hardcoded -> render() compila + tests basicos pasan.
|
||||
- `fn run` debe poder ejecutar tests de las nuevas funciones.
|
||||
|
||||
## Doctor
|
||||
|
||||
`fn doctor cpp-apps` añadir check: apps con tablas custom (heuristica: `ImGui::BeginTable` en main.cpp) sugieren migracion a `data_table_cpp_viz`.
|
||||
|
||||
## Riesgos
|
||||
|
||||
- Linker bloat: cada app que use `data_table_cpp_viz` arrastra lua54 (~150KB) + implot (~200KB). Aceptable.
|
||||
- API stability: una vez en registry hay que mantener `render()` signature. Cualquier breaking change requiere proposal.
|
||||
- Tests duplicados: borrar self_test.cpp del playground si los tests se mueven al registry.
|
||||
|
||||
## No-objetivos
|
||||
|
||||
- Migrar a otras tecnologias (web, mobile) — fase futura via TS/Kotlin equivalentes.
|
||||
- Reescribir apps que no usen tablas — fuera de scope.
|
||||
Reference in New Issue
Block a user