- jz_bm_material_file_texts caches the pdftotext output per file
- the River job jz.bm.extract_material_text extracts and resyncs
- the management multipart attach queues it inside its transaction
- file_texts in the document and a file snippet with its name
- Material is a beachcomber Searchable (index jz_bm_materials) in the
hand-written models/material_search.go; jz.bm requires summercms v0.6.4
- classes.MaterialIndexer asks Typesense for up to 250 candidates with
body highlights; the app-wide Gate is on only for jz.bm-marked contexts
- GET /_bm/api/v1/materials takes q: candidates are re-gated, counted and
paged in SQL in rank order, each row with at most one plain snippet
- search failure answers 503 Search is unavailable.; without q the list
is unchanged
A material may be private: only its author and the users it is shared
with see it. Every student read (list, detail, course detail and
counters, the checklist linked material, the token twins) goes through
one visibility fragment. Existing materials stay public with no author.
GET/PUT /_bm/api/v1/materials/{id}/access let the author, a material
manager, toggle the flag and pick the users; the first change of an
author-less material makes the caller its author.
- jz.bm.mcp-links on the token twins and the management API: under MCP,
url and *_url strings starting with a single / get the app base
- material answers under MCP leave the body out unless include_body,
marking it with body_omitted; write answers never echo it
- jz.bm.manage keys a dispatched call by user
- bm_materials and bm_material student tools
Plain HTTP answers are unchanged.
The material admin form gets the "Na zjazd" picker, every student
material JSON carries meeting_id, and GET /materials accepts meeting=
inside the published-only scope, so the Pulpit hero can list the
zjazd's materials next to its readings.
Dashboard, courses with counters, schedule, meetings, deadlines,
readings with per-user progress (mark and unmark) and paginated
published materials with tags and files, behind golem15.user's
jwt.auth. Responses are built field by field with Warsaw RFC 3339
timestamps; bad query parameters answer 422 in Laravel's shape.