SDK Reference

Misc

Two standalone utilities that don't fit the other module pages: BugReport (bugReport.ts) and GetAvailableCatalog (company/catalog/available.ts).

BugReport

A user-submitted bug report, optionally scoped to a company.

Not company-namespaced:Queried/created against the account-level /bug-reports endpoint — unlike almost every other domain class, which is scoped under /company/{companyID}/.... Full CRUD DataStructure<BugReportData>.

Data fields

FieldTypeNotes
idstring
titlestring
statusBugReportStatus"open" | "in_progress" | "resolved" | "closed"
priorityBugReportPriority"low" | "medium" | "high" | "critical"
createdAt?stringpresent on LazyBugReportData already
userIDstringfull data only
companyID?string | nullfull data only — optional company scope
description?string | nullfull data only
appVersion?string | nullfull data only
platform?string | nullfull data only
updatedAt?stringfull data only
resolvedAt?string | nullfull data only

LazyBugReportData is { id, title, status, priority, createdAt? }.

Constructing

ts
new BugReport(id: string);                                  // lazy — triggers preloadData(true)
new BugReport(data: LazyBugReportData | BugReportData, lazy?);

Static methods

ts
BugReport.create(body: CreateBugReportBody): Promise<SimpleResult<{ id: string }>>

CreateBugReportBody = { title, description?, companyID?, priority?, appVersion?, platform? }. POST /bug-reports with the body wrapped in an array ([body]) — a bulk-shaped endpoint used for a single-item create. Returns just the new id; statusdefaults to whatever the backend assigns — it isn't settable at create time since it's not part of CreateBugReportBody.

Note:A deprecated standalone wrapper also exists: CreateBugReport(body) — it just delegates to BugReport.create(body). Prefer the static method per the SDK-wide convention of calling class methods rather than standalone functions.
ts
BugReport.deleteMany(ids: string[]): Promise<SimpleResult<EventData>>

DELETE /bug-reports with { ids } in the body — bulk delete in one call, unlike the per-instance delete() below.

ts
BugReport.query(data: QueryRequest): Promise<SimpleResult<BugReport[]>>

POST /bug-reports/query with the standard { filter, logic = "and", sort, limit, offset, lazy = true } shape. Wraps each result row in new BugReport(r, lazy).

Instance methods

ts
report.save(): Promise<SimpleResult<EventData>>

PATCH /bug-reports?id={id} — sends only the mutable subset (title, description, status, priority, appVersion, platform), not the full cached object.

ts
report.delete(): Promise<SimpleResult<EventData>>

DELETE /bug-reports?id={id} — single-item delete (see deleteMany above for bulk).

GetAvailableCatalog

ts
GetAvailableCatalog(company: Company, opts?: GetAvailableCatalogOptions): Promise<SimpleResult<AvailableCatalogResponse>>

GET /company/{companyID}/catalog/available — fetches a company's entirebuyable/bookable catalog (products, services, upcoming class instances) in a single call, with every item annotated for the caller's (or a specified member's) eligibility, rather than filtered down to only what's eligible. A full class is still returned with isFull: true, canBook: falserather than dropped — callers decide how to present ineligible items (e.g. grayed-out) instead of losing them silently. This batches the same eligibility checks the booking-create flow runs at actual booking time, so it's designed to be called once per screen load rather than once per class/product/service.

Options

ts
interface GetAvailableCatalogOptions {
  memberID?: string;
  days?: number;
}
  • memberID?— view eligibility on behalf of another member instead of the caller's own. Requires CHECKOUTS CREATE permission (mirrors the payerUserIDpattern on checkout); for callers without that permission, it's silently ignoredand eligibility falls back to the caller's own — no error is raised.
  • days? — how many days of upcoming class instances to include. Backend defaults to 14 when omitted.

Response shape

ts
interface AvailableCatalogResponse {
  products: AvailableCatalogProduct[];
  services: AvailableCatalogService[];
  classes: AvailableCatalogClassInstance[];
}
ts
interface AvailableCatalogProduct extends LazyProductData {
  inStock: boolean; // true when stock is NULL (unlimited) or > 0
}

type AvailableCatalogService = LazyServiceData; // no eligibility annotations — services have no availability concept

interface AvailableCatalogClassInstance extends LazyClassInstanceData {
  className: string;
  classCapacity: number;
  classPrice?: number;
  spotsAvailable: number;   // remaining open (non-waitlist) spots; can be 0 while willWaitlist is still true
  isFull: boolean;
  willWaitlist: boolean;    // a booking made now would land on the waitlist, not a confirmed spot
  alreadyBooked: boolean;   // the target member already holds a non-canceled booking on this instance
  hasCredit: boolean;       // the target member holds an unused Credit applicable to this instance's class (or a tag)
  canBook: boolean;         // false when alreadyBooked, or full with waitlisting disabled
}

How this differs from plain query() calls

Product.query() / Service.query() / ClassInstance.query()GetAvailableCatalog()
ScopeOne resource type per call, arbitrary filtersAll three resource types in one call, fixed to upcoming/catalog-relevant rows
EligibilityNone — raw rows onlyEvery product/class annotated (inStock, spotsAvailable, isFull, willWaitlist, alreadyBooked, hasCredit, canBook)
Caller-specificNoYes — computed for the caller (or opts.memberID, permission-gated)
Use caseAdmin/staff list pages, arbitrary search/sortStorefront/booking screens deciding what to show a specific member and whether they can act on it

Services get no extra annotations (AvailableCatalogService is a plain type alias for LazyServiceData) since the schema has no availability concept for them — only products (inStock) and class instances (the full eligibility set) are enriched.