[ Case Study · Laravel 13 · Vue 3 ]

WaveTicket

A managed-IT helpdesk with SLAs, line-by-line quotes and on-site visits, built to plug into RIVER ERP: an alpha-stage, French-language client portal and back office from RAIN.

Client
In-house product
Engagement
In-house product build
Disciplines
Product · UX · Laravel · Vue
Year
2026
WaveTicket ticket detail with SLA dates, event timeline and a three-line quote awaiting client approval — light modeWaveTicket ticket detail with SLA dates, event timeline and a three-line quote awaiting client approval — dark mode
01 · Overview

A helpdesk that proves what the support contract is worth.

A company that sells monthly IT support contracts to small businesses lives or dies on one question its clients ask at renewal time: what did we actually get for the money? A ticket inbox does not answer it. The provider also has to answer every request within a response time that depends on how urgent it is, turn some tickets into billable quotes for a new disk, a licence or a cloning job, send a technician on site when a printer or a network refuses to cooperate, and keep each client company's data strictly apart, because agents store the remote-access credentials they use to log into clients' machines. WaveTicket is RAIN's answer to that brief: a French-language client portal and back office for managed IT services.

Client employees open tickets from the portal. Internal agents work them against priority-based SLAs, from 15 minutes for a first response on a critical issue to three days for resolving a low-priority one. When a ticket needs hardware or a licence, the agent escalates it to a quote, a "devis", that the client's decision-maker accepts, rejects or adjusts line by line. When it needs hands on site, a manager assigns a technician and a time window, and the visit moves from requested to scheduled, en route, arrived and completed. Each client company gets a dashboard of "déblocages", the times its people were unblocked this month against last month, with open and at-risk tickets and a six-month trend, plus a monthly PDF report to forward to whoever signs the contract.

WaveTicket is an in-house RAIN product at alpha stage, version 1.0.0-alpha. It is a Laravel 13 API with 38 endpoints behind a Vue 3 single-page app, multi-tenant by company, with seven roles across the provider and its clients. Every account, whether seeded or imported in bulk, must change its password and enrol in TOTP two-factor authentication before it reaches a single screen. It is designed to plug into RIVER ERP, RAIN's own ERP: an accepted quote is handed to RIVER as an order through a dedicated client interface. Today that interface runs on a stub driver while the RIVER API adapter is built, and the product is not yet deployed to production.

System & technology
38

JSON API endpoints behind the Vue 3 app

13

Screens, from 2FA onboarding to admin

7

Roles across the provider and its clients

15 min → 72 h

SLA range, first response to resolution

02 · Architecture & Design

The provider's real workflow, written down as state machines.

Most helpdesks bolt contracts, quotes and field visits onto a generic ticket. WaveTicket starts from the provider's actual way of working and makes every step explicit, enforced on the server and recorded on the ticket, so the client portal can never show something the back office did not do.

01

Three explicit state machines

Tickets move through 9 statuses, from open and assigned to awaiting client, awaiting quote, awaiting approval or on site, then resolved and closed. Quotes have 10 statuses and on-site visits 6. Every transition goes through a service class that writes an event to the ticket's timeline, so the history is complete by construction.

02

Tenancy in the data layer

Every client-owned record carries a company key and a global Eloquent scope filters on it automatically, resolved per request by a dedicated middleware. A client user cannot see another company's tickets even through a hand-crafted API call. Internal roles bypass the scope so agents see their whole queue.

03

Security enforced at the API, not only in the UI

Two middlewares refuse every API call until the user has changed their temporary password and enrolled TOTP two-factor authentication, and the router guard mirrors them in the browser. Sign-in uses Laravel Fortify with confirmed 2FA, a QR code rendered as SVG and recovery codes, over Sanctum's cookie-based SPA sessions with CSRF protection.

04

Seven roles, two sides of the desk

On the provider side: super admin, manager, IT agent and technician. On the client side: company owner, decision-maker and employee. Quote decisions belong to the client's decision-maker, only internal roles see internal notes, and an activity log records changes to users and companies.

05

SLAs that come from the priority

Each of the four priorities carries its own targets: first response in 15 minutes, 1 hour, 4 hours or 24 hours, and resolution in 2, 8, 24 or 72 hours from critical to low. Deadlines are shown on each ticket and counted as "at risk" on the dashboard before they are missed.

