host: typed relations — Phase 1, generalize edges to carry a kind
Plan: plans/typed-posts-and-relations.md. "Typing is just relating to a type",
types are posts. Phase 1 lifts the hard-coded kind:"related" into a parameter,
driven by one registry — the spine the later phases (type resolution, tags,
picker) build on. Zero user-visible change.
- host/blog-rel-kinds registry: {kind,label,symmetric,candidates[,inverse-label]}
for related (symmetric) / is-a / tagged (directed). One place knows each kind's
direction, label, and candidate set.
- host/blog-relate!/unrelate! take a kind; symmetric kinds write both directions,
directed kinds write one. host/blog-out/in read children/parents per kind;
host/blog-related = out(slug,"related") (back-compat).
- relate/unrelate routes carry a `kind` form field (default "related"), validated
against the registry. delete drops edges across ALL kinds + both directions.
6 tests: symmetric reads both sides, directed writes one (inverse via host/blog-in),
unrelate is kind-scoped, unknown kind rejected, default kind = related. 244/244;
Playwright picker 4/4 (related path unchanged).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -267,10 +267,10 @@
|
||||
(list true false))
|
||||
(host-bl-test "relate-options excludes already-related candidates"
|
||||
(begin
|
||||
(host/blog-relate! "alpha-post" "beta-post")
|
||||
(host/blog-relate! "alpha-post" "beta-post" "related")
|
||||
(contains? (dream-resp-body (host-bl-app (host-bl-req "/alpha-post/relate-options"))) "Beta Post"))
|
||||
false)
|
||||
(host/blog-unrelate! "alpha-post" "beta-post")
|
||||
(host/blog-unrelate! "alpha-post" "beta-post" "related")
|
||||
(host-bl-test "relate-picker.js served as javascript"
|
||||
(dream-resp-header (host-bl-app (host-bl-req "/relate-picker.js")) "content-type")
|
||||
"application/javascript; charset=utf-8")
|
||||
@@ -281,6 +281,40 @@
|
||||
(host-bl-test "related block: empty when anonymous + no relations"
|
||||
(= (host/blog--related-block "gamma-post" false) "") true)
|
||||
|
||||
;; -- Phase 1: relations carry a kind --
|
||||
(host-bl-test "symmetric kind (related) reads from both sides"
|
||||
(begin
|
||||
(host/blog-relate! "alpha-post" "gamma-post" "related")
|
||||
(list (contains? (host/blog-out "alpha-post" "related") "gamma-post")
|
||||
(contains? (host/blog-out "gamma-post" "related") "alpha-post")))
|
||||
(list true true))
|
||||
(host-bl-test "directed kind (tagged) writes one direction; inverse via host/blog-in"
|
||||
(begin
|
||||
(host/blog-relate! "alpha-post" "beta-post" "tagged")
|
||||
(list (contains? (host/blog-out "alpha-post" "tagged") "beta-post")
|
||||
(contains? (host/blog-out "beta-post" "tagged") "alpha-post")
|
||||
(contains? (host/blog-in "beta-post" "tagged") "alpha-post")))
|
||||
(list true false true))
|
||||
(host-bl-test "unrelate is kind-scoped (related edge survives a tagged unrelate)"
|
||||
(begin
|
||||
(host/blog-unrelate! "alpha-post" "beta-post" "tagged")
|
||||
(list (contains? (host/blog-out "alpha-post" "tagged") "beta-post")
|
||||
(contains? (host/blog-out "alpha-post" "related") "gamma-post")))
|
||||
(list false true))
|
||||
(host/blog-unrelate! "alpha-post" "gamma-post" "related")
|
||||
(host-bl-test "relate-submit rejects an unknown kind (no-op)"
|
||||
(begin
|
||||
(host-bl-wapp (host-bl-send "POST" "/alpha-post/relate" "Bearer good"
|
||||
"application/x-www-form-urlencoded" "other=beta-post&kind=bogus"))
|
||||
(contains? (host/blog-out "alpha-post" "bogus") "beta-post"))
|
||||
false)
|
||||
(host-bl-test "default kind is related (no kind field)"
|
||||
(begin
|
||||
(host-bl-wapp (host-bl-send "POST" "/alpha-post/relate" "Bearer good"
|
||||
"application/x-www-form-urlencoded" "other=beta-post"))
|
||||
(contains? (host/blog-out "alpha-post" "related") "beta-post"))
|
||||
true)
|
||||
|
||||
;; -- experimental unguarded create-only route (POST /new, no auth) --
|
||||
(define host-bl-oapp (host/make-app (list host/blog-open-create-routes host/blog-routes)))
|
||||
(host/blog-use-store! (persist/open))
|
||||
|
||||
Reference in New Issue
Block a user