# fn-registry Registry personal de codigo reutilizable con busqueda FTS. Diseñado para composicion funcional y agentes. ## Explorar el registry (USAR SIEMPRE) La BD SQLite `registry.db` es tu mapa del repositorio. Antes de escribir codigo, SIEMPRE consultala para saber que existe, evitar duplicados y descubrir funciones reutilizables. ```bash # Buscar funciones por texto libre (FTS5) sqlite3 registry.db "SELECT id, kind, purity, description FROM functions WHERE id IN (SELECT id FROM functions_fts WHERE functions_fts MATCH 'slice') ORDER BY name;" # Listar todas las funciones de un dominio sqlite3 registry.db "SELECT id, purity, signature FROM functions WHERE domain = 'finance' ORDER BY name;" # Listar solo puras de un dominio sqlite3 registry.db "SELECT id, signature FROM functions WHERE domain = 'core' AND purity = 'pure' ORDER BY name;" # Listar solo impuras sqlite3 registry.db "SELECT id, domain, error_type FROM functions WHERE purity = 'impure' ORDER BY domain, name;" # Buscar tipos por dominio sqlite3 registry.db "SELECT id, algebraic, description FROM types WHERE domain = 'cybersecurity';" # Ver que funciones usa un pipeline o funcion compuesta sqlite3 registry.db "SELECT id, uses_functions, uses_types FROM functions WHERE uses_functions != '[]';" # Ver funciones que dependen de un tipo concreto sqlite3 registry.db "SELECT id FROM functions WHERE uses_types LIKE '%ohlcv_go_finance%';" # Buscar por tag sqlite3 registry.db "SELECT id, tags FROM functions WHERE tags LIKE '%generic%';" # Contar entradas por dominio sqlite3 registry.db "SELECT domain, COUNT(*) FROM functions GROUP BY domain;" # Ver todo el schema sqlite3 registry.db ".schema" ``` La BD usa WAL mode — puedes leerla mientras se escribe sin bloqueos. ## Estructura del repositorio ``` fn-registry/ functions/ # Codigo y docs de funciones core/ # Utilidades genericas (filter, map, pipeline, retry...) finance/ # Indicadores, riesgo, IO de mercado datascience/ # Estadistica, DSP, IO de datos cybersecurity/ # Crypto, analisis de red, IO de seguridad pipelines/ # Composiciones de funciones, siempre impuras components/ # Componentes React (.tsx) types/ # Tipos algebraicos (product y sum) core/ # Result, Option, Pair, Error finance/ # OHLCV, Tick, BollingerResult, DrawdownResult datascience/ # OutlierResult cybersecurity/ # CIDRBlock, ThreatResult, PortResult registry/ # Libreria Go: modelos, SQLite, parser, indexer, validacion cmd/fn/ # CLI docs/ # Schema de documentacion v1.0 (fuente de verdad del diseño) docs/templates/ # Plantillas de frontmatter para function, pipeline, component, type registry.db # Indice SQLite FTS5+WAL (regenerable, NO commitear) ``` ## Build ```bash CGO_ENABLED=1 go build -tags fts5 ./... CGO_ENABLED=1 go test -tags fts5 ./... CGO_ENABLED=1 go build -tags fts5 -o fn ./cmd/fn/ ``` ## Reglas para añadir funciones nuevas ### Antes de crear 1. **Consulta la BD** para verificar que no existe algo similar: ```bash sqlite3 registry.db "SELECT id, description FROM functions WHERE id IN (SELECT id FROM functions_fts WHERE functions_fts MATCH 'tu busqueda');" ``` 2. **Identifica el dominio** correcto: core, finance, datascience, cybersecurity, o crea uno nuevo si no encaja 3. **Decide la purity**: pure si no tiene side effects, impure si tiene IO/estado/goroutines/tiempo ### Archivos a crear Cada funcion requiere EXACTAMENTE dos archivos: 1. **Implementacion** `functions/{domain}/{name}.go` — codigo real, compilable 2. **Documentacion** `functions/{domain}/{name}.md` — frontmatter YAML con metadata ### Formato del .md (frontmatter YAML) ```yaml --- name: nombre_snake_case kind: function # function | pipeline | component lang: go # go | python | typescript | sql domain: core # core | finance | datascience | cybersecurity | ... version: "1.0.0" purity: pure # pure | impure signature: "func NombreCompleto(...) ..." description: "Descripcion en español de que hace y cuando usarla." tags: [tag1, tag2, tag3] uses_functions: [] # IDs de funciones del registry que invoca uses_types: [] # IDs de tipos del registry que recibe returns: [] # IDs de tipos del registry que devuelve returns_optional: false error_type: "" # ID de tipo de error, obligatorio si impure imports: [] # dependencias externas fuera del registry tested: false tests: [] test_file_path: "" file_path: "functions/{domain}/{name}.go" --- ## Ejemplo ` `` go resultado := MiFuncion(input) ` `` ## Notas Explicacion adicional si es necesario. ``` ### Reglas de integridad (el indexer las valida) | Regla | Condicion | |---|---| | Pipeline siempre impuro | `kind: pipeline` -> `purity: impure` + `uses_functions` no vacio | | Pura sin side effects | `purity: pure` -> `returns_optional: false` + `error_type: ""` | | Impura declara errores | `purity: impure` -> `error_type` obligatorio (usar `error_go_core`) | | Tests coherentes | `tested: true` -> `test_file_path` y `tests` obligatorios | | Referencias validas | `uses_functions`, `uses_types`, `returns`, `error_type` deben apuntar a IDs existentes | | Component tiene framework | `kind: component` -> `framework` obligatorio, `returns` vacio (usar `emits`) | | Rutas relativas | `file_path` siempre relativa a la raiz, nunca absoluta | | IDs unicos | Formato `{name}_{lang}_{domain}`, colisiones rechazadas | ### Campo `returns` vs tipo nativo El campo `returns` en el .md es para IDs de tipos del registry (ej: `ohlcv_go_finance`), NO para tipos nativos de Go (`float64`, `string`, `bool`). Si la funcion devuelve tipos nativos, deja `returns: []`. ### Despues de crear ```bash # Regenerar el indice ./fn index # o CGO_ENABLED=1 go build -tags fts5 -o fn ./cmd/fn/ && ./fn index # Verificar que se indexo sin errores ./fn show {name}_{lang}_{domain} ``` ## Reglas para añadir tipos nuevos Cada tipo requiere dos archivos: `types/{domain}/{name}.go` y `types/{domain}/{name}.md`. ```yaml --- name: nombre_snake_case lang: go domain: core version: "1.0.0" algebraic: product # product (struct) | sum (interface/union) definition: | type MiTipo struct { ... } description: "Descripcion en español." tags: [tag1, tag2] uses_types: [] # IDs de otros tipos que compone (sin auto-referencias) file_path: "types/{domain}/{name}.go" --- ``` ## Convenciones - **IDs:** `{name}_{lang}_{domain}` (ej: `filter_slice_go_core`) - **Nombres:** snake_case para funciones, PascalCase para tipos en Go - **Paquete Go:** el nombre del directorio (core, finance, datascience, cybersecurity) - **Tipos en firmas:** usar tipos nativos (float64, []float64, string) para evitar imports circulares entre paquetes de funciones. Documentar los tipos del registry en `uses_types`/`returns` del .md - **Purity:** puras en el centro, impuras en los bordes. Una pura NUNCA depende de una impura - **Stubs impuros:** si la implementacion real requiere dependencias externas no disponibles, crear stub con `return ..., fmt.Errorf("not implemented")` y documentar completamente el .md ## Fuentes de verdad | Que | Donde | |---|---| | Codigo | archivos .go / .py / .tsx | | Documentacion | archivos .md junto al codigo | | Diseño del schema | carpeta docs/ | | Indice de busqueda | registry.db (regenerable con `fn index`) | ## CLI (cmd/fn) ```bash fn index # Regenera registry.db desde los .md fn search "texto" # Busqueda FTS fn search -k function -p pure -d core "slice" fn list # Lista todo fn list -d finance -k function # Lista por dominio y kind fn show filter_slice_go_core # Muestra entrada completa fn add -k function # Muestra template para copiar ```