# Arquitectura del sistema

---

## Dos bases de datos, dos propósitos

| | Registry (esta BBDD) | Operacional (por proyecto) |
|---|---|---|
| **Qué almacena** | Lo que sabes hacer | Lo que has hecho y cómo fluye |
| **Naturaleza** | Conocimiento estático | Conocimiento dinámico |
| **Cuándo cambia** | Solo al añadir código | En cada proyecto activo |
| **Scope** | Compartida entre todos los proyectos | Local a cada proyecto |
| **Tablas** | `functions`, `types` | `entities`, `relations` |

---

## Registry — estructura de directorios

```
fn-registry/
  functions/
    core/
      filter_slice.go
      filter_slice.md
    finance/
      parse_ohlcv.go
      parse_ohlcv.md
    io/
      fetch_ticks.go
      fetch_ticks.md
    pipelines/
      tick_to_ohlcv.go
      tick_to_ohlcv.md
    components/
      DataTable.tsx
      DataTable.md
  types/
    core/
      result.go
      result.md
    finance/
      ohlcv.go
      ohlcv.md
  registry.db       ← SQLite, solo índice FTS. Regenerable siempre.
  fn                ← binario CLI
```

Los archivos `.go` / `.tsx` son la **fuente de verdad del código**.
Los archivos `.md` son la **fuente de verdad de la documentación**.
`registry.db` es solo el índice — si se borra, `fn index` lo regenera en segundos.

---

## CLI — comandos

```bash
fn search "filter predicate sin mutar"   # búsqueda FTS sobre nombre, descripción, tags, signature
fn search -k function -p pure "slice"    # filtrar por kind y purity
fn search -l go -d finance "ohlcv"       # filtrar por lang y domain
fn search -k component "tabla datos"     # buscar componentes React

fn add                                   # abre $EDITOR con template según kind
fn show filter_slice_go_core             # imprime entrada completa
fn index                                 # regenera registry.db desde los .md

fn list                                  # lista todas las entradas
fn list -d finance                       # lista por dominio
fn list -k pipeline                      # lista solo pipelines
```

---

## Operacional — tablas por proyecto

Cada proyecto tiene su propia BBDD operacional que referencia IDs del registry.

### Entities

Instancias concretas de tipos registrados dentro de un contexto de ejecución.

| Campo | Tipo | Descripción |
|---|---|---|
| `id` | string | Identificador único |
| `name` | string | Nombre semántico (`ticks_btcusdt`) |
| `type_ref` | string | Referencia al `types.id` del registry |
| `description` | text | Qué representa en este dominio concreto |
| `tags` | []string | Etiquetas |

### Relations

Cómo las entidades se conectan a través de funciones o pipelines.

| Campo | Tipo | Descripción |
|---|---|---|
| `id` | string | Identificador único |
| `from_entity` | string | Entidad origen |
| `to_entity` | string | Entidad destino |
| `via` | string | `functions.id` que transforma |
| `description` | text | Qué ocurre en esta transformación |
| `purity` | enum | `pure` \| `impure` |

---

## El agente y el registry

El agente consulta el registry para:

1. **Descubrir** qué funciones y tipos existen en un dominio
2. **Razonar** sobre composabilidad comparando `returns` con `uses_types`
3. **Priorizar** funciones puras para el núcleo del pipeline
4. **Aislar** impuras en los bordes
5. **Verificar** que los contratos no están rotos comparando `version`

El agente consulta la operacional para:

1. Entender qué entidades fluyen en este proyecto concreto
2. Ver qué transformaciones ya están modeladas
3. Detectar patrones de uso frecuentes

---

## Mejoras incorporadas al schema v1.0

| Problema | Solución |
|---|---|
| IDs frágiles con colisiones | Formato `{name}_{lang}_{domain}` + UUID interno |
| `lang` libre fragmenta el índice | Enum controlado, normalizado al indexar |
| Sin versionado | Campo `version` semver en functions y types |
| `file_path` absoluta se rompe al mover | Siempre relativa a la raíz del registry |
| Sin contexto de dominio | Campo `domain` obligatorio |
| Sin trazabilidad temporal | `created_at` / `updated_at` automáticos |
| `signature` ambigua en lenguajes dinámicos | Convención formal definida para Python/SQL |
| Pura que devuelve opcional mal modelada | Regla: modelar como tipo suma, no `returns_optional: true` |