06

Quotes the client approves line by line

A quote is a set of priced lines, such as an SSD, a cloning service and a Microsoft 365 licence. The client can accept one line, reject another and lower a quantity on a third; the quote then lands in a partially accepted state with exactly what was agreed, instead of an all-or-nothing yes or no.

07

A swappable boundary to RIVER ERP

The ERP is reached only through a RiverClient interface. Accepted quotes are submitted as RIVER orders through it. Today a stub driver returns placeholder references; the HTTP adapter for the real RIVER API replaces it with a configuration change, without touching the ticket or quote code.

08

Secrets handled as secrets

Remote-access details on user profiles, such as AnyDesk and TeamViewer IDs and passwords and extra credentials, are encrypted at rest with Laravel's encrypted casts. Ticket attachments live on a private disk and are only streamed, inline or as downloads, after an authorisation check.

09

Bulk onboarding with one-time credential sheets

An admin uploads a plain text list of email addresses. WaveTicket creates the accounts with strong temporary passwords, stores the credentials encrypted, and offers them once as a PDF behind a download link that expires after 24 hours. Every new user then goes through the forced password change and 2FA enrolment.

10

Reporting that sells the renewal

The client dashboard counts unblocks this month against last month, open and at-risk tickets, and draws a six-month trend with a hand-rolled SVG sparkline. The monthly report is available as a JSON preview and as a PDF rendered with dompdf, including a week-by-week evolution chart.

11

An API-first single-page app

Laravel serves one Blade shell and a JSON API under /api; Vue 3 with Vue Router, Pinia, VueUse and TypeScript does the rest. The same 38 endpoints the portal uses could serve a mobile client or another integration later.

12

A quiet, token-based interface

Tailwind CSS v4 theme tokens define a blue brand scale and slate surfaces with light and dark values. A light, dark or system toggle is stored per browser and applied by an inline script before first paint, so the theme never flashes. Internal notes stand out with an amber ring so an agent never mistakes one for a client reply.

13

One command to run it

A development script picks free ports for the API and the Vite server and injects the matching Sanctum stateful domains, so cookie authentication works on the first try. Make targets cover install, fresh migrations with a seeded demo company, builds and tests.

03 · Everything inside

Tickets, SLAs, quotes, site visits and the reports that tie them together.

Every screen, workflow and safeguard in the alpha, grouped by who uses it and what it does. Hover any item for what it does.

Client portal07
  • Tableau de bord
  • Nouveau ticket
  • Mes tickets
  • Détail du ticket
  • Validation du devis
  • Rapport mensuel
  • Rapport PDF
Ticket workflow08
  • 9 statuses
  • 4 priorities
  • 6 categories
  • Assignment
  • Public replies
  • Internal notes
  • Event timeline
  • Attachments
SLA engine06
  • Critical: 15 min / 2 h
  • High: 1 h / 8 h
  • Medium: 4 h / 24 h
  • Low: 24 h / 72 h
  • Deadlines on the ticket
  • At-risk counter
Quotes (devis)07
  • Escalate to quote
  • Priced lines
  • Accept a line
  • Reject a line
  • Adjust quantity
  • Partially accepted
  • Order to RIVER
On-site visits06
  • Visit request
  • Technician assignment
  • Time window
  • En route
  • Arrived
  • Completed or cancelled
Accounts & security08
  • Login
  • 2FA challenge
  • Forced password change
  • Forced 2FA setup
  • Recovery codes
  • Tenant isolation
  • Encrypted remote access
  • Private files
Administration06
  • Admin home
  • Bulk user import
  • One-time credential PDF
  • Sociétés
  • 7 roles
  • Activity log
Interface06
  • Système / Clair / Sombre
  • No theme flash
  • Status pills
  • Sparkline
  • File dropzone
  • Onboarding stepper
Engineering08
  • Laravel 13
  • Vue 3 + TypeScript
  • Tailwind CSS v4
  • 38 endpoints
  • 13 models, 20 migrations
  • 8 services, 7 enums
  • dompdf
  • Dev runner

62 screens, workflow states and safeguards in a single Laravel 13 + Vue 3 alpha.

