inmake DOCS
Docs / Modules / The console

The console

The Modules area of CRM & Studio: the catalog, the module page, the review queue.

Documentation everywhere a module is chosen or run. The module page has a Documentation tab (after Overview) rendering the package's docs in the console language (marked + DOMPurify; external links open in a new tab), a catalog card has a Documentation button, and the install page's Grants step links the same dialog — so the guide is readable before anything is installed. A version published before the rule shows an empty state.

The platform review queue is /platform/modules (a sid-less top-level route, meta.platformOnly; linked from the Modules page for platform admins): one card per in_review version with its report, notes, egress and Open in sandbox for its ui/ pages; Approve / Reject (notes required to reject), Check again, Upload to catalog, and — master only — Yank a version.

The Modules area. Modules is its own area on the console's rail (the seventh, before Settings). Its pane has two system pages — Catalog (/store/:sid/modules, visible to a manager or to any member whose develop capability is readable; mutations need a manager) and Upload package (/store/:sid/modules/upload, platform admins only for now) — and an Installed block: one row per installed module (icon, name, a health dot: ok / not configured / failing; disabled ones dimmed) linking to its detail. The Modules page lists installed modules as a table and the catalog as cards grouped by category behind a chip row, each with a UiChip status (not configured / unverified / verified {date} / failing / disabled); a catalog card's Install opens the upload page in install mode (modules/install/:key), whose stepper shows only Grants → Install — one component, two entry points, so "grants before any store is touched" has exactly one implementation.

The upload page (UploadPackageView, four steps: package → check → grants → install / update). Pick the zip; the browser pre-flights it (archive listing, validateManifest, size caps — the same row ids the server emits); the bytes go through the console proxy to POST /system/module/upload with progress; the Check step renders the ModuleCheckReportCard — an error keeps the page there, a warn is shown and the flow continues; the Grants step shows the access ∩ MODULE_MAX_ACCESS and scope trees read-only (the diff against the installed version on an update, via ModuleGrantsDiff: grants widened, schema fields removed, egress added) with the explicit accept; the last step is one button — Install on {store}, Update {store} to {version}, or Submitted for review (platform target, later phase). A managed module (§8.7) shows Runs in: your space cloud on the Grants step instead of an endpoint, and its install / update ends on a Deploying card (the state chip, the function id, the project) that polls /api/module/deploy/status every 15 s until the install lands at the target version, or shows the deploy's error with Try again; a 409 deploy_unavailable is a toast naming the reason. The detail page's About shows Deployed function (URL · project · version) in place of the endpoint.

The detail page (/store/:sid/modules/:id, ModuleView): a header with the module icon, name, the status chip, the hosting chip and the version, an Enabled switch; tabs Overview · Elements · Gallery · Documentation · Data · Logs · Grants (Elements only for a module with a kit or routes.web; Gallery, the Elements page's specimen wall narrowed to the module's own elements, only for a module with a kit). Overview holds the Update available card (release notes, the grant diff, Review and update → the upload page's Grants step), the Configuration card (ModuleConfigCard: non-secret fields, write-only secrets with a set indicator, a public toggle per field, Verify, Save) and the Health table (one row per point: last ok, consecutive failures, timeout, fallback; outbox pending / dead in the foot). The right rail: About (vendor, category

  • tags, source + registry key, installed by / at, grants accepted, endpoint, the drift chip), Data it owns (content collections → the collection view, records collections, state/ key count, the {entity}.modules.{id} fields it may write), Pages & widgets (one link per manifest.admin.pages[] entry → /store/:sid/modules/:id/pages/:page, ModuleFrame — the module's own page in a sandboxed cross-origin iframe with the session-token handshake of §4.2; shown for a connected module that declares pages), Identity (the managed token's note, the hook entry id, the three keys, Reroll keys) and the Danger zone (Uninstall · keep data / Uninstall · purge). Logs lists the outbox rows; Grants shows the installed version's trees read-only with a note on what MODULE_MAX_ACCESS denies. Every mutation is a manager verb; a develop: read editor sees the page.

The Elements tab (components/modules/ModuleElements.vue, one POST /api/module/elements call): a table of the module's kit elements — name + id, a state chip (As shipped / Customized / Conflict / Missing), the version the body is based on — with Edit (opens the library at /store/:sid/elements?element={id}), Duplicate (a derived copy), Reset to module version on a customized row, Replace with the module's element on a conflict (force) and Restore on a missing one (the last three are manager actions; edits need the web capability, not this route's develop). Under the table a live preview (ModuleElementsPreview.vue): a tab per element that is in the library, drawn on the store's design with the module's runtime and the store's real data — its /m/{id}/** requests go to the module read-only, nothing is written (a row's Preview selects it; admin/docs/elements.md "Module elements"). Below it Your elements using this module (the derived and custom ones, "based on {element} · {version}"), a runtime line (size, disabled, or no runtime marker yet), a note when the install is not restamped (stamped: false), and the primary action Build a new element → /store/:sid/elements?module={id}, which opens the library's new element dialog pre-bound to the module. The update card links here ("customized elements are kept"); the disable and uninstall confirmations say what happens to placements. Elsewhere in the console: the element library shows a module chip per row, hides delete on owned elements, offers Duplicate, and shows a note with the computed state on the selected element; the element picker shows the chip, does not offer elements of a disabled module, never embeds a module element and warns on a placement whose module is off (admin/docs/elements.md). Runtime docs are hidden from the library and the picker — only this tab reports them.