Quickback Docs

Connecting

Run the CMS in demo mode with mock data or connect it to a live Quickback API.

Connecting

The CMS supports two modes: demo mode for development and testing, and live mode for connecting to a real Quickback API.

Demo Mode

When no VITE_API_URL is set, the CMS runs in demo mode:

  • Uses a mock API client backed by localStorage
  • Loads seed data from JSON files in data/mock/
  • Provides a role switcher in the header to test owner/admin/member access
  • Simulates authentication sessions without a real backend

Demo mode is useful for prototyping your schema, testing guard behavior across roles, and verifying masking rules before deploying.

.env.development
# No VITE_API_URL — CMS runs in demo mode

Mock Data

Place JSON files in data/mock/ matching your table names:

data/mock/
  contact.json       # Array of contact records
  project.json       # Array of project records
  invoice.json       # Array of invoice records
  _meta.json         # Mock session and org metadata

Each file contains an array of records. The mock client loads them on startup and persists changes to localStorage.

Role Switcher

In demo mode, the header displays a role switcher dropdown allowing you to switch between owner, admin, and member roles in real time. This lets you verify:

  • Which CRUD buttons appear per role
  • Which form fields are editable
  • Which masking rules apply
  • Which actions are available
  • Which views are accessible

Live Mode

Set VITE_API_URL to connect to a real Quickback API:

.env.production
VITE_API_URL=https://api.example.com

In live mode, the CMS:

  • Reads the Better Auth session from cookies
  • Fetches the user's organization membership and role
  • Makes real API calls to the Quickback backend for all CRUD operations
  • Applies server-side security (firewall, guards, masking) in addition to client-side UI filtering

API Client Interface

The CMS communicates with the backend through a standard interface:

interface IApiClient {
  list(table: string, params?: ListParams): Promise<ListResult>;
  get(table: string, id: string): Promise<Record | null>;
  create(table: string, data: Record): Promise<Record>;
  update(table: string, id: string, data: Partial<Record>): Promise<Record>;
  delete(table: string, id: string): Promise<void>;
  executeAction(
    table: string,
    actionName: string,
    recordId: string | null,
    input: Record
  ): Promise<Record>;
  listView(
    table: string,
    viewName: string,
    params?: ListParams
  ): Promise<ListResult>;
}

List Parameters

interface ListParams {
  page?: number;
  pageSize?: number;
  sort?: string;
  order?: "asc" | "desc";
  search?: string;
  filters?: Record<string, unknown>;
}

List Result

interface ListResult {
  data: Record[];
  total: number;
  page: number;
  pageSize: number;
}

Both the mock client and the live client implement this same interface. The CMS code is identical in both modes — only the underlying transport changes.

Server-Side Security

In live mode, all four Quickback security layers (firewall, CRUD access, guards, masking) are enforced server-side. The CMS hides unauthorized UI elements as a convenience, but the API rejects unauthorized requests regardless.

How the Client is Created

The CMS auto-creates the API client based on configuration:

  1. No VITE_API_URL — Instantiates the mock client, loads seed data from data/mock/, and uses localStorage for persistence.
  2. VITE_API_URL is set — Instantiates the live client, reads the auth session cookie, and makes fetch requests to the Quickback API using the standard REST endpoints (/api/v1/{table}).

The client is provided via React context (ApiClientContext) and available throughout the component tree.

Next Steps

  • Table Views — Browse and Data Table view modes
  • Security — How roles, guards, and masking work in the CMS

On this page