PanelRP — Laravel FiveM project

Open-source FiveM/QBCore server admin panel with roleplay tooling.

PanelRP — Laravel FiveM project
Role
Founder, full stack developer
Stack
Laravel 12 · Livewire 4 · Lua
Architecture
One database per community
Status
Live

Context

A roleplay community — FiveM with QBCore or ESX, Minecraft, DayZ, Arma 3 — runs its players, jobs, website and subscriptions with a set of tools that don’t talk to each other. The game server keeps its own data, which a panel cannot read directly without opening its database to the world.

Business challenge

Give FiveM server owners an open-source admin panel for QBCore ecosystems.

Solution

PanelRP gives each community an isolated space in its own MySQL database. The game is connected through a bridge: a Lua resource on FiveM, a Java plugin on Minecraft, both sending heartbeats and events to a dedicated API. Each game is a module discovered at boot, and game data can also be synchronised over a direct connection or an SSH tunnel.

Outcome

Live at panelrp.com, in four languages, with ten game modules, a twelve-step onboarding, a public website with a visual editor, and Stripe subscriptions including VIP sales through Stripe Connect. The test suite runs in three parallel shards and security is checked by CodeQL and OWASP ZAP.

My role

Full-stack developer

Architecture

Users

  • FiveM server (Lua resource)
  • Minecraft server (plugin)
  • Community public website
  • Community admin
  • Discord

Application

  • Laravel 12 · Livewire 4
  • Tenant resolution
  • game-bridge v1 API
  • Dispatcher and 9 handlers
  • 10 game modules
  • Sync orchestrator

External services

  • MySQL: core + one database per tenant
  • Game databases (PDO or SSH)
  • Redis
  • Stripe · Stripe Connect
  • Sentry · Nightwatch · Prometheus
  • PostHog

The flow, step by step

  1. Sign-up

    The owner creates an account, then a community in the creation wizard.

  2. Provisioning

    The creation service opens a dedicated database, runs the tenant migrations and installs the chosen game module.

  3. Onboarding

    A twelve-step Livewire wizard connects the game database, maps its tables, sets up Discord and the theme.

  4. Bridge

    An API key is generated; the Lua resource uses it to call the panel. Only its HMAC fingerprint is stored.

  5. Events

    The bridge sends heartbeats and events; a middleware finds the community from the key’s fingerprint.

  6. Handling

    The dispatcher routes each event to the right handler — economy, police… — which updates the community database.

Data model

The main entities, their key fields and their relations.

Tenant (core)

  • name · slug · domain
  • database
  • game_type · framework
  • modules_config
  • n—1 User (owner)
  • 1—n Subscription
  • 1—n GameBridgeEvent

Plan · Subscription (core)

  • plan
  • status
  • Stripe payments
  • Subscription 1—n Payment

GameBridgeEvent (core)

  • target · event_type
  • occurred_at
  • license · payload
  • n—1 Tenant

SyncConnection (core)

  • source (mysql_direct, ssh_mysql, sql_dump)
  • sync direction
  • 1—n DatabaseSyncMapping

Player (tenant)

  • name · status
  • money · bank_balance
  • last_seen_at · metadata
  • n—1 Job
  • n—1 House

Job (tenant)

  • name · salary
  • max_employees
  • category
  • 1—n JobEmployee

JobEmployee (tenant)

  • job_role_id
  • salary
  • status
  • n—1 Job
  • n—1 Player

WebsitePage (tenant)

  • title · slug
  • content · is_published
  • SEO meta

Full technical sheet

