ticket pre-sale management system

Manage every seat.
Every match. Every sale.

MioCa is an internal operations tool for football clubs — built to handle stadiums, events, pre-sale windows, customer records, and ticket issuance without the overhead of a bloated SaaS platform.

Stadium Layout Editor Pre-sale Windows QR Ticket Generation Customer Management No Router Lib SQLite Backend Zero CSS Framework
mio@ca — zsh
# start the platform
$ npm run dev
 
backend http://localhost:3001
frontend http://localhost:5173
 
database server/data.db (auto-created)
proxy /api/* → :3001
 
$
6
Core Modules
12+
API Endpoints
1
File Backend
0
External Auth

Everything in one place.

Six tightly integrated modules cover the full lifecycle from venue creation to ticket validation — no third-party integrations required.

[STAD]
Stadium Management
Define venues with capacity, section layout stored as structured JSON. Edit layout fields live and persist them to the database instantly.
[EVNT]
Event Creation
Create matches with home/away teams, competition name, date, stadium, and status. Status transitions: draft → active → sold out / completed / cancelled.
[PRES]
Pre-sale Configuration
Per-event pre-sale windows with start/end times, per-customer purchase limits, total seat caps, and public or restricted access types.
[TICK]
Ticket Booking
Manual ticket issuance linked to customer records. Each ticket carries section, row, seat, and price. Confirmation generates a unique QR code.
[CUST]
Customer Records
Search customers by name or ID. Create new records with full contact details. View all tickets associated with a customer in one panel.
[FAV]
Favorites Sidebar
Pin any event, stadium, or customer to the sidebar for instant access. Favorites persist in the database and sync across sessions automatically.

Granular control over who buys, when, and how many.

Each event gets its own pre-sale window. Set a precise open and close timestamp, cap the number of tickets any single customer can purchase, impose an overall seat limit, and restrict access to public or internal-only channels.

  • Per-event presale window — start and end timestamps stored in UTC, displayed in local time
  • Per-customer purchase cap — prevents bulk buying, configurable per event
  • Total ticket limit — enforce scarcity independent of stadium capacity
  • Access type: Public or Restricted — control visibility and eligibility
  • Free-text notes field — attach internal instructions or conditions
Pre-sale Settings
Event
Real Betis vs Sevilla FC
Sale Start
2026-03-10 09:00
Sale End
2026-03-17 23:59
Max per Customer
4 tickets
Total Limit
1,200 seats
Access Type
Public Restricted
Notes
Members get priority. General sale opens 48h after member window.

From booking to QR in a single workflow.

Tickets are created manually, linked to a customer and an event, and immediately assigned a unique identifier. The QR code is generated client-side and displayed inline — ready to print or share.

  • Manual booking flow — select event, customer, section, row, seat, and price
  • Unique ticket ID generated on creation — traceable in the database
  • QR code rendered directly in the ticket view — no external service
  • Status tracking — pending, confirmed, cancelled
  • Full ticket list filterable by event — exportable view per match
Ticket States
3
Fields per Ticket
8+
QR Generation
Client
Linked Records
2
Real Betis vs Sevilla FC
La Liga  ·  Estadio Benito Villamarin  ·  22 Mar 2026
Customer
Maria G.
Section
Norte Alto
Row
C
Seat
14
Price
€ 48.00
Booked
05 Mar 2026

Minimal stack. Maximum control.

No routers, no UI libraries, no ORM. Every layer is explicit and readable — chosen for simplicity and long-term maintainability.

Frontend
React + Vite
TypeScript, no routing library. Navigation is a single NavState object in App.tsx — switch on view ID.
Backend
Express
Single server.js file. Schema init + all route handlers in one place. No ORM — raw SQL via better-sqlite3.
Database
SQLite
Auto-created as data.db on first run. JSON columns (e.g. stadium layout) serialized manually. Zero config.
Styling
Pure CSS
No Tailwind, no component library. All tokens in :root, all styles in styles.css. JetBrains Mono throughout.
API Client
Axios
Thin wrapper in api.ts organized by resource. Vite proxies /api/* to :3001 — no CORS config in dev.
Monorepo
Concurrently
Root package.json runs both packages with a single npm run dev. No workspace tooling or build pipeline needed.
Main
Dashboard
Venues
All Stadiums
New Stadium
Events
All Events
New Event
Pre-sale
Tickets
All Bookings
Book Ticket
Customers
Search
New Customer
Events
24
Tickets
1,847
Confirmed
1,612
Customers
389
Match
Date
Stadium
Status
Betis vs Sevilla
22 Mar 2026
B. Villamarin
active
Betis vs Athletic
05 Apr 2026
B. Villamarin
draft
Betis vs Villarreal
19 Apr 2026
B. Villamarin
draft
Betis vs Real Madrid
03 May 2026
B. Villamarin
draft