Files
rose-ash/lib/host/relations.sx
giles 11aba081f4
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 20s
host: Phase 3 — relations READ cut-over (get-children/get-parents), 121/121
Migrate the two internal relations read queries onto lib/relations: GET
/internal/data/get-children + /get-parents dispatch to relations/children
and relations/parents. Bridge the Quart (type,id) node key to a graph atom
symbol "type:id" with relation-type as the edge kind; optional child/parent
-type params filter by "type:" prefix. Golden tests pin each endpoint to
subsystem-call + envelope. Ledger entries flipped to :migrated (off-Quart
coverage 27% -> 45%).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 17:24:37 +00:00

59 lines
3.5 KiB
Plaintext

;; lib/host/relations.sx — Relations domain endpoints on the host. The relations
;; service is internal-only (no public routes): Quart exposes it as signed
;; /internal/data/{query} reads + /internal/actions/{action} writes. This migrates
;; the two READ queries — get-children, get-parents — straight onto the SX host,
;; dispatching to the lib/relations subsystem (a saturating Datalog graph).
;;
;; Node model: the Quart relations API keys nodes by a (type, id) pair; the graph
;; subsystem keys them by an opaque atom. We bridge by composing the atom as the
;; symbol "type:id", with the relation-type as the edge kind. Optional child-type
;; / parent-type params filter the result by that "type:" prefix — matching the
;; Quart queries' optional type narrowing.
;; Depends on lib/relations/* + lib/host/handler.sx + lib/dream/* (query params).
;; ── node helpers ────────────────────────────────────────────────────
(define host/-rel-node
(fn (type id) (string->symbol (str type ":" id))))
(define host/-rel-node-type?
(fn (node type) (starts-with? (symbol->string node) (str type ":"))))
(define host/-rel-strings
(fn (nodes) (map (fn (n) (symbol->string n)) nodes)))
;; ── GET /internal/data/get-children ─────────────────────────────────
;; query: parent-type, parent-id, relation-type (required); child-type (optional
;; filter). Returns the child node ids ("type:id") for the parent under that kind.
(define host/relations-children
(fn (req)
(let ((ptype (dream-query-param req "parent-type"))
(pid (dream-query-param req "parent-id"))
(kind (dream-query-param req "relation-type")))
(if (and ptype pid kind)
(let ((kids (relations/children (host/-rel-node ptype pid) (string->symbol kind)))
(ctype (dream-query-param req "child-type")))
(let ((sel (if ctype (filter (fn (k) (host/-rel-node-type? k ctype)) kids) kids)))
(host/ok (host/-rel-strings sel))))
(host/error 400 "missing parameter")))))
;; ── GET /internal/data/get-parents ──────────────────────────────────
;; query: child-type, child-id, relation-type (required); parent-type (optional
;; filter). Returns the parent node ids ("type:id") for the child under that kind.
(define host/relations-parents
(fn (req)
(let ((ctype (dream-query-param req "child-type"))
(cid (dream-query-param req "child-id"))
(kind (dream-query-param req "relation-type")))
(if (and ctype cid kind)
(let ((ps (relations/parents (host/-rel-node ctype cid) (string->symbol kind)))
(ptype (dream-query-param req "parent-type")))
(let ((sel (if ptype (filter (fn (p) (host/-rel-node-type? p ptype)) ps) ps)))
(host/ok (host/-rel-strings sel))))
(host/error 400 "missing parameter")))))
;; ── read route group ────────────────────────────────────────────────
;; Internal data reads (the signed-internal-auth gate is a separate middleware
;; concern, like the feed reads); these dispatch straight to the subsystem.
(define host/relations-routes
(list
(dream-get "/internal/data/get-children" host/relations-children)
(dream-get "/internal/data/get-parents" host/relations-parents)))