Commit Graph

4 Commits

Author SHA1 Message Date
sergio d9e21fbedc feat(tahuantinsuyu): fase 12 — Control::ChartPicker para Synastry
Cualquier carta del DB se puede elegir como partner de sinastría
(no solo hermanas del contacto actual). El módulo SynastryModule
declara un Control::ChartPicker; el panel renderea un dropdown que
abre un popup con todas las cartas; el shell inyecta las opciones y
resuelve el partner desde la selección persistida.

- modules: nueva variante Control::ChartPicker { key, label } sin
  default — las opciones las inyecta el host. SynastryModule.controls()
  agrega un picker con key="partner_chart_id".
- store: list_all_charts() — query sin filtros, ordenada por label
  case-insensitive. Pensada para selectores cross-contact.
- panel:
  - ChartOption struct público (id + label).
  - chart_options Vec + chart_picker_value HashMap + chart_picker_open
    Option (solo uno abierto a la vez).
  - APIs públicas set_chart_options / set_chart_picker para sync.
  - set_active_kind inicializa picker_value a None ("automático").
  - render_chart_picker: botón "▾ label" en bg_button; al click toggle
    un popup absolute con (automático) + separador + cada chart_option
    clickable. select_picker emite ControlChanged con Value::String(id)
    o Value::Null.
- shell:
  - new() llama refresh_chart_options al final para popular el panel
    desde el boot.
  - refresh_chart_options() builds Vec<ChartOption> desde
    list_all_charts (label + birth_brief "YYYY-MM-DD · Lugar"). Lo
    llamamos también desde TreeEvent::HierarchyChanged para que el
    dropdown refleje altas/bajas.
  - resolve_synastry_partner reemplaza find_synastry_partner: 1) lee
    module_configs["synastry"]["partner_chart_id"] y resuelve el chart;
    2) fallback al automático (primera hermana). El fallback significa
    que el módulo sigue funcionando sin elegir manualmente.
  - sync_panel_from_configs ahora maneja Value::String / Value::Null
    → set_chart_picker, así el picker se restaura al cargar una carta.

Persistencia: el partner_chart_id va al config_json (fase 11), así
que cada carta recuerda con quién hizo sinastría la última vez.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 11:17:35 +00:00
sergio 22e6ed6a71 feat(tahuantinsuyu): fase 11 — persistencia de module_configs por carta
Los toggles, sliders y partner pickers de cada overlay (transit,
progression, solar_arc, synastry) ahora persisten por carta en la
tabla SQLite `module_state` (que estaba creada desde fase 1 pero
sin cablear). Cambiar de carta y volver mantiene exactamente el
estado que el usuario dejó.

- shell:
  - apply_selection(Chart): tras setear defaults (target_age_years =
    edad actual), llama load_persisted_module_states(chart.id) que
    mergea sobre los defaults los valores guardados. Luego
    sync_panel_from_configs empuja todos los toggles/sliders al
    panel para reflejar el estado restaurado. Render al final.
  - load_persisted_module_states: lee list_module_states(chart_id),
    reconstruye el JSON combinado (mergea `enabled` de la columna
    SQL en el config), y lo mergea sobre lo que ya hay en
    module_configs. Vacant entries se insertan tal cual; occupied
    se patchean field-a-field para no perder defaults no guardados.
  - sync_panel_from_configs: itera module_configs, push toggle/slider
    al panel por cada key Bool/f64.
  - persist_module(module_id): extrae enabled del JSON, deja resto en
    config_json, llama upsert_module_state. Invocada desde
    on_panel_event "else" tras cada update + desde on_canvas_event
    para [T] + tras auto-disable del conflicting module en mutual
    exclusion.
- store: nuevo test module_state_roundtrip que cubre upsert/list +
  cambio de enabled vía upsert (UPSERT clause de fase 1 vuelve a
  validarse).

Flujo de usuario: ajustás el slider de progresión a 42.5 años,
activás synastry, cambiás de carta, volvés — todo está como lo
dejaste. La DB persiste por chart_id, así que distintos sujetos
mantienen estados independientes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 11:11:29 +00:00
sergio bcb92b537e feat(tahuantinsuyu): fase 2 — CRUD UX sobre el tree (menú, modales, form natal)
Right-click sobre el explorador izquierdo abre menú contextual cuyas
opciones dependen del target (raíz, group, contact o chart). Modales
flotantes para crear/renombrar usando yahweh-widget-text-input; un
form más completo de 11 campos para la birth data al crear cartas
natales. Borrar pide confirmación por window.prompt nativo.

- tahuantinsuyu-store: rename_contact, rename_chart, move_group,
  move_contact (los `move_*` para fase posterior de drag-to-nest).
- tahuantinsuyu-tree: estado interno (Menu, Modal enum, ChartForm),
  handlers de ContextMenuRequested, render overlays.
  Soporta seis modales: rename de g/c/h, create group/contact, form
  natal completo con parseo + reporte de errores inline.
  Auto-expande el contact tras crear una carta.
  Nuevo evento TreeEvent::HierarchyChanged tras cada mutación.
- shell: maneja HierarchyChanged sin propagar selección.

`cargo check` y `cargo test` verdes. Fase 3 viene con engine real
contra eternal-astrology + pintado de la rueda.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 01:13:17 +00:00
sergio c48638fe87 feat(tahuantinsuyu): scaffolding del estudio astrológico (10 crates + ventana 3-panes)
Módulo nuevo `modules/tahuantinsuyu/` con 9 crates reusables + app
`apps/tahuantinsuyu` ejecutable que abre la ventana del explorador y
coordina los widgets:

- tahuantinsuyu-card: Card Brahman + spawn_sidecar (flows
  chart-request/chart-result).
- tahuantinsuyu-model: tipos agnósticos (Group/Contact/Chart,
  StoredBirthData, StoredChartConfig, ChartKind, TreeSelection).
- tahuantinsuyu-store: persistencia SQLite (rusqlite) con migración v1,
  CRUD por entidad y descenso recursivo `charts_under_group`.
- tahuantinsuyu-engine: bridge agnóstico al canvas vía `RenderModel`
  (Layer/Glyph/Geometry). Feature `eternal-bridge` (off por default)
  reservada para enchufar eternal-astrology desde ~/eternal.
- tahuantinsuyu-modules: registry de módulos pluggables (Module trait
  + Control schema) con `NatalModule` placeholder.
- tahuantinsuyu-theme: AstroPalette (elementos / modos / planetas /
  aspectos) con variantes dark + light sobre yahweh-theme.
- tahuantinsuyu-canvas: widget GPUI con CanvasState (Empty / Wheel /
  Thumbnails). Render placeholder hasta cablear la rueda real.
- tahuantinsuyu-tree: explorador izquierdo sobre yahweh-widget-tree,
  prefijos g:/c:/h: para Group/Contact/Chart.
- tahuantinsuyu-panel: control panel inferior que lee Controls de los
  módulos del registry y los pinta.
- apps/tahuantinsuyu: binario `tahuantinsuyu` (launch_app-style) con
  Shell coordinador (tree↔canvas↔panel), DB en $XDG_DATA_HOME.

Workspace Cargo.toml actualizado con los 10 miembros. `cargo check`
verde, tests unitarios verdes (model/store/engine/modules/theme/card).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 01:06:03 +00:00