04 · How it competes

Built around the contract, the quote and the visit.

IT providers usually choose between a general helpdesk, an open-source service desk or a full PSA suite. WaveTicket is narrower and more opinionated: contract-centric reporting, line-level quote approval and an ERP hand-off designed in from the start. The comparison below is a positioning view of the alpha, not a benchmark.

vs. Zendesk and Freshdesk
General helpdesks handle tickets and SLAs well but stop at the ticket. WaveTicket adds quotes the client approves line by line, technician dispatch and a monthly report built to justify the support contract.
vs. GLPI
Popular in francophone IT and broad in scope. WaveTicket trades that breadth for a focused client portal, mandatory two-factor sign-in for every user and a modern single-page interface.
vs. PSA suites
ConnectWise PSA, Autotask and HaloPSA cover far more ground, with the cost and set-up time to match. WaveTicket covers the core loop of a small provider, self-hosted and in French.
vs. email and spreadsheets
No more counting unblocks by hand at renewal time. Every request, decision and visit is timestamped, tied to an SLA and summed up in the client's own dashboard.
Feature-by-feature
WaveTicketZendesk / FreshdeskGLPIPSA suites
Client "unblocks" dashboard per company✓○○○
Per-priority response and resolution SLAs✓✓✓✓
Quotes approved line by line by the client✓—○○
On-site technician dispatch✓○○✓
Monthly client PDF report✓○○✓
Two-factor sign-in mandatory for every user✓○○○
Encrypted remote-access credentials per user✓—○○
Bulk accounts with one-time credential PDF✓○○○
French-first interface✓✓✓○
Self-hosted, no per-agent fees✓—✓—
Accepted quotes handed to RIVER ERP (stub driver today)○———
✓ included  ·  ○ partial / add-on / configuration / in progress  ·  — not available
05 · Outcome

An alpha that already runs the whole loop, from ticket to order.

WaveTicket reached 1.0.0-alpha with its first four milestones in place: the client portal and dashboard, the ticket workflow with internal notes and private attachments, the SLA engine, line-by-line quotes, on-site dispatch, bulk onboarding with one-time credential sheets, mandatory two-factor sign-in and the monthly PDF report, across 38 API endpoints and 13 screens. A seeded demo company exercises every path, from an open Outlook ticket to a three-line hardware quote awaiting approval and a technician visit booked for the next afternoon.

It is an in-house product, not a live system, and we describe it that way. It is not deployed, it has no users or clients, and we make no usage or performance claims. The RIVER ERP hand-off runs on a stub until the HTTP adapter is built against RIVER's API. Next on the roadmap: that adapter, agents opening tickets on a client's behalf, contract and billing management screens, email notifications, signature capture at the end of an on-site visit, and a real automated test suite to replace Laravel's two example tests. What the alpha already shows is the kind of product RAIN builds for service businesses: the real workflow made explicit, secured at the API and connected to the back office that bills it.

WaveTicket — FAQ

WaveTicket is a French-language helpdesk and client portal for IT providers that sell monthly support contracts. It covers tickets with per-priority SLAs, quotes that clients approve line by line, on-site technician visits, and a per-company dashboard and monthly PDF report.

No. WaveTicket is an in-house RAIN product at version 1.0.0-alpha. It runs with a seeded demo company but is not deployed to production and has no users or clients yet.

Accepted quotes are submitted to RIVER ERP as orders through a dedicated RiverClient interface. Today that interface uses a stub driver; the HTTP adapter for RIVER's API is the next step and can be switched in by configuration.

Each client company's data is isolated by a global scope on every query. Every user must change their temporary password and enrol TOTP two-factor authentication before reaching the app, remote-access credentials are encrypted at rest, and attachments are served only after an access check.

First response is due within 15 minutes, 1 hour, 4 hours or 24 hours, and resolution within 2, 8, 24 or 72 hours, for critical, high, medium and low priority respectively. The dashboard counts tickets at risk of missing their targets.

Yes. RAIN builds custom SaaS and client portals on Laravel and Vue from Casablanca. Custom platforms typically take 8 to 16 weeks, and fixed-scope projects start at $10,000.

Want a product like this?

Custom projects from $10,000, monthly plans from $7,500. Kickoff within 3–5 business days.