Multi-tenant from the first commit

The helpdesk for teams that would rather ship.

Tickets, a customer portal, a help centre, sprint planning, and the insights to show for it — built on the parts that are painful to retrofit later: row-level tenant isolation, stateless services, and domain events from the first commit.

Tenant isolation
Enforced by Postgres RLS
Services
Stateless & scalable
Events
Emitted day one
Built on a boring, durable stack
  • Go · gin
  • Postgres · RLS
  • React 19
  • Redis
  • PWA · Capacitor
Features

Everything a support team needs, nothing it doesn't.

Tickets and a customer portal, the sprint board your engineers already wanted, and the numbers to show for it — on an architecture that scales to many tenants without a rewrite.

Tenant isolation by default

Every table carries tenant_id with row-level security. Tenant A can never read tenant B — and there's a test that proves it.

Server-driven ticket lists

Search, faceted filters, sorting, and pagination all run server-side — correct across pages and fast on large inboxes. Save your own views as filters over the queue, each a card with a live count.

Rich, keyboard-first replies

A Tiptap composer with formatting, drag-and-drop images, and internal notes. A ⌘K command palette moves you anywhere in a keystroke.

A portal your customers log into

Client companies get their own accounts — or consumers sign themselves up. They file tickets, follow the thread, and read the help centre, seeing nothing but their own.

Knowledge base & help centre

Categories and articles with draft/published and internal/public states. Write once: staff see everything, the portal only ever sees what you made public.

Planning, built in

A board, a backlog, a triage lane, and sprints with a real burndown graph. Every issue has its own page and comment thread. Link an issue to the tickets that asked for it, and close the loop when it ships.

Insights, not just counters

Volume against resolution over any window, backlog and response times as trends, reopen and first-contact rates, and where the load sits — by agent, tag, priority, department, channel and status. Filter the whole page, and arrange the panels you care about.

Linear & Jira, in sync

Push a ticket to the tracker your engineers live in and keep one canonical status mapping. API credentials stay in the environment, never in a tenant record.

An AI assistant, if you want one

A chat assistant for your agents — and optionally for the portal — on Scaleway's serverless models. Off by default, pay-per-token, nothing to babysit.

And the parts nobody writes a headline about

Run the workspace

  • Dashboard widgets you arrange
  • Custom statuses, colours & tags
  • Teams and departments
  • Branding: logo, accent, typography
  • Auto-close for stale tickets

Keep everyone honest

  • Followers, in-app inbox & email
  • CSAT surveys, scored by agent & tag
  • A role matrix you can edit
  • Event log & background job runs
  • Whole-workspace export & import

Reach & access

  • Invite-only email/password + Google
  • Short-lived signed cookie sessions
  • English, Danish & Swedish
  • Installable PWA, iOS/Android-ready
  • Rate limiting that fails open
The workspace

A ticket view built for triage, not scrolling.

The detail view puts the conversation on one side and everything you act on — status, priority, assignment, tags — on the other. An activity timeline threads customer messages, replies, and internal notes with the domain events behind them.

  • Activity timeline with real domain events
  • Properties rail: status, priority, assignee, tags
  • Every mutating control gated by RBAC permissions
Carl Customer10:02

The invoice for March shows the wrong amount — it's double.

Agnes changed status to Open

Agnes AgentReply

Thanks Carl — confirmed the duplicate charge, refunding now.

Foundations

The invariants that are present from commit one.

These are the things you can't bolt on later. Slate treats them as non-negotiable, so growth is a scaling problem — not a rewrite.

100% of tenant data scoped by tenant_id
RLS enforced & tested for cross-tenant leaks
0 app & session state in process memory — Postgres & Redis only
1st class events via a transactional outbox
Contact

Get in touch.

Questions about the project, running it yourself, or anything else? Send a note and we'll come back to you.

Run real support in an afternoon.

Spin up the stack with Docker, seed a tenant, and open your first ticket. The guides walk you through the rest.