Skip to content

Architecture

This section provides the technical specifications required for implementing the HNS Ticketing System backend.

Overview

The HNS Ticketing System uses a hybrid modular monolith architecture with selective service extraction:

  • Core Backend: PHP/Symfony monolith handling most business logic
  • Queue Service: standalone waiting-room service (Node 20 + Fastify + Valkey 8), developed in a sibling repo; the backend integrates as the first tenant and gates protected endpoints via GET /access
  • Notification delivery: Email via NATS Event Bus → external mailer microservice (Mailgun); push via synchronous Firebase SDK from the request handler. Queue notifications are owned by waiting-room. See Microservices Strategy → Notification Delivery.
  • Data Layer: PostgreSQL (system of record — including cart and seat-lock state via match_seat_inventory.locked_until) + Redis (only the /access decision cache) + Grafana Loki (audit logs) + Grafana (dashboards). NATS JetStream is the cross-service event transport.
┌─────────────────────────────────────────────────────────────────────────┐
│                     Mobile App / Admin Portal / Quota Portal            │
└───────────────────────────────────┬─────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                         Ticketing Backend (Symfony)                      │
│  ┌───────────────────────────────────────────────────────────────────┐  │
│  │ Bounded Contexts: User/Profile, Match/Stadium, Inventory, Orders, │  │
│  │ Tickets, Quotas, Payments, Loyalty, Blacklist, Support, Petrol    │  │
│  └───────────────────────────────────────────────────────────────────┘  │
└────────────┬────────────────────────────────────────────┬───────────────┘
             │                                            │
      ┌──────▼──────┐                            ┌────────▼────────┐
      │ waiting-room│  ◄── GET /access ───       │ Notification    │
      │ (separate   │       (1–5s cache)         │ Workers (PHP)   │
      │ deployment) │                            │ Email, Push     │
      │ Node + Fast │                            └────────┬────────┘
      │ Valkey + PG │                                     │
      └──────┬──────┘                                     │
             │                                            │
   (own DB/Valkey)              ┌─────────────────────────┘
                                │
                    ┌───────────▼───────────────────────────────┐
                    │ PostgreSQL │ Redis │ Loki │ Grafana       │
                    │ (txn data) │(cache)│(audit)│(dashboards)  │
                    └─────────────────────────────────────────┘

Documentation Index

Core Technical Specifications

Document Description Use Case
Architecture Overview High-level system architecture, component responsibilities, integration patterns Understanding the big picture
Microservices Strategy Service boundaries, extraction rationale, communication patterns Understanding deployment decisions
Data Model Complete database schema with all tables, columns, types, constraints, indexes, and relationships Database design and implementation
Audit Logging Infrastructure Grafana Loki audit log architecture, ingestion, retention, dashboards Audit log implementation
API Specification OpenAPI 3.0 specification for all REST endpoints API implementation and integration

Supporting Documentation

Document Description
Architecture-Features Mapping How epics/features map to architectural components
ADR 0001: waiting-room extraction Decision record for building the Queue Service as the standalone waiting-room repo
Stadium Design Tool Tech Technical specification for stadium design component
Traefik Dashboard One-pager with clickable links to every local-dev Traefik route

Quick Reference

Technology Stack

Component Technology Purpose
Backend PHP 8.2+ / Symfony 7.x Core business logic
Queue Service waiting-room (Node 20 + Fastify 5 + Valkey 8) Waiting queue + capacity-mode origin gating
Database PostgreSQL 15+ System of record
Cache (backend) Redis 7+ /access decision cache
Event bus NATS JetStream Cross-service events (mail.*, user.updated, stripe.*, planned domain events) via the hns_ticketing_events stream
Payment Stripe Card processing
Email Mailgun Transactional email
Push Firebase FCM Mobile notifications
Accounting e-racuni.com Invoicing/fiscalization
Audit Logs Grafana Loki Centralized audit log aggregation
Audit Dashboards Grafana Audit visualization and alerting

Key Design Decisions

  1. Modular Monolith First: Single deployable with clear module boundaries, extractable later
  2. PostgreSQL Optimistic Locking: FOR UPDATE SKIP LOCKED for concurrent seat allocation
  3. Postgres-Backed Seat Locks: match_seat_inventory.locked_until set to sessionExpiresAt from waiting-room's GET /access response — seat lock and queue session share one clock
  4. Standalone Queue Service: waiting-room (Node + Valkey) handles 100k+ concurrent WebSocket users; backend gates protected endpoints via GET /access
  5. Event-Driven Cross-Service Communication: NATS JetStream for everything cross-service (Stripe events, mail.*, user.updated, planned domain events). Redis is not used as a cross-service transport — only for the /access decision cache and the Symfony framework cache/sessions.
  6. Centralized Audit Logging: All audit logs stored in Grafana Loki, keeping PostgreSQL focused on transactional data

API Base URLs

Environment URL
Production https://api.ulaznice.hns.family/api/v1
Staging https://api.staging.ulaznice.hns.family/api/v1

Authentication

All authenticated endpoints require a Bearer token:

Authorization: Bearer <jwt_token>

Tokens are obtained via Drupal SSO integration. See API Specification for details.

For Backend Developers

If you're implementing the backend, start with these documents in order:

  1. Architecture Overview - Understand component responsibilities
  2. Data Model - Set up database schema
  3. API Specification - Implement endpoints
  4. Audit Logging Infrastructure - Configure Loki audit log pipeline

Each endpoint in the API spec references related: - Epic (E1-E15) - Feature files - Business rules

For Frontend Developers

The API Specification provides everything needed for frontend integration:

  • All REST endpoints with request/response schemas
  • Authentication requirements
  • Error response formats
  • WebSocket protocol for queue (see E5 section)

Key Business Rules Summary

Rule Value Reference
Max tickets per purchase 4 E4-F5
Cart reservation timeout 20 minutes E4-F4
Queue purchase window 20 minutes E5-F4
Self-service transfer cutoff 48 hours E9-F5
Loyalty point expiration 5 years E6-F1
OIB validation ISO 7064 MOD 11-10 E1-F5
Home ticket VAT 5% E8-F2
Away ticket VAT 0% E8-F2
Service fee 6% (configurable) E8-F2

Last Updated: May 2026