codebase
← Work

Edited product

CBTicket

Our in-house ticket-tracking tool — from idea to first production deployment in about ten days. Proof that you can move fast without giving up any rigour.

Lead time
~10 days
Mode
Sprint
Coverage
~880 tests · 80%
  • Next.js (App Router)
  • TypeScript
  • Prisma / PostgreSQL
  • Better Auth
  • Tailwind / shadcn
  • Kamal / Ansible

Tracking our requests, our way

We needed a request-tracking tool tuned to the way we work: wired to our GitLab issues, hosted in France, cookie-free, and able to serve both our internal exchanges and those with the people we work with. Generic SaaS tools impose their model; developer trackers don’t speak to non-technical users. We wanted our own.

CBTicket is that product: a multi-organisation, white-label ticketing app, designed, specified and shipped to production in about ten days — from idea to a first useful version — then deepened in stride. It’s our proof of speed, on a tool we use ourselves every day.

The bet: showing you can move fast without giving up any rigour. The rest of this page spells it out — first what the tool does, then how it’s built.

What it does, concretely

  • A tree-shaped, reseller-style organisation. Organisations nest: Codebase operates the tool, hosts its own clients, who host theirs. Everyone only sees their own scope.
  • White-label by point of view. The brand on screen (name, logo, colour) adapts to the organisation you’re looking from — the same ticket appears as “CB Ticket” for us and as “Néroli Ticket” for the client concerned, without duplicating the product.
  • Three audiences on the same URL. Super-admin, manager and requester share the app but not the same view: the requester follows their request’s progress without ever seeing the backstage (internal notes, assignments).
  • Rich tickets. Conversation, team-only internal notes, attachments, labels, types, priorities, links between tickets (duplicate, blocker) and mentions.
  • A GitLab bridge. A ticket links to a GitLab issue: client-side tracking and dev-side work stay in sync, each in its own tool.
  • Sovereignty and GDPR by default. Hosting in France, cookie-free, data controlled end to end.

Ticket list with faceted filtering by status, type, priority, project, label, assignee and organisation

A ticket’s detail brings together, on a single page, the conversation, attachments, labels, links to other tickets, the link to the GitLab issue and an audit log — who changed what, and when.

Support ticket detail: conversation, labels, link to a GitLab issue and audit log

Depending on the organisation you sign in from, the interface changes brand, and the requester gets a stripped-down view — their request’s progress, step by step, without seeing the team’s internal exchanges.

White-label “Néroli Ticket” view of a ticket, with a team-only internal note

Simplified requester view: request progress shown step by step, with no internal note

The screens above run on entirely fictional demo data (made-up organisations and people).

How it’s built — and why that’s reassuring

CBTicket was built fast, but not in a rush. The speed comes precisely from the rigour of the method, and that’s what makes it credible:

  • A spec-driven method. Every change is specified, reviewed and tracked before it’s coded — 38 changes archived to date, across 19 capabilities. The code follows the decision, never the other way round.
  • Locked-down authorisation. The code that decides who sees what is locked down and guarded by property tests: you can’t accidentally widen what an organisation or a requester is allowed to see.
  • Quality measured, not promised. ~880 tests under an 80% coverage gate: a regression that would drop below the bar breaks the release.
  • Security by design. Authentication delegated to Better Auth, an OWASP-style audit, encrypted secrets, strict data isolation between organisations.
  • Data-safe deployment. The 26 Prisma migrations are replayable and reversible: a new version ships without putting existing data at risk.

Under the hood

For technical teams, the deliberate choice is simplicity — a clear monolith rather than a premature distributed architecture:

  • Application Next.js (App Router) + TypeScript, UI in Tailwind / shadcn.
  • Data Prisma on PostgreSQL; tree-shaped multi-tenant model, white-label per organisation.
  • Identity Better Auth, with rights derived from a position in the organisation tree.
  • Infrastructure Kamal deployment, Ansible provisioning, Scaleway (France) hosting, transactional email and S3-compatible object storage.

A monolith isn’t a shortcoming: it’s the right level of complexity for this product, and a guarantee of maintainability.

In short

CBTicket is an idea taken to production in about ten days, then deepened without ever sacrificing rigour: spec-driven, locked-down authorisation, ~880 tests under a coverage gate, hardened security, data sovereignty. Proof, on our own tool, that fast and well don’t conflict — and exactly the kind of end-to-end ownership I can bring to your project.

A project like this one?

Describe your need, I come back with a spec and a plan — often in a single conversation.