--- id: "0107d" title: "Sacar lua_engine/llm_anthropic/join_tables/auto_detect_type del modulo data_table — politica de tiers" status: pendiente type: refactor domain: - cpp-stack - meta scope: module priority: alta depends: - "0107c" blocks: [] related: - "0107" created: 2026-05-17 updated: 2026-05-17 tags: [modules, data-table, policy, tiers, lua, llm] --- # 0107d — Politica members generales + tiers Parte del issue principal [0107](0107-modules-standardization.md). ## Problema `data_table` module hoy lleva como miembros `lua_engine`, `llm_anthropic`, `join_tables`, `auto_detect_type`. Esos 4 son **utiles fuera de tablas**: - `lua_engine`: scripting general. - `llm_anthropic`: LLM wrapper, util en chat_ia (proximo modulo) y otros. - `join_tables`: util en cualquier app que combine tablas (no solo data_table::render). - `auto_detect_type`: util en data import generico. Forzar membership infla el modulo y obliga a las apps a tragarse 4 deps pesadas (lua + curl + libllm + http) aunque solo quieran render basico. ## Decision Politica de tiers: ```yaml # module.md (post-0107d) members: # core_members: esenciales, sin ellos no hay funcionalidad - data_table_chips_cpp_viz - data_table_grid_cpp_viz - data_table_drill_cpp_viz - data_table_color_rules_cpp_viz - data_table_viz_panels_cpp_viz - compute_stage_cpp_core - compute_pipeline_cpp_core - compute_column_stats_cpp_core - tql_emit_cpp_core - tql_helpers_cpp_core - tql_apply_cpp_core - tql_to_sql_cpp_core - viz_render_cpp_viz uses_functions: # Deps externas usadas por el modulo (no son miembros del modulo) - lua_engine_cpp_core # TQL scripting (opt-in via feature flag interno) - llm_anthropic_cpp_core # Ask AI panel (opt-in via FN_LLM_ANTHROPIC) - join_tables_cpp_core # Joins - auto_detect_type_cpp_core # Detect tipos al cargar nueva tabla ``` Distincion: - **`members`**: funciones que el modulo POSEE — viven en `cpp/functions/viz/` y nadie mas las usa directamente (renderizan dentro del modulo). - **`uses_functions`**: funciones que el modulo CONSUME — viven en `cpp/functions/core/`, son utiles fuera del modulo, otras apps pueden importarlas directamente. Apps consumidoras de `data_table`: - Si solo llaman `data_table::render(...)` → solo `uses_modules: [data_table_cpp]`, nada mas. - Si ademas usan `lua_engine` directamente para sus propios scripts → anaden `lua_engine_cpp_core` a `uses_functions` (no es duplicado, es uso directo independiente). ## Tareas - [ ] **4.1** Editar `modules/data_table/module.md`: separar `members` core de `uses_functions`. Bump version 2.1.0. - [ ] **4.2** Editar `modules/data_table/CMakeLists.txt`: `lua_engine.cpp`, `llm_anthropic.cpp`, `join_tables.cpp`, `auto_detect_type.cpp` quedan dentro de la static lib (el modulo los usa internamente), pero el linkage transitivo se controla via PUBLIC vs PRIVATE. Si una app NO usa directamente lua/llm fuera del modulo, igual los recibe pero solo como impl detail del modulo. Decidir: SI mantenemos lua/llm/join dentro de la static lib del modulo (PUBLIC link) o sacamos al app para que cada una decida (PRIVATE en modulo, app linkea por su lado). - [ ] **4.3** Documentar tier en `docs/MODULES_API.md` (0107f). - [ ] **4.4** `fn doctor modules` (0107a) entiende la distincion members vs uses_functions y NO marca drift cuando una app lista en `uses_functions` algo que el modulo declara en su `uses_functions` (no es miembro). - [ ] **4.5** Actualizar 7 app.md: si un app necesita lua/llm/join standalone, declararlo. Si no, no. ## Decisiones de diseno **Decision 4.2 detallada:** mantener lua/llm/join dentro de `fn_module_data_table` static lib (PUBLIC), porque: - 100% de las apps que linkean `fn_module_data_table` hoy lo usan para tablas, que usan internamente lua/llm/join. - Cero apps quieren un "data_table ligero sin lua". Si llegara ese caso → split modulo en `data_table_core` + `data_table_full`. Mientras tanto, KISS. - La distincion `members` vs `uses_functions` queda solo en `module.md` (metadata) — el CMakeLists agrupa todo bajo la static lib. ## Riesgos - Ambiguedad "¿el modulo posee X o lo usa?": resolver via 1 regla simple — si `X` aparece como funcion suelta consumida por otras apps fuera del modulo, va a `uses_functions`. Si nadie mas la usa, es `member`.