Skip to content

How it fits together

For whoever is running the desk, and anybody deciding whether to.

One Laravel application, one database, one server. Everything below is part of that application unless it says otherwise.

The pieces

┌──────────────────────────────────────────┐
agents ─────────► │ Staff web app (Vue) │
│ ────────────────────────────────────── │
clients ────────► │ Integration API ← platform module │
(through their │ Chat widget + site snippet │
billing portal) │ Public status feed / report intake │
└───────────────┬──────────────────────────┘
│ Laravel (PHP)
┌─────────┴─────────┐
│ │
┌─────▼─────┐ ┌──────▼──────┐
│ MySQL / │ │ Queue │ emails, AI, campaigns,
│ MariaDB │ │ workers │ knowledge, webhooks
└───────────┘ └──────┬──────┘
┌───────────┐ ┌──────▼──────┐
│ storage/ │ │ Scheduler │ mail polling, holds,
│ (files) │ │ (cron) │ closures, pruning
└───────────┘ └─────────────┘
┌─────────────────────────────────┐
│ Reverb (websockets) optional │
└─────────────────────────────────┘
  • The staff web app is a single-page Vue application talking to the same API everything else uses.
  • The queue workers do everything slow or outward-facing. No worker, no email.
  • The scheduler is one cron entry a minute that triggers everything periodic.
  • Reverb pushes live updates. Optional; without it the app polls.
  • Files (attachments, inbound originals, repository mirrors) are plain files under storage/app.

How people reach it

WhoHow
Agents and administratorsThe web app, signed in with a password plus optional two-factor or a passkey
Clients with an accountTheir billing portal, through a module that calls the integration API
Clients without oneA guest ticket and an emailed link, or by writing to a mailbox the desk reads
Anybody on your websiteThe chat widget, the announcement bar, the status embed
Bug and security reportersThe public report form
Scripts and assistantsAn automation key scoped to one project

Brands are the boundary

Everything in the desk belongs to a brand: departments, clients, tickets, tags, canned responses, knowledge, rules, mailboxes, chat settings, AI configuration, projects. One install can run any number of companies without them seeing each other.

Staff belong to brands and to departments within them, and that membership is enforced in the policies that answer every request, not in the screens. An agent who is not in a brand cannot see its tickets through the list, through search, through the API, or through an AI answer.

Read Brands next; it is the concept the rest of the desk hangs off.

What can be switched off

Most of the desk is optional, and a small install can ignore most of this documentation:

FeatureOff means
Live chatNo widget, no visitor tracking; tickets and email work as normal
Inbound emailClients reach you through the portal or the widget only
AINo drafts, summaries, triage or console; nothing is sent to any provider
Knowledge baseNo reference answers; canned responses still work
Issue trackerNo projects, boards, releases or repositories
ReportsNo public bug or security intake
Status pageNo components, incidents or subscribers
Mass mailNo campaigns
Platform connectionClients are guests, or records you make yourself

Nothing here is a licence tier; they are switches, and an unused feature costs nothing but the rows it does not have.

The data, in one paragraph

Tickets belong to a department, which belongs to a brand. A ticket is opened by a client (an account, or a guest sender) and carries replies, notes, attachments and activity. Tickets can be linked to issues, which live in projects, which belong to a brand and may be restricted to named members. Reports from the public land as issues too. Everything anybody did is in the audit log, kept for as long as you configure. Files never live in the database; the database holds the row that names the file.