Builder Guide
React component catalog and copy/paste kit
Copy styled or unstyled React starters for all first-class capabilities, native page modules, Universal Inbox, GoClaw, menus, shell layouts, data bindings and exact API contracts.
This is the source-driven inventory and copy/paste kit for BuildWithHQ React pages and the tenant shell around them. It covers every documented first-class capability, core blocks, native page modules, Universal Inbox, GoClaw review work, menus, page bootstrap, data bindings, exported browser functions, HTTP routes, VB service members, and reviewed SQL procedures. The generated files live under catalog-generator/generated/.
The current inventory contains 23 first-class capabilities, 23 page SDK/API surfaces, 21 bound page renderers, 166 page-module server operations, 47 additional tenant/design routes, 184 tenant API exports, 12 Design API exports, and 18 Inbox/GoClaw client methods. All 166 page-module operations resolve to reviewed stored-procedure contracts; the generated page-module gap count is 0.
Choose native or custom presentation
| Approach | Use it when | What you own |
|---|---|---|
| Native first-class block | You want the complete module behavior. | Page composition, menu placement, design tokens and permitted block props. BuildWithHQ owns SDK parsing, API calls, authorization-aware states and writes. |
| Unstyled starter | You need your own markup or design system. | Semantic presentation, accessibility and state rendering. Inject the official authenticated loader and keep its parser. |
| Styled starter | You want a production-shaped starting layout. | The same contract as unstyled, plus opt-in CSS. The supplied desktop catalog is left aligned at 280px / flexible / 280px. |
Do not turn a React prop into an authorization decision. The server derives SaaS app, tenant account, user, DataRole and location from verified identity. Browser-supplied record IDs, page keys, filters and binding keys are query targets only.
Every first-class capability
The capability catalog separates native page blocks, tenant-shell components, and background services. Every capability has a generated unstyled and styled explanatory React export. Those cards tell a developer what is available; they do not imitate or replace the secured native behavior.
Universal Inbox shell-component
Collects configured external email, optional support tickets, SMS, web-form submissions, and other inbound communications into one secured attention layer where unsorted work stays visible and routing rules can classify, prioritize, assign, and queue it for action.
| Experience | Inbound work & triage |
|---|---|
| Native page key | Not a page block |
| React implementation | UniversalInbox, UniversalInboxBell |
| API roots | /api/inbox, /api/inbox/items |
What developers can build
- Receive configured inbound email and SMS through native Conversations and messages.
- Let an account owner enable Ticketing per inbound email address and assign stable mailbox-scoped ticket numbers.
- Use New, Open, WaitingCustomer, WaitingInternal, Snoozed, Resolved, and Closed as one controlled ticket-resolution lifecycle.
- Receive web-form submissions and other authenticated inbound source events without losing their native source record.
- Keep unmatched or unsorted items visible for human triage instead of dropping them into a hidden channel silo.
- Apply deterministic routing rules and permitted AI classification to assign queues, owners, tags, priorities, and due/SLA attention.
- Open the full native source context, prepare replies or actions, approve governed suggestions, snooze, reassign, and complete work.
- Increment ActivityVersion when new source activity arrives so stale drafts or actions cannot execute.
Common uses
- One intake queue for support, sales, service, operations, and customer requests.
- A technical-support mailbox with durable ticket identity and resolution state.
- Sorting unknown inbound communication before it reaches a team or person.
- Shared ownership, SLA, escalation, and GoClaw-assisted preparation across external channels.
Security boundary: An item is visible only when the current user can access its source record and effective queue scope. Routing never grants source access. GoClaw preparation, approval, and execution reapply the user's record/DataRole/location envelope, AI-read gate, action permission, and current ActivityVersion.
Checklists & Signoffs page-module
Attaches reusable, versioned checklists to authorized records and lets each item require notes, documents, or photos before the completed run enters the existing Workflow signoff path.
| Experience | Evidence-backed work acceptance |
|---|---|
| Native page key | module.checklists-signoffs |
| React implementation | ChecklistsSignoffsModule |
| API roots | /api/modules/checklists-signoffs |
What developers can build
- Create reusable versioned templates with ordered required or optional items.
- Attach a template snapshot to any authorized universal record.
- Track up to 1,000 ordered run items with completion actor, time, note, and revision.
- Require one or more native File documents or photos as proof for selected items.
- Calculate bounded progress and refuse submission while required work or evidence is missing.
- Submit exactly one current run to the existing Workflow and Universal Inbox approval path.
- Support rejection, editing, proof replacement, resubmission, approval, and replayable history.
- Reject stale revisions and make duplicate completion, submission, and decision requests idempotent.
Common uses
- Work-order inspection and closeout proof.
- Project stage-gate and quality checklists.
- Support-ticket diagnostic or escalation checkoffs.
- Safety, compliance, onboarding, handoff, and document-review signoffs.
Security boundary: Every list, detail, item update, evidence link/download, submission, and decision derives tenant, user, DataRole, Location, and source-record scope from server identity. Evidence links do not grant File access, and Workflow permissions—not checklist UI state—control signoff authority.
Open the complete Checklists & Signoffs implementation guide
GoClaw virtual assistant shell-component
Adds a dedicated virtual assistant to a user account that researches, summarizes, classifies, drafts, and proposes work without ever receiving more access or action authority than that user.
| Experience | Permission-bound AI assistance |
|---|---|
| Native page key | Not a page block |
| React implementation | GoClawApprovalQueue |
| API roots | /api/goclaw/agents, /api/goclaw/approvals |
What developers can build
- Read only records, fields, locations, and Inbox context the represented user may read—and only when AI access is also allowed.
- Research, classify, summarize, draft replies, and prepare structured next actions.
- Create suggestion batches whose evidence, risk, confidence, required permission, and inputs can be reviewed.
- Route material or customer-facing actions through configured policy or human approval before deterministic execution.
- Respect action budgets, leases, retries, stale-context fences, and idempotent execution.
- Record attribution, approval/refusal, tool/action evidence, results, failures, ratings, and correlation history.
Common uses
- Triage and response preparation for permitted Universal Inbox work.
- Account, case, project, support, or operations research and follow-up suggestions.
- A personal daily assistant that reduces preparation work while the user retains decision authority.
Security boundary: GoClaw operates on behalf of one user. Its effective access is the intersection of that user's tenant, DataRole, record, field, location, and action permissions with AI-specific CanAiReadRecords, secure-field exclusions, tool policy, quotas, approval policy, and the current source/Inbox activity version. The result can be narrower than the user's normal access, never wider.
Open the complete GoClaw virtual assistant implementation guide
AI Insights background-service
Runs permission-aware AI analysis in the background each day to create prioritized, evidence-backed insights and governed next actions from meaningful changes in authorized business records.
| Experience | Proactive daily findings |
|---|---|
| Native page key | Not a page block |
| React implementation | No interactive renderer is currently exposed |
| API roots | Background service contracts |
What developers can build
- Run a durable daily background cycle for configured insight types and source scopes.
- Read only AI-eligible records and evidence through tenant, DataRole, field, location, and CanAiReadRecords controls.
- Create structured insights with source record, type/category, title, summary, recommended action, priority, confidence, severity, evidence, model/profile provenance, and lifecycle dates.
- Use source version/context fingerprints and current-state checks to avoid repeatedly presenting stale or duplicate findings.
- Deliver each insight only to users who can currently access its source record; losing source access removes the insight from their secured feed.
- Let each user view, pin, snooze, hide, dismiss, or advance an insight without changing another user's personal feed state.
- Turn a recommended next step into a governed action that still requires the current user's action permission and configured policy or approval.
Common uses
- Daily account risk, opportunity, renewal, follow-up, and customer-health findings.
- Operational exceptions, overdue work, recurring issues, quality changes, and material KPI movement.
- Proactive company-knowledge, case, service, sales, support, or asset insights with evidence links.
Security boundary: Insight generation applies the AI-read envelope before model context is assembled. Insight visibility is inherited from the source record and rechecked at read time. Evidence, recommendations, and actions cannot reveal or operate on records, fields, locations, or tools outside the current user's permissions; material execution uses action-specific permission and policy/approval.
Contacts page-module
Provides a secured contact directory with configurable contact types, search, create/detail experiences, custom fields, relationships, activity, and favorites.
| Experience | People & organizations |
|---|---|
| Native page key | module.contacts |
| React implementation | ContactsModule |
| API roots | /api/modules/contacts |
What developers can build
- Search and browse only the contacts visible to the current user.
- Create contacts with name, company, email, phone, and configurable type fields.
- Show secured contact detail, custom fields, related records, activity, and favorite state.
- Reuse the same contact identity across other modules instead of creating duplicate people records.
Common uses
- Customer and prospect directories.
- Members, vendors, partners, or project stakeholders.
- The person/company context behind conversations, events, work orders, files, and cases.
Security boundary: Contact lists and details apply SaaS, tenant, DataRole, location, record, and field rules. Create and edit controls appear only when secured responses grant the corresponding capability; hidden or encrypted dynamic fields are not returned.
Work Orders page-module
Tracks work requests through a secured lifecycle with number, customer, location, summary, priority, status, assignments, related records, and service evidence.
| Experience | Operational work |
|---|---|
| Native page key | module.work-orders |
| React implementation | WorkOrdersModule |
| API roots | /api/modules/work-orders |
What developers can build
- Search and filter work orders by text and status.
- Create work with summary, description, priority, and optional customer context.
- Move work through the supported status lifecycle with optimistic concurrency.
- Assign team members, designate primary responsibility, and expose related-record counts.
- Let the tenant choose whether Work Order payment collection is disabled, optional, required, manual, at creation, or required before completion.
- Show secured payment history and queue idempotent charges against protected, consented payment methods without exposing card or provider secrets.
Common uses
- Field service and maintenance dispatch.
- Facilities, asset, repair, installation, or inspection follow-up.
- Internal service requests and operational task queues that need a stronger lifecycle than a simple task.
Security boundary: The service limits rows by SaaS app, tenant, DataRole, and location and separately checks create, transition, assignment, and payment authority. The account owner manages payment policy and external connector references. Collection requires the existing CanBillRecords capability plus edit and record scope; customer and assignee identifiers are query/action targets, not proof of access.
Reservations page-module
Turns a bookable product purchase into one secured workflow: contact identity, capacity-protected reservation, protected charge, calendar event, tenant-user assignment, resource booking, and scheduled before/after-service follow-up.
| Experience | Sell, schedule & follow up |
|---|---|
| Native page key | module.reservations |
| React implementation | ReservationsModule |
| API roots | /api/modules/reservations |
What developers can build
- Define bookable products with duration, price/currency, party limits, concurrent capacity, buffers, hold time, and default location, resource, assignee, and follow-up timing.
- Create or safely reuse an authorized Contact and preserve the purchaser's name, email, phone, and notes.
- Create a capacity-protected Reservation and linked Calendar event, with an optional Resource booking and an active tenant user assigned to deliver the service.
- Queue the existing idempotent charge-intent pipeline using a protected payment-method reference; the API never receives card numbers, security codes, processor credentials, or raw payment tokens.
- Keep paid bookings pending and private until the charge worker reports success, then promote the reservation, event, resource, and follow-ups transactionally.
- Track Pending Payment, Requires Action, Confirmed, Checked In, Completed, Cancelled, No Show, and Payment Failed with optimistic concurrency and an audit timeline.
- Schedule separate pre-service and post-service follow-up date/time, recipient email, subject, message, delivery state, attempts, sent time, and outbound-message reference.
- Use idempotency keys to make checkout retries safe and prevent duplicate contacts, charges, calendar events, and reservations.
- Let the tenant account owner choose disabled, optional, or required collection; creation, manual, or completion timing; full or deposit collection; partial-payment rules; currency; minimum charge; and paid-before-completion enforcement.
- Give users with the existing billing capability a secured balance, payment history, charge history, and protected charge action for the reservation record.
Common uses
- Paid consultations and professional-service appointments.
- Tours, classes, lessons, events, and capacity-limited sessions.
- Installations, inspections, salon/wellness visits, rentals, and service calls.
- Free appointments that still need contact, calendar, assignment, capacity, and follow-up.
Security boundary: List/detail access is inherited from secured universal Records. Product management and mutations require current DataRole capability. Locations and contact targets are revalidated in the user's scope, assignees must be active tenant users, capacity is fenced transactionally, and identity comes from verified server context. The tenant account owner controls payment policy and connector references; collection requires the existing CanBillRecords capability plus record scope. Raw card data and provider credentials are never accepted or persisted by Reservations.
Calendar page-module
Provides secured month/agenda scheduling for events, attendees, resources, reminders, locations, private events, custom fields, relationships, activity, and favorites.
| Experience | Time & scheduling |
|---|---|
| Native page key | module.calendar |
| React implementation | CalendarModule |
| API roots | /api/modules/calendar |
What developers can build
- Browse monthly event ranges and search visible events.
- Create timed or all-day events with location, reminder, color, and privacy settings.
- Show attendee responses, resource bookings, custom fields, related records, and activity.
- Favorite important events and connect them to customers, projects, work orders, or cases.
Common uses
- Customer meetings and project milestones.
- Technician visits, inspections, shifts, or resource schedules.
- Renewal dates, campaign launches, approval deadlines, and case hearings.
Security boundary: Calendar queries enforce tenant, DataRole, location, and private-event rules. Attendees and related records are independently secured, and event creation/editing requires the corresponding server permission.
Files & attachments page-module
Provides private file upload, download, metadata, tags, record attachments, comments, locks, custom fields, relationships, activity, and favorites without exposing storage coordinates.
| Experience | Documents & evidence |
|---|---|
| Native page key | module.files |
| React implementation | FilesModule |
| API roots | /api/modules/files |
What developers can build
- Search and filter secured file metadata by name and content type.
- Upload, describe, tag, edit, and privately download authorized files.
- Attach one file to multiple permitted records without duplicating the binary.
- Show comments, locks, custom fields, relations, activity, and favorite state.
Common uses
- Customer and project documents.
- Inspection photos, work-order evidence, manuals, and invoices.
- Case evidence, knowledge source files, and signed approvals.
Security boundary: Download and upload flow through authenticated backend endpoints. The browser never receives provider credentials, tenant database identity, storage paths, or unrestricted object-store locations; attachment targets are reauthorized independently.
Conversations & messages page-module
Provides native channel threads with participants, messages, status, priority, internal notes, outbound replies, related context, activity, dynamic fields, and favorites.
| Experience | Customer & team communication |
|---|---|
| Native page key | module.conversations |
| React implementation | ConversationsModule |
| API roots | /api/modules/conversations |
What developers can build
- Search and filter conversation threads by status.
- Create internal conversations and manage subject, priority, and lifecycle.
- Read escaped message history and post internal notes or permitted outbound replies.
- Expose unread/favorite state, dynamic fields, related records, and activity.
Common uses
- Customer support and success communication.
- Project, sales, case, and operations correspondence.
- The native thread behind Universal Inbox triage and governed AI suggestions.
Security boundary: Conversation, message, channel, DataRole, and location access is enforced server-side. Outbound capability and edit rights are explicit; provider credentials and direct channel endpoints never reach the browser.
Open the complete Conversations & messages implementation guide
Company news page-module
Publishes searchable internal announcements with draft, scheduled, published, and expired visibility, author controls, custom fields, relationships, activity, and favorites.
| Experience | Announcements |
|---|---|
| Native page key | module.company-news |
| React implementation | CompanyNewsModule |
| API roots | /api/modules/company-news |
What developers can build
- Search visible announcements and open their secured detail.
- Author and edit announcements only when the response grants edit permission.
- Control draft, scheduled, published, and expired visibility.
- Connect announcements to records, activity, custom fields, and personal favorites.
Common uses
- Internal news and release announcements.
- Location-specific closures, safety notices, or operating updates.
- Policy and program communications linked to supporting records or files.
Security boundary: Publication state, SaaS, tenant, DataRole, and location are evaluated by secured reads. Announcement bodies render as escaped text, and authoring controls depend on server-reported permission.
Knowledge Core page-module
Turns tenant knowledge into owned, revisioned, reviewable records that connect to business context, answer questions, support permission-aware AI/RAG, and learn safely from resolved support work.
| Experience | Maintained, cited knowledge |
|---|---|
| Native page key | module.knowledge-articles |
| React implementation | KnowledgeArticlesModule |
| API roots | /api/modules/knowledge-articles, /api/modules/knowledge-core |
What developers can build
- Create Draft knowledge and publish or archive it through permission-checked lifecycle actions.
- Preserve immutable revisions, publication history, authority, AI eligibility, and optimistic-concurrency evidence.
- Assign one primary accountable owner to a user or DataRole and schedule recurring review work.
- Relate knowledge to any authorized RecordId and retrieve bounded contextual knowledge without copying the business record.
- Capture unanswered questions, repeated occurrences, usage, feedback, and secured knowledge-gap signals.
- Register only Published, AI-eligible revisions for secured semantic/multimodal retrieval with exact citations.
- Bring current support knowledge into fenced GoClaw Inbox context and turn resolved cases into sanitized Draft candidates.
Common uses
- Owned product documentation, policies, procedures, FAQs, and employee help.
- Customer-safe help centers and support answers with exact current citations.
- Contextual playbooks linked to customers, products, cases, work orders, files, and conversations.
- Permission-aware AI/RAG sources whose authority and freshness must be inspectable.
- A controlled support learning loop that turns reusable resolutions into reviewable Drafts.
Security boundary: Every list, item, relation, review, question, feedback, support-context, and AI path derives the SaaS app, tenant, user, DataRole, location, record, field, and permission scope from verified server identity. CanAiReadRecords is required before AI context. Publication, ownership, review, support learning, and archive actions have separate permission checks; customer-visible context excludes internal-only sources.
Web links page-module
Maintains searchable, categorized, location-aware external links with descriptions, custom fields, relationships, activity, and favorites.
| Experience | Curated external resources |
|---|---|
| Native page key | module.web-links |
| React implementation | WebLinksModule |
| API roots | /api/modules/web-links |
What developers can build
- Search links and filter them by category.
- Create and edit title, URL, description, category, and custom fields.
- Open only contract-validated HTTP or HTTPS destinations in an isolated browsing context.
- Relate and favorite links while preserving location-aware access.
Common uses
- Team resource directories.
- Customer/vendor portals and external documentation.
- Research links connected to cases, projects, accounts, or knowledge.
Security boundary: The server accepts strict host-based HTTP(S) URLs without embedded credentials. The runtime opens destinations with an isolated external context and applies normal tenant, DataRole, and location checks to the link record.
Chat rooms page-module
Provides secured team rooms with messages, unread state, membership, room administration, mute settings, reactions, archives, custom fields, relations, activity, and favorites.
| Experience | Real-time team discussion |
|---|---|
| Native page key | module.chat-rooms |
| React implementation | ChatRoomsModule |
| API roots | /api/modules/chat-rooms |
What developers can build
- Search active or archived rooms and see unread counts.
- Create/edit rooms, post messages, and react with bounded reaction types.
- Manage members, room administrators, mute state, and archive state when authorized.
- Show location, dynamic fields, related records, activity, and favorites.
Common uses
- Project or operations team chat.
- Location, department, incident, or customer team rooms.
- Informal collaboration adjacent to records that retain the formal work state.
Security boundary: Room visibility and posting require both normal tenant/DataRole/location access and current membership/room capability. Member administration, editing, and archiving are separately authorized.
Discussion boards page-module
Provides boards, topics, threaded posts, replies, pin/lock moderation, archives, owned-post editing, custom fields, relations, activity, and favorites.
| Experience | Structured community discussion |
|---|---|
| Native page key | module.discussion-boards |
| React implementation | DiscussionBoardsModule |
| API roots | /api/modules/discussion-boards |
What developers can build
- Search active or archived boards and browse topic/post counts.
- Create boards and topics, reply to topics, and edit owned or otherwise authorized content.
- Pin or lock topics and archive boards with the required moderation capability.
- Favorite boards/topics and show secured relations, activity, location, and dynamic fields.
Common uses
- Customer or partner communities.
- Internal Q&A, proposals, and long-running technical discussions.
- Program, project, or policy forums that benefit from topic-level history.
Security boundary: Board, topic, and post operations enforce tenant, DataRole, location, ownership, and moderation rules. Locked topics refuse ordinary replies, and edit controls reflect secured response capabilities.
Mail reader page-module
Provides a read-focused view across authorized personal/shared mail accounts with search, unread filtering, plain-text message detail, read state, relations, activity, dynamic fields, and favorites.
| Experience | Secured inbound mail |
|---|---|
| Native page key | module.mail-reader |
| React implementation | MailReaderModule |
| API roots | /api/modules/mail-reader |
What developers can build
- Select authorized personal or shared accounts and view unread counts.
- Search messages and filter unread mail.
- Read safe plain-text headers, previews, and bodies; raw HTML is not rendered.
- Mark permitted messages read/unread and connect them to favorites, relations, activity, and custom fields.
Common uses
- Shared operations or support mailbox review.
- Account/project email research linked to business records.
- Read-focused compliance or case correspondence views.
Security boundary: Account ownership/shared access, SaaS, tenant, DataRole, and location are enforced server-side. Incoming-server settings, credential references, raw HTML, and private provider details are excluded from browser responses.
Favorites page-module
Gives each user a secured cross-module list of saved records with search, module filters, pinning, change tracking, related context, activity, and dynamic fields.
| Experience | Personal workspace |
|---|---|
| Native page key | module.favorites |
| React implementation | FavoritesModule |
| API roots | /api/modules/favorites |
What developers can build
- Search personal favorites and filter by source module.
- Pin, reorder, remove, and optionally track changes on saved records.
- Show current secured status, location, relations, activity, and dynamic fields.
- Collapse duplicate favorite targets into a coherent personal workspace.
Common uses
- Pinned customers, projects, cases, files, or articles.
- A personal watch list for records whose changes matter.
- Cross-module navigation for frequently used work.
Security boundary: Only the current user's favorite rows are returned. Target records, related records, fields, activity, and location are independently secured, so a favorite never preserves access after permission is removed.
Notifications page-module
Provides recipient-scoped alerts with unread filtering, detail, dismissal, source-record context, relations, activity, and source favorites.
| Experience | Personal alerts |
|---|---|
| Native page key | module.notifications |
| React implementation | NotificationsModule |
| API roots | /api/modules/notifications |
What developers can build
- Search current-recipient notifications and filter unread items.
- Open bounded detail and mark or dismiss notification state.
- Show a permitted source title, location, relations, and activity.
- Favorite an authorized source record directly from the notification.
Common uses
- Assignment, mention, publication, and status-change alerts.
- Workflow completion, failure, or approval attention.
- Personal reminders that link back to the canonical source record.
Security boundary: Only rows for the current recipient and app/account are returned. Linked source metadata appears only after its normal DataRole and location checks; the browser cannot submit recipient or permission authority.
Dynamic/custom records page-module
Renders tenant-owned custom modules from their validated field schema with secured list, search, create, detail, edit, status, relations, activity, and favorites.
| Experience | Builder-defined data |
|---|---|
| Native page key | module.dynamic-records |
| React implementation | DynamicModulesModule |
| API roots | /api/modules/dynamic |
What developers can build
- Load only a validated tenant-owned module key supplied by the page contract.
- Render the public field schema while excluding hidden and encrypted fields.
- Search, create, inspect, edit, and change status according to existing permissions.
- Participate in relations, activity, location scope, and favorites through universal RecordId.
Common uses
- Industry-specific business objects.
- Rapidly modeled MVP records and internal tools.
- Reusable template-defined objects that do not need a specialized native experience.
Security boundary: The server accepts only tenant-owned custom module keys and refuses generic access to built-in modules. Field schema, DataRole, field, record, and location rules determine which values and controls are returned.
Open the complete Dynamic/custom records implementation guide
ActiveWorkplace page-module
Pins any permitted Record into a collaborative workplace over its secured recursive relationship graph, with people, GoClaws, workflows, Record Pulse, Inbox attention, activity, and read-only Graph Playback.
| Experience | Recursive work coordination |
|---|---|
| Native page key | module.active-workplace |
| React implementation | ActiveWorkplaceModule |
| API roots | /api/modules/active-workplace |
What developers can build
- Pin any currently permitted Record once as the workplace root.
- Capture a cycle-safe, bounded Active Graph over existing typed Record Relations.
- Coordinate named users, GoClaw assistants, and published workflows with explicit responsibilities.
- Track Active, Waiting, At Risk, Stale, Dormant, and Resolved Record Pulse states.
- Create or touch one Universal Inbox attention item when a workplace becomes At Risk or Stale.
- Record meaningful comments, participant changes, status transitions, related-record changes, and graph refreshes in an immutable activity stream.
- Reconstruct retained workplace, participant, graph, and activity state through unmistakably read-only Graph Playback while applying current permissions.
- Accept bounded builder defaults for root modules, graph depth/nodes, stale timing, participant types, GoClaw watchers, comments, and playback.
Common uses
- Complex customer, case, opportunity, project, asset, incident, contract, or collections coordination.
- A Wave-like shared work surface around connected records without copying those records.
- Cross-team handoffs where responsibilities, inactivity, dependencies, and history must stay visible.
- GoClaw monitoring and workflow participation under the same permissions and approvals as the rest of the app.
Security boundary: The server derives app, account, user, DataRole, and locations. Root creation requires current read/edit access; each displayed graph node is reauthorized; GoClaw assignment requires independent AI-read access; and playback applies current authorization before returning any retained identity or event. Direct table access is denied to runtime and Pulse-worker roles.
Record relations page-module
Explores authorized records as a bounded relationship graph and supports typed relation creation/removal only when both endpoints are editable.
| Experience | Connected context |
|---|---|
| Native page key | module.record-graph |
| React implementation | RecordGraphModule |
| API roots | /api/modules/record-graph |
What developers can build
- Search visible seed records across modules.
- Traverse secured relationships through bounded depth levels.
- Show nodes, typed edges, module, location, status, activity counts, and favorites.
- Add or remove a typed relation only when both record endpoints and the relation operation are authorized.
Common uses
- Customer/account 360-degree context.
- Case, project, asset, and work dependency exploration.
- Impact analysis and relationship-first CRM experiences.
Security boundary: Every traversed node is independently checked for SaaS, tenant, DataRole, record, and location visibility. Inaccessible nodes and edges are omitted, and mutation requires edit authority on both endpoints.
Record activity page-module
Shows a paged, filterable, chronological activity timeline for an authorized record with actor, event type/state, date range, relations, and favorite state.
| Experience | Timeline & history |
|---|---|
| Native page key | module.record-activity |
| React implementation | RecordActivityModule |
| API roots | /api/modules/record-activity |
What developers can build
- Search visible records across modules and select a record timeline.
- Filter activity by event type and date range.
- Group events chronologically with summary, actor, state, and occurrence time.
- Page bounded history and show secured relation/favorite context.
Common uses
- Customer, project, work-order, case, and asset timelines.
- Operational handoffs and investigation context.
- A user-facing history adjacent to formal compliance/audit evidence.
Security boundary: The selected record must pass normal scope checks, and only safe activity summaries/metadata are rendered. Private event detail payloads stay outside the browser surface.
Global secured search page-module
Searches permitted records across modules and also uses permission-filtered vector retrieval to find meaningfully related information in indexed uploads, PDFs, images, screenshots, tables, diagrams, and text.
| Experience | Cross-module discovery |
|---|---|
| Native page key | module.global-search |
| React implementation | GlobalSearchModule |
| API roots | /api/modules/global-search |
What developers can build
- Run bounded text search across authorized modules and records.
- Search eligible indexed uploads, PDFs, images, screenshots, tables, diagrams, and extracted text in a shared vector space.
- Find conceptually related information even when the source uses different words from the query.
- Retrieve the original text, page, image, and source identity so results can retain evidence and citations.
- Filter by module and page through stable result envelopes.
- Show safe matched-field snippets plus module, status, location, relation, activity, and update context.
- Add or remove favorites without leaving the result list.
Common uses
- App-wide command and search experiences.
- Finding a record when its owning module is unknown.
- Discovering related material across records and uploaded documents.
- Finding a PDF page, image, screenshot, chart, table, or diagram from a natural-language description.
- Cross-module navigation in relationship-heavy applications.
Security boundary: The server applies SaaS, tenant, CanAiReadRecords, DataRole, location, record, field, and AI-eligibility rules before vector candidates or visual evidence can be returned. Unindexed, deleted, AI-excluded, or otherwise unauthorized content is absent from results. Relevance never grants access, and counts, snippets, citations, and related context must not reveal inaccessible records or fields.
Open the complete Global secured search implementation guide
Styled preview
First-class module
Universal Inbox
Waiting for customer
New and unassigned
The unstyled exports contain the same landmarks, labels, lists, tables, loading state, empty state and error state without any CSS dependency.
Start a complete page
The safest custom page starts with the official runtime bootstrap and renderer. The browser supplies only the page key. The server returns the applicable shell, menu, component contracts and authorized page document.
import { useEffect, useState, type ReactNode } from "react";
import type { RuntimeBootstrap } from "@buildwithhq/page-runtime";
export interface RuntimePageStarterProps {
readonly pageKey: string;
readonly loadBootstrap: (pageKey: string) => Promise<RuntimeBootstrap>;
readonly renderBootstrap: (bootstrap: RuntimeBootstrap) => ReactNode;
readonly styled?: boolean;
}
export const RuntimePageStarter = ({ pageKey, loadBootstrap, renderBootstrap, styled = false }: RuntimePageStarterProps) => {
const [bootstrap, setBootstrap] = useState<RuntimeBootstrap | null>(null);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
let active = true;
setBootstrap(null); setError(null);
void loadBootstrap(pageKey).then((value) => { if (active) setBootstrap(value); })
.catch((failure: unknown) => { if (active) setError(failure instanceof Error ? failure.message : "Page unavailable."); });
return () => { active = false; };
}, [loadBootstrap, pageKey]);
return <main className={styled ? "bwhq-runtime-page" : undefined}>
{!bootstrap && !error && <p role="status">Loading page…</p>}
{error && <p role="alert">{error}</p>}
{bootstrap && renderBootstrap(bootstrap)}
</main>;
};
/* In apps/tenant-runtime, wire this to loadRuntimeBootstrap and RuntimePageRenderer.
Authentication is already held by the official API client; do not add SaaSAppId,
AppAccountId, UserId, DataRole or database-name props to this component. */
Inside apps/tenant-runtime, pass loadRuntimeBootstrap as loadBootstrap and render with RuntimePageRenderer. Keep the existing in-memory authenticated client; do not create a second token store.
Core page blocks
| Component key | Purpose | Registry source |
|---|---|---|
core.button | Button | packages/ui/src/index.tsx |
core.container | Container | packages/ui/src/index.tsx |
core.data-grid | Data Grid | packages/ui/src/index.tsx |
core.form | Form | packages/ui/src/index.tsx |
core.record-list | Record List | packages/ui/src/index.tsx |
core.text | Text | packages/ui/src/index.tsx |
Every block requires stable _id, _type, props, and children. The current runtime accepts up to 5,000 blocks and 60 levels of depth. A block type must have a returned component contract or it fails closed as unavailable.
Menus and user types
A menu item is a Page, Group, Module, or External target. Page items point to shared pageKey values; they do not copy page content. User Types choose the intended menu and dashboard, while DataRoles and Locations independently authorize the resulting data.
const menu = [
{ id: "work", label: "Work", targetType: "Group", sortOrder: 10 },
{ id: "inbox", parentId: "work", label: "Inbox", targetType: "Page", pageKey: "inbox", sortOrder: 10 },
{ id: "contacts", parentId: "work", label: "Contacts", targetType: "Page", pageKey: "contacts", sortOrder: 20 },
] satisfies readonly BuildWithHQMenuItem[];
<BuildWithHQMenu
items={menu}
activePageKey={pageKey}
resolvePageHref={(key) => `/?page=${encodeURIComponent(key)}`}
styled
/>
Copy the complete styled/unstyled menu component
import type { ReactNode } from "react";
export interface BuildWithHQMenuItem {
readonly id: string;
readonly parentId?: string | null;
readonly label: string;
readonly iconKey?: string | null;
readonly targetType: "Page" | "Group" | "Module" | "External";
readonly pageKey?: string | null;
readonly url?: string | null;
readonly sortOrder: number;
}
export interface BuildWithHQMenuProps {
readonly items: readonly BuildWithHQMenuItem[];
readonly activePageKey?: string;
readonly resolvePageHref: (pageKey: string) => string;
readonly icon?: (iconKey: string) => ReactNode;
readonly styled?: boolean;
}
const safeExternalUrl = (value: string | null | undefined): string | undefined => {
if (!value || value.length > 2000) return undefined;
try {
const url = new URL(value);
return url.protocol === "https:" && !url.username && !url.password ? url.toString() : undefined;
} catch { return undefined; }
};
export const BuildWithHQMenu = ({ items, activePageKey, resolvePageHref, icon, styled = false }: BuildWithHQMenuProps) => {
const roots = items.filter((item) => !item.parentId).sort((left, right) => left.sortOrder - right.sortOrder);
const renderItem = (item: BuildWithHQMenuItem): ReactNode => {
const children = items.filter((candidate) => candidate.parentId === item.id).sort((left, right) => left.sortOrder - right.sortOrder);
if (item.targetType === "Group") return <li key={item.id}><span>{item.iconKey && icon?.(item.iconKey)}{item.label}</span>{children.length > 0 && <ul>{children.map(renderItem)}</ul>}</li>;
const href = item.targetType === "Page" && item.pageKey ? resolvePageHref(item.pageKey)
: item.targetType === "External" ? safeExternalUrl(item.url) : undefined;
return <li key={item.id}>{href ? <a href={href} aria-current={item.pageKey === activePageKey ? "page" : undefined}>{item.iconKey && icon?.(item.iconKey)}{item.label}</a> : <span aria-disabled="true">{item.label}</span>}</li>;
};
return <nav aria-label="Application" className={styled ? "bwhq-app-menu" : undefined}><ul>{roots.map(renderItem)}</ul></nav>;
};Tenant workspace and shell components
The page renderer is only the center stage. Universal Inbox, the Inbox bell, GoClaw approval review, Assets, document metadata and the owner-only Design studio are shell surfaces in the current application. The generated workspace shell keeps the menu left-aligned, gives the middle column all remaining width, and reserves an optional 280px context rail.
| Component | Import/source | Current use | Props observed in App |
|---|---|---|---|
GoClawApprovalQueue | @buildwithhq/universal-inbox | apps/tenant-runtime/src/App.tsx:256 | client, onClose, onOpenInbox |
RuntimeAssetManager | ./RuntimeAssetManager | apps/tenant-runtime/src/App.tsx:282 | onClose |
RuntimeDocumentMetadata | ./RuntimeDocumentMetadata | apps/tenant-runtime/src/App.tsx:220 | page |
RuntimePageRenderer | ./PageRenderer | apps/tenant-runtime/src/App.tsx:331 | components, page |
SaasDesignStudio | ./SaasDesignStudio | apps/tenant-runtime/src/App.tsx:290 | components, onClose, onPublished, saasAppId |
UniversalInbox | @buildwithhq/universal-inbox | apps/tenant-runtime/src/App.tsx:275 | client, initialInboxItemId, key |
UniversalInboxBell | @buildwithhq/universal-inbox | apps/tenant-runtime/src/App.tsx:242 | client, onOpenInbox |
Copy the styled/unstyled workspace shell
import type { ReactNode } from "react";
export interface TenantWorkspaceShellProps {
readonly applicationName: string;
readonly pageTitle: string;
readonly menu: ReactNode;
readonly children: ReactNode;
readonly headerActions?: ReactNode;
readonly contextPanel?: ReactNode;
readonly styled?: boolean;
}
const TenantWorkspaceShellBody = ({ applicationName, pageTitle, menu, children, headerActions, contextPanel, styled = false }: TenantWorkspaceShellProps) => (
<div className={styled ? "bwhq-workspace" : undefined}>
<header className={styled ? "bwhq-workspace__header" : undefined}>
<div><p>{applicationName}</p><h1>{pageTitle}</h1></div>
{headerActions && <div aria-label="Page actions">{headerActions}</div>}
</header>
<div className={styled ? "bwhq-workspace__columns" : undefined}>
<aside aria-label="Application menu" className={styled ? "bwhq-workspace__menu" : undefined}>{menu}</aside>
<main className={styled ? "bwhq-workspace__main" : undefined}>{children}</main>
{contextPanel && <aside aria-label="Page context" className={styled ? "bwhq-workspace__context" : undefined}>{contextPanel}</aside>}
</div>
</div>
);
export const UnstyledTenantWorkspaceShell = (props: Omit<TenantWorkspaceShellProps, "styled">) =>
<TenantWorkspaceShellBody {...props} styled={false} />;
export const StyledTenantWorkspaceShell = (props: Omit<TenantWorkspaceShellProps, "styled">) =>
<TenantWorkspaceShellBody {...props} styled />;Copy Universal Inbox, support-ticket and GoClaw starters
import { useEffect, useState } from "react";
import {
GoClawApprovalQueue,
UniversalInbox,
type ApprovalQueueClient,
type ApprovalQueueItem,
type InboxQueueItem,
type UniversalInboxClient,
} from "@buildwithhq/universal-inbox";
interface InboxStarterProps {
readonly client: UniversalInboxClient;
readonly ticketingOnly?: boolean;
readonly assignedToMe?: boolean;
readonly onOpen?: (inboxItemId: string) => void;
readonly styled?: boolean;
}
export const HeadlessInboxQueueStarter = ({ client, ticketingOnly, assignedToMe, onOpen, styled = false }: InboxStarterProps) => {
const [items, setItems] = useState<readonly InboxQueueItem[]>([]);
const [error, setError] = useState<string>();
const [loading, setLoading] = useState(true);
useEffect(() => {
const controller = new AbortController();
setLoading(true); setError(undefined);
void client.list({ ticketingOnly, assignedToMe, topN: 100 }, controller.signal)
.then(setItems)
.catch((failure: unknown) => { if (!controller.signal.aborted) setError(failure instanceof Error ? failure.message : "Inbox unavailable."); })
.finally(() => { if (!controller.signal.aborted) setLoading(false); });
return () => controller.abort();
}, [assignedToMe, client, ticketingOnly]);
return <section aria-busy={loading} className={styled ? "bwhq-headless-list" : undefined}>
<h2>{ticketingOnly ? "Support tickets" : "Universal Inbox"}</h2>
{loading && <p role="status">Loading inbox…</p>}
{error && <p role="alert">{error}</p>}
{!loading && !error && items.length === 0 && <p>No visible work.</p>}
<ul>{items.map((item) => <li key={item.inboxItemId}><button type="button" onClick={() => onOpen?.(item.inboxItemId)}><strong>{item.ticket?.key ? item.ticket.key + " · " : ""}{item.subject || item.source.sourceType}</strong><span>{item.status} · {item.previewText || "No preview"}</span></button></li>)}</ul>
</section>;
};
interface ApprovalStarterProps {
readonly client: ApprovalQueueClient;
readonly onOpen?: (item: ApprovalQueueItem) => void;
readonly styled?: boolean;
}
export const HeadlessApprovalQueueStarter = ({ client, onOpen, styled = false }: ApprovalStarterProps) => {
const [items, setItems] = useState<readonly ApprovalQueueItem[]>([]);
const [error, setError] = useState<string>();
useEffect(() => {
const controller = new AbortController();
void client.list(100, controller.signal).then(setItems)
.catch((failure: unknown) => { if (!controller.signal.aborted) setError(failure instanceof Error ? failure.message : "Approval queue unavailable."); });
return () => controller.abort();
}, [client]);
return <section className={styled ? "bwhq-headless-list" : undefined}>
<h2>GoClaw approval work</h2>{error && <p role="alert">{error}</p>}
<ul>{items.map((item) => <li key={item.suggestionBatchId}><button type="button" onClick={() => onOpen?.(item)}><strong>{item.subject || item.summary || item.sourceType}</strong><span>{item.batchStatus}{item.isStale ? " · stale" : ""}</span></button></li>)}</ul>
</section>;
};
/* These two exports preserve the complete native behaviors. The bare export adds
no wrapper CSS, but the native package intentionally ships its own module CSS. */
export const BareNativeUniversalInbox = (props: { readonly client: UniversalInboxClient; readonly initialInboxItemId?: string }) =>
<UniversalInbox {...props} />;
export const FramedNativeUniversalInbox = (props: { readonly client: UniversalInboxClient; readonly initialInboxItemId?: string }) =>
<div className="bwhq-native-frame"><UniversalInbox {...props} /></div>;
export const BareNativeGoClawApprovalQueue = (props: { readonly client: ApprovalQueueClient }) =>
<GoClawApprovalQueue {...props} />;
export const FramedNativeGoClawApprovalQueue = (props: { readonly client: ApprovalQueueClient }) =>
<div className="bwhq-native-frame"><GoClawApprovalQueue {...props} /></div>;The native Universal Inbox and GoClaw components intentionally import their production CSS. A “bare native” wrapper adds no frame but does not remove that CSS. The headless list exports are presentation starters only; use the native component for the complete ticket, human-state, workflow and approval lifecycle unless you deliberately implement every needed typed client action.
Custom data bindings
A binding key resolves through /api/runtime/data/{bindingKey} and sp_ResolveDataBindingByKey to an approved sp_ds_* operation. The runtime derives identity, validates the configured JSON root, and caps the result. It never accepts ad-hoc SQL, a connection string, credentials, or a browser-selected tenant database.
Copy the complete styled/unstyled data list
import { useEffect, useState, type ReactNode } from "react";
export type JsonValue = string | number | boolean | null | JsonValue[] | { readonly [key: string]: JsonValue };
export type DataBindingLoader = (bindingKey: string, signal: AbortSignal) => Promise<{ readonly data: JsonValue }>;
export interface DataBoundListProps<T> {
readonly bindingKey: string;
readonly loadBinding: DataBindingLoader;
readonly selectItems: (data: JsonValue) => readonly T[];
readonly itemKey: (item: T) => string;
readonly renderItem: (item: T) => ReactNode;
readonly emptyMessage?: string;
readonly styled?: boolean;
}
export function DataBoundList<T>({ bindingKey, loadBinding, selectItems, itemKey, renderItem, emptyMessage = "No visible records.", styled = false }: DataBoundListProps<T>) {
const [items, setItems] = useState<readonly T[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const controller = new AbortController();
setLoading(true); setError(null);
void loadBinding(bindingKey, controller.signal)
.then((result) => setItems(selectItems(result.data)))
.catch((failure: unknown) => { if (!controller.signal.aborted) setError(failure instanceof Error ? failure.message : "Data source unavailable."); })
.finally(() => { if (!controller.signal.aborted) setLoading(false); });
return () => controller.abort();
}, [bindingKey, loadBinding, selectItems]);
return <section aria-busy={loading} className={styled ? "bwhq-data-list" : undefined}>
{loading && <p role="status">Loading…</p>}
{error && <p role="alert">{error}</p>}
{!loading && !error && items.length === 0 && <p>{emptyMessage}</p>}
{!loading && !error && items.length > 0 && <ul>{items.map((item) => <li key={itemKey(item)}>{renderItem(item)}</li>)}</ul>}
</section>;
}First-class module recipes
Use an unstyled native block when the module alone is sufficient. Use its styled composition to place a supported core.text heading and the module inside a supported stack container. Both invoke the same native renderer and secured API.
Every module and operation
Expand a surface to copy both page-block forms and inspect every browser → HTTP → service → SQL chain. “Server API only” means the endpoint is implemented but the bundled component does not currently call it. “Not observed” means no runtime observation file was supplied; it is not a failure claim.
Active Workplace module.active-workplace 11 operations
API base: /api/modules/active-workplace
Renderer: ActiveWorkplaceModule
SDK descriptor: packages/module-sdk/src/activeWorkplace.ts:1
Unstyled native block
{
"_id": "active-workplace-module",
"_type": "module.active-workplace",
"props": {
"title": "Active Workplace"
},
"children": []
}Styled composition
{
"_id": "active-workplace-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "active-workplace-heading",
"_type": "core.text",
"_parent": "active-workplace-section",
"props": {
"text": "Active Workplace",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "active-workplace-module",
"_type": "module.active-workplace",
"props": {
"title": "Active Workplace"
},
"children": [],
"_parent": "active-workplace-section"
}
]
}
| HTTP route | Browser function | Service member | Reviewed procedure | Evidence |
|---|---|---|---|---|
GET/api/modules/active-workplace | listActiveWorkplaces | ITenantActiveWorkplaceService.ListAsync | sp_ActiveWorkplace_ListSecured | declared-interface not-observed |
POST/api/modules/active-workplace | createActiveWorkplace | ITenantActiveWorkplaceService.CreateAsync | sp_ActiveWorkplace_CreateSecured | declared-interface not-observed |
GET/api/modules/active-workplace/{activeWorkplaceId:guid} | getActiveWorkplace | ITenantActiveWorkplaceService.GetAsync | sp_ActiveWorkplace_GetSecured | declared-interface not-observed |
PATCH/api/modules/active-workplace/{activeWorkplaceId:guid} | updateActiveWorkplace | ITenantActiveWorkplaceService.UpdateAsync | sp_ActiveWorkplace_UpdateSecured | declared-interface not-observed |
POST/api/modules/active-workplace/{activeWorkplaceId:guid}/status | setActiveWorkplaceStatus | ITenantActiveWorkplaceService.SetStatusAsync | sp_ActiveWorkplace_SetStatusSecured | declared-interface not-observed |
GET/api/modules/active-workplace/{activeWorkplaceId:guid}/participants/catalog | getActiveWorkplaceParticipantCatalog | ITenantActiveWorkplaceService.GetParticipantCatalogAsync | sp_ActiveWorkplace_GetParticipantCatalogSecured | declared-interface not-observed |
POST/api/modules/active-workplace/{activeWorkplaceId:guid}/participants | addActiveWorkplaceParticipant | ITenantActiveWorkplaceService.AddParticipantAsync | sp_ActiveWorkplace_AddParticipantSecured | declared-interface not-observed |
DELETE/api/modules/active-workplace/{activeWorkplaceId:guid}/participants/{activeWorkplaceParticipantId:guid} | removeActiveWorkplaceParticipant | ITenantActiveWorkplaceService.RemoveParticipantAsync | sp_ActiveWorkplace_RemoveParticipantSecured | declared-interface not-observed |
POST/api/modules/active-workplace/{activeWorkplaceId:guid}/activity | recordActiveWorkplaceActivity | ITenantActiveWorkplaceService.RecordActivityAsync | sp_ActiveWorkplace_RecordActivitySecured | declared-interface not-observed |
POST/api/modules/active-workplace/{activeWorkplaceId:guid}/graph/refresh | refreshActiveWorkplaceGraph | ITenantActiveWorkplaceService.RefreshGraphAsync | sp_ActiveWorkplace_RefreshGraphSecured | declared-interface not-observed |
GET/api/modules/active-workplace/{activeWorkplaceId:guid}/playback | getActiveWorkplacePlayback | ITenantActiveWorkplaceService.GetPlaybackAsync | sp_ActiveWorkplace_GetPlaybackSecured | declared-interface not-observed |
Ai Insights module.ai-insights 3 operations
API base: /api/modules/ai-insights
Renderer: AiInsightsModule
SDK descriptor: packages/module-sdk/src/aiInsights.ts:1
Unstyled native block
{
"_id": "ai-insights-module",
"_type": "module.ai-insights",
"props": {
"title": "Ai Insights"
},
"children": []
}Styled composition
{
"_id": "ai-insights-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "ai-insights-heading",
"_type": "core.text",
"_parent": "ai-insights-section",
"props": {
"text": "Ai Insights",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "ai-insights-module",
"_type": "module.ai-insights",
"props": {
"title": "Ai Insights"
},
"children": [],
"_parent": "ai-insights-section"
}
]
}
| HTTP route | Browser function | Service member | Reviewed procedure | Evidence |
|---|---|---|---|---|
GET/api/modules/ai-insights | listAiInsights | ITenantAiInsightsService.ListAsync | sp_AiInsights_ListSecured | declared-interface not-observed |
GET/api/modules/ai-insights/{insightId:guid} | getAiInsight | ITenantAiInsightsService.GetAsync | sp_AiInsights_GetSecured | declared-interface not-observed |
PUT/api/modules/ai-insights/{insightId:guid}/state | setAiInsightState | ITenantAiInsightsService.SetStateAsync | sp_AiInsights_SetStateSecured | declared-interface not-observed |
Calendar module.calendar 5 operations
API base: /api/modules/calendar
Renderer: CalendarModule
SDK descriptor: packages/module-sdk/src/calendar.ts:1
Unstyled native block
{
"_id": "calendar-module",
"_type": "module.calendar",
"props": {
"title": "Calendar"
},
"children": []
}Styled composition
{
"_id": "calendar-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "calendar-heading",
"_type": "core.text",
"_parent": "calendar-section",
"props": {
"text": "Calendar",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "calendar-module",
"_type": "module.calendar",
"props": {
"title": "Calendar"
},
"children": [],
"_parent": "calendar-section"
}
]
}
| HTTP route | Browser function | Service member | Reviewed procedure | Evidence |
|---|---|---|---|---|
GET/api/modules/calendar | listCalendarEvents | ITenantCalendarService.ListAsync | sp_Calendar_ListSecured | declared-interface not-observed |
GET/api/modules/calendar/{recordId:guid} | getCalendarEvent | ITenantCalendarService.GetAsync | sp_Calendar_GetSecured | declared-interface not-observed |
POST/api/modules/calendar | createCalendarEvent | ITenantCalendarService.CreateAsync | sp_Calendar_CreateSecured | declared-interface not-observed |
PUT/api/modules/calendar/{recordId:guid} | updateCalendarEvent | ITenantCalendarService.UpdateAsync | sp_Calendar_UpdateSecured | declared-interface not-observed |
PUT/api/modules/calendar/{recordId:guid}/favorite | setCalendarFavorite | ITenantCalendarService.SetFavoriteAsync | sp_Calendar_SetFavoriteSecured | declared-interface not-observed |
Chat Rooms module.chat-rooms 9 operations
API base: /api/modules/chat-rooms
Renderer: ChatRoomsModule
SDK descriptor: packages/module-sdk/src/chatRooms.ts:1
Unstyled native block
{
"_id": "chat-rooms-module",
"_type": "module.chat-rooms",
"props": {
"title": "Chat Rooms"
},
"children": []
}Styled composition
{
"_id": "chat-rooms-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "chat-rooms-heading",
"_type": "core.text",
"_parent": "chat-rooms-section",
"props": {
"text": "Chat Rooms",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "chat-rooms-module",
"_type": "module.chat-rooms",
"props": {
"title": "Chat Rooms"
},
"children": [],
"_parent": "chat-rooms-section"
}
]
}
| HTTP route | Browser function | Service member | Reviewed procedure | Evidence |
|---|---|---|---|---|
GET/api/modules/chat-rooms | listChatRooms | ITenantChatRoomsService.ListAsync | sp_ChatRooms_ListSecured | declared-interface not-observed |
GET/api/modules/chat-rooms/{recordId:guid} | getChatRoom | ITenantChatRoomsService.GetAsync | sp_ChatRooms_GetSecured | declared-interface not-observed |
POST/api/modules/chat-rooms | createChatRoom | ITenantChatRoomsService.CreateAsync | sp_ChatRooms_CreateSecured | declared-interface not-observed |
PUT/api/modules/chat-rooms/{recordId:guid} | updateChatRoom | ITenantChatRoomsService.UpdateAsync | sp_ChatRooms_UpdateSecured | declared-interface not-observed |
POST/api/modules/chat-rooms/{recordId:guid}/messages | postChatMessage | ITenantChatRoomsService.PostMessageAsync | sp_ChatRooms_PostMessageSecured | declared-interface not-observed |
PUT/api/modules/chat-rooms/{recordId:guid}/messages/{chatMessageId:guid}/reaction | setChatReaction | ITenantChatRoomsService.SetReactionAsync | sp_ChatRooms_SetReactionSecured | declared-interface not-observed |
PUT/api/modules/chat-rooms/{recordId:guid}/members/{memberUserId:guid} | setChatRoomMember | ITenantChatRoomsService.SetMemberAsync | sp_ChatRooms_SetMemberSecured | declared-interface not-observed |
PUT/api/modules/chat-rooms/{recordId:guid}/read | markChatRoomRead | ITenantChatRoomsService.MarkReadAsync | sp_ChatRooms_MarkReadSecured | declared-interface not-observed |
PUT/api/modules/chat-rooms/{recordId:guid}/favorite | setChatRoomFavorite | ITenantChatRoomsService.SetFavoriteAsync | sp_ChatRooms_SetFavoriteSecured | declared-interface not-observed |
Checklists Signoffs module.checklists-signoffs 9 operations
API base: /api/modules/checklists-signoffs
Renderer: ChecklistsSignoffsModule
SDK descriptor: packages/module-sdk/src/checklistsSignoffs.ts:1
Unstyled native block
{
"_id": "checklists-signoffs-module",
"_type": "module.checklists-signoffs",
"props": {
"title": "Checklists Signoffs"
},
"children": []
}Styled composition
{
"_id": "checklists-signoffs-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "checklists-signoffs-heading",
"_type": "core.text",
"_parent": "checklists-signoffs-section",
"props": {
"text": "Checklists Signoffs",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "checklists-signoffs-module",
"_type": "module.checklists-signoffs",
"props": {
"title": "Checklists Signoffs"
},
"children": [],
"_parent": "checklists-signoffs-section"
}
]
}
| HTTP route | Browser function | Service member | Reviewed procedure | Evidence |
|---|---|---|---|---|
GET/api/modules/checklists-signoffs/templates | listChecklistTemplates | ITenantChecklistsService.ListTemplatesAsync | sp_Checklists_ListTemplatesSecured | declared-interface not-observed |
POST/api/modules/checklists-signoffs/templates | createChecklistTemplate | ITenantChecklistsService.CreateTemplateAsync | sp_Checklists_CreateTemplateSecured | declared-interface not-observed |
GET/api/modules/checklists-signoffs/runs | listChecklistRuns | ITenantChecklistsService.ListRunsAsync | sp_Checklists_ListRunsSecured | declared-interface not-observed |
GET/api/modules/checklists-signoffs/runs/{checklistRunId:guid} | getChecklistRun | ITenantChecklistsService.GetRunAsync | sp_Checklists_GetRunSecured | declared-interface not-observed |
POST/api/modules/checklists-signoffs/runs | startChecklistRun | ITenantChecklistsService.StartRunAsync | sp_Checklists_StartRunSecured | declared-interface not-observed |
PUT/api/modules/checklists-signoffs/items/{checklistRunItemId:guid} | updateChecklistItem | ITenantChecklistsService.UpdateItemAsync | sp_Checklists_UpdateItemSecured | declared-interface not-observed |
POST/api/modules/checklists-signoffs/items/{checklistRunItemId:guid}/proof | attachChecklistProof | ITenantChecklistsService.AttachProofAsync | sp_Checklists_AttachProofSecured | declared-interface not-observed |
DELETE/api/modules/checklists-signoffs/proof/{checklistItemEvidenceId:guid} | removeChecklistProof | ITenantChecklistsService.RemoveProofAsync | sp_Checklists_RemoveProofSecured | declared-interface not-observed |
POST/api/modules/checklists-signoffs/runs/{checklistRunId:guid}/submit | submitChecklistForSignoff | ITenantChecklistsService.SubmitAsync | sp_Checklists_SubmitForSignoffSecured | declared-interface not-observed |
Company News module.company-news 5 operations
API base: /api/modules/company-news
Renderer: CompanyNewsModule
SDK descriptor: packages/module-sdk/src/companyNews.ts:1
Unstyled native block
{
"_id": "company-news-module",
"_type": "module.company-news",
"props": {
"title": "Company News"
},
"children": []
}Styled composition
{
"_id": "company-news-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "company-news-heading",
"_type": "core.text",
"_parent": "company-news-section",
"props": {
"text": "Company News",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "company-news-module",
"_type": "module.company-news",
"props": {
"title": "Company News"
},
"children": [],
"_parent": "company-news-section"
}
]
}
| HTTP route | Browser function | Service member | Reviewed procedure | Evidence |
|---|---|---|---|---|
GET/api/modules/company-news | listCompanyNews | ITenantCompanyNewsService.ListAsync | sp_CompanyNews_ListSecured | declared-interface not-observed |
GET/api/modules/company-news/{recordId:guid} | getCompanyNews | ITenantCompanyNewsService.GetAsync | sp_CompanyNews_GetSecured | declared-interface not-observed |
POST/api/modules/company-news | createCompanyNews | ITenantCompanyNewsService.CreateAsync | sp_CompanyNews_CreateSecured | declared-interface not-observed |
PUT/api/modules/company-news/{recordId:guid} | updateCompanyNews | ITenantCompanyNewsService.UpdateAsync | sp_CompanyNews_UpdateSecured | declared-interface not-observed |
PUT/api/modules/company-news/{recordId:guid}/favorite | setCompanyNewsFavorite | ITenantCompanyNewsService.SetFavoriteAsync | sp_CompanyNews_SetFavoriteSecured | declared-interface not-observed |
Contacts module.contacts 5 operations
API base: /api/modules/contacts
Renderer: ContactsModule
SDK descriptor: packages/module-sdk/src/index.ts:1
Unstyled native block
{
"_id": "contacts-module",
"_type": "module.contacts",
"props": {
"title": "Contacts"
},
"children": []
}Styled composition
{
"_id": "contacts-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "contacts-heading",
"_type": "core.text",
"_parent": "contacts-section",
"props": {
"text": "Contacts",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "contacts-module",
"_type": "module.contacts",
"props": {
"title": "Contacts"
},
"children": [],
"_parent": "contacts-section"
}
]
}
| HTTP route | Browser function | Service member | Reviewed procedure | Evidence |
|---|---|---|---|---|
GET/api/modules/contacts | listContacts | ITenantContactsService.ListAsync | sp_Contacts_ListSecured | declared-interface not-observed |
GET/api/modules/contacts/{recordId:guid} | getContact | ITenantContactsService.GetAsync | sp_Contacts_GetSecured | declared-interface not-observed |
POST/api/modules/contacts | createContact | ITenantContactsService.CreateAsync | sp_Contacts_CreateSecured | declared-interface not-observed |
PUT/api/modules/contacts/{recordId:guid} | updateContact | ITenantContactsService.UpdateAsync | sp_Contacts_UpdateSecured | declared-interface not-observed |
PUT/api/modules/contacts/{recordId:guid}/favorite | setContactFavorite | ITenantContactsService.SetFavoriteAsync | sp_Contacts_SetFavoriteSecured | declared-interface not-observed |
Conversations module.conversations 7 operations
API base: /api/modules/conversations
Renderer: ConversationsModule
SDK descriptor: packages/module-sdk/src/conversations.ts:1
Unstyled native block
{
"_id": "conversations-module",
"_type": "module.conversations",
"props": {
"title": "Conversations"
},
"children": []
}Styled composition
{
"_id": "conversations-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "conversations-heading",
"_type": "core.text",
"_parent": "conversations-section",
"props": {
"text": "Conversations",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "conversations-module",
"_type": "module.conversations",
"props": {
"title": "Conversations"
},
"children": [],
"_parent": "conversations-section"
}
]
}
| HTTP route | Browser function | Service member | Reviewed procedure | Evidence |
|---|---|---|---|---|
GET/api/modules/conversations | listConversations | ITenantConversationsService.ListAsync | sp_Conversations_ListSecured | declared-interface not-observed |
GET/api/modules/conversations/{recordId:guid} | getConversation | ITenantConversationsService.GetAsync | sp_Conversations_GetSecured | declared-interface not-observed |
POST/api/modules/conversations | createConversation | ITenantConversationsService.CreateAsync | sp_Conversations_CreateSecured | declared-interface not-observed |
PUT/api/modules/conversations/{recordId:guid} | updateConversation | ITenantConversationsService.UpdateAsync | sp_Conversations_UpdateSecured | declared-interface not-observed |
POST/api/modules/conversations/{recordId:guid}/messages | postConversationMessage | ITenantConversationsService.ReplyAsync | sp_Conversations_ReplySecured | declared-interface not-observed |
POST/api/modules/conversations/direct | Server API only | ITenantConversationsService.SendDirectAsync | sp_Conversations_SendDirectSecured | declared-interface not-observed |
PUT/api/modules/conversations/{recordId:guid}/favorite | setConversationFavorite | ITenantConversationsService.SetFavoriteAsync | sp_Conversations_SetFavoriteSecured | declared-interface not-observed |
Discussion Boards module.discussion-boards 10 operations
API base: /api/modules/discussion-boards
Renderer: DiscussionBoardsModule
SDK descriptor: packages/module-sdk/src/discussionBoards.ts:1
Unstyled native block
{
"_id": "discussion-boards-module",
"_type": "module.discussion-boards",
"props": {
"title": "Discussion Boards"
},
"children": []
}Styled composition
{
"_id": "discussion-boards-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "discussion-boards-heading",
"_type": "core.text",
"_parent": "discussion-boards-section",
"props": {
"text": "Discussion Boards",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "discussion-boards-module",
"_type": "module.discussion-boards",
"props": {
"title": "Discussion Boards"
},
"children": [],
"_parent": "discussion-boards-section"
}
]
}
| HTTP route | Browser function | Service member | Reviewed procedure | Evidence |
|---|---|---|---|---|
GET/api/modules/discussion-boards | listDiscussionBoards | ITenantDiscussionBoardsService.ListAsync | sp_DiscussionBoards_ListSecured | declared-interface not-observed |
GET/api/modules/discussion-boards/{recordId:guid} | getDiscussionBoard | ITenantDiscussionBoardsService.GetBoardAsync | sp_DiscussionBoards_GetBoardSecured | declared-interface not-observed |
POST/api/modules/discussion-boards | createDiscussionBoard | ITenantDiscussionBoardsService.CreateBoardAsync | sp_DiscussionBoards_CreateBoardSecured | declared-interface not-observed |
PUT/api/modules/discussion-boards/{recordId:guid} | updateDiscussionBoard | ITenantDiscussionBoardsService.UpdateBoardAsync | sp_DiscussionBoards_UpdateBoardSecured | declared-interface not-observed |
POST/api/modules/discussion-boards/{boardRecordId:guid}/topics | createDiscussionTopic | ITenantDiscussionBoardsService.CreateTopicAsync | sp_DiscussionBoards_CreateTopicSecured | declared-interface not-observed |
GET/api/modules/discussion-boards/topics/{recordId:guid} | getDiscussionTopic | ITenantDiscussionBoardsService.GetTopicAsync | sp_DiscussionBoards_GetTopicSecured | declared-interface not-observed |
PUT/api/modules/discussion-boards/topics/{recordId:guid} | updateDiscussionTopic | ITenantDiscussionBoardsService.UpdateTopicAsync | sp_DiscussionBoards_UpdateTopicSecured | declared-interface not-observed |
POST/api/modules/discussion-boards/topics/{topicRecordId:guid}/posts | postDiscussionReply | ITenantDiscussionBoardsService.PostReplyAsync | sp_DiscussionBoards_PostReplySecured | declared-interface not-observed |
PUT/api/modules/discussion-boards/posts/{recordId:guid} | updateDiscussionPost | ITenantDiscussionBoardsService.UpdatePostAsync | sp_DiscussionBoards_UpdatePostSecured | declared-interface not-observed |
PUT/api/modules/discussion-boards/records/{recordId:guid}/favorite | setDiscussionFavorite | ITenantDiscussionBoardsService.SetFavoriteAsync | sp_DiscussionBoards_SetFavoriteSecured | declared-interface not-observed |
Dynamic Records module.dynamic-records 6 operations
API base: /api/modules/dynamic
Renderer: DynamicModulesModule
SDK descriptor: packages/module-sdk/src/dynamicModules.ts:1
Unstyled native block
{
"_id": "module-dynamic-records-module",
"_type": "module.dynamic-records",
"props": {
"title": "Dynamic Records"
},
"children": []
}Styled composition
{
"_id": "module-dynamic-records-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "module-dynamic-records-heading",
"_type": "core.text",
"_parent": "module-dynamic-records-section",
"props": {
"text": "Dynamic Records",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "module-dynamic-records-module",
"_type": "module.dynamic-records",
"props": {
"title": "Dynamic Records"
},
"children": [],
"_parent": "module-dynamic-records-section"
}
]
}
| HTTP route | Browser function | Service member | Reviewed procedure | Evidence |
|---|---|---|---|---|
GET/api/modules/dynamic/{moduleKey}/schema | getDynamicModuleSchema | ITenantDynamicModulesService.GetSchemaAsync | sp_DynamicModules_GetSchemaSecured | declared-interface not-observed |
GET/api/modules/dynamic/{moduleKey} | listDynamicModuleRecords | ITenantDynamicModulesService.ListAsync | sp_DynamicModules_ListSecured | declared-interface not-observed |
GET/api/modules/dynamic/{moduleKey}/{recordId:guid} | getDynamicModuleRecord | ITenantDynamicModulesService.GetAsync | sp_DynamicModules_GetSecured | declared-interface not-observed |
POST/api/modules/dynamic/{moduleKey} | createDynamicModuleRecord | ITenantDynamicModulesService.CreateAsync | sp_DynamicModules_CreateSecured | declared-interface not-observed |
PUT/api/modules/dynamic/{moduleKey}/{recordId:guid} | updateDynamicModuleRecord | ITenantDynamicModulesService.UpdateAsync | sp_DynamicModules_UpdateSecured | declared-interface not-observed |
PUT/api/modules/dynamic/{moduleKey}/{recordId:guid}/favorite | setDynamicModuleFavorite | ITenantDynamicModulesService.SetFavoriteAsync | sp_DynamicModules_SetFavoriteSecured | declared-interface not-observed |
Favorites module.favorites 4 operations
API base: /api/modules/favorites
Renderer: FavoritesModule
SDK descriptor: packages/module-sdk/src/favorites.ts:1
Unstyled native block
{
"_id": "favorites-module",
"_type": "module.favorites",
"props": {
"title": "Favorites"
},
"children": []
}Styled composition
{
"_id": "favorites-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "favorites-heading",
"_type": "core.text",
"_parent": "favorites-section",
"props": {
"text": "Favorites",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "favorites-module",
"_type": "module.favorites",
"props": {
"title": "Favorites"
},
"children": [],
"_parent": "favorites-section"
}
]
}
| HTTP route | Browser function | Service member | Reviewed procedure | Evidence |
|---|---|---|---|---|
GET/api/modules/favorites | listFavorites | ITenantFavoritesService.ListAsync | sp_Favorites_ListSecured | declared-interface not-observed |
GET/api/modules/favorites/{recordId:guid} | getFavorite | ITenantFavoritesService.GetAsync | sp_Favorites_GetSecured | declared-interface not-observed |
PUT/api/modules/favorites/{recordId:guid}/favorite | setFavorite | ITenantFavoritesService.SetAsync | sp_Favorites_SetSecured | declared-interface not-observed |
PUT/api/modules/favorites/{recordId:guid}/preferences | updateFavoritePreferences | ITenantFavoritesService.UpdateAsync | sp_Favorites_UpdateSecured | declared-interface not-observed |
Files module.files 8 operations
API base: /api/modules/files
Renderer: FilesModule
SDK descriptor: packages/module-sdk/src/files.ts:1
Unstyled native block
{
"_id": "files-module",
"_type": "module.files",
"props": {
"title": "Files"
},
"children": []
}Styled composition
{
"_id": "files-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "files-heading",
"_type": "core.text",
"_parent": "files-section",
"props": {
"text": "Files",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "files-module",
"_type": "module.files",
"props": {
"title": "Files"
},
"children": [],
"_parent": "files-section"
}
]
}
| HTTP route | Browser function | Service member | Reviewed procedure | Evidence |
|---|---|---|---|---|
GET/api/modules/files | listFiles | ITenantFilesService.ListAsync | sp_Files_ListSecured | declared-interface not-observed |
GET/api/modules/files/{recordId:guid} | getFile | ITenantFilesService.GetAsync | sp_Files_GetSecured | declared-interface not-observed |
POST/api/modules/files/upload | uploadFile | ITenantFilesService.UploadAsync | sp_Files_CreateSecured | declared-interface not-observed |
PUT/api/modules/files/{recordId:guid} | updateFile | ITenantFilesService.UpdateAsync | sp_Files_UpdateSecured | declared-interface not-observed |
POST/api/modules/files/{recordId:guid}/attachments | attachFile | ITenantFilesService.AttachAsync | sp_Files_AttachSecured | declared-interface not-observed |
DELETE/api/modules/files/{recordId:guid}/attachments/{attachmentId:guid} | detachFile | ITenantFilesService.DetachAsync | sp_Files_DetachSecured | declared-interface not-observed |
PUT/api/modules/files/{recordId:guid}/favorite | setFileFavorite | ITenantFilesService.SetFavoriteAsync | sp_Files_SetFavoriteSecured | declared-interface not-observed |
GET/api/modules/files/{recordId:guid}/content | downloadFileContent | ITenantFilesServiceFactory.CreateAsync | sp_Files_ListSecuredsp_Files_GetSecuredsp_Files_CreateSecuredsp_Files_UpdateSecuredsp_Files_AttachSecuredsp_Files_DetachSecuredsp_Files_SetFavoriteSecuredsp_Files_GetDownloadSecured | declared-interface not-observed |
Global Search module.global-search 2 operations
API base: /api/modules/global-search
Renderer: GlobalSearchModule
SDK descriptor: packages/module-sdk/src/globalSearch.ts:1
Unstyled native block
{
"_id": "global-search-module",
"_type": "module.global-search",
"props": {
"title": "Global Search"
},
"children": []
}Styled composition
{
"_id": "global-search-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "global-search-heading",
"_type": "core.text",
"_parent": "global-search-section",
"props": {
"text": "Global Search",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "global-search-module",
"_type": "module.global-search",
"props": {
"title": "Global Search"
},
"children": [],
"_parent": "global-search-section"
}
]
}
| HTTP route | Browser function | Service member | Reviewed procedure | Evidence |
|---|---|---|---|---|
GET/api/modules/global-search | searchGlobalRecords | ITenantGlobalSearchService.SearchAsync | sp_GlobalSearch_SearchSecured | declared-interface not-observed |
PUT/api/modules/global-search/records/{recordId:guid}/favorite | setGlobalSearchFavorite | ITenantGlobalSearchService.SetFavoriteAsync | sp_Favorites_SetSecured | declared-interface not-observed |
Knowledge Articles module.knowledge-articles 5 operations
API base: /api/modules/knowledge-articles
Renderer: KnowledgeArticlesModule
SDK descriptor: packages/module-sdk/src/knowledgeArticles.ts:1
Unstyled native block
{
"_id": "knowledge-articles-module",
"_type": "module.knowledge-articles",
"props": {
"title": "Knowledge Articles"
},
"children": []
}Styled composition
{
"_id": "knowledge-articles-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "knowledge-articles-heading",
"_type": "core.text",
"_parent": "knowledge-articles-section",
"props": {
"text": "Knowledge Articles",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "knowledge-articles-module",
"_type": "module.knowledge-articles",
"props": {
"title": "Knowledge Articles"
},
"children": [],
"_parent": "knowledge-articles-section"
}
]
}
| HTTP route | Browser function | Service member | Reviewed procedure | Evidence |
|---|---|---|---|---|
GET/api/modules/knowledge-articles | listKnowledgeArticles | ITenantKnowledgeArticlesService.ListAsync | sp_KnowledgeArticles_ListSecured | declared-interface not-observed |
GET/api/modules/knowledge-articles/{recordId:guid} | getKnowledgeArticle | ITenantKnowledgeArticlesService.GetAsync | sp_KnowledgeArticles_GetSecured | declared-interface not-observed |
POST/api/modules/knowledge-articles | createKnowledgeArticle | ITenantKnowledgeArticlesService.CreateAsync | sp_KnowledgeArticles_CreateSecured | declared-interface not-observed |
PUT/api/modules/knowledge-articles/{recordId:guid} | updateKnowledgeArticle | ITenantKnowledgeArticlesService.UpdateAsync | sp_KnowledgeArticles_UpdateSecured | declared-interface not-observed |
PUT/api/modules/knowledge-articles/{recordId:guid}/favorite | setKnowledgeArticleFavorite | ITenantKnowledgeArticlesService.SetFavoriteAsync | sp_KnowledgeArticles_SetFavoriteSecured | declared-interface not-observed |
Knowledge Articles module.knowledge-articles 32 operations
API base: /api/modules/knowledge-core
Renderer: KnowledgeArticlesModule
SDK descriptor: packages/module-sdk/src/knowledgeCore.ts:1
Unstyled native block
{
"_id": "knowledge-articles-module",
"_type": "module.knowledge-articles",
"props": {
"title": "Knowledge Articles"
},
"children": []
}Styled composition
{
"_id": "knowledge-articles-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "knowledge-articles-heading",
"_type": "core.text",
"_parent": "knowledge-articles-section",
"props": {
"text": "Knowledge Articles",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "knowledge-articles-module",
"_type": "module.knowledge-articles",
"props": {
"title": "Knowledge Articles"
},
"children": [],
"_parent": "knowledge-articles-section"
}
]
}
| HTTP route | Browser function | Service member | Reviewed procedure | Evidence |
|---|---|---|---|---|
GET/api/modules/knowledge-core | listKnowledgeCore | IKnowledgeCoreService.ListAsync | sp_kc_ListKnowledgeItemsSecured | declared-interface not-observed |
GET/api/modules/knowledge-core/{recordId:guid} | getKnowledgeCore | IKnowledgeCoreService.GetAsync | sp_kc_GetKnowledgeItemSecured | declared-interface not-observed |
POST/api/modules/knowledge-core | createKnowledgeCore | IKnowledgeCoreService.CreateDraftAsync | sp_kc_CreateKnowledgeItem | declared-interface not-observed |
PUT/api/modules/knowledge-core/{recordId:guid} | updateKnowledgeCore | IKnowledgeCoreService.UpdateDraftAsync | sp_kc_UpdateKnowledgeItem | declared-interface not-observed |
POST/api/modules/knowledge-core/{recordId:guid}/publish | publishKnowledgeCore | IKnowledgeCoreService.PublishAsync | sp_kc_PublishKnowledgeItem | declared-interface not-observed |
POST/api/modules/knowledge-core/{recordId:guid}/archive | archiveKnowledgeCore | IKnowledgeCoreService.ArchiveAsync | sp_kc_ArchiveKnowledgeItem | declared-interface not-observed |
GET/api/modules/knowledge-core/{recordId:guid}/revisions | getKnowledgeCoreRevisions | IKnowledgeCoreService.GetRevisionHistoryAsync | sp_kc_GetRevisionHistorySecured | declared-interface not-observed |
POST/api/modules/knowledge-core/{recordId:guid}/restore | Server API only | IKnowledgeCoreService.RestoreRevisionAsDraftAsync | sp_kc_RestoreRevisionAsDraft | declared-interface not-observed |
GET/api/modules/knowledge-core/collections | listKnowledgeCoreCollections | IKnowledgeCoreService.ListCollectionsAsync | sp_kc_ListCollectionsSecured | declared-interface not-observed |
POST/api/modules/knowledge-core/collections | Server API only | IKnowledgeCoreService.CreateCollectionAsync | sp_kc_CreateCollection | declared-interface not-observed |
PUT/api/modules/knowledge-core/collections/{collectionId:guid} | Server API only | IKnowledgeCoreService.UpdateCollectionAsync | sp_kc_UpdateCollection | declared-interface not-observed |
POST/api/modules/knowledge-core/collections/{collectionId:guid}/items/{recordId:guid} | Server API only | IKnowledgeCoreService.AddToCollectionAsync | sp_kc_AddKnowledgeItemToCollection | declared-interface not-observed |
DELETE/api/modules/knowledge-core/collections/{collectionId:guid}/items/{recordId:guid} | Server API only | IKnowledgeCoreService.RemoveFromCollectionAsync | sp_kc_RemoveKnowledgeItemFromCollection | declared-interface not-observed |
GET/api/modules/knowledge-core/{recordId:guid}/owners | getKnowledgeCoreOwners | IKnowledgeCoreService.GetOwnersAsync | sp_kc_GetKnowledgeOwnersSecured | declared-interface not-observed |
POST/api/modules/knowledge-core/{recordId:guid}/owners | Server API only | IKnowledgeCoreService.SetOwnerAsync | sp_kc_SetKnowledgeOwner | declared-interface not-observed |
DELETE/api/modules/knowledge-core/owners/{knowledgeOwnerId:guid} | Server API only | IKnowledgeCoreService.RemoveOwnerAsync | sp_kc_RemoveKnowledgeOwner | declared-interface not-observed |
GET/api/modules/knowledge-core/unowned | Server API only | IKnowledgeCoreService.GetUnownedAsync | sp_kc_GetUnownedKnowledgeSecured | declared-interface not-observed |
GET/api/modules/knowledge-core/reviews | listKnowledgeReviews | IKnowledgeCoreService.ListDueReviewsAsync | sp_kc_ListDueReviewsSecured | declared-interface not-observed |
POST/api/modules/knowledge-core/reviews/{reviewCycleId:guid}/begin | beginKnowledgeReview | IKnowledgeCoreService.BeginReviewAsync | sp_kc_BeginReview | declared-interface not-observed |
POST/api/modules/knowledge-core/reviews/{reviewCycleId:guid}/complete | completeKnowledgeReview | IKnowledgeCoreService.CompleteReviewAsync | sp_kc_CompleteReview | declared-interface not-observed |
POST/api/modules/knowledge-core/reviews/{reviewCycleId:guid}/reassign | reassignKnowledgeReview | IKnowledgeCoreService.ReassignReviewAsync | sp_kc_ReassignReview | declared-interface not-observed |
GET/api/modules/knowledge-core/health | getKnowledgeHealth | IKnowledgeCoreService.GetHealthAsync | sp_kc_GetKnowledgeHealthSecured | declared-interface not-observed |
GET/api/modules/knowledge-core/questions | listKnowledgeQuestions | IKnowledgeCoreService.ListQuestionsAsync | sp_kc_GetOpenQuestionsSecured | declared-interface not-observed |
POST/api/modules/knowledge-core/questions | createKnowledgeQuestion | IKnowledgeCoreService.CreateQuestionAsync | sp_kc_CreateQuestion | declared-interface not-observed |
POST/api/modules/knowledge-core/questions/{knowledgeQuestionId:guid}/assign | assignKnowledgeQuestion | IKnowledgeCoreService.AssignQuestionAsync | sp_kc_AssignQuestion | declared-interface not-observed |
POST/api/modules/knowledge-core/questions/{knowledgeQuestionId:guid}/answer | answerKnowledgeQuestion | IKnowledgeCoreService.AnswerQuestionAsync | sp_kc_AnswerQuestion | declared-interface not-observed |
POST/api/modules/knowledge-core/questions/{knowledgeQuestionId:guid}/convert | convertKnowledgeQuestion | IKnowledgeCoreService.ConvertQuestionAsync | sp_kc_ConvertQuestionToKnowledge | declared-interface not-observed |
POST/api/modules/knowledge-core/{recordId:guid}/feedback | recordKnowledgeFeedback | IKnowledgeCoreService.RecordFeedbackAsync | sp_kc_RecordFeedback | declared-interface not-observed |
GET/api/modules/knowledge-core/{recordId:guid}/feedback | getKnowledgeFeedback | IKnowledgeCoreService.GetFeedbackSummaryAsync | sp_kc_GetKnowledgeFeedbackSummarySecured | declared-interface not-observed |
GET/api/modules/knowledge-core/gaps | getKnowledgeGaps | IKnowledgeCoreService.GetKnowledgeGapsAsync | sp_kc_GetKnowledgeGapsSecured | declared-interface not-observed |
GET/api/modules/knowledge-core/support-learning/candidates | Server API only | IKnowledgeCoreService.ListSupportLearningCandidatesAsync | sp_kc_GetSupportLearningCandidatesSecured | delegated-interface not-observed |
POST/api/modules/knowledge-core/support-learning/candidates | Server API only | IKnowledgeCoreService.CreateSupportResolutionCandidateAsync | sp_kc_CreateSupportResolutionCandidate | delegated-interface not-observed |
Mail Reader module.mail-reader 4 operations
API base: /api/modules/mail-reader
Renderer: MailReaderModule
SDK descriptor: packages/module-sdk/src/mailReader.ts:1
Unstyled native block
{
"_id": "mail-reader-module",
"_type": "module.mail-reader",
"props": {
"title": "Mail Reader"
},
"children": []
}Styled composition
{
"_id": "mail-reader-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "mail-reader-heading",
"_type": "core.text",
"_parent": "mail-reader-section",
"props": {
"text": "Mail Reader",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "mail-reader-module",
"_type": "module.mail-reader",
"props": {
"title": "Mail Reader"
},
"children": [],
"_parent": "mail-reader-section"
}
]
}
| HTTP route | Browser function | Service member | Reviewed procedure | Evidence |
|---|---|---|---|---|
GET/api/modules/mail-reader | listMailReaderMessages | ITenantMailReaderService.ListAsync | sp_MailReader_ListSecured | declared-interface not-observed |
GET/api/modules/mail-reader/{recordId:guid} | getMailReaderMessage | ITenantMailReaderService.GetAsync | sp_MailReader_GetSecured | declared-interface not-observed |
PUT/api/modules/mail-reader/{recordId:guid}/read | setMailReaderRead | ITenantMailReaderService.SetReadAsync | sp_MailReader_SetReadSecured | declared-interface not-observed |
PUT/api/modules/mail-reader/{recordId:guid}/favorite | setMailReaderFavorite | ITenantMailReaderService.SetFavoriteAsync | sp_MailReader_SetFavoriteSecured | declared-interface not-observed |
Notifications module.notifications 4 operations
API base: /api/modules/notifications
Renderer: NotificationsModule
SDK descriptor: packages/module-sdk/src/notifications.ts:1
Unstyled native block
{
"_id": "notifications-module",
"_type": "module.notifications",
"props": {
"title": "Notifications"
},
"children": []
}Styled composition
{
"_id": "notifications-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "notifications-heading",
"_type": "core.text",
"_parent": "notifications-section",
"props": {
"text": "Notifications",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "notifications-module",
"_type": "module.notifications",
"props": {
"title": "Notifications"
},
"children": [],
"_parent": "notifications-section"
}
]
}
| HTTP route | Browser function | Service member | Reviewed procedure | Evidence |
|---|---|---|---|---|
GET/api/modules/notifications | listNotifications | ITenantNotificationsService.ListAsync | sp_Notifications_ListSecured | declared-interface not-observed |
GET/api/modules/notifications/{notificationId:guid} | getNotification | ITenantNotificationsService.GetAsync | sp_Notifications_GetSecured | declared-interface not-observed |
PUT/api/modules/notifications/{notificationId:guid}/state | setNotificationState | ITenantNotificationsService.SetStateAsync | sp_Notifications_SetStateSecured | declared-interface not-observed |
PUT/api/modules/notifications/{notificationId:guid}/source-favorite | setNotificationSourceFavorite | ITenantNotificationsService.SetSourceFavoriteAsync | sp_Notifications_SetSourceFavoriteSecured | declared-interface not-observed |
Payments Module API-only 7 operations
API base: /api/modules/payments
Renderer: Not a page renderer
SDK descriptor: packages/module-sdk/src/payments.ts:1
| HTTP route | Browser function | Service member | Reviewed procedure | Evidence |
|---|---|---|---|---|
GET/api/modules/payments/settings | getTenantPaymentSettings | ITenantPaymentsService.GetSettingsAsync | sp_TenantPayments_GetSettingsSecured | declared-interface not-observed |
PUT/api/modules/payments/settings/{moduleKey} | updateTenantPaymentPolicy | ITenantPaymentsService.UpdatePolicyAsync | sp_TenantPayments_UpdatePolicySecured | declared-interface not-observed |
PUT/api/modules/payments/connectors | upsertTenantPaymentConnector | ITenantPaymentsService.UpsertConnectorAsync | sp_TenantPayments_UpsertConnectorSecured | declared-interface not-observed |
DELETE/api/modules/payments/connectors/{connectorId:guid} | deactivateTenantPaymentConnector | ITenantPaymentsService.DeactivateConnectorAsync | sp_TenantPayments_DeactivateConnectorSecured | declared-interface not-observed |
GET/api/modules/payments/methods | Server API only | ITenantPaymentsService.ListMethodsAsync | sp_TenantPayments_ListMethodsSecured | declared-interface not-observed |
GET/api/modules/payments/records/{recordId:guid} | getTenantRecordPayments | ITenantPaymentsService.GetRecordSummaryAsync | sp_TenantPayments_GetRecordSummarySecured | declared-interface not-observed |
POST/api/modules/payments/records/{recordId:guid}/charges | createTenantRecordCharge | ITenantPaymentsService.CreateChargeAsync | sp_TenantPayments_CreateChargeSecured | declared-interface not-observed |
Record Activity module.record-activity 3 operations
API base: /api/modules/record-activity
Renderer: RecordActivityModule
SDK descriptor: packages/module-sdk/src/recordActivity.ts:1
Unstyled native block
{
"_id": "record-activity-module",
"_type": "module.record-activity",
"props": {
"title": "Record Activity"
},
"children": []
}Styled composition
{
"_id": "record-activity-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "record-activity-heading",
"_type": "core.text",
"_parent": "record-activity-section",
"props": {
"text": "Record Activity",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "record-activity-module",
"_type": "module.record-activity",
"props": {
"title": "Record Activity"
},
"children": [],
"_parent": "record-activity-section"
}
]
}
| HTTP route | Browser function | Service member | Reviewed procedure | Evidence |
|---|---|---|---|---|
GET/api/modules/record-activity/records | searchRecordActivity | ITenantRecordActivityService.SearchAsync | sp_RecordActivity_SearchSecured | declared-interface not-observed |
GET/api/modules/record-activity/{recordId:guid} | getRecordActivity | ITenantRecordActivityService.GetAsync | sp_RecordActivity_GetSecured | declared-interface not-observed |
PUT/api/modules/record-activity/{recordId:guid}/favorite | setRecordActivityFavorite | ITenantRecordActivityService.SetFavoriteAsync | sp_Favorites_SetSecured | declared-interface not-observed |
Record Graph module.record-graph 9 operations
API base: /api/modules/record-graph
Renderer: RecordGraphModule
SDK descriptor: packages/module-sdk/src/recordGraph.ts:1
Unstyled native block
{
"_id": "record-graph-module",
"_type": "module.record-graph",
"props": {
"title": "Record Graph"
},
"children": []
}Styled composition
{
"_id": "record-graph-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "record-graph-heading",
"_type": "core.text",
"_parent": "record-graph-section",
"props": {
"text": "Record Graph",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "record-graph-module",
"_type": "module.record-graph",
"props": {
"title": "Record Graph"
},
"children": [],
"_parent": "record-graph-section"
}
]
}
| HTTP route | Browser function | Service member | Reviewed procedure | Evidence |
|---|---|---|---|---|
GET/api/modules/record-graph/records | searchRecordGraph | ITenantRecordGraphService.SearchAsync | sp_RecordGraph_SearchSecured | declared-interface not-observed |
GET/api/modules/record-graph/{recordId:guid} | getRecordGraph | ITenantRecordGraphService.GetAsync | sp_RecordGraph_GetSecured | declared-interface not-observed |
PUT/api/modules/record-graph/{recordId:guid}/relations | addRecordGraphRelation | ITenantRecordGraphService.AddRelationAsync | sp_RecordGraph_AddRelationSecured | declared-interface not-observed |
DELETE/api/modules/record-graph/relations/{recordRelationId:guid} | removeRecordGraphRelation | ITenantRecordGraphService.RemoveRelationAsync | sp_RecordGraph_RemoveRelationSecured | declared-interface not-observed |
PUT/api/modules/record-graph/{recordId:guid}/favorite | setRecordGraphFavorite | ITenantRecordGraphService.SetFavoriteAsync | sp_Favorites_SetSecured | declared-interface not-observed |
GET/api/modules/record-graph/{recordId:guid}/knowledge | getRelatedKnowledge | ITenantRecordGraphService.GetRelatedKnowledgeAsync | sp_kc_GetRelatedKnowledgeSecured | declared-interface not-observed |
GET/api/modules/record-graph/{recordId:guid}/knowledge/candidates | getContextualKnowledge | ITenantRecordGraphService.GetContextualKnowledgeAsync | sp_kc_GetContextualKnowledgeCandidatesSecured | declared-interface not-observed |
PUT/api/modules/record-graph/{recordId:guid}/knowledge | linkKnowledgeToRecord | ITenantRecordGraphService.LinkKnowledgeAsync | sp_kc_LinkKnowledgeToRecord | declared-interface not-observed |
DELETE/api/modules/record-graph/knowledge-relations/{recordRelationId:guid} | unlinkKnowledgeFromRecord | ITenantRecordGraphService.UnlinkKnowledgeAsync | sp_kc_UnlinkKnowledgeFromRecord | declared-interface not-observed |
Reservations module.reservations 7 operations
API base: /api/modules/reservations
Renderer: ReservationsModule
SDK descriptor: packages/module-sdk/src/reservations.ts:1
Unstyled native block
{
"_id": "reservations-module",
"_type": "module.reservations",
"props": {
"title": "Reservations"
},
"children": []
}Styled composition
{
"_id": "reservations-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "reservations-heading",
"_type": "core.text",
"_parent": "reservations-section",
"props": {
"text": "Reservations",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "reservations-module",
"_type": "module.reservations",
"props": {
"title": "Reservations"
},
"children": [],
"_parent": "reservations-section"
}
]
}
| HTTP route | Browser function | Service member | Reviewed procedure | Evidence |
|---|---|---|---|---|
GET/api/modules/reservations/products | listReservationProducts | ITenantReservationsService.ListProductsAsync | sp_ReservationProducts_ListSecured | declared-interface not-observed |
POST/api/modules/reservations/products | saveReservationProduct | ITenantReservationsService.UpsertProductAsync | sp_ReservationProducts_UpsertSecured | declared-interface not-observed |
GET/api/modules/reservations | listReservations | ITenantReservationsService.ListAsync | sp_Reservations_ListSecured | declared-interface not-observed |
GET/api/modules/reservations/{recordId:guid} | getReservation | ITenantReservationsService.GetAsync | sp_Reservations_GetSecured | declared-interface not-observed |
POST/api/modules/reservations/purchase | purchaseReservation | ITenantReservationsService.PurchaseAsync | sp_Reservations_PurchaseSecured | declared-interface not-observed |
PUT/api/modules/reservations/{recordId:guid}/status | setReservationStatus | ITenantReservationsService.SetStatusAsync | sp_Reservations_SetStatusSecured | declared-interface not-observed |
PUT/api/modules/reservations/{recordId:guid}/followups | updateReservationFollowup | ITenantReservationsService.UpdateFollowupAsync | sp_ReservationFollowups_UpdateSecured | declared-interface not-observed |
Web Links module.web-links 5 operations
API base: /api/modules/web-links
Renderer: WebLinksModule
SDK descriptor: packages/module-sdk/src/webLinks.ts:1
Unstyled native block
{
"_id": "web-links-module",
"_type": "module.web-links",
"props": {
"title": "Web Links"
},
"children": []
}Styled composition
{
"_id": "web-links-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "web-links-heading",
"_type": "core.text",
"_parent": "web-links-section",
"props": {
"text": "Web Links",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "web-links-module",
"_type": "module.web-links",
"props": {
"title": "Web Links"
},
"children": [],
"_parent": "web-links-section"
}
]
}
| HTTP route | Browser function | Service member | Reviewed procedure | Evidence |
|---|---|---|---|---|
GET/api/modules/web-links | listWebLinks | ITenantWebLinksService.ListAsync | sp_WebLinks_ListSecured | declared-interface not-observed |
GET/api/modules/web-links/{recordId:guid} | getWebLink | ITenantWebLinksService.GetAsync | sp_WebLinks_GetSecured | declared-interface not-observed |
POST/api/modules/web-links | createWebLink | ITenantWebLinksService.CreateAsync | sp_WebLinks_CreateSecured | declared-interface not-observed |
PUT/api/modules/web-links/{recordId:guid} | updateWebLink | ITenantWebLinksService.UpdateAsync | sp_WebLinks_UpdateSecured | declared-interface not-observed |
PUT/api/modules/web-links/{recordId:guid}/favorite | setWebLinkFavorite | ITenantWebLinksService.SetFavoriteAsync | sp_WebLinks_SetFavoriteSecured | declared-interface not-observed |
Work Orders module.work-orders 6 operations
API base: /api/modules/work-orders
Renderer: WorkOrdersModule
SDK descriptor: packages/module-sdk/src/workOrders.ts:1
Unstyled native block
{
"_id": "work-orders-module",
"_type": "module.work-orders",
"props": {
"title": "Work Orders"
},
"children": []
}Styled composition
{
"_id": "work-orders-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "work-orders-heading",
"_type": "core.text",
"_parent": "work-orders-section",
"props": {
"text": "Work Orders",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "work-orders-module",
"_type": "module.work-orders",
"props": {
"title": "Work Orders"
},
"children": [],
"_parent": "work-orders-section"
}
]
}
| HTTP route | Browser function | Service member | Reviewed procedure | Evidence |
|---|---|---|---|---|
GET/api/modules/work-orders | listWorkOrders | ITenantWorkOrdersService.ListAsync | sp_WorkOrders_ListSecured | declared-interface not-observed |
GET/api/modules/work-orders/{recordId:guid} | getWorkOrder | ITenantWorkOrdersService.GetAsync | sp_WorkOrders_GetSecured | declared-interface not-observed |
POST/api/modules/work-orders | createWorkOrder | ITenantWorkOrdersService.CreateAsync | sp_WorkOrders_CreateSecured | declared-interface not-observed |
PUT/api/modules/work-orders/{recordId:guid} | updateWorkOrder | ITenantWorkOrdersService.UpdateAsync | sp_WorkOrders_UpdateSecured | declared-interface not-observed |
PUT/api/modules/work-orders/{recordId:guid}/status | setWorkOrderStatus | ITenantWorkOrdersService.SetStatusAsync | sp_WorkOrders_SetStatusSecured | declared-interface not-observed |
PUT/api/modules/work-orders/{recordId:guid}/assignment | assignWorkOrder | ITenantWorkOrdersService.AssignAsync | sp_WorkOrders_AssignSecured | declared-interface not-observed |
Complete browser, client and non-page route inventory
The API inventory keeps exported helpers even when they delegate and have no direct fetch call. Compiler-extracted route expressions are shown as written and resolved only when static source declares the path. Universal Inbox and GoClaw client methods are listed separately because they are package factories rather than top-level functions in apps/tenant-runtime/src/api.ts.
Tenant runtime browser API 184 exported functions
Source: apps/tenant-runtime/src/api.ts
| Function | Transport/delegation | Return | Source |
|---|---|---|---|
acquirePageEditLock | PUT /api/runtime/pages/{value}/edit-lock | Promise<PageEditLock> | apps/tenant-runtime/src/api.ts:1285 |
addActiveWorkplaceParticipant | POST /api/modules/active-workplace/{activeWorkplaceId}/participants | Promise<ActiveWorkplaceMutation> | apps/tenant-runtime/src/api.ts:1023 |
addRecordGraphRelation | PUT /api/modules/record-graph/{recordId}/relations | Promise<RecordGraphMutation> | apps/tenant-runtime/src/api.ts:974 |
adoptTenantPage | POST pageAdoptionBase(pageKey) | Promise<TenantPageAdoptionResult> | apps/tenant-runtime/src/api.ts:1312 |
answerKnowledgeQuestion | POST /api/modules/knowledge-core/questions/{knowledgeQuestionId}/answer | Promise<KnowledgeQuestionMutation> | apps/tenant-runtime/src/api.ts:1138 |
archiveKnowledgeCore | POST /api/modules/knowledge-core/{recordId}/archive | Promise<KnowledgeCoreMutation> | apps/tenant-runtime/src/api.ts:1126 |
assignKnowledgeQuestion | POST /api/modules/knowledge-core/questions/{knowledgeQuestionId}/assign | Promise<KnowledgeQuestionMutation> | apps/tenant-runtime/src/api.ts:1137 |
assignWorkOrder | PUT /api/modules/work-orders/{recordId}/assignment | Promise<WorkOrderMutation> | apps/tenant-runtime/src/api.ts:587 |
attachChecklistProof | POST /api/modules/checklists-signoffs/items/{checklistRunItemId}/proof | Promise<ChecklistMutation> | apps/tenant-runtime/src/api.ts:620 |
attachFile | POST /api/modules/files/{recordId}/attachments | Promise<FileMutation> | apps/tenant-runtime/src/api.ts:762 |
beginKnowledgeReview | POST /api/modules/knowledge-core/reviews/{reviewCycleId}/begin | Promise<KnowledgeReviewMutation> | apps/tenant-runtime/src/api.ts:1132 |
clearTenantSession | Delegates through clearBuilderDesignSession | void | apps/tenant-runtime/src/api.ts:347 |
completeKnowledgeReview | POST /api/modules/knowledge-core/reviews/{reviewCycleId}/complete | Promise<KnowledgeReviewMutation> | apps/tenant-runtime/src/api.ts:1133 |
convertKnowledgeQuestion | POST /api/modules/knowledge-core/questions/{knowledgeQuestionId}/convert | Promise<KnowledgeQuestionMutation> | apps/tenant-runtime/src/api.ts:1139 |
createActiveWorkplace | POST /api/modules/active-workplace | Promise<ActiveWorkplaceMutation> | apps/tenant-runtime/src/api.ts:1015 |
createCalendarEvent | POST /api/modules/calendar | Promise<CalendarMutation> | apps/tenant-runtime/src/api.ts:712 |
createChatRoom | POST /api/modules/chat-rooms | Promise<ChatRoomMutation> | apps/tenant-runtime/src/api.ts:901 |
createChecklistTemplate | POST /api/modules/checklists-signoffs/templates | Promise<ChecklistMutation> | apps/tenant-runtime/src/api.ts:596 |
createCompanyNews | POST /api/modules/company-news | Promise<CompanyNewsMutation> | apps/tenant-runtime/src/api.ts:843 |
createContact | POST /api/modules/contacts | Promise<ContactMutation> | apps/tenant-runtime/src/api.ts:549 |
createConversation | POST /api/modules/conversations | Promise<ConversationMutation> | apps/tenant-runtime/src/api.ts:801 |
createDiscussionBoard | POST /api/modules/discussion-boards | Promise<DiscussionMutation> | apps/tenant-runtime/src/api.ts:923 |
createDiscussionTopic | POST /api/modules/discussion-boards/{boardRecordId}/topics | Promise<DiscussionMutation> | apps/tenant-runtime/src/api.ts:927 |
createDynamicModuleRecord | POST /api/modules/dynamic/{moduleKey} | Promise<DynamicModuleMutation> | apps/tenant-runtime/src/api.ts:1076 |
createKnowledgeArticle | POST /api/modules/knowledge-articles | Promise<KnowledgeArticleMutation> | apps/tenant-runtime/src/api.ts:1098 |
createKnowledgeCore | POST /api/modules/knowledge-core | Promise<KnowledgeCoreMutation> | apps/tenant-runtime/src/api.ts:1123 |
createKnowledgeQuestion | POST /api/modules/knowledge-core/questions | Promise<KnowledgeQuestionMutation> | apps/tenant-runtime/src/api.ts:1136 |
createTenantRecordCharge | POST /api/modules/payments/records/{recordId}/charges | Promise<TenantPaymentMutation> | apps/tenant-runtime/src/api.ts:690 |
createWebLink | POST /api/modules/web-links | Promise<WebLinkMutation> | apps/tenant-runtime/src/api.ts:875 |
createWorkOrder | POST /api/modules/work-orders | Promise<WorkOrderMutation> | apps/tenant-runtime/src/api.ts:575 |
deactivateTenantPaymentConnector | DELETE /api/modules/payments/connectors/{connectorId} | Promise<TenantPaymentMutation> | apps/tenant-runtime/src/api.ts:677 |
deleteTenantAsset | DELETE /api/assets/{assetId} | Promise<TenantAssetMutation> | apps/tenant-runtime/src/api.ts:1360 |
detachFile | DELETE /api/modules/files/{recordId}/attachments/{attachmentId} | Promise<FileMutation> | apps/tenant-runtime/src/api.ts:769 |
downloadFileContent | GET /api/modules/files/{recordId}/content | Promise<Blob> | apps/tenant-runtime/src/api.ts:783 |
getActiveWorkplace | GET /api/modules/active-workplace/{activeWorkplaceId} | Promise<ActiveWorkplaceDetail> | apps/tenant-runtime/src/api.ts:1013 |
getActiveWorkplaceParticipantCatalog | GET /api/modules/active-workplace/{activeWorkplaceId}/participants/catalog | Promise<ActiveWorkplaceParticipantCatalog> | apps/tenant-runtime/src/api.ts:1021 |
getActiveWorkplacePlayback | GET /api/modules/active-workplace/{activeWorkplaceId}/playback?${new URLSearchParams({at:asOfUtc})} | Promise<ActiveWorkplacePlayback> | apps/tenant-runtime/src/api.ts:1031 |
getAiInsight | GET /api/modules/ai-insights/{id} | Promise<AiInsightDetail> | apps/tenant-runtime/src/api.ts:1067 |
getCalendarEvent | GET /api/modules/calendar/{recordId} | Promise<CalendarEventDetail> | apps/tenant-runtime/src/api.ts:707 |
getChatRoom | GET /api/modules/chat-rooms/{recordId} | Promise<ChatRoomDetail> | apps/tenant-runtime/src/api.ts:899 |
getChecklistRun | GET /api/modules/checklists-signoffs/runs/{checklistRunId} | Promise<ChecklistRunDetail> | apps/tenant-runtime/src/api.ts:608 |
getCompanyNews | GET /api/modules/company-news/{recordId} | Promise<CompanyNewsDetail> | apps/tenant-runtime/src/api.ts:838 |
getContact | GET /api/modules/contacts/{recordId} | Promise<ContactDetail> | apps/tenant-runtime/src/api.ts:544 |
getContextualKnowledge | GET /api/modules/record-graph/{recordId}/knowledge/candidates?${new URLSearchParams({requireAiRead:String(requireAiRead),maxCandidates:String(maxCandidates)})} | Promise<ContextualKnowledgeResponse> | apps/tenant-runtime/src/api.ts:982 |
getConversation | GET /api/modules/conversations/{recordId} | Promise<ConversationDetail> | apps/tenant-runtime/src/api.ts:796 |
getDiscussionBoard | GET /api/modules/discussion-boards/{recordId} | Promise<DiscussionBoardDetail> | apps/tenant-runtime/src/api.ts:921 |
getDiscussionTopic | GET /api/modules/discussion-boards/topics/{recordId} | Promise<DiscussionTopicDetail> | apps/tenant-runtime/src/api.ts:929 |
getDynamicModuleRecord | GET /api/modules/dynamic/{moduleKey}/{recordId} | Promise<DynamicModuleDetail> | apps/tenant-runtime/src/api.ts:1075 |
getDynamicModuleSchema | GET /api/modules/dynamic/{moduleKey}/schema | Promise<DynamicModuleSchema> | apps/tenant-runtime/src/api.ts:1073 |
getFavorite | GET /api/modules/favorites/{recordId} | Promise<FavoriteDetail> | apps/tenant-runtime/src/api.ts:957 |
getFile | GET /api/modules/files/{recordId} | Promise<FileDetail> | apps/tenant-runtime/src/api.ts:737 |
getKnowledgeArticle | GET /api/modules/knowledge-articles/{recordId} | Promise<KnowledgeArticleDetail> | apps/tenant-runtime/src/api.ts:1093 |
getKnowledgeCore | GET /api/modules/knowledge-core/{recordId} | Promise<KnowledgeCoreDetail> | apps/tenant-runtime/src/api.ts:1122 |
getKnowledgeCoreOwners | GET /api/modules/knowledge-core/{recordId}/owners | Promise<KnowledgeOwners> | apps/tenant-runtime/src/api.ts:1129 |
getKnowledgeCoreRevisions | GET /api/modules/knowledge-core/{recordId}/revisions | Promise<KnowledgeRevisionHistory> | apps/tenant-runtime/src/api.ts:1127 |
getKnowledgeFeedback | GET /api/modules/knowledge-core/{recordId}/feedback | Promise<KnowledgeFeedbackSummary> | apps/tenant-runtime/src/api.ts:1142 |
getKnowledgeGaps | GET /api/modules/knowledge-core/gaps?days=90&top=50 | Promise<KnowledgeGapList> | apps/tenant-runtime/src/api.ts:1140 |
getKnowledgeHealth | GET /api/modules/knowledge-core/health | Promise<KnowledgeHealth> | apps/tenant-runtime/src/api.ts:1131 |
getMailReaderMessage | GET /api/modules/mail-reader/{recordId} | Promise<MailReaderMessageDetail> | apps/tenant-runtime/src/api.ts:945 |
getNotification | GET /api/modules/notifications/{id} | Promise<NotificationDetail> | apps/tenant-runtime/src/api.ts:1049 |
getPageRevision | GET `${pageRevisionBase(pageKey)}/${pageRevisionId(pageHistoryId)}` | Promise<PageRevisionSnapshot> | apps/tenant-runtime/src/api.ts:1252 |
getRecordActivity | GET /api/modules/record-activity/{recordId}?{query} | Promise<RecordActivityResponse> | apps/tenant-runtime/src/api.ts:997 |
getRecordGraph | GET /api/modules/record-graph/{recordId}?${new URLSearchParams({maxDepth:String(maxDepth),maxNodes:"100"})} | Promise<RecordGraphResponse> | apps/tenant-runtime/src/api.ts:972 |
getRelatedKnowledge | GET /api/modules/record-graph/{recordId}/knowledge?${new URLSearchParams({maxItems:String(maxItems)})} | Promise<RelatedKnowledgeResponse> | apps/tenant-runtime/src/api.ts:980 |
getReservation | GET /api/modules/reservations/{recordId} | Promise<ReservationDetail> | apps/tenant-runtime/src/api.ts:648 |
getTenantAccessToken | Local/session helper | string | null | apps/tenant-runtime/src/api.ts:345 |
getTenantPageDrift | GET pageAdoptionBase(pageKey) | Promise<TenantPageDrift> | apps/tenant-runtime/src/api.ts:1302 |
getTenantPaymentSettings | GET /api/modules/payments/settings | Promise<TenantPaymentSettings> | apps/tenant-runtime/src/api.ts:665 |
getTenantRecordPayments | GET /api/modules/payments/records/{recordId} | Promise<TenantRecordPaymentSummary> | apps/tenant-runtime/src/api.ts:686 |
getWebLink | GET /api/modules/web-links/{recordId} | Promise<WebLinkDetail> | apps/tenant-runtime/src/api.ts:870 |
getWorkOrder | GET /api/modules/work-orders/{recordId} | Promise<WorkOrderDetail> | apps/tenant-runtime/src/api.ts:571 |
linkKnowledgeToRecord | PUT /api/modules/record-graph/{recordId}/knowledge | Promise<KnowledgeRelationMutation> | apps/tenant-runtime/src/api.ts:984 |
listActiveWorkplaces | GET /api/modules/active-workplace?{query} | Promise<ActiveWorkplaceList> | apps/tenant-runtime/src/api.ts:1007 |
listAiInsights | GET /api/modules/ai-insights?{query} | Promise<AiInsightList> | apps/tenant-runtime/src/api.ts:1053 |
listCalendarEvents | GET /api/modules/calendar?{query} | Promise<CalendarEventList> | apps/tenant-runtime/src/api.ts:695 |
listChatRooms | GET /api/modules/chat-rooms?{query} | Promise<ChatRoomsList> | apps/tenant-runtime/src/api.ts:894 |
listChecklistRuns | GET /api/modules/checklists-signoffs/runs?{query} | Promise<ChecklistRunList> | apps/tenant-runtime/src/api.ts:601 |
listChecklistTemplates | GET /api/modules/checklists-signoffs/templates | Promise<ChecklistTemplateList> | apps/tenant-runtime/src/api.ts:592 |
listCompanyNews | GET /api/modules/company-news?{query} | Promise<CompanyNewsList> | apps/tenant-runtime/src/api.ts:827 |
listContacts | GET /api/modules/contacts?{query} | Promise<ContactList> | apps/tenant-runtime/src/api.ts:528 |
listConversations | GET /api/modules/conversations?{query} | Promise<ConversationList> | apps/tenant-runtime/src/api.ts:788 |
listDiscussionBoards | GET /api/modules/discussion-boards?{query} | Promise<DiscussionBoardsList> | apps/tenant-runtime/src/api.ts:916 |
listDynamicModuleRecords | GET /api/modules/dynamic/{moduleKey}?{q} | Promise<DynamicModuleList> | apps/tenant-runtime/src/api.ts:1074 |
listFavorites | GET /api/modules/favorites?{query} | Promise<FavoritesList> | apps/tenant-runtime/src/api.ts:952 |
listFiles | GET /api/modules/files?{query} | Promise<FileList> | apps/tenant-runtime/src/api.ts:729 |
listKnowledgeArticles | GET /api/modules/knowledge-articles?{query} | Promise<KnowledgeArticlesList> | apps/tenant-runtime/src/api.ts:1080 |
listKnowledgeCore | GET /api/modules/knowledge-core?{query} | Promise<KnowledgeCoreList> | apps/tenant-runtime/src/api.ts:1117 |
listKnowledgeCoreCollections | GET /api/modules/knowledge-core/collections | Promise<KnowledgeCollections> | apps/tenant-runtime/src/api.ts:1128 |
listKnowledgeQuestions | GET /api/modules/knowledge-core/questions?{query} | Promise<KnowledgeQuestionList> | apps/tenant-runtime/src/api.ts:1135 |
listKnowledgeReviews | GET /api/modules/knowledge-core/reviews | Promise<KnowledgeReviewList> | apps/tenant-runtime/src/api.ts:1130 |
listMailReaderMessages | GET /api/modules/mail-reader?{query} | Promise<MailReaderList> | apps/tenant-runtime/src/api.ts:940 |
listNotifications | GET /api/modules/notifications?{query} | Promise<NotificationList> | apps/tenant-runtime/src/api.ts:1043 |
listPageRevisions | GET `${pageRevisionBase(pageKey)}?limit=${limit}` | Promise<readonly PageRevision[]> | apps/tenant-runtime/src/api.ts:1242 |
listReservationProducts | GET /api/modules/reservations/products?includeInactive={includeInactive} | Promise<ReservationProductList> | apps/tenant-runtime/src/api.ts:633 |
listReservations | GET /api/modules/reservations?{query} | Promise<ReservationList> | apps/tenant-runtime/src/api.ts:641 |
listTenantAssets | GET /api/assets{suffix} | Promise<TenantAssetList> | apps/tenant-runtime/src/api.ts:1334 |
listTenantPageDrift | GET /api/runtime/pages/drift | Promise<readonly TenantPageDrift[]> | apps/tenant-runtime/src/api.ts:1307 |
listTenantPaymentMethods | GET /api/modules/payments/methods{query} | Promise<TenantPaymentMethodList> | apps/tenant-runtime/src/api.ts:681 |
listTenantSessions | GET /api/auth/tenant/sessions | Promise<TenantSecuritySessionsSnapshot> | apps/tenant-runtime/src/api.ts:513 |
listWebLinks | GET /api/modules/web-links?{query} | Promise<WebLinksList> | apps/tenant-runtime/src/api.ts:862 |
listWorkOrders | GET /api/modules/work-orders?{query} | Promise<WorkOrderList> | apps/tenant-runtime/src/api.ts:564 |
loadRuntimeBootstrap | GET /api/runtime/bootstrap/{pageKey} | Promise<RuntimeBootstrap> | apps/tenant-runtime/src/api.ts:1174 |
loadRuntimeBootstrapBySlug | GET /api/runtime/route?{value} | Promise<RuntimeBootstrap> | apps/tenant-runtime/src/api.ts:1183 |
loadRuntimeDataBinding | GET /api/runtime/data/{bindingKey} | Promise<RuntimeDataBinding> | apps/tenant-runtime/src/api.ts:1213 |
loadTenantAssetContent | GET url | Promise<Blob> | apps/tenant-runtime/src/api.ts:1368 |
loginTenant | POST /api/auth/tenant/login | Promise<TenantLoginResult> | apps/tenant-runtime/src/api.ts:1144 |
logoutAllTenantSessions | POST /api/auth/tenant/logout-all | Promise<void> | apps/tenant-runtime/src/api.ts:520 |
logoutTenant | POST /api/auth/tenant/logout | Promise<void> | apps/tenant-runtime/src/api.ts:498 |
markChatRoomRead | PUT /api/modules/chat-rooms/{recordId}/read | Promise<ChatRoomMutation> | apps/tenant-runtime/src/api.ts:911 |
onTenantSessionExpired | Local/session helper | (() => void) | apps/tenant-runtime/src/api.ts:430 |
postChatMessage | POST /api/modules/chat-rooms/{recordId}/messages | Promise<ChatRoomMutation> | apps/tenant-runtime/src/api.ts:905 |
postConversationMessage | POST /api/modules/conversations/{recordId}/messages | Promise<ConversationMutation> | apps/tenant-runtime/src/api.ts:813 |
postDiscussionReply | POST /api/modules/discussion-boards/topics/{topicRecordId}/posts | Promise<DiscussionMutation> | apps/tenant-runtime/src/api.ts:933 |
publishKnowledgeCore | POST /api/modules/knowledge-core/{recordId}/publish | Promise<KnowledgeCoreMutation> | apps/tenant-runtime/src/api.ts:1125 |
purchaseReservation | POST /api/modules/reservations/purchase | Promise<ReservationMutation> | apps/tenant-runtime/src/api.ts:652 |
reassignKnowledgeReview | POST /api/modules/knowledge-core/reviews/{reviewCycleId}/reassign | Promise<KnowledgeReviewMutation> | apps/tenant-runtime/src/api.ts:1134 |
recordActiveWorkplaceActivity | POST /api/modules/active-workplace/{activeWorkplaceId}/activity | Promise<ActiveWorkplaceMutation> | apps/tenant-runtime/src/api.ts:1027 |
recordKnowledgeFeedback | POST /api/modules/knowledge-core/{recordId}/feedback | Promise<KnowledgeFeedbackMutation> | apps/tenant-runtime/src/api.ts:1141 |
refreshActiveWorkplaceGraph | POST /api/modules/active-workplace/{activeWorkplaceId}/graph/refresh | Promise<ActiveWorkplaceMutation> | apps/tenant-runtime/src/api.ts:1029 |
refreshTenantSession | Delegates through refreshTenantSessionCore | Promise<TenantRefreshSuccess> | apps/tenant-runtime/src/api.ts:419 |
releasePageEditLock | DELETE /api/runtime/pages/{value}/edit-lock | Promise<PageEditLockRelease> | apps/tenant-runtime/src/api.ts:1292 |
removeActiveWorkplaceParticipant | DELETE /api/modules/active-workplace/{activeWorkplaceId}/participants/{participantId} | Promise<ActiveWorkplaceMutation> | apps/tenant-runtime/src/api.ts:1025 |
removeChecklistProof | DELETE /api/modules/checklists-signoffs/proof/{checklistItemEvidenceId} | Promise<ChecklistMutation> | apps/tenant-runtime/src/api.ts:624 |
removeRecordGraphRelation | DELETE /api/modules/record-graph/relations/{recordRelationId} | Promise<RecordGraphMutation> | apps/tenant-runtime/src/api.ts:976 |
restorePageRevision | POST `${pageRevisionBase(pageKey)}/${pageRevisionId(pageHistoryId)}/restore` | Promise<PageRestoreResult> | apps/tenant-runtime/src/api.ts:1273 |
restoreTenantSession | Delegates through refreshTenantSession | Promise<TenantRefreshSuccess> | apps/tenant-runtime/src/api.ts:428 |
revokeTenantSession | DELETE /api/auth/tenant/sessions/{sessionId} | Promise<void> | apps/tenant-runtime/src/api.ts:516 |
saveReservationProduct | POST /api/modules/reservations/products | Promise<ReservationMutation> | apps/tenant-runtime/src/api.ts:637 |
saveTenantPage | POST `${pageRevisionBase(pageKey)}/save` | Promise<PageSaveReport> | apps/tenant-runtime/src/api.ts:1261 |
searchGlobalRecords | GET /api/modules/global-search?{parameters} | Promise<GlobalSearchResponse> | apps/tenant-runtime/src/api.ts:1034 |
searchRecordActivity | GET /api/modules/record-activity/records?{query} | Promise<RecordActivitySearchResponse> | apps/tenant-runtime/src/api.ts:989 |
searchRecordGraph | GET /api/modules/record-graph/records?{query} | Promise<RecordGraphSearchResponse> | apps/tenant-runtime/src/api.ts:964 |
setActiveWorkplaceStatus | POST /api/modules/active-workplace/{activeWorkplaceId}/status | Promise<ActiveWorkplaceMutation> | apps/tenant-runtime/src/api.ts:1019 |
setAiInsightState | PUT /api/modules/ai-insights/{id}/state | Promise<AiInsightState> | apps/tenant-runtime/src/api.ts:1069 |
setCalendarFavorite | PUT /api/modules/calendar/{recordId}/favorite | Promise<CalendarMutation> | apps/tenant-runtime/src/api.ts:722 |
setChatReaction | PUT /api/modules/chat-rooms/{recordId}/messages/{chatMessageId}/reaction | Promise<ChatRoomMutation> | apps/tenant-runtime/src/api.ts:907 |
setChatRoomFavorite | PUT /api/modules/chat-rooms/{recordId}/favorite | Promise<ChatRoomMutation> | apps/tenant-runtime/src/api.ts:913 |
setChatRoomMember | PUT /api/modules/chat-rooms/{recordId}/members/{memberUserId} | Promise<ChatRoomMutation> | apps/tenant-runtime/src/api.ts:909 |
setCompanyNewsFavorite | PUT /api/modules/company-news/{recordId}/favorite | Promise<CompanyNewsMutation> | apps/tenant-runtime/src/api.ts:855 |
setContactFavorite | PUT /api/modules/contacts/{recordId}/favorite | Promise<ContactMutation> | apps/tenant-runtime/src/api.ts:559 |
setConversationFavorite | PUT /api/modules/conversations/{recordId}/favorite | Promise<ConversationMutation> | apps/tenant-runtime/src/api.ts:820 |
setDiscussionFavorite | PUT /api/modules/discussion-boards/records/{recordId}/favorite | Promise<DiscussionMutation> | apps/tenant-runtime/src/api.ts:937 |
setDynamicModuleFavorite | PUT /api/modules/dynamic/{moduleKey}/{recordId}/favorite | Promise<DynamicModuleMutation> | apps/tenant-runtime/src/api.ts:1078 |
setFavorite | PUT /api/modules/favorites/{recordId}/favorite | Promise<FavoriteMutation> | apps/tenant-runtime/src/api.ts:959 |
setFileFavorite | PUT /api/modules/files/{recordId}/favorite | Promise<FileMutation> | apps/tenant-runtime/src/api.ts:776 |
setGlobalSearchFavorite | PUT /api/modules/global-search/records/{recordId}/favorite | Promise<FavoriteMutation> | apps/tenant-runtime/src/api.ts:1040 |
setKnowledgeArticleFavorite | PUT /api/modules/knowledge-articles/{recordId}/favorite | Promise<KnowledgeArticleMutation> | apps/tenant-runtime/src/api.ts:1110 |
setMailReaderFavorite | PUT /api/modules/mail-reader/{recordId}/favorite | Promise<MailReaderMutation> | apps/tenant-runtime/src/api.ts:949 |
setMailReaderRead | PUT /api/modules/mail-reader/{recordId}/read | Promise<MailReaderMutation> | apps/tenant-runtime/src/api.ts:947 |
setNotificationSourceFavorite | PUT /api/modules/notifications/{id}/source-favorite | Promise<NotificationMutation> | apps/tenant-runtime/src/api.ts:1051 |
setNotificationState | PUT /api/modules/notifications/{id}/state | Promise<NotificationMutation> | apps/tenant-runtime/src/api.ts:1050 |
setRecordActivityFavorite | PUT /api/modules/record-activity/{recordId}/favorite | Promise<FavoriteMutation> | apps/tenant-runtime/src/api.ts:1004 |
setRecordGraphFavorite | PUT /api/modules/record-graph/{recordId}/favorite | Promise<FavoriteMutation> | apps/tenant-runtime/src/api.ts:978 |
setReservationStatus | PUT /api/modules/reservations/{recordId}/status | Promise<ReservationMutation> | apps/tenant-runtime/src/api.ts:656 |
setWebLinkFavorite | PUT /api/modules/web-links/{recordId}/favorite | Promise<WebLinkMutation> | apps/tenant-runtime/src/api.ts:887 |
setWorkOrderStatus | PUT /api/modules/work-orders/{recordId}/status | Promise<WorkOrderMutation> | apps/tenant-runtime/src/api.ts:583 |
startChecklistRun | POST /api/modules/checklists-signoffs/runs | Promise<ChecklistMutation> | apps/tenant-runtime/src/api.ts:612 |
submitChecklistForSignoff | POST /api/modules/checklists-signoffs/runs/{checklistRunId}/submit | Promise<ChecklistMutation> | apps/tenant-runtime/src/api.ts:628 |
submitRuntimeForm | POST /api/runtime/forms/{pageKey}/{formName}/submissions | Promise<RuntimeFormSubmissionResponse> | apps/tenant-runtime/src/api.ts:1198 |
tenantSessionFetch | GET input | Promise<Response> | apps/tenant-runtime/src/api.ts:486 |
undoTenantPageAdoption | DELETE pageAdoptionBase(pageKey) | Promise<boolean> | apps/tenant-runtime/src/api.ts:1325 |
unlinkKnowledgeFromRecord | DELETE /api/modules/record-graph/knowledge-relations/{recordRelationId} | Promise<KnowledgeRelationMutation> | apps/tenant-runtime/src/api.ts:986 |
updateActiveWorkplace | PATCH /api/modules/active-workplace/{activeWorkplaceId} | Promise<ActiveWorkplaceMutation> | apps/tenant-runtime/src/api.ts:1017 |
updateCalendarEvent | PUT /api/modules/calendar/{recordId} | Promise<CalendarMutation> | apps/tenant-runtime/src/api.ts:717 |
updateChatRoom | PUT /api/modules/chat-rooms/{recordId} | Promise<ChatRoomMutation> | apps/tenant-runtime/src/api.ts:903 |
updateChecklistItem | PUT /api/modules/checklists-signoffs/items/{checklistRunItemId} | Promise<ChecklistMutation> | apps/tenant-runtime/src/api.ts:616 |
updateCompanyNews | PUT /api/modules/company-news/{recordId} | Promise<CompanyNewsMutation> | apps/tenant-runtime/src/api.ts:848 |
updateContact | PUT /api/modules/contacts/{recordId} | Promise<ContactMutation> | apps/tenant-runtime/src/api.ts:554 |
updateConversation | PUT /api/modules/conversations/{recordId} | Promise<ConversationMutation> | apps/tenant-runtime/src/api.ts:806 |
updateDiscussionBoard | PUT /api/modules/discussion-boards/{recordId} | Promise<DiscussionMutation> | apps/tenant-runtime/src/api.ts:925 |
updateDiscussionPost | PUT /api/modules/discussion-boards/posts/{recordId} | Promise<DiscussionMutation> | apps/tenant-runtime/src/api.ts:935 |
updateDiscussionTopic | PUT /api/modules/discussion-boards/topics/{recordId} | Promise<DiscussionMutation> | apps/tenant-runtime/src/api.ts:931 |
updateDynamicModuleRecord | PUT /api/modules/dynamic/{moduleKey}/{recordId} | Promise<DynamicModuleMutation> | apps/tenant-runtime/src/api.ts:1077 |
updateFavoritePreferences | PUT /api/modules/favorites/{recordId}/preferences | Promise<FavoriteMutation> | apps/tenant-runtime/src/api.ts:961 |
updateFile | PUT /api/modules/files/{recordId} | Promise<FileMutation> | apps/tenant-runtime/src/api.ts:755 |
updateKnowledgeArticle | PUT /api/modules/knowledge-articles/{recordId} | Promise<KnowledgeArticleMutation> | apps/tenant-runtime/src/api.ts:1103 |
updateKnowledgeCore | PUT /api/modules/knowledge-core/{recordId} | Promise<KnowledgeCoreMutation> | apps/tenant-runtime/src/api.ts:1124 |
updateReservationFollowup | PUT /api/modules/reservations/{recordId}/followups | Promise<ReservationMutation> | apps/tenant-runtime/src/api.ts:660 |
updateTenantPaymentPolicy | PUT /api/modules/payments/settings/{moduleKey} | Promise<TenantPaymentMutation> | apps/tenant-runtime/src/api.ts:669 |
updateWebLink | PUT /api/modules/web-links/{recordId} | Promise<WebLinkMutation> | apps/tenant-runtime/src/api.ts:880 |
updateWorkOrder | PUT /api/modules/work-orders/{recordId} | Promise<WorkOrderMutation> | apps/tenant-runtime/src/api.ts:579 |
uploadFile | POST /api/modules/files/upload | Promise<FileMutation> | apps/tenant-runtime/src/api.ts:742 |
uploadTenantAsset | POST /api/assets | Promise<TenantAssetMutation> | apps/tenant-runtime/src/api.ts:1347 |
upsertTenantPaymentConnector | PUT /api/modules/payments/connectors | Promise<TenantPaymentMutation> | apps/tenant-runtime/src/api.ts:673 |
In-SaaS Design authoring API 12 exported functions
Source: apps/tenant-runtime/src/designApi.ts
| Function | Transport/delegation | Return | Source |
|---|---|---|---|
clearBuilderDesignSession | Local/session helper | void | apps/tenant-runtime/src/designApi.ts:100 |
createDesignPage | POST /api/apps/{saasAppId}/pages | Promise<{ readonly pageKey: string; readonly pageVersion: number; readonly duplicatedFromPageKey?: string | null }> | apps/tenant-runtime/src/designApi.ts:148 |
getBuilderDesignSession | Local/session helper | BuilderDesignSession | null | apps/tenant-runtime/src/designApi.ts:98 |
loadDesignAuthoringMap | GET /api/apps/{saasAppId}/authoring | Promise<DesignAuthoringMap> | apps/tenant-runtime/src/designApi.ts:127 |
loadDesignPageDraft | GET /api/apps/{saasAppId}/pages/{pageKey} | Promise<DesignPageDraft> | apps/tenant-runtime/src/designApi.ts:156 |
loadDesignPageHistory | GET /api/apps/{saasAppId}/pages/{pageKey}/history?limit=25 | Promise<readonly DesignPageHistoryItem[]> | apps/tenant-runtime/src/designApi.ts:180 |
publishDesignPage | POST /api/apps/{saasAppId}/pages/{pageKey}/publish | Promise<{ readonly published: boolean; readonly publishedVersion: number }> | apps/tenant-runtime/src/designApi.ts:171 |
saveDesignMenu | PUT /api/apps/{saasAppId}/authoring/user-types/{userTypeKey}/menu | Promise<{ readonly menuVersion: number; readonly userTypeVersion: number }> | apps/tenant-runtime/src/designApi.ts:139 |
saveDesignPageDraft | PUT /api/apps/{saasAppId}/pages/{pageKey}/draft | Promise<DesignDraftSaveResult> | apps/tenant-runtime/src/designApi.ts:159 |
saveDesignUserType | PUT /api/apps/{saasAppId}/authoring/user-types/{userTypeKey} | Promise<{ readonly version: number }> | apps/tenant-runtime/src/designApi.ts:130 |
setBuilderDesignSession | Local/session helper | void | apps/tenant-runtime/src/designApi.ts:94 |
validateDesignPage | POST /api/apps/{saasAppId}/pages/{pageKey}/validate | Promise<DesignPageValidation> | apps/tenant-runtime/src/designApi.ts:168 |
createUniversalInboxHttpClient 13 public methods
Default same-origin base: /api/inbox/items
| Method | Compiler-extracted call | Source |
|---|---|---|
list | request(`${basePath}?${filterQuery(filter)}`, signal) | modules/universal-inbox/src/client.ts:121 |
get | request(`${basePath}/${encodeURIComponent(normalizedId)}`, signal) | modules/universal-inbox/src/client.ts:124 |
badge | request(`${basePath.replace(/\/items$/, "")}/badge`, signal) | modules/universal-inbox/src/client.ts:132 |
notifications | request(`${notificationsPath}/notifications?top=${topN}`, signal) | modules/universal-inbox/src/client.ts:135 |
deliveryDebug | request(`${root}/delivery/debug?${query}`, signal) | modules/universal-inbox/src/client.ts:142 |
retryDelivery | fetchImplementation(`${root}/delivery/${encodeURIComponent(outboundMessageId.toLowerCase())}/retry`, { method: "POST", credentials: "same-origin", headers, signal }) | modules/universal-inbox/src/client.ts:148 |
setReadState | mutate(inboxItemId, { isUnread }, signal) | modules/universal-inbox/src/client.ts:162 |
setStatus | mutate(inboxItemId, { status, ...(snoozedUntilUtc ? { snoozedUntilUtc } : {}) }, signal) | modules/universal-inbox/src/client.ts:163 |
setPriority | mutate(inboxItemId, { priority }, signal) | modules/universal-inbox/src/client.ts:165 |
setAssignment | mutate(inboxItemId, { assignmentMode }, signal) | modules/universal-inbox/src/client.ts:171 |
getEmailTicketingSettings | request(`${root}/email-channels/ticketing`, signal) | modules/universal-inbox/src/client.ts:177 |
setEmailTicketing | fetchImplementation(`${root}/email-channels/${encodeURIComponent(channelConnectionId.toLowerCase())}/ticketing`, { method: "PUT", credentials: "same-origin", headers, body: JSON.stringify({ isTicketingEnabled, ticketPrefix: normalizedPrefix }), signal }) | modules/universal-inbox/src/client.ts:181 |
decideWorkflowApproval | fetchImplementation(`${basePath}/${encodeURIComponent(inboxItemId.toLowerCase())}/workflow-approval`, {
method: "POST",
credentials: "same-origin",
headers,
body: JSON.stringify({
expectedActivityVersion,
decision,
...(normalizedReason ? { reason: normalizedReason } : {}),
}),
signal,
}) | modules/universal-inbox/src/client.ts:200 |
createApprovalQueueHttpClient 5 public methods
Default same-origin base: /api/goclaw/approvals
| Method | Compiler-extracted call | Source |
|---|---|---|
list | fetchImplementation(basePath + "?top=" + encodeURIComponent(String(topN)), {
method: "GET",
credentials: "same-origin",
headers: headers(),
signal,
}) | modules/universal-inbox/src/approvalClient.ts:94 |
approve | fetchImplementation(batchPath(suggestionBatchId, "approve"), {
method: "POST",
credentials: "same-origin",
headers: headers(true),
body: JSON.stringify(input),
signal,
}) | modules/universal-inbox/src/approvalClient.ts:110 |
reject | disposition(suggestionBatchId, "reject", reviewNotes, signal) | modules/universal-inbox/src/approvalClient.ts:125 |
takeOver | disposition(suggestionBatchId, "take-over", reviewNotes, signal) | modules/universal-inbox/src/approvalClient.ts:128 |
retry | disposition(suggestionBatchId, "retry", reviewNotes, signal) | modules/universal-inbox/src/approvalClient.ts:131 |
Non-page tenant and Design server routes
These are the additional server routes outside the 163 page-module operations. A declared-interface row proves the controller-to-procedure chain. An unresolved row remains useful route/controller evidence but is not presented as a one-procedure contract; orchestration and factory services can legitimately span multiple operations.
| Host | Route | Browser | Service | Procedure/evidence |
|---|---|---|---|---|
| tenant-runtime | POST/api/ai/datachat/ask | No direct browser join | Factory/controller orchestration | Orchestration/unresolved to one procedureunresolved |
| tenant-runtime | POST/api/ai/datachat/glossary/confirm | No direct browser join | Factory/controller orchestration | Orchestration/unresolved to one procedureunresolved |
| tenant-runtime | GET/api/assets | No direct browser join | ITenantAssetsService.ListAsync | sp_SaasAppAssets_ListSecureddeclared-interface |
| tenant-runtime | POST/api/assets | uploadTenantAsset | ITenantAssetsService.UploadAsync | sp_SaasAppAssets_CreateSecureddeclared-interface |
| tenant-runtime | GET/api/assets/{assetId:guid}/content | No direct browser join | ITenantAssetsServiceFactory.CreateAsync | sp_SaasAppAssets_ListSecured, sp_SaasAppAssets_CreateSecured, sp_SaasAppAssets_GetContentSecured, sp_SaasAppAssets_DeleteSecureddeclared-interface |
| tenant-runtime | DELETE/api/assets/{assetId:guid} | deleteTenantAsset | ITenantAssetsService.DeleteAsync | sp_SaasAppAssets_DeleteSecureddeclared-interface |
| tenant-runtime | PUT/api/goclaw/agents/{goClawAgentId:guid}/authority | No direct browser join | Factory/controller orchestration | Orchestration/unresolved to one procedureunresolved |
| tenant-runtime | GET/api/goclaw/approvals | No direct browser join | Factory/controller orchestration | Orchestration/unresolved to one procedureunresolved |
| tenant-runtime | POST/api/goclaw/approvals/{suggestionBatchId:guid}/approve | No direct browser join | Factory/controller orchestration | Orchestration/unresolved to one procedureunresolved |
| tenant-runtime | POST/api/goclaw/approvals/{suggestionBatchId:guid}/reject | No direct browser join | Factory/controller orchestration | Orchestration/unresolved to one procedureunresolved |
| tenant-runtime | POST/api/goclaw/approvals/{suggestionBatchId:guid}/take-over | No direct browser join | Factory/controller orchestration | Orchestration/unresolved to one procedureunresolved |
| tenant-runtime | POST/api/goclaw/approvals/{suggestionBatchId:guid}/retry | No direct browser join | Factory/controller orchestration | Orchestration/unresolved to one procedureunresolved |
| tenant-runtime | GET/api/inbox/items | No direct browser join | IUniversalInboxService.GetQueueAsync | sp_Inbox_GetQueueSecureddeclared-interface |
| tenant-runtime | GET/api/inbox/email-channels/ticketing | No direct browser join | IUniversalInboxService.GetEmailTicketingSettingsAsync | sp_Inbox_GetEmailTicketingSettingsSecureddeclared-interface |
| tenant-runtime | PUT/api/inbox/email-channels/{channelConnectionId:guid}/ticketing | No direct browser join | IUniversalInboxService.SetEmailTicketingAsync | sp_Inbox_SetEmailTicketingSecureddeclared-interface |
| tenant-runtime | GET/api/inbox/items/{inboxItemId:guid} | No direct browser join | IUniversalInboxService.GetItemAsync | sp_Inbox_GetItemDetailSecureddeclared-interface |
| tenant-runtime | GET/api/inbox/badge | No direct browser join | IUniversalInboxService.GetBadgeAsync | sp_GetInboxBadgeSecureddeclared-interface |
| tenant-runtime | GET/api/inbox/notifications | No direct browser join | IUniversalInboxService.GetNotificationsAsync | sp_GetInboxNotificationsSecureddeclared-interface |
| tenant-runtime | GET/api/inbox/delivery/debug | No direct browser join | IUniversalInboxService.GetDeliveryDebugAsync | sp_GetDeliveryDebugSecureddeclared-interface |
| tenant-runtime | POST/api/inbox/delivery/{outboundMessageId:guid}/retry | No direct browser join | IUniversalInboxService.RetryDeliveryAsync | sp_RetryOutboundMessagedeclared-interface |
| tenant-runtime | PUT/api/inbox/items/{inboxItemId:guid}/human-state | No direct browser join | IUniversalInboxService.SetReadStateAsync | sp_Inbox_MarkReaddeclared-interface |
| tenant-runtime | POST/api/inbox/items/{inboxItemId:guid}/workflow-approval | No direct browser join | Factory/controller orchestration | Orchestration/unresolved to one procedureunresolved |
| tenant-runtime | GET/api/runtime/bootstrap/{pageKey} | loadRuntimeBootstrap | ITenantBootstrapService.LoadAsync | sp_Runtime_GetPageBootstrapdeclared-interface |
| tenant-runtime | GET/api/runtime/data/{bindingKey} | loadRuntimeDataBinding | ITenantDataBindingService.ResolveAsync | sp_ResolveDataBindingByKey, buildwithHQ_CustomerCopy::dbo.declared-interface |
| tenant-runtime | POST/api/runtime/forms/{pageKey}/{formName}/submissions | submitRuntimeForm | ITenantFormsServiceFactory.CreateAsync | sp_SubmitPageFormdeclared-interface |
| tenant-runtime | GET/api/runtime/pages/{pageKey}/adoption | No direct browser join | Factory/controller orchestration | Orchestration/unresolved to one procedureunresolved |
| tenant-runtime | POST/api/runtime/pages/{pageKey}/adoption | No direct browser join | ITenantPageRevisionsService.AdoptAsync | sp_ApplyTenantPageAdoptiondeclared-interface |
| tenant-runtime | DELETE/api/runtime/pages/{pageKey}/adoption | No direct browser join | ITenantPageRevisionsService.UndoAdoptionAsync | sp_AssertTenantPageOwner, sp_GetPageHistory, sp_ValidatePageJson, sp_UndoTenantPageAdoptiondeclared-interface |
| tenant-runtime | GET/api/runtime/pages/drift | listTenantPageDrift | ITenantPageRevisionsServiceFactory.CreateAsync | sp_AssertTenantPageOwner, sp_GetPageHistory, sp_GetPageHistoryJson, sp_SaveTenantPageOverrideRaw, sp_ValidatePageJson, sp_RestorePageVersion, sp_AcquirePageEditLock, sp_ReleasePageEditLock, sp_GetPageDrift, sp_ApplyTenantPageAdoption, sp_UndoTenantPageAdoptiondeclared-interface |
| tenant-runtime | PUT/api/runtime/pages/{pageKey}/edit-lock | acquirePageEditLock | ITenantPageRevisionsService.AcquireEditLockAsync | sp_AcquirePageEditLockdeclared-interface |
| tenant-runtime | DELETE/api/runtime/pages/{pageKey}/edit-lock | releasePageEditLock | ITenantPageRevisionsService.ReleaseEditLockAsync | sp_ReleasePageEditLockdeclared-interface |
| tenant-runtime | GET/api/runtime/pages/{pageKey}/revisions | No direct browser join | Factory/controller orchestration | Orchestration/unresolved to one procedureunresolved |
| tenant-runtime | GET/api/runtime/pages/{pageKey}/revisions/{pageHistoryId:guid} | No direct browser join | ITenantPageRevisionsService.GetAsync | sp_GetPageHistoryJsondeclared-interface |
| tenant-runtime | POST/api/runtime/pages/{pageKey}/revisions/save | No direct browser join | ITenantPageRevisionsService.SaveAsync | sp_SaveTenantPageOverrideRawdeclared-interface |
| tenant-runtime | POST/api/runtime/pages/{pageKey}/revisions/{pageHistoryId:guid}/restore | No direct browser join | ITenantPageRevisionsService.RestoreAsync | sp_RestorePageVersiondeclared-interface |
| tenant-runtime | GET/api/runtime/route | loadRuntimeBootstrapBySlug | ITenantPageRouteService.LoadBySlugAsync | sp_ResolvePageBySlugdeclared-interface |
| tenant-runtime | POST/api/webhooks/twilio/sms | No direct browser join | Factory/controller orchestration | Orchestration/unresolved to one procedureunresolved |
| control-plane | GET/api/apps/{saasAppId:guid}/authoring | loadDesignAuthoringMap | IBuilderSaasAuthoringService.GetAsync | sp_Builder_GetUserTypeAuthoringMapdeclared-interface |
| control-plane | PUT/api/apps/{saasAppId:guid}/authoring/user-types/{userTypeKey} | saveDesignUserType | IBuilderSaasAuthoringService.UpsertUserTypeAsync | sp_Builder_UpsertUserTypedeclared-interface |
| control-plane | PUT/api/apps/{saasAppId:guid}/authoring/user-types/{userTypeKey}/menu | saveDesignMenu | IBuilderSaasAuthoringService.SaveMenuAsync | sp_Builder_SaveUserTypeMenudeclared-interface |
| control-plane | GET/api/apps/{saasAppId:guid}/pages | No direct browser join | IBuilderPageAdministrationService.ListAsync | sp_ListSaasAppPagesdeclared-interface |
| control-plane | POST/api/apps/{saasAppId:guid}/pages | createDesignPage | IBuilderPageAdministrationService.CreateAsync | sp_CreateSaasAppPagedeclared-interface |
| control-plane | GET/api/apps/{saasAppId:guid}/pages/{pageKey} | loadDesignPageDraft | Factory/controller orchestration | Orchestration/unresolved to one procedureunresolved |
| control-plane | PUT/api/apps/{saasAppId:guid}/pages/{pageKey}/draft | saveDesignPageDraft | IBuilderPageAdministrationService.SaveDraftAsync | sp_GetPageDraft, sp_SaveBasePageRawdeclared-interface |
| control-plane | POST/api/apps/{saasAppId:guid}/pages/{pageKey}/validate | validateDesignPage | IBuilderPageAdministrationService.ValidateAsync | sp_ValidatePageJsondeclared-interface |
| control-plane | POST/api/apps/{saasAppId:guid}/pages/{pageKey}/publish | publishDesignPage | IBuilderPageAdministrationService.PublishAsync | sp_PublishBasePagedeclared-interface |
| control-plane | GET/api/apps/{saasAppId:guid}/pages/{pageKey}/history | loadDesignPageHistory | IBuilderPageAdministrationService.HistoryAsync | sp_GetPageHistorydeclared-interface |
Complete React catalog source
The searchable component is generated from the same JSON used above. Import the CSS only for the styled export.
BuildWithHQComponentCatalog.tsx
import { useMemo, useState } from "react";
import { buildWithHQCatalog, type CatalogModule } from "./catalog-data.generated";
export interface BuildWithHQComponentCatalogProps {
readonly initialModuleKey?: string;
readonly styled?: boolean;
}
const procedureNames = (module: CatalogModule): readonly string[] =>
[...new Set(module.operations.flatMap((operation) =>
operation.procedures.map((procedure) => procedure.procedure ?? procedure.key),
))];
const CatalogBody = ({ initialModuleKey, styled = false }: BuildWithHQComponentCatalogProps) => {
const [query, setQuery] = useState("");
const initial = buildWithHQCatalog.modules.find((module) =>
module.module_key === initialModuleKey || module.component_key === initialModuleKey,
) ?? buildWithHQCatalog.modules[0];
const [selectedKey, setSelectedKey] = useState(initial?.api_base_path ?? "");
const filtered = useMemo(() => {
const needle = query.trim().toLocaleLowerCase("en-US");
if (!needle) return buildWithHQCatalog.modules;
return buildWithHQCatalog.modules.filter((module) => [
module.display_name,
module.module_key,
module.component_key,
module.api_base_path,
...module.operations.map((operation) => operation.route),
...procedureNames(module),
].some((value) => value?.toLocaleLowerCase("en-US").includes(needle)));
}, [query]);
const selected = filtered.find((module) => module.api_base_path === selectedKey)
?? filtered[0]
?? buildWithHQCatalog.modules[0];
return (
<section className={styled ? "bwhq-catalog bwhq-catalog--styled" : undefined}>
<header className={styled ? "bwhq-catalog__header" : undefined}>
<div>
<p>Generated component and contract evidence</p>
<h1>BuildWithHQ component catalog</h1>
<p>{buildWithHQCatalog.totals.modules} SDK surfaces, {buildWithHQCatalog.totals.components_bound} page renderers and {buildWithHQCatalog.totals.operations} server operations.</p>
</div>
<label>
Search components, routes or procedures
<input value={query} onChange={(event) => setQuery(event.target.value)} type="search" />
</label>
</header>
<div className={styled ? "bwhq-catalog__layout" : undefined}>
<nav aria-label="First-class modules" className={styled ? "bwhq-catalog__menu" : undefined}>
<h2>Modules and API surfaces</h2>
<ul>
{filtered.map((module) => (
<li key={module.api_base_path}>
<button type="button" aria-current={selected === module ? "page" : undefined} onClick={() => setSelectedKey(module.api_base_path)}>
<span>{module.display_name}</span>
<small>{module.operations.length} operations</small>
</button>
</li>
))}
</ul>
</nav>
<main className={styled ? "bwhq-catalog__main" : undefined}>
{selected ? (
<article>
<header>
<p>{selected.component_key ?? "Server API surface"}</p>
<h2>{selected.display_name}</h2>
<code>{selected.api_base_path}</code>
</header>
<dl className={styled ? "bwhq-catalog__facts" : undefined}>
<div><dt>React renderer</dt><dd>{selected.component.name ?? "Not a page renderer"}</dd></div>
<div><dt>SDK descriptor</dt><dd>{selected.descriptor.file}:{selected.descriptor.line}</dd></div>
<div><dt>Runtime proof</dt><dd>{selected.operations.filter((operation) => operation.runtime_evidence.status === "observed").length}/{selected.operations.length} observed in supplied evidence</dd></div>
</dl>
<div className={styled ? "bwhq-catalog__table" : undefined}>
<table>
<thead><tr><th>HTTP</th><th>Browser function</th><th>Service member</th><th>Stored procedure</th><th>Evidence</th></tr></thead>
<tbody>
{selected.operations.map((operation) => (
<tr key={operation.operation_id}>
<td><strong>{operation.method}</strong><br /><code>{operation.route}</code></td>
<td>{operation.browser_calls.length ? operation.browser_calls.map((call) => <code key={call.function}>{call.function}<br /></code>) : <span>Server API only</span>}</td>
<td><code>{operation.service.interface}.{operation.service.method}</code></td>
<td>{operation.procedures.map((procedure) => <code key={procedure.key}>{procedure.procedure ?? procedure.key}<br /></code>)}</td>
<td>{operation.join_evidence}<br /><small>{operation.runtime_evidence.status}</small></td>
</tr>
))}
</tbody>
</table>
</div>
</article>
) : <p>No catalog entry matches that search.</p>}
</main>
<aside className={styled ? "bwhq-catalog__aside" : undefined}>
<h2>Authoring contracts</h2>
<h3>Core blocks</h3>
<ul>{buildWithHQCatalog.core_components.map((component) => <li key={component.component_key}><code>{component.component_key}</code></li>)}</ul>
<h3>Safe data flow</h3>
<ol>
<li>Load the server-produced page bootstrap.</li>
<li>Render only returned component contracts.</li>
<li>Call the authenticated API or a reviewed binding key.</li>
<li>Let SQL apply tenant, DataRole, record and location scope.</li>
</ol>
<p><strong>Never send a database name or tenant identifier as proof of access.</strong></p>
</aside>
</div>
</section>
);
};
export const UnstyledBuildWithHQComponentCatalog = (props: Omit<BuildWithHQComponentCatalogProps, "styled">) =>
<CatalogBody {...props} styled={false} />;
export const StyledBuildWithHQComponentCatalog = (props: Omit<BuildWithHQComponentCatalogProps, "styled">) =>
<CatalogBody {...props} styled />;buildwithhq-component-catalog.css
.bwhq-catalog--styled {
--catalog-border: #dce2ea;
--catalog-ink: #172033;
--catalog-muted: #637087;
--catalog-accent: #3659e3;
color: var(--catalog-ink);
font: 14px/1.5 Inter, ui-sans-serif, system-ui, sans-serif;
width: 100%;
}
.bwhq-catalog--styled * { box-sizing: border-box; }
.bwhq-catalog__header { align-items: end; border-bottom: 1px solid var(--catalog-border); display: flex; gap: 32px; justify-content: space-between; padding: 24px; }
.bwhq-catalog__header h1 { font-size: clamp(1.8rem, 4vw, 3rem); margin: 0; }
.bwhq-catalog__header p { color: var(--catalog-muted); margin: 4px 0; }
.bwhq-catalog__header label { display: grid; font-weight: 700; gap: 6px; min-width: min(360px, 100%); }
.bwhq-catalog__header input { border: 1px solid var(--catalog-border); border-radius: 8px; font: inherit; padding: 10px 12px; }
.bwhq-catalog__layout { display: grid; grid-template-columns: minmax(220px, 280px) minmax(0, 1fr) minmax(220px, 280px); min-height: 680px; width: 100%; }
.bwhq-catalog__menu, .bwhq-catalog__aside { padding: 20px; }
.bwhq-catalog__menu { border-right: 1px solid var(--catalog-border); }
.bwhq-catalog__aside { border-left: 1px solid var(--catalog-border); }
.bwhq-catalog__menu h2, .bwhq-catalog__aside h2 { font-size: 1rem; margin-top: 0; }
.bwhq-catalog__menu ul, .bwhq-catalog__aside ul { list-style: none; margin: 0; padding: 0; }
.bwhq-catalog__menu button { background: transparent; border: 0; border-radius: 7px; color: inherit; cursor: pointer; display: grid; font: inherit; padding: 9px 10px; text-align: left; width: 100%; }
.bwhq-catalog__menu button[aria-current="page"] { background: #eef2ff; color: #243da2; }
.bwhq-catalog__menu small { color: var(--catalog-muted); }
.bwhq-catalog__main { min-width: 0; padding: 28px; }
.bwhq-catalog__main article > header p { color: var(--catalog-accent); font-weight: 700; margin: 0; }
.bwhq-catalog__main article > header h2 { font-size: 2rem; margin: 2px 0 8px; }
.bwhq-catalog__facts { display: grid; gap: 10px; grid-template-columns: repeat(3, minmax(0, 1fr)); margin: 24px 0; }
.bwhq-catalog__facts div { background: #f7f9fc; border-radius: 8px; padding: 12px; }
.bwhq-catalog__facts dt { color: var(--catalog-muted); font-size: .75rem; font-weight: 700; text-transform: uppercase; }
.bwhq-catalog__facts dd { margin: 4px 0 0; overflow-wrap: anywhere; }
.bwhq-catalog__table { overflow-x: auto; }
.bwhq-catalog__table table { border-collapse: collapse; min-width: 900px; width: 100%; }
.bwhq-catalog__table th, .bwhq-catalog__table td { border-bottom: 1px solid var(--catalog-border); padding: 10px; text-align: left; vertical-align: top; }
.bwhq-catalog__table code { font: 12px/1.45 "JetBrains Mono", ui-monospace, monospace; overflow-wrap: anywhere; }
.bwhq-catalog__aside li { margin: 5px 0; }
@media (max-width: 1050px) { .bwhq-catalog__layout { grid-template-columns: 240px minmax(0, 1fr); } .bwhq-catalog__aside { border-left: 0; border-top: 1px solid var(--catalog-border); grid-column: 1 / -1; } }
@media (max-width: 720px) { .bwhq-catalog__header { align-items: stretch; flex-direction: column; } .bwhq-catalog__layout { display: block; } .bwhq-catalog__menu { border-bottom: 1px solid var(--catalog-border); border-right: 0; } .bwhq-catalog__facts { grid-template-columns: 1fr; } }
.bwhq-capability { border: 1px solid var(--catalog-border, #dce2ea); border-radius: 12px; color: var(--catalog-ink, #172033); display: grid; gap: 12px; padding: 20px; }
.bwhq-capability header p, .bwhq-capability header h2 { margin: 0; }
.bwhq-capability header p { color: var(--catalog-accent, #3659e3); font-weight: 700; }
.bwhq-capability header span { background: #eef2ff; border-radius: 999px; display: inline-block; margin-top: 8px; padding: 3px 9px; }
.bwhq-capability h3, .bwhq-capability p, .bwhq-capability ul, .bwhq-capability dl { margin: 0; }
.bwhq-capability dl { display: grid; gap: 8px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.bwhq-capability dl div { background: #f7f9fc; border-radius: 8px; padding: 10px; }
.bwhq-capability dt { color: #637087; font-size: .75rem; font-weight: 700; text-transform: uppercase; }
.bwhq-capability dd { margin: 3px 0 0; overflow-wrap: anywhere; }
.bwhq-workspace { color: var(--catalog-ink, #172033); width: 100%; }
.bwhq-workspace__header { align-items: center; border-bottom: 1px solid var(--catalog-border, #dce2ea); display: flex; justify-content: space-between; padding: 16px 24px; }
.bwhq-workspace__header p, .bwhq-workspace__header h1 { margin: 0; }
.bwhq-workspace__columns { display: grid; grid-template-columns: minmax(220px, 280px) minmax(0, 1fr) minmax(220px, 280px); min-height: 640px; }
.bwhq-workspace__menu, .bwhq-workspace__main, .bwhq-workspace__context { padding: 20px; }
.bwhq-workspace__menu { border-right: 1px solid var(--catalog-border, #dce2ea); }
.bwhq-workspace__context { border-left: 1px solid var(--catalog-border, #dce2ea); }
.bwhq-app-menu ul { list-style: none; margin: 0; padding: 0; }
.bwhq-app-menu li { margin: 4px 0; }
.bwhq-app-menu a, .bwhq-app-menu span { border-radius: 7px; color: inherit; display: block; padding: 8px 10px; text-decoration: none; }
.bwhq-app-menu a[aria-current="page"] { background: #eef2ff; color: #243da2; font-weight: 700; }
.bwhq-data-list, .bwhq-headless-list, .bwhq-native-frame { border: 1px solid var(--catalog-border, #dce2ea); border-radius: 10px; padding: 16px; }
.bwhq-data-list ul, .bwhq-headless-list ul { list-style: none; margin: 0; padding: 0; }
.bwhq-headless-list button { align-items: start; background: transparent; border: 0; border-bottom: 1px solid var(--catalog-border, #dce2ea); cursor: pointer; display: grid; gap: 3px; padding: 10px 0; text-align: left; width: 100%; }
.bwhq-headless-list button span { color: #637087; }
.bwhq-runtime-page { min-width: 0; width: 100%; }
.bwhq-headless-resource, .bwhq-headless-directory { color: var(--catalog-ink, #172033); display: grid; gap: 16px; width: 100%; }
.bwhq-headless-resource > header, .bwhq-headless-directory > header { align-items: end; display: flex; gap: 20px; justify-content: space-between; }
.bwhq-headless-resource header p, .bwhq-headless-resource header h2, .bwhq-headless-directory h1 { margin: 0; }
.bwhq-headless-resource label, .bwhq-headless-directory label { display: grid; gap: 4px; }
.bwhq-headless-resource input, .bwhq-headless-directory input { border: 1px solid var(--catalog-border, #dce2ea); border-radius: 7px; font: inherit; padding: 8px 10px; }
.bwhq-headless-resource > ul { display: grid; gap: 0; list-style: none; margin: 0; padding: 0; }
.bwhq-headless-resource > ul li { border-bottom: 1px solid var(--catalog-border, #dce2ea); display: grid; padding: 10px 0; }
.bwhq-headless-resource > ul li span { color: #637087; }
.bwhq-headless-resource > nav { align-items: center; display: flex; gap: 10px; justify-content: center; }
.bwhq-headless-resource form { border: 1px solid var(--catalog-border, #dce2ea); border-radius: 10px; display: grid; gap: 10px; padding: 16px; }
.bwhq-headless-resource form h3 { margin: 0; }
.bwhq-headless-directory details { border: 1px solid var(--catalog-border, #dce2ea); border-radius: 8px; padding: 12px; }
.bwhq-headless-directory summary { cursor: pointer; display: flex; justify-content: space-between; }
.bwhq-headless-directory table { border-collapse: collapse; margin-top: 10px; width: 100%; }
.bwhq-headless-directory th, .bwhq-headless-directory td { border-bottom: 1px solid var(--catalog-border, #dce2ea); padding: 8px; text-align: left; vertical-align: top; }
@media (max-width: 1050px) { .bwhq-workspace__columns { grid-template-columns: 240px minmax(0, 1fr); } .bwhq-workspace__context { border-left: 0; border-top: 1px solid var(--catalog-border, #dce2ea); grid-column: 1 / -1; } }
@media (max-width: 720px) { .bwhq-capability dl { grid-template-columns: 1fr; } .bwhq-workspace__columns { display: block; } .bwhq-workspace__menu { border-bottom: 1px solid var(--catalog-border, #dce2ea); border-right: 0; } .bwhq-headless-resource > header, .bwhq-headless-directory > header { align-items: stretch; flex-direction: column; } .bwhq-headless-directory { overflow-x: auto; } }All first-class capability components
import { buildWithHQCatalog, type CatalogCapability } from "./catalog-data.generated";
export interface FirstClassCapabilityProps {
readonly capability: CatalogCapability;
readonly styled?: boolean;
readonly showSecurity?: boolean;
}
const implementationLabel = (capability: CatalogCapability): string => {
if (capability.implementation.kind === "page-module") return "Native page module";
if (capability.implementation.kind === "shell-component") return "Tenant shell component";
return "Background platform capability";
};
export const FirstClassCapability = ({ capability, styled = false, showSecurity = true }: FirstClassCapabilityProps) => (
<article className={styled ? "bwhq-capability" : undefined} data-capability={capability.slug}>
<header>
<p>{capability.experience}</p>
<h2>{capability.title}</h2>
<span>{implementationLabel(capability)}</span>
</header>
<p>{capability.summary}</p>
<h3>What developers can build</h3>
<ul>{capability.capabilities.map((item) => <li key={item}>{item}</li>)}</ul>
<h3>Common uses</h3>
<ul>{capability.common_uses.map((item) => <li key={item}>{item}</li>)}</ul>
<dl>
<div><dt>Page block</dt><dd>{capability.implementation.native_component_key ?? "Not a page block"}</dd></div>
<div><dt>React</dt><dd>{capability.implementation.react_components.map((item) => item.component).join(", ") || "No interactive renderer is currently exposed"}</dd></div>
<div><dt>API roots</dt><dd>{capability.implementation.api_base_paths.join(", ") || "Background service contracts"}</dd></div>
</dl>
{showSecurity && <details><summary>Security boundary</summary><p>{capability.security}</p></details>}
<p><a href={capability.documentation_path}>Implementation guide for {capability.title}</a></p>
</article>
);
export const UnstyledFirstClassCapability = (props: Omit<FirstClassCapabilityProps, "styled">) =>
<FirstClassCapability {...props} styled={false} />;
export const StyledFirstClassCapability = (props: Omit<FirstClassCapabilityProps, "styled">) =>
<FirstClassCapability {...props} styled />;
export const firstClassCapabilities = buildWithHQCatalog.first_class_capabilities;
export const UnstyledUniversalInboxCapability = () => <UnstyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "universal-inbox")!} />;
export const StyledUniversalInboxCapability = () => <StyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "universal-inbox")!} />;
export const UnstyledChecklistsSignoffsCapability = () => <UnstyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "checklists-signoffs")!} />;
export const StyledChecklistsSignoffsCapability = () => <StyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "checklists-signoffs")!} />;
export const UnstyledGoclawCapability = () => <UnstyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "goclaw")!} />;
export const StyledGoclawCapability = () => <StyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "goclaw")!} />;
export const UnstyledAiInsightsCapability = () => <UnstyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "ai-insights")!} />;
export const StyledAiInsightsCapability = () => <StyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "ai-insights")!} />;
export const UnstyledContactsCapability = () => <UnstyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "contacts")!} />;
export const StyledContactsCapability = () => <StyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "contacts")!} />;
export const UnstyledWorkOrdersCapability = () => <UnstyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "work-orders")!} />;
export const StyledWorkOrdersCapability = () => <StyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "work-orders")!} />;
export const UnstyledReservationsCapability = () => <UnstyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "reservations")!} />;
export const StyledReservationsCapability = () => <StyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "reservations")!} />;
export const UnstyledCalendarCapability = () => <UnstyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "calendar")!} />;
export const StyledCalendarCapability = () => <StyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "calendar")!} />;
export const UnstyledFilesCapability = () => <UnstyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "files")!} />;
export const StyledFilesCapability = () => <StyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "files")!} />;
export const UnstyledConversationsCapability = () => <UnstyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "conversations")!} />;
export const StyledConversationsCapability = () => <StyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "conversations")!} />;
export const UnstyledCompanyNewsCapability = () => <UnstyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "company-news")!} />;
export const StyledCompanyNewsCapability = () => <StyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "company-news")!} />;
export const UnstyledKnowledgeCoreCapability = () => <UnstyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "knowledge-core")!} />;
export const StyledKnowledgeCoreCapability = () => <StyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "knowledge-core")!} />;
export const UnstyledWebLinksCapability = () => <UnstyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "web-links")!} />;
export const StyledWebLinksCapability = () => <StyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "web-links")!} />;
export const UnstyledChatRoomsCapability = () => <UnstyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "chat-rooms")!} />;
export const StyledChatRoomsCapability = () => <StyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "chat-rooms")!} />;
export const UnstyledDiscussionBoardsCapability = () => <UnstyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "discussion-boards")!} />;
export const StyledDiscussionBoardsCapability = () => <StyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "discussion-boards")!} />;
export const UnstyledMailReaderCapability = () => <UnstyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "mail-reader")!} />;
export const StyledMailReaderCapability = () => <StyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "mail-reader")!} />;
export const UnstyledFavoritesCapability = () => <UnstyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "favorites")!} />;
export const StyledFavoritesCapability = () => <StyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "favorites")!} />;
export const UnstyledNotificationsCapability = () => <UnstyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "notifications")!} />;
export const StyledNotificationsCapability = () => <StyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "notifications")!} />;
export const UnstyledDynamicRecordsCapability = () => <UnstyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "dynamic-records")!} />;
export const StyledDynamicRecordsCapability = () => <StyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "dynamic-records")!} />;
export const UnstyledActiveWorkplaceCapability = () => <UnstyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "active-workplace")!} />;
export const StyledActiveWorkplaceCapability = () => <StyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "active-workplace")!} />;
export const UnstyledRecordRelationsCapability = () => <UnstyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "record-relations")!} />;
export const StyledRecordRelationsCapability = () => <StyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "record-relations")!} />;
export const UnstyledRecordActivityCapability = () => <UnstyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "record-activity")!} />;
export const StyledRecordActivityCapability = () => <StyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "record-activity")!} />;
export const UnstyledGlobalSearchCapability = () => <UnstyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "global-search")!} />;
export const StyledGlobalSearchCapability = () => <StyledFirstClassCapability capability={firstClassCapabilities.find((item) => item.slug === "global-search")!} />;All native module block exports
import type { RuntimePageBlock } from "@buildwithhq/page-runtime";
export interface NativeModuleRecipe {
readonly moduleKey: string | null;
readonly componentKey: string;
readonly rendererKey: string;
readonly displayName: string;
readonly apiBasePath: string;
readonly unstyledBlock: RuntimePageBlock;
readonly styledComposition: RuntimePageBlock;
}
export const nativeModuleRecipes = [
{
"moduleKey": "active-workplace",
"componentKey": "module.active-workplace",
"rendererKey": "module.active-workplace",
"displayName": "Active Workplace",
"apiBasePath": "/api/modules/active-workplace",
"unstyledBlock": {
"_id": "active-workplace-module",
"_type": "module.active-workplace",
"props": {
"title": "Active Workplace"
},
"children": []
},
"styledComposition": {
"_id": "active-workplace-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "active-workplace-heading",
"_type": "core.text",
"_parent": "active-workplace-section",
"props": {
"text": "Active Workplace",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "active-workplace-module",
"_type": "module.active-workplace",
"_parent": "active-workplace-section",
"props": {
"title": "Active Workplace"
},
"children": []
}
]
}
},
{
"moduleKey": "ai_insights",
"componentKey": "module.ai-insights",
"rendererKey": "module.ai-insights",
"displayName": "Ai Insights",
"apiBasePath": "/api/modules/ai-insights",
"unstyledBlock": {
"_id": "ai-insights-module",
"_type": "module.ai-insights",
"props": {
"title": "Ai Insights"
},
"children": []
},
"styledComposition": {
"_id": "ai-insights-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "ai-insights-heading",
"_type": "core.text",
"_parent": "ai-insights-section",
"props": {
"text": "Ai Insights",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "ai-insights-module",
"_type": "module.ai-insights",
"_parent": "ai-insights-section",
"props": {
"title": "Ai Insights"
},
"children": []
}
]
}
},
{
"moduleKey": "calendar",
"componentKey": "module.calendar",
"rendererKey": "module.calendar",
"displayName": "Calendar",
"apiBasePath": "/api/modules/calendar",
"unstyledBlock": {
"_id": "calendar-module",
"_type": "module.calendar",
"props": {
"title": "Calendar"
},
"children": []
},
"styledComposition": {
"_id": "calendar-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "calendar-heading",
"_type": "core.text",
"_parent": "calendar-section",
"props": {
"text": "Calendar",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "calendar-module",
"_type": "module.calendar",
"_parent": "calendar-section",
"props": {
"title": "Calendar"
},
"children": []
}
]
}
},
{
"moduleKey": "chat-rooms",
"componentKey": "module.chat-rooms",
"rendererKey": "module.chat-rooms",
"displayName": "Chat Rooms",
"apiBasePath": "/api/modules/chat-rooms",
"unstyledBlock": {
"_id": "chat-rooms-module",
"_type": "module.chat-rooms",
"props": {
"title": "Chat Rooms"
},
"children": []
},
"styledComposition": {
"_id": "chat-rooms-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "chat-rooms-heading",
"_type": "core.text",
"_parent": "chat-rooms-section",
"props": {
"text": "Chat Rooms",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "chat-rooms-module",
"_type": "module.chat-rooms",
"_parent": "chat-rooms-section",
"props": {
"title": "Chat Rooms"
},
"children": []
}
]
}
},
{
"moduleKey": "checklists_signoffs",
"componentKey": "module.checklists-signoffs",
"rendererKey": "module.checklists-signoffs",
"displayName": "Checklists Signoffs",
"apiBasePath": "/api/modules/checklists-signoffs",
"unstyledBlock": {
"_id": "checklists-signoffs-module",
"_type": "module.checklists-signoffs",
"props": {
"title": "Checklists Signoffs"
},
"children": []
},
"styledComposition": {
"_id": "checklists-signoffs-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "checklists-signoffs-heading",
"_type": "core.text",
"_parent": "checklists-signoffs-section",
"props": {
"text": "Checklists Signoffs",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "checklists-signoffs-module",
"_type": "module.checklists-signoffs",
"_parent": "checklists-signoffs-section",
"props": {
"title": "Checklists Signoffs"
},
"children": []
}
]
}
},
{
"moduleKey": "company-news",
"componentKey": "module.company-news",
"rendererKey": "module.company-news",
"displayName": "Company News",
"apiBasePath": "/api/modules/company-news",
"unstyledBlock": {
"_id": "company-news-module",
"_type": "module.company-news",
"props": {
"title": "Company News"
},
"children": []
},
"styledComposition": {
"_id": "company-news-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "company-news-heading",
"_type": "core.text",
"_parent": "company-news-section",
"props": {
"text": "Company News",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "company-news-module",
"_type": "module.company-news",
"_parent": "company-news-section",
"props": {
"title": "Company News"
},
"children": []
}
]
}
},
{
"moduleKey": "contacts",
"componentKey": "module.contacts",
"rendererKey": "module.contacts",
"displayName": "Contacts",
"apiBasePath": "/api/modules/contacts",
"unstyledBlock": {
"_id": "contacts-module",
"_type": "module.contacts",
"props": {
"title": "Contacts"
},
"children": []
},
"styledComposition": {
"_id": "contacts-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "contacts-heading",
"_type": "core.text",
"_parent": "contacts-section",
"props": {
"text": "Contacts",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "contacts-module",
"_type": "module.contacts",
"_parent": "contacts-section",
"props": {
"title": "Contacts"
},
"children": []
}
]
}
},
{
"moduleKey": "conversations",
"componentKey": "module.conversations",
"rendererKey": "module.conversations",
"displayName": "Conversations",
"apiBasePath": "/api/modules/conversations",
"unstyledBlock": {
"_id": "conversations-module",
"_type": "module.conversations",
"props": {
"title": "Conversations"
},
"children": []
},
"styledComposition": {
"_id": "conversations-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "conversations-heading",
"_type": "core.text",
"_parent": "conversations-section",
"props": {
"text": "Conversations",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "conversations-module",
"_type": "module.conversations",
"_parent": "conversations-section",
"props": {
"title": "Conversations"
},
"children": []
}
]
}
},
{
"moduleKey": "discussion-boards",
"componentKey": "module.discussion-boards",
"rendererKey": "module.discussion-boards",
"displayName": "Discussion Boards",
"apiBasePath": "/api/modules/discussion-boards",
"unstyledBlock": {
"_id": "discussion-boards-module",
"_type": "module.discussion-boards",
"props": {
"title": "Discussion Boards"
},
"children": []
},
"styledComposition": {
"_id": "discussion-boards-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "discussion-boards-heading",
"_type": "core.text",
"_parent": "discussion-boards-section",
"props": {
"text": "Discussion Boards",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "discussion-boards-module",
"_type": "module.discussion-boards",
"_parent": "discussion-boards-section",
"props": {
"title": "Discussion Boards"
},
"children": []
}
]
}
},
{
"moduleKey": null,
"componentKey": "module.dynamic-records",
"rendererKey": "module.dynamic-records",
"displayName": "Dynamic Records",
"apiBasePath": "/api/modules/dynamic",
"unstyledBlock": {
"_id": "dynamic-records-module",
"_type": "module.dynamic-records",
"props": {
"title": "Dynamic Records"
},
"children": []
},
"styledComposition": {
"_id": "dynamic-records-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "dynamic-records-heading",
"_type": "core.text",
"_parent": "dynamic-records-section",
"props": {
"text": "Dynamic Records",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "dynamic-records-module",
"_type": "module.dynamic-records",
"_parent": "dynamic-records-section",
"props": {
"title": "Dynamic Records"
},
"children": []
}
]
}
},
{
"moduleKey": "favorites",
"componentKey": "module.favorites",
"rendererKey": "module.favorites",
"displayName": "Favorites",
"apiBasePath": "/api/modules/favorites",
"unstyledBlock": {
"_id": "favorites-module",
"_type": "module.favorites",
"props": {
"title": "Favorites"
},
"children": []
},
"styledComposition": {
"_id": "favorites-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "favorites-heading",
"_type": "core.text",
"_parent": "favorites-section",
"props": {
"text": "Favorites",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "favorites-module",
"_type": "module.favorites",
"_parent": "favorites-section",
"props": {
"title": "Favorites"
},
"children": []
}
]
}
},
{
"moduleKey": "files",
"componentKey": "module.files",
"rendererKey": "module.files",
"displayName": "Files",
"apiBasePath": "/api/modules/files",
"unstyledBlock": {
"_id": "files-module",
"_type": "module.files",
"props": {
"title": "Files"
},
"children": []
},
"styledComposition": {
"_id": "files-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "files-heading",
"_type": "core.text",
"_parent": "files-section",
"props": {
"text": "Files",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "files-module",
"_type": "module.files",
"_parent": "files-section",
"props": {
"title": "Files"
},
"children": []
}
]
}
},
{
"moduleKey": "global-search",
"componentKey": "module.global-search",
"rendererKey": "module.global-search",
"displayName": "Global Search",
"apiBasePath": "/api/modules/global-search",
"unstyledBlock": {
"_id": "global-search-module",
"_type": "module.global-search",
"props": {
"title": "Global Search"
},
"children": []
},
"styledComposition": {
"_id": "global-search-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "global-search-heading",
"_type": "core.text",
"_parent": "global-search-section",
"props": {
"text": "Global Search",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "global-search-module",
"_type": "module.global-search",
"_parent": "global-search-section",
"props": {
"title": "Global Search"
},
"children": []
}
]
}
},
{
"moduleKey": "knowledge-articles",
"componentKey": "module.knowledge-articles",
"rendererKey": "module.knowledge-articles",
"displayName": "Knowledge Articles",
"apiBasePath": "/api/modules/knowledge-articles",
"unstyledBlock": {
"_id": "knowledge-articles-module",
"_type": "module.knowledge-articles",
"props": {
"title": "Knowledge Articles"
},
"children": []
},
"styledComposition": {
"_id": "knowledge-articles-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "knowledge-articles-heading",
"_type": "core.text",
"_parent": "knowledge-articles-section",
"props": {
"text": "Knowledge Articles",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "knowledge-articles-module",
"_type": "module.knowledge-articles",
"_parent": "knowledge-articles-section",
"props": {
"title": "Knowledge Articles"
},
"children": []
}
]
}
},
{
"moduleKey": "mail-reader",
"componentKey": "module.mail-reader",
"rendererKey": "module.mail-reader",
"displayName": "Mail Reader",
"apiBasePath": "/api/modules/mail-reader",
"unstyledBlock": {
"_id": "mail-reader-module",
"_type": "module.mail-reader",
"props": {
"title": "Mail Reader"
},
"children": []
},
"styledComposition": {
"_id": "mail-reader-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "mail-reader-heading",
"_type": "core.text",
"_parent": "mail-reader-section",
"props": {
"text": "Mail Reader",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "mail-reader-module",
"_type": "module.mail-reader",
"_parent": "mail-reader-section",
"props": {
"title": "Mail Reader"
},
"children": []
}
]
}
},
{
"moduleKey": "notifications",
"componentKey": "module.notifications",
"rendererKey": "module.notifications",
"displayName": "Notifications",
"apiBasePath": "/api/modules/notifications",
"unstyledBlock": {
"_id": "notifications-module",
"_type": "module.notifications",
"props": {
"title": "Notifications"
},
"children": []
},
"styledComposition": {
"_id": "notifications-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "notifications-heading",
"_type": "core.text",
"_parent": "notifications-section",
"props": {
"text": "Notifications",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "notifications-module",
"_type": "module.notifications",
"_parent": "notifications-section",
"props": {
"title": "Notifications"
},
"children": []
}
]
}
},
{
"moduleKey": "record-activity",
"componentKey": "module.record-activity",
"rendererKey": "module.record-activity",
"displayName": "Record Activity",
"apiBasePath": "/api/modules/record-activity",
"unstyledBlock": {
"_id": "record-activity-module",
"_type": "module.record-activity",
"props": {
"title": "Record Activity"
},
"children": []
},
"styledComposition": {
"_id": "record-activity-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "record-activity-heading",
"_type": "core.text",
"_parent": "record-activity-section",
"props": {
"text": "Record Activity",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "record-activity-module",
"_type": "module.record-activity",
"_parent": "record-activity-section",
"props": {
"title": "Record Activity"
},
"children": []
}
]
}
},
{
"moduleKey": "record-graph",
"componentKey": "module.record-graph",
"rendererKey": "module.record-graph",
"displayName": "Record Graph",
"apiBasePath": "/api/modules/record-graph",
"unstyledBlock": {
"_id": "record-graph-module",
"_type": "module.record-graph",
"props": {
"title": "Record Graph"
},
"children": []
},
"styledComposition": {
"_id": "record-graph-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "record-graph-heading",
"_type": "core.text",
"_parent": "record-graph-section",
"props": {
"text": "Record Graph",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "record-graph-module",
"_type": "module.record-graph",
"_parent": "record-graph-section",
"props": {
"title": "Record Graph"
},
"children": []
}
]
}
},
{
"moduleKey": "reservations",
"componentKey": "module.reservations",
"rendererKey": "module.reservations",
"displayName": "Reservations",
"apiBasePath": "/api/modules/reservations",
"unstyledBlock": {
"_id": "reservations-module",
"_type": "module.reservations",
"props": {
"title": "Reservations"
},
"children": []
},
"styledComposition": {
"_id": "reservations-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "reservations-heading",
"_type": "core.text",
"_parent": "reservations-section",
"props": {
"text": "Reservations",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "reservations-module",
"_type": "module.reservations",
"_parent": "reservations-section",
"props": {
"title": "Reservations"
},
"children": []
}
]
}
},
{
"moduleKey": "web-links",
"componentKey": "module.web-links",
"rendererKey": "module.web-links",
"displayName": "Web Links",
"apiBasePath": "/api/modules/web-links",
"unstyledBlock": {
"_id": "web-links-module",
"_type": "module.web-links",
"props": {
"title": "Web Links"
},
"children": []
},
"styledComposition": {
"_id": "web-links-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "web-links-heading",
"_type": "core.text",
"_parent": "web-links-section",
"props": {
"text": "Web Links",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "web-links-module",
"_type": "module.web-links",
"_parent": "web-links-section",
"props": {
"title": "Web Links"
},
"children": []
}
]
}
},
{
"moduleKey": "work_orders",
"componentKey": "module.work-orders",
"rendererKey": "module.work-orders",
"displayName": "Work Orders",
"apiBasePath": "/api/modules/work-orders",
"unstyledBlock": {
"_id": "work-orders-module",
"_type": "module.work-orders",
"props": {
"title": "Work Orders"
},
"children": []
},
"styledComposition": {
"_id": "work-orders-section",
"_type": "core.container",
"props": {
"layout": "stack"
},
"children": [
{
"_id": "work-orders-heading",
"_type": "core.text",
"_parent": "work-orders-section",
"props": {
"text": "Work Orders",
"variant": "heading",
"align": "left"
},
"children": []
},
{
"_id": "work-orders-module",
"_type": "module.work-orders",
"_parent": "work-orders-section",
"props": {
"title": "Work Orders"
},
"children": []
}
]
}
}
] as const satisfies readonly NativeModuleRecipe[];
export const ActiveWorkplaceUnstyledBlock = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.active-workplace")!.unstyledBlock;
export const ActiveWorkplaceStyledComposition = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.active-workplace")!.styledComposition;
export const AiInsightsUnstyledBlock = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.ai-insights")!.unstyledBlock;
export const AiInsightsStyledComposition = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.ai-insights")!.styledComposition;
export const CalendarUnstyledBlock = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.calendar")!.unstyledBlock;
export const CalendarStyledComposition = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.calendar")!.styledComposition;
export const ChatRoomsUnstyledBlock = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.chat-rooms")!.unstyledBlock;
export const ChatRoomsStyledComposition = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.chat-rooms")!.styledComposition;
export const ChecklistsSignoffsUnstyledBlock = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.checklists-signoffs")!.unstyledBlock;
export const ChecklistsSignoffsStyledComposition = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.checklists-signoffs")!.styledComposition;
export const CompanyNewsUnstyledBlock = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.company-news")!.unstyledBlock;
export const CompanyNewsStyledComposition = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.company-news")!.styledComposition;
export const ContactsUnstyledBlock = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.contacts")!.unstyledBlock;
export const ContactsStyledComposition = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.contacts")!.styledComposition;
export const ConversationsUnstyledBlock = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.conversations")!.unstyledBlock;
export const ConversationsStyledComposition = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.conversations")!.styledComposition;
export const DiscussionBoardsUnstyledBlock = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.discussion-boards")!.unstyledBlock;
export const DiscussionBoardsStyledComposition = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.discussion-boards")!.styledComposition;
export const DynamicRecordsUnstyledBlock = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.dynamic-records")!.unstyledBlock;
export const DynamicRecordsStyledComposition = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.dynamic-records")!.styledComposition;
export const FavoritesUnstyledBlock = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.favorites")!.unstyledBlock;
export const FavoritesStyledComposition = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.favorites")!.styledComposition;
export const FilesUnstyledBlock = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.files")!.unstyledBlock;
export const FilesStyledComposition = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.files")!.styledComposition;
export const GlobalSearchUnstyledBlock = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.global-search")!.unstyledBlock;
export const GlobalSearchStyledComposition = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.global-search")!.styledComposition;
export const KnowledgeArticlesUnstyledBlock = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.knowledge-articles")!.unstyledBlock;
export const KnowledgeArticlesStyledComposition = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.knowledge-articles")!.styledComposition;
export const MailReaderUnstyledBlock = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.mail-reader")!.unstyledBlock;
export const MailReaderStyledComposition = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.mail-reader")!.styledComposition;
export const NotificationsUnstyledBlock = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.notifications")!.unstyledBlock;
export const NotificationsStyledComposition = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.notifications")!.styledComposition;
export const RecordActivityUnstyledBlock = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.record-activity")!.unstyledBlock;
export const RecordActivityStyledComposition = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.record-activity")!.styledComposition;
export const RecordGraphUnstyledBlock = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.record-graph")!.unstyledBlock;
export const RecordGraphStyledComposition = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.record-graph")!.styledComposition;
export const ReservationsUnstyledBlock = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.reservations")!.unstyledBlock;
export const ReservationsStyledComposition = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.reservations")!.styledComposition;
export const WebLinksUnstyledBlock = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.web-links")!.unstyledBlock;
export const WebLinksStyledComposition = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.web-links")!.styledComposition;
export const WorkOrdersUnstyledBlock = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.work-orders")!.unstyledBlock;
export const WorkOrdersStyledComposition = nativeModuleRecipes.find((recipe) => recipe.componentKey === "module.work-orders")!.styledComposition;Regenerate and verify
python catalog-generator/generate_catalog.py
python catalog-generator/generate_catalog.py --check
apps\tenant-runtime\node_modules\.bin\tsc.cmd -p catalog-generator\generated\tsconfig.json
# Optional: merge dev/test route-to-SQL observations
python catalog-generator/generate_catalog.py --observations C:\absolute\path\observations.jsonl
Enable runtime observation only in a disposable Development/Test tenant-runtime process with an absolute CatalogCapture:OutputPath. The capture feature refuses Production and writes no request data, identity, host, token, SQL parameters, result, or connection details.
A generated catalog is an implementation inventory, not an authorization bypass, production capacity claim, penetration-test result, or proof that every route was exercised. Keep negative-path, cross-tenant, concurrency, accessibility, browser and failure-recovery tests alongside it.