Files
rose-ash/shared/sx/ref/boundary.sx
2026-03-06 12:28:32 +00:00

467 lines
11 KiB
Plaintext

;; ==========================================================================
;; boundary.sx — SX boundary contract
;;
;; Declares everything allowed to cross the host-SX boundary:
;; I/O primitives (Tier 2) and page helpers (Tier 3).
;;
;; Pure primitives (Tier 1) are declared in primitives.sx.
;; This file declares what primitives.sx does NOT cover:
;; async/side-effectful host functions that need request context.
;;
;; Format:
;; (define-io-primitive "name"
;; :params (param1 param2 &key ...)
;; :returns "type"
;; :async true
;; :doc "description"
;; :context :request)
;;
;; (define-page-helper "name"
;; :params (param1 param2)
;; :returns "type"
;; :service "service-name")
;;
;; Bootstrappers read this file and emit frozen sets + validation
;; functions for the target language.
;; ==========================================================================
;; --------------------------------------------------------------------------
;; Tier 1: Pure primitives — declared in primitives.sx
;; --------------------------------------------------------------------------
(declare-tier :pure :source "primitives.sx")
;; --------------------------------------------------------------------------
;; Tier 2: I/O primitives — async, side-effectful, need host context
;; --------------------------------------------------------------------------
(define-io-primitive "frag"
:params (service frag-type &key)
:returns "string"
:async true
:doc "Fetch cross-service HTML fragment."
:context :request)
(define-io-primitive "query"
:params (service query-name &key)
:returns "any"
:async true
:doc "Fetch data from another service via internal HTTP."
:context :request)
(define-io-primitive "action"
:params (service action-name &key)
:returns "any"
:async true
:doc "Call an action on another service via internal HTTP."
:context :request)
(define-io-primitive "current-user"
:params ()
:returns "dict?"
:async true
:doc "Current authenticated user dict, or nil."
:context :request)
(define-io-primitive "htmx-request?"
:params ()
:returns "boolean"
:async true
:doc "True if current request has HX-Request header."
:context :request)
(define-io-primitive "service"
:params (service-or-method &rest args &key)
:returns "any"
:async true
:doc "Call a domain service method. Two-arg: (service svc method). One-arg: (service method) uses bound handler service."
:context :request)
(define-io-primitive "request-arg"
:params (name &rest default)
:returns "any"
:async true
:doc "Read a query string argument from the current request."
:context :request)
(define-io-primitive "request-path"
:params ()
:returns "string"
:async true
:doc "Current request path."
:context :request)
(define-io-primitive "nav-tree"
:params ()
:returns "list"
:async true
:doc "Navigation tree as list of node dicts."
:context :request)
(define-io-primitive "get-children"
:params (&key parent-type parent-id)
:returns "list"
:async true
:doc "Fetch child entities for a parent."
:context :request)
(define-io-primitive "g"
:params (key)
:returns "any"
:async true
:doc "Read a value from the Quart request-local g object."
:context :request)
(define-io-primitive "csrf-token"
:params ()
:returns "string"
:async true
:doc "Current CSRF token string."
:context :request)
(define-io-primitive "abort"
:params (status &rest message)
:returns "nil"
:async true
:doc "Raise HTTP error from SX."
:context :request)
(define-io-primitive "url-for"
:params (endpoint &key)
:returns "string"
:async true
:doc "Generate URL for a named endpoint."
:context :request)
(define-io-primitive "route-prefix"
:params ()
:returns "string"
:async true
:doc "Service URL prefix for dev/prod routing."
:context :request)
(define-io-primitive "root-header-ctx"
:params ()
:returns "dict"
:async true
:doc "Dict with root header values (cart-mini, auth-menu, nav-tree, etc.)."
:context :request)
(define-io-primitive "post-header-ctx"
:params ()
:returns "dict"
:async true
:doc "Dict with post-level header values."
:context :request)
(define-io-primitive "select-colours"
:params ()
:returns "string"
:async true
:doc "Shared select/hover CSS class string."
:context :request)
(define-io-primitive "account-nav-ctx"
:params ()
:returns "any"
:async true
:doc "Account nav fragments, or nil."
:context :request)
(define-io-primitive "app-rights"
:params ()
:returns "dict"
:async true
:doc "User rights dict from g.rights."
:context :request)
(define-io-primitive "federation-actor-ctx"
:params ()
:returns "dict?"
:async true
:doc "Serialized ActivityPub actor dict or nil."
:context :request)
(define-io-primitive "request-view-args"
:params (key)
:returns "any"
:async true
:doc "Read a URL view argument from the current request."
:context :request)
(define-io-primitive "cart-page-ctx"
:params ()
:returns "dict"
:async true
:doc "Dict with cart page header values."
:context :request)
(define-io-primitive "events-calendar-ctx"
:params ()
:returns "dict"
:async true
:doc "Dict with events calendar header values."
:context :request)
(define-io-primitive "events-day-ctx"
:params ()
:returns "dict"
:async true
:doc "Dict with events day header values."
:context :request)
(define-io-primitive "events-entry-ctx"
:params ()
:returns "dict"
:async true
:doc "Dict with events entry header values."
:context :request)
(define-io-primitive "events-slot-ctx"
:params ()
:returns "dict"
:async true
:doc "Dict with events slot header values."
:context :request)
(define-io-primitive "events-ticket-type-ctx"
:params ()
:returns "dict"
:async true
:doc "Dict with ticket type header values."
:context :request)
(define-io-primitive "market-header-ctx"
:params ()
:returns "dict"
:async true
:doc "Dict with market header data."
:context :request)
;; Moved from primitives.py — these need host context (infra/config/Quart)
(define-io-primitive "app-url"
:params (service &rest path)
:returns "string"
:async false
:doc "Full URL for a service: (app-url \"blog\" \"/my-post/\")."
:context :config)
(define-io-primitive "asset-url"
:params (&rest path)
:returns "string"
:async false
:doc "Versioned static asset URL."
:context :config)
(define-io-primitive "config"
:params (key)
:returns "any"
:async false
:doc "Read a value from app-config.yaml."
:context :config)
(define-io-primitive "jinja-global"
:params (key &rest default)
:returns "any"
:async false
:doc "Read a Jinja environment global."
:context :request)
(define-io-primitive "relations-from"
:params (entity-type)
:returns "list"
:async false
:doc "List of RelationDef dicts for an entity type."
:context :config)
;; --------------------------------------------------------------------------
;; Tier 3: Page helpers — service-scoped, registered per app
;; --------------------------------------------------------------------------
;; SX docs service
(define-page-helper "highlight"
:params (code lang)
:returns "sx-source"
:service "sx")
(define-page-helper "primitives-data"
:params ()
:returns "dict"
:service "sx")
(define-page-helper "special-forms-data"
:params ()
:returns "dict"
:service "sx")
(define-page-helper "reference-data"
:params (slug)
:returns "dict"
:service "sx")
(define-page-helper "attr-detail-data"
:params (slug)
:returns "dict"
:service "sx")
(define-page-helper "header-detail-data"
:params (slug)
:returns "dict"
:service "sx")
(define-page-helper "event-detail-data"
:params (slug)
:returns "dict"
:service "sx")
(define-page-helper "read-spec-file"
:params (filename)
:returns "string"
:service "sx")
(define-page-helper "bootstrapper-data"
:params (target)
:returns "dict"
:service "sx")
(define-page-helper "bundle-analyzer-data"
:params ()
:returns "dict"
:service "sx")
;; Blog service
(define-page-helper "editor-data"
:params (&key)
:returns "dict"
:service "blog")
(define-page-helper "editor-page-data"
:params (&key)
:returns "dict"
:service "blog")
(define-page-helper "post-admin-data"
:params (&key slug)
:returns "dict"
:service "blog")
(define-page-helper "post-data-data"
:params (&key slug)
:returns "dict"
:service "blog")
(define-page-helper "post-preview-data"
:params (&key slug)
:returns "dict"
:service "blog")
(define-page-helper "post-entries-data"
:params (&key slug)
:returns "dict"
:service "blog")
(define-page-helper "post-settings-data"
:params (&key slug)
:returns "dict"
:service "blog")
(define-page-helper "post-edit-data"
:params (&key slug)
:returns "dict"
:service "blog")
;; Events service
(define-page-helper "calendar-admin-data"
:params (&key calendar-slug)
:returns "dict"
:service "events")
(define-page-helper "day-admin-data"
:params (&key calendar-slug year month day)
:returns "dict"
:service "events")
(define-page-helper "slots-data"
:params (&key calendar-slug)
:returns "dict"
:service "events")
(define-page-helper "slot-data"
:params (&key calendar-slug slot-id)
:returns "dict"
:service "events")
(define-page-helper "entry-data"
:params (&key calendar-slug entry-id)
:returns "dict"
:service "events")
(define-page-helper "entry-admin-data"
:params (&key calendar-slug entry-id year month day)
:returns "dict"
:service "events")
(define-page-helper "ticket-types-data"
:params (&key calendar-slug entry-id year month day)
:returns "dict"
:service "events")
(define-page-helper "ticket-type-data"
:params (&key calendar-slug entry-id ticket-type-id year month day)
:returns "dict"
:service "events")
(define-page-helper "tickets-data"
:params (&key)
:returns "dict"
:service "events")
(define-page-helper "ticket-detail-data"
:params (&key code)
:returns "dict"
:service "events")
(define-page-helper "ticket-admin-data"
:params (&key)
:returns "dict"
:service "events")
(define-page-helper "markets-data"
:params (&key)
:returns "dict"
:service "events")
;; Market service
(define-page-helper "all-markets-data"
:params (&key)
:returns "dict"
:service "market")
(define-page-helper "page-markets-data"
:params (&key slug)
:returns "dict"
:service "market")
(define-page-helper "page-admin-data"
:params (&key slug)
:returns "dict"
:service "market")
(define-page-helper "market-home-data"
:params (&key page-slug market-slug)
:returns "dict"
:service "market")
;; --------------------------------------------------------------------------
;; Boundary types — what's allowed to cross the host-SX boundary
;; --------------------------------------------------------------------------
(define-boundary-types
(list "number" "string" "boolean" "nil" "keyword"
"list" "dict" "sx-source" "style-value"))