---
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`.