Languages
PHP 8.4, Lua 5.4 (FiveM bridge), TypeScript and Vue (visual editor), Java (Minecraft bridge)
Framework
Laravel 12, Livewire 4, Jetstream, Fortify
Front end
Tailwind 4, Alpine 3, Vite 8, Chart.js, GSAP; visual editor in Vue 3
Database
MySQL 8: a core database (82 migrations) and one database per community (170 migrations)
Cache and queues
Redis for cache, sessions and queues
Authentication
Fortify, Jetstream, Sanctum; Socialite (Discord, Google, Facebook, Microsoft); separate guard for community members; magic link
Payments
Stripe Checkout and webhooks; Stripe Connect for VIP sales
Game integration
HTTP JSON with a Bearer key; QBCore, ESX and Standalone adapters; sync over PDO or an SSH tunnel
Discord
OAuth, per-community webhooks, CI notifications
Hosting
Dedicated server, self-hosted GitHub runner
CI/CD
8 workflows: CI, deployment, assets, release draft, restore drill, CodeQL, OWASP ZAP, Discord
Tests
PHPUnit 11 (298 files, about 1,600 tests) in three parallel shards, Playwright (36 specs), Vitest (22 files)
Quality
PHPStan and Larastan level 5 with a baseline, Rector (PHP 8.4, code quality, dead code), Pint
Observability
Sentry, Laravel Nightwatch, Prometheus metrics, PostHog, structured JSON logs
Languages (UI)
French, English, Spanish, Dutch
Security
Configurable CSP, HTMLPurifier, captcha, bridge keys hashed with HMAC-SHA256, 180 requests per minute per key, tenant isolation scan

Key features

  • Multi-tenant

    Slug, subdomain or custom domain, dedicated database per community.

  • Onboarding

    Twelve steps, from the game database to the website theme.

  • Framework detection

    The panel recognises the game database layout by fingerprint and suggests the mapping.

  • Public website

    Visual editor and starter templates by community type.

  • Server management

    Players, jobs, employees and bans.

  • Monetisation

    Stripe subscriptions and VIP sales through Stripe Connect.

Problems solved

  1. Tenant tests not isolated

    ProblemA connection purge run after the test transaction had opened destroyed it: tests leaked into each other.

    FixOrder fixed: sync failures dropped from 39 to 8, and five real defects surfaced, including dates silently set to null.

  2. Connection stuck on the previous tenant

    ProblemA community without a database could inherit the previous one’s connection.

    FixExplicit 503 response, and the database is deselected between requests.

  3. Test suite over 90 minutes

    ProblemCI had become unusable.

    FixSplit into platform and tenant shards running in parallel.

  4. Security scan that never ran

    ProblemThe CodeQL workflow had been invalid since it was created.

    FixWorkflow fixed, SQL false positives in the audit corrected.

  5. Bridge keys in clear text

    ProblemGame server API keys were stored as is.

    FixHMAC-SHA256 fingerprint, with a fallback read to migrate old keys.

Technical choices

Choice Why
One database per community Isolation comes from the database itself, not from a tenant_id filter a query could forget.
A bridge rather than direct access The game server pushes its events; its database never has to be opened to the panel.
Tests on MySQL only Tests must see MySQL’s real locking behaviour.
PHP 8.4 minimum Required by Symfony 8.1, used by the dependencies.

Timeline

  1. October 2025 First CHANGELOG entries
  2. February 2026 Version 1.2: editor, light and dark themes
  3. May 2026 Guided onboarding
  4. September 2026 Version 1.3: automatic set-up by fingerprint
  5. September 2026 Minecraft bridge and live handlers
  6. October 2026 Version 1.3.123

In numbers

10
game modules
252
migrations
298
PHP test files
4
languages

Taken from the project’s source code and Git history on 8 October 2026. No usage or revenue figures are published.

Related projects

SaaS
Jan 2022 — Dec 2022
MissionsCMS — Web App project
Mission management system with tracking dashboards and workflow tools.
Laravel, Livewire, Alpine.js, TailwindCSS
View project
SaaS
Sep 2025 — present
Lodate — Web App project
Appointment scheduling system with reminders and clean interface navigation.
Laravel, Livewire, Alpine.js, TailwindCSS
View project
SaaS
Oct 2024 — present
Vetzy — Laravel SaaS project
SaaS veterinary booking platform for clinics and pet owners with scheduling, notifications and client portal.
PHP, Laravel, Livewire, TailwindCSS, SaaS
View project
Packages Laravel
Jan 2022 — present
LarappeUI — Laravel project
Laravel UI kit and reusable component library for faster product delivery.
Laravel, Livewire, Alpine.js, TailwindCSS
View project

Available for PHP / Laravel / WordPress / Silverstripe missions in Belgium and remote EU.