From 2d3f4b4448d0b6729ae8bb9cd68a63fa8810b23b Mon Sep 17 00:00:00 2001 From: Egutierrez Date: Sat, 28 Mar 2026 04:37:54 +0100 Subject: [PATCH] feat: migracion SQL, template DB y generador para fn_operations 001_init.sql como espejo del schema, gentemplate para crear operations.db vacias con schema aplicado, y template lista para copiar con fn ops init. --- fn_operations/cmd/gentemplate/main.go | 27 +++++++ fn_operations/migrations/001_init.sql | 80 +++++++++++++++++++ fn_operations/project_template/operations.db | Bin 0 -> 53248 bytes 3 files changed, 107 insertions(+) create mode 100644 fn_operations/cmd/gentemplate/main.go create mode 100644 fn_operations/migrations/001_init.sql create mode 100644 fn_operations/project_template/operations.db diff --git a/fn_operations/cmd/gentemplate/main.go b/fn_operations/cmd/gentemplate/main.go new file mode 100644 index 00000000..0689f441 --- /dev/null +++ b/fn_operations/cmd/gentemplate/main.go @@ -0,0 +1,27 @@ +package main + +import ( + "fmt" + "os" + + ops "fn-registry/fn_operations" +) + +func main() { + path := "fn_operations/project_template/operations.db" + if len(os.Args) > 1 { + path = os.Args[1] + } + + // Remove existing template + os.Remove(path) + + db, err := ops.Open(path) + if err != nil { + fmt.Fprintf(os.Stderr, "error: %v\n", err) + os.Exit(1) + } + defer db.Close() + + fmt.Printf("Template DB created at %s\n", path) +} diff --git a/fn_operations/migrations/001_init.sql b/fn_operations/migrations/001_init.sql new file mode 100644 index 00000000..31bc8cb6 --- /dev/null +++ b/fn_operations/migrations/001_init.sql @@ -0,0 +1,80 @@ +-- fn_operations schema v1.0.0 +-- Espejo del schema en fn_operations/db.go para referencia y tooling externo. + +PRAGMA journal_mode=WAL; +PRAGMA foreign_keys=ON; + +CREATE TABLE IF NOT EXISTS types_snapshot ( + id TEXT PRIMARY KEY, + version TEXT NOT NULL DEFAULT '1.0.0', + lang TEXT NOT NULL, + algebraic TEXT NOT NULL CHECK(algebraic IN ('product','sum')), + definition TEXT NOT NULL DEFAULT '', + description TEXT NOT NULL DEFAULT '', + snapped_at TEXT NOT NULL +); + +CREATE TABLE IF NOT EXISTS entities ( + id TEXT PRIMARY KEY, + name TEXT NOT NULL, + type_ref TEXT NOT NULL, + status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active','stale','corrupted','archived')), + description TEXT NOT NULL DEFAULT '', + domain TEXT NOT NULL DEFAULT '', + tags TEXT NOT NULL DEFAULT '[]', + source TEXT NOT NULL, + metadata TEXT NOT NULL DEFAULT '{}', + notes TEXT NOT NULL DEFAULT '', + created_at TEXT NOT NULL, + updated_at TEXT NOT NULL +); + +CREATE TABLE IF NOT EXISTS relations ( + id TEXT PRIMARY KEY, + name TEXT NOT NULL, + from_entity TEXT NOT NULL DEFAULT '', + to_entity TEXT NOT NULL, + via TEXT NOT NULL DEFAULT '', + description TEXT NOT NULL DEFAULT '', + purity TEXT NOT NULL DEFAULT '' CHECK(purity IN ('','pure','impure')), + direction TEXT NOT NULL DEFAULT 'unidirectional' CHECK(direction IN ('unidirectional','bidirectional','inverse')), + weight REAL, + status TEXT NOT NULL DEFAULT 'designed' CHECK(status IN ('designed','implemented','tested','running','deprecated')), + started_at TEXT, + ended_at TEXT, + "order" INTEGER, + tags TEXT NOT NULL DEFAULT '[]', + notes TEXT NOT NULL DEFAULT '', + created_at TEXT NOT NULL, + updated_at TEXT NOT NULL +); + +CREATE TABLE IF NOT EXISTS relation_inputs ( + id TEXT PRIMARY KEY, + relation_id TEXT NOT NULL REFERENCES relations(id) ON DELETE CASCADE, + entity_id TEXT NOT NULL REFERENCES entities(id), + role TEXT NOT NULL, + "order" INTEGER +); + +CREATE VIRTUAL TABLE IF NOT EXISTS entities_fts USING fts5( + id, name, description, tags, domain, + content='entities', content_rowid='rowid' +); + +CREATE TRIGGER IF NOT EXISTS entities_ai AFTER INSERT ON entities BEGIN + INSERT INTO entities_fts(rowid, id, name, description, tags, domain) + VALUES (new.rowid, new.id, new.name, new.description, new.tags, new.domain); +END; + +CREATE TRIGGER IF NOT EXISTS entities_ad AFTER DELETE ON entities BEGIN + INSERT INTO entities_fts(entities_fts, rowid, id, name, description, tags, domain) + VALUES ('delete', old.rowid, old.id, old.name, old.description, old.tags, old.domain); +END; + +CREATE TRIGGER IF NOT EXISTS entities_au AFTER UPDATE ON entities BEGIN + INSERT INTO entities_fts(entities_fts, rowid, id, name, description, tags, domain) + VALUES ('delete', old.rowid, old.id, old.name, old.description, old.tags, old.domain); + INSERT INTO entities_fts(rowid, id, name, description, tags, domain) + VALUES (new.rowid, new.id, new.name, new.description, new.tags, new.domain); +END; diff --git a/fn_operations/project_template/operations.db b/fn_operations/project_template/operations.db new file mode 100644 index 0000000000000000000000000000000000000000..301fada8393ac94cc7b4e7609ea915d02ada9e68 GIT binary patch literal 53248 zcmeI(?{C{g7zgk;ZR5sm*YW})n95E=lN&8-SB<@zCXu#Y7cHb)nr;jPksDt#Yl)rN zPPY#6qTMv!u)m0Z03_Zb-t&rgyx|4X-te4%q;Z;LT@XU4z7bvQyYu4%f?CzM`>8xv;sZm046wEm;0mg-UkrZioh3rA{4N(>4nwC0!_OYvl?n zlqy@Dy6T?iE_FJglN@vGr>2o(;?L5XJjV>~)*Q3tnYNWqyaA{Am=EIP`}`??FtW zBo>n>2x9W9qL{SO#*s4bPtc3%i3u_y#DNoJgcG!(6}7RSAi_9w&IK4NCos&nVwfRD zn3M04t^aEVwCCi^wQJJhd!D}A;L$L}Dyr6OYtO9rDVmE?BEMGDnA)d>y7ZXcEf+q| zmmjh_+QS^%&$0)F%I&S43M+3tC~O?e%9-oerNj46-qx^duK7G3N?0~K1EoUIkN*0P84jGVc0MLNu%ytipQi;afPXNKI9s?{Zz*TwqtxYNwBR^765 z-S_RT&h{X5rg$dMpxy3X~zCi2A`}-)-2n$Kmj^X*qN0()3a0#PGXs7~blB zph1&&R%#V?EUKQ<&O7}ET z498a(%&#tORaj}KSY&1GmR8nE>-4!0HF7DXD9F&M zy4q8ae)Zv$oVjp8`az1hc0}D&UrYBCiXsOF4Q0=gI}>QV2*y68&5Va-}?$Mg<@4rA^#tx-U1{kFD#XDMu2DA88~HK)=keK%0erhkwX zlW3R@uZi@e{swf`w#-f|y`hF(cZz7=qTYKN<<#BSMRZeZpF1vB{kuNpX8n;D41vB$ z6)6zc)4jGkbX4SH)-7&CA%vIs_wUsC!)x#+%^0=JsUCNO1E+0Srd6jRgSTkVx+wOe zp?(}XsnR!O-+-dwl%hdFr>IX#Q$w*)1VIn<`|4|vAC^s#ge?a^`+JJRMPQv+ShSw0 zi*}3l%YJoAb~TmCXcykLwA|xG<;pMTC*;iHqV)Zf*p?bC^2yj@ic0_GTJjEBoEG|? zaEKw$=uVLUI%VoU?>GHnO-`j=8Y0JQw&S#0Vv2LB?$jR9b>VEEa+L*Je=uROP`g&y zyUf39x1CzJ$;A4jPMX})#Yf=@mg9SU``v$^L@Sf2%=+S>B#Kg?x*8o#9epXunQT^i zY5OT8X4kE{mfmt7*l-6@hv>>a@-)sr~KLaWPHm#+$>hHlk^dFyFQb$X-D zcOBiV^(J7rs~y+-yGqNkjdsnW9CF*uV6!mzo@vp~L9t`T=J7ZZ5yUC8OklP8FX~IkTAOHafKmY;|fB*y_009UI|IzJmB?KS<0SG_<0uX=z1Rwwb2tZ(51n~TSTxJS!LI45~fB*y_009U<00Izz z00c%C!1Mpn?QkUoAOHafKmY;|fB*y_009UI|IzJmB?KS<0SG_<0uX=z1Rwwb2tZ(51jO_I