Preskoči na sadržaj

Admin Portal Implementation Tasks

This document provides a sequenced, comprehensive task list for AI-assisted implementation of the HNS Admin Portal (Symfony Twig + Alpine.js frontend).

Overview

Attribute Value
Technology PHP 8.2+ / Symfony 7.x / Twig
Frontend Alpine.js + Tailwind CSS
Canvas Library Konva.js (for stadium visualization)
Authentication MFA via Drupal SSO
Reference Architecture Overview
API Spec API Specification

Portal Responsibilities

The Admin Portal serves HNS staff for:

  • Match lifecycle management (create, configure, publish, close, cancel)
  • Stadium configuration (sectors, seat maps, pricing)
  • Seat inventory operations (status changes, bulk operations)
  • Quota management (creation, allocation, monitoring)
  • Customer support operations (lookup, transfer, refund)
  • Blacklist management (import, search, violation monitoring)
  • Reporting and analytics (sales, financial, attendance)
  • Access control (barcode export, attendance import)
File Scope
Ticketing Backend Tasks Backend API implementation
Visual Stadium Editor Tasks Konva.js seat map designer (part of Admin Portal)

Task Legend

Symbol Status
⬜ Not started
🟡 In progress
✅ Complete
❌ Blocked

Implementation Sequence

Tasks are organized in dependency order:

  1. Phase 1: Foundation - Project setup, authentication, layout
  2. Phase 2: Match Management - CRUD, stadium config, sales phases
  3. Phase 3: Inventory Operations - Seat status, bulk ops, visualization
  4. Phase 4: Distribution - Quotas, customer support
  5. Phase 5: Security & Reporting - Blacklist, reports, access control

Phase 1: Foundation

1.1 Project Setup

Symfony Bundle Configuration

Status Task Verification
✅ Create AdminBundle with Twig templates directory ls src/AdminBundle/templates/ shows structure
✅ Configure Tailwind CSS with HNS brand colors (#B90202 primary) Build outputs correct CSS
✅ Install and configure Alpine.js Alpine directives work in templates
✅ Create base layout template (base.html.twig) Layout renders with header/sidebar
✅ Configure asset compilation (Webpack Encore or Vite) npm run build succeeds
✅ Set up route prefix /admin/* with firewall Routes resolve correctly

Design System Setup

Status Task Verification
✅ Create color palette Tailwind config (HNS red, status colors) Colors available in classes
✅ Create typography scale (headings, body, labels) Font sizes consistent
✅ Create spacing scale following 4px grid Spacing utilities work
✅ Create shadow/elevation tokens Shadows render correctly
✅ Document design tokens in docs/styleguide.md Guide accessible

1.2 Authentication & Authorization

MFA Authentication

Status Task Verification
✅ Implement Drupal SSO integration for admin login SSO redirect works
✅ Create login page with HNS branding Page renders correctly
✅ Implement MFA challenge step (TOTP) MFA prompt appears
✅ Handle MFA verification and session creation Session created after MFA
✅ Implement logout with SSO session termination Logout clears all sessions
✅ Add session timeout warning (5 min before expiry) Warning modal appears
✅ Implement session refresh on activity Session extends on interaction

Role-Based Access Control

Status Task Verification
✅ Define admin roles enum (Super Admin, Match Manager, Support Agent, Reports Viewer) Enum created
✅ Create role hierarchy configuration Hierarchy documented
✅ Implement @IsGranted annotations on controllers Access denied for wrong role
✅ Create Twig is_granted() checks for UI elements Buttons hidden for unauthorized
✅ Implement role-based menu filtering Sidebar shows only permitted items
✅ Add audit logging for all admin actions Audit events dispatched to Loki

1.3 Layout & Navigation

Main Layout

Status Task Verification
✅ Create header component (logo, user menu, notifications) Header renders
✅ Create collapsible sidebar navigation Sidebar toggles
✅ Create breadcrumb component Breadcrumbs show path
✅ Create main content area with responsive padding Content area responsive
✅ Create footer with version info Footer shows version
✅ Implement dark mode toggle (optional) Theme switches
Status Task Verification
✅ Create sidebar menu items with icons Menu renders with icons
✅ Implement active state highlighting Current page highlighted
✅ Create collapsible menu sections Sections expand/collapse
✅ Add menu item badges (counts, alerts) Badges display
✅ Implement keyboard navigation Tab/arrow keys work

Menu Structure:

Dashboard
Matches
├── All Matches
├── Create Match
└── Calendar View
Stadiums
├── Templates
├── Seat Maps (→ Visual Editor)
└── Snake Configuration
Inventory
├── Seat Status
├── Bulk Operations
└── Visualization
Quotas
├── All Quotas
├── Create Quota
└── Import CSV
Support
├── Ticket Lookup
├── Transfers
└── Refunds
Blacklist
├── Search
├── Import
└── Violations
Reports
├── Sales
├── Financial
└── Attendance
Settings
└── Access Control Export

1.4 Shared Components

Form Components

Status Task Verification
✅ Create text input component with validation states Input renders with error state
✅ Create select/dropdown component Dropdown works
✅ Create date picker component (flatpickr or similar) Date selection works
✅ Create date-time picker with timezone support DateTime selection works
✅ Create checkbox and radio button components Checkboxes work
✅ Create file upload component with drag-drop File upload works
✅ Create form validation service (client-side) Validation runs on submit
✅ Create form error summary component Errors summarized

Data Display Components

Status Task Verification
✅ Create data table component with sorting Columns sortable
✅ Add table filtering (search, column filters) Filters work
✅ Add table pagination Pagination works
✅ Add table row selection (single, multi) Selection works
✅ Add table export (CSV, Excel) Export downloads
✅ Create card component for summary stats Cards render
✅ Create badge/tag component for statuses Badges show colors
✅ Create progress bar component Progress displays

Feedback Components

Status Task Verification
✅ Create toast notification system Toasts appear
✅ Create modal dialog component Modals open/close
✅ Create confirmation dialog (delete, dangerous actions) Confirmation required
✅ Create loading spinner/skeleton Loading states show
✅ Create empty state component Empty states render
✅ Create error boundary component Errors caught gracefully

Phase 2: Match Management (E2)

2.1 Match List & Dashboard

Match Listing

Status Task Verification
✅ Create matches index page (/admin/matches) Page renders
✅ Implement data table with match list Table shows matches
✅ Add status filter (Draft, Published, Active, Closed, Cancelled) Filter works
✅ Add date range filter Date filter works
✅ Add search by team name Search works
✅ Show match status badges with colors Badges colored correctly
✅ Add quick actions (Edit, View, Configure Stadium) Actions work
✅ Implement row click to view details Navigation works

Match Calendar View

Status Task Verification
✅ Create calendar page (/admin/matches/calendar) Calendar renders
✅ Implement month/week/day views Views switch
✅ Show matches on calendar with status colors Matches visible
✅ Click match to view/edit Navigation works
⬜ Add drag-drop to reschedule (with confirmation) Reschedule works

2.2 Match CRUD

Create Match

Status Task Verification
✅ Create match form page (/admin/matches/create) Form renders
✅ Add home team selector (Croatia fixed for HOME matches) Selector works
✅ Add away team input/selector Team entry works
✅ Add competition input Competition saved
✅ Add kick-off date-time picker DateTime works
✅ Add match type selector (HOME/AWAY) Type selection works
✅ Add venue selector (for HOME: Croatian stadiums) Venue selection works
❌ ~~Add queue enabled toggle~~ REMOVED — queue is auto-scaling microservice, not per-match toggle
✅ Implement form validation Validation runs
✅ Submit to POST /admin/matches API called, redirect to edit

Edit Match

Status Task Verification
✅ Create match edit page (/admin/matches/{id}/edit) Page loads with data
✅ Pre-populate form with existing data Fields filled
✅ Add status change dropdown Status managed via detail page lifecycle actions
✅ Validate status transitions Backend validates transitions
✅ Add notification preference (notify/silent on save) Preference saved
✅ Show warning when changing published match Warning displayed
✅ Submit to PUT /admin/matches/{id} API called

Match Details View

Status Task Verification
✅ Create match detail page (/admin/matches/{id}) Page renders
✅ Show match info card (teams, venue, kickoff) Info displayed
✅ Show sales summary (tickets sold, revenue) Summary shows (placeholder)
✅ Show inventory summary by sector Sector breakdown shown
✅ Show sales phase timeline Phases displayed
✅ Add action buttons (Edit, Configure Stadium, Publish, Cancel) Actions work
✅ Add tabs for sections (Details, Stadium, Phases, Inventory) Tabs navigate

2.3 Sales Phase Configuration

Sales Phase List

Status Task Verification
✅ Create sales phases section on match edit page Section renders
✅ Show timeline visualization of phases Timeline visible
✅ List phases with start/end times Phases listed
✅ Show phase type badges (Loyalty, General, Quota Only) Badges colored
✅ Add/Edit/Delete phase buttons Buttons work

Sales Phase Form

Status Task Verification
✅ Create phase form modal Modal opens
✅ Add phase type selector Type selectable
✅ Add start/end date-time pickers Dates selectable
✅ Add ticket limit input Limit saved
✅ Add eligibility rules builder (JSON) Rules configurable
✅ Validate no overlap with other phases Overlap prevented
✅ Submit to POST/PUT /admin/matches/{id}/sales-phases API called

2.4 Stadium Configuration

Stadium Template Selection

Status Task Verification
✅ Create stadium config page (/admin/matches/{id}/stadium) Page renders
✅ Show stadium template selector (for HOME matches) Templates listed
⬜ Show "Create New" option (for AWAY matches) Option available
✅ Preview selected template (sectors, capacity) Preview shows
✅ Confirm template copy to match Copy creates config
⬜ Show import from previous match option Import works

Sector Configuration

Status Task Verification
✅ List match sectors with configuration Sectors listed
✅ Show sector capacity (total, sellable, technical) Capacities shown
✅ Add availability toggle (Active/Closed/Maintenance) Toggle works
✅ Add purpose selector (General, Away Fans, VIP, Press, Free) Selector works
✅ Add price category assignment Category assigned (base price)
⬜ Link to seat map editor for sector Link navigates
✅ Bulk update selected sectors Bulk update works

Price Categories

Status Task Verification
⬜ Create price categories section Section renders
⬜ List existing categories with colors Categories listed
⬜ Add create category form (name, price, currency, color) Creation works
⬜ Edit/delete categories Edit/delete work
⬜ Prevent delete if category assigned to sectors Delete blocked

Stadium Validation

Status Task Verification
✅ Add "Validate Configuration" button Button visible
✅ Call POST /admin/matches/{id}/stadium/validate API called
✅ Display validation errors (unassigned sectors, pricing gaps) Errors shown
✅ Display validation warnings Warnings shown
✅ Show configuration summary (capacity, sectors) Summary displayed
✅ Lock configuration button (after validation passes) Lock works

Visual Stadium Editor Integration

Separate Task File

The Visual Stadium Editor (Konva.js canvas) has its own comprehensive task file: Visual Stadium Editor Tasks

Integration points with Admin Portal:

Status Task Verification
⬜ Add "Design Seat Map" button on sector row Button visible
⬜ Navigate to /admin/stadiums/{stadiumId}/sectors/{sectorId}/seat-map Navigation works
⬜ Pass sector context to editor component Context loaded
⬜ Handle editor save callback (refresh sector data) Data refreshes
⬜ Show seat map status badge (None/Draft/Active) Status shown
⬜ Show seat count from seat map Count displayed

2.5 Match Lifecycle Actions

Publish Match

Status Task Verification
✅ Add "Publish" button (visible for DRAFT matches) Button visible
✅ Show pre-publish checklist (stadium configured, phases set) Checklist shown
✅ Require all checklist items passed Publish blocked if incomplete
✅ Confirmation modal with summary Modal shows
✅ Call PUT /admin/matches/{id} with status=PUBLISHED API called
✅ Show success notification Toast appears

Cancel Match

Status Task Verification
✅ Add "Cancel Match" button (visible for PUBLISHED/ACTIVE) Button visible
✅ Show cancellation impact summary (tickets to refund) Summary shown
✅ Require Super Admin approval for published matches ROLE_SUPER_ADMIN on route
✅ Add cancellation reason input Reason required
✅ Confirmation modal with warning Modal shows warning
✅ Call POST /admin/matches/{id}/cancel API called
⬜ Show progress for refund processing Progress displayed

Close Match

Status Task Verification
✅ Add "Close Match" button (visible for ACTIVE, after kickoff) Button visible
✅ Show attendance import option Option available
✅ If no attendance: require reason Attendance input shown
✅ Call POST /admin/matches/{id}/close API called
⬜ Show loyalty points calculation trigger Progress shown

Phase 3: Inventory Operations (E3)

3.1 Seat Inventory View

Inventory Dashboard

Status Task Verification
✅ Create inventory page (/admin/matches/{id}/inventory) Page renders
✅ Show match header with summary stats Stats displayed
✅ Show sector cards with status breakdown Cards show counts
✅ Add status filter (show only Available, Sold, etc.) Filter works
✅ Add sector selector Selector works
✅ Real-time update toggle (auto-refresh) Auto-refresh works

Seat Grid View

Status Task Verification
✅ Create seat grid component for sector Grid renders
✅ Color-code seats by status (10 colors) Colors correct
✅ Show row labels on left Labels visible
✅ Show seat numbers on hover Tooltip shows
✅ Click seat to select Selection works
✅ Shift+click for range select Range works
✅ Ctrl+click to toggle Toggle works
✅ Show selection count Count displayed

Stadium Visualization

For full Konva.js canvas visualization with zoom/pan, see Visual Stadium Editor Tasks - Section 7: Inventory Mode


3.2 Seat Status Operations

Individual Seat Change

Status Task Verification
✅ Click seat to open detail modal Modal opens
✅ Show seat info (sector, row, seat, current status) Info displayed
✅ Show ticket info if sold (holder, order, purchase date) Ticket info shown
✅ Add status change dropdown Dropdown shows valid transitions
✅ Require reason for status change Reason required
✅ Show warning for locked seats (in cart) Warning displayed
✅ Call PUT /admin/seats/{id}/status API called
✅ Update grid after change Grid refreshes

Bulk Seat Operations

Status Task Verification
✅ Add "Bulk Operations" panel when seats selected Panel appears
✅ Show selected seats summary Summary displayed
✅ Add new status dropdown Status selectable
✅ Add reason input Reason enterable
✅ Add optional current status filter Filter available
✅ Show preview of affected seats Preview shown
✅ Call POST /admin/seats/bulk-status API called
✅ Show progress bar for large operations Progress visible
✅ Show results (updated, skipped) Results displayed

Selection Tools

Status Task Verification
✅ Add "Select by Row Range" tool Tool available
✅ Input from row, to row Inputs work
✅ Add "Select by Status" tool Tool available
✅ Checkbox for each status to include Checkboxes work
✅ Add "Select All" / "Clear Selection" buttons Buttons work
✅ Add "Invert Selection" button Inversion works

3.3 Seat Search & Lookup

Search Interface

Status Task Verification
✅ Create seat search page (/admin/seats/search) Page renders
✅ Add search by seat number input Search works
✅ Add search by ticket holder email Search works
✅ Add search by order ID Search works
✅ Add search by quota ID Search works
✅ Add match filter Filter works
✅ Add status filter Filter works
✅ Add date range filter (purchase date) Filter works

Search Results

Status Task Verification
✅ Display results in data table Table shows results
✅ Show seat info (match, sector, row, seat) Info displayed
✅ Show status badge Badge colored
✅ Show ticket holder name (if sold) Name shown
✅ Add action buttons (View Details, Change Status) Actions work
✅ Click row to open detail modal Modal opens
✅ Export search results Export works

Phase 4: Distribution (E7, E10)

4.1 Quota Management

Quota List

Status Task Verification
✅ Create quotas index page (/admin/quotas) Page renders
✅ Show data table with quotas Table displays
✅ Add match filter Filter works
✅ Add status filter (Active, Claimed, Expired) Filter works
✅ Add organization filter Filter works
✅ Show quota summary (allocated, claimed, remaining) Summary shown
✅ Add quick actions (View, Edit, Resend Invite) Actions work

Create Quota

Status Task Verification
✅ Create quota form page (/admin/quotas/create) Form renders
✅ Add match selector Match selectable
✅ Add organization/partner name input Name saved
✅ Add contact email input Email saved
✅ Add quantity input Quantity saved
✅ Add sector selector Sector selectable
✅ Add price category assignment Category assigned
✅ Add deferred payment toggle Toggle works
✅ Add delegation enabled toggle Toggle works
✅ Add expiration date picker Date saved
✅ Submit to POST /admin/quotas API called
✅ Show seat allocation result Result displayed

Quota Detail

Status Task Verification
✅ Create quota detail page (/admin/quotas/{id}) Page renders
✅ Show quota info card Info displayed
✅ Show allocation breakdown (claimed, unclaimed, expired) Breakdown shown
✅ List tickets in quota with holder info Tickets listed
✅ Show sub-quotas if delegation enabled Sub-quotas listed
✅ Add "Resend Invitation" button Button works
✅ Add "Cancel Quota" button Button works
✅ Add "Extend Expiration" button Button works

CSV Import

Status Task Verification
✅ Create CSV import page (/admin/quotas/import) Page renders
✅ Show CSV template download link Download works
✅ Add file upload with drag-drop Upload works
✅ Validate CSV structure Validation runs
✅ Show preview of quotas to create Preview displayed
✅ Show validation errors per row Errors highlighted
✅ Confirm import button Import executes
✅ Show import results (created, failed) Results displayed

4.2 Customer Support Operations

Ticket Lookup

Status Task Verification
✅ Create support lookup page (/admin/support/lookup) Page renders
✅ Add search by barcode/QR value Search works
✅ Add search by order ID Search works
✅ Add search by email Search works
✅ Add search by OIB Search works
✅ Display ticket details Details shown
✅ Show ticket holder info Holder info shown
✅ Show order history History displayed
✅ Add action buttons (Transfer, Refund, Reissue) Actions available

Ticket Transfer

Status Task Verification
✅ Create transfer form modal Modal opens
✅ Input new holder details (name, OIB/passport) Fields available
✅ Input new delivery email Email input works
✅ Run blacklist check on submit Check runs
✅ Show blacklist warning if matched Warning displayed
✅ Require transfer reason Reason required
✅ Call POST /admin/tickets/{id}/transfer API called
✅ Show transfer confirmation Confirmation shown
✅ Trigger notification to new holder Notification sent

Ticket Refund

Status Task Verification
✅ Create refund form modal Modal opens
✅ Show refund amount calculation Amount calculated
✅ Show service fee deduction (if applicable) Fee shown
✅ Require refund reason Reason required
✅ Confirm refund action Confirmation required
✅ Call POST /admin/tickets/{id}/refund API called
✅ Show refund processing status Status displayed
✅ Handle partial refund option Partial works

Emergency Ticket Printing

Status Task Verification
✅ Add "Print Ticket" button on ticket detail Button visible
✅ Generate printable ticket PDF PDF generated
✅ Include barcode/QR on print Code visible
✅ Log print action to audit Audit event dispatched to Loki

Phase 5: Security & Reporting (E11, E14, E13)

5.1 Blacklist Management

Status Task Verification
✅ Create blacklist search page (/admin/blacklist) Page renders
✅ Add search by OIB Search works
✅ Add search by name (optional field) Search works
✅ Show results with entry details Results displayed
✅ Show entry status (Active, Removed) Status shown
✅ Add action buttons (View, Remove) Actions work

Blacklist Entry Management

Minimal Required Fields

Only OIB is required. First name and last name are optional.

Status Task Verification
✅ Create entry form modal Modal opens
✅ Input OIB (required, with checksum validation) OIB validated
✅ Input first name (optional) Name saved
✅ Input last name (optional) Name saved
✅ Submit to POST /admin/blacklist API called
✅ Show impact on existing tickets Impact displayed

Blacklist CSV Import

Status Task Verification
✅ Create import page (/admin/blacklist/import) Page renders
✅ Download CSV template Template downloads
✅ Upload and validate CSV Validation runs
✅ Show preview with validation errors Preview shown
✅ Import valid entries Import executes
✅ Show import summary Summary displayed

Violation Monitoring

Status Task Verification
✅ Create violations report page (/admin/blacklist/violations) Page renders
✅ Show attempted purchases blocked by blacklist List displayed
✅ Filter by date range Filter works
✅ Filter by match Filter works
✅ Show violator details (OIB, name) Details shown
✅ Show violation timestamp and context Context shown
✅ Export violations report Export works

5.2 Reporting & Analytics

Sales Reports

Status Task Verification
✅ Create sales report page (/admin/reports/sales) Page renders
✅ Add match selector Selector works
✅ Add date range filter Filter works
✅ Show summary cards (total tickets, revenue, avg price) Cards display
✅ Show sales by sector chart Chart renders
✅ Show sales by channel chart (App, Quota, Petrol) Chart renders
✅ Show sales timeline chart Chart renders
✅ Export to Excel Export works

Real-Time Match Dashboard

Status Task Verification
✅ Create match dashboard page (/admin/reports/match/{id}/dashboard) Page renders
✅ Show live ticket sold count Count updates
✅ Show live revenue Revenue updates
✅ Show inventory by sector (visual) Visualization shows
✅ Show queue status (if active) Queue stats shown
✅ Auto-refresh every 30 seconds Refresh works
✅ Show sales velocity (tickets/minute) Velocity calculated

Financial Reconciliation

Status Task Verification
✅ Create financial report page (/admin/reports/financial) Page renders
✅ Add date range filter Filter works
✅ Show revenue summary (gross, fees, net) Summary shown
✅ Show payment method breakdown Breakdown shown
✅ Show refunds summary Refunds shown
✅ Show invoices/credit notes list List displayed
✅ Export to Excel Export works
✅ Generate PDF report PDF generates

5.3 Access Control Export/Import

Barcode Export

Status Task Verification
✅ Create export page (/admin/matches/{id}/export) Page renders
✅ Show export options Options displayed
✅ Add "Export Barcodes" button Button visible
✅ Include buffer codes for late sales Buffer included
✅ Generate Excel file Excel downloads
✅ Show filename with match ID and timestamp Filename correct
✅ Log export action Audit event dispatched to Loki

Attendee Export (Away Matches)

Status Task Verification
✅ Add "Export Attendees" button (AWAY matches only) Button visible
✅ Include holder names and seat assignments Data included
✅ Filter by sector option Filter works
✅ Generate Excel file Excel downloads

Attendance Import

Status Task Verification
✅ Create import section on match close page Section renders
✅ Upload attendance Excel file Upload works
✅ Parse and validate barcodes Parsing works
✅ Show preview (matched, unmatched) Preview shown
✅ Show unmatched barcodes list List displayed
✅ Confirm import Import executes
✅ Update ticket attendance status Status updated
✅ Trigger loyalty points calculation Trigger works

5.4 Stadium Template Management

Template List

Status Task Verification
✅ Create stadiums index page (/admin/stadiums) Page renders
✅ Show data table with templates Table displays
✅ Filter by type (HOME/AWAY) Filter works
✅ Show capacity and sector count Info displayed
✅ Add action buttons (View, Edit Sectors) Actions work

Template Sectors

Status Task Verification
✅ Create sectors page (/admin/stadiums/{id}/sectors) Page renders
✅ List sectors with capacity Sectors listed
✅ Show seat map status per sector Status shown
✅ Add "Design Seat Map" link Link works
✅ Add "Configure Snake" link Link works
✅ Add/Edit/Delete sector actions Actions work

Snake Algorithm Configuration

Status Task Verification
✅ Create snake config page (/admin/sectors/{id}/snake) Page renders
✅ Show best row selector Selector works
✅ Show traversal direction toggle Toggle works
✅ Show within-row strategy selector Selector works
✅ Preview fill order visualization Preview works
✅ Save configuration Save works

5.5 Petrol Management (E12-F4)

Feature: E12-F4: Petrol Deeplink & QR Code Admin Management

Flow: Admin Petrol Setup

Petrol Overview (already partially implemented)

Status Task Verification
✅ Create Petrol admin controller (/admin/petrol) Route registered
✅ Implement /admin/petrol/api/overview proxy Returns pin/reservation/sales summary
✅ Implement /admin/petrol/api/pins proxy with filters List renders

Petrol Quotas (Unified Section)

Status Task Verification
⬜ Add "Petrol Quotas" sub-route under /admin/petrol/quotas with list + create + detail views Routes render
⬜ Build Create Petrol Quota form in Petrol section (match, recipient email, sectors, quantity, algorithm, expiration) Form POSTs to backend /admin/petrol/quotas
⬜ Hide the forced flags (quota_type, deferred_payment, subquota, transfer) from the form — backend enforces Flags forced server-side; form doesn't expose them
⬜ Build Petrol quotas list with inline QR thumbnail Thumbnail renders
⬜ SVG + PNG (≥600×600) download actions per row Files download, decode to hns://petrol-sales/{quota-id}
⬜ Copy-to-clipboard for deeplink URL Copies to clipboard
⬜ Columns: match, recipient, counters (allocated/reserved/sold), quota status, deferred-payment status, created/expires All columns present
⬜ Filters: match, quota status, deferred-payment status, date range Filters work
⬜ Cancel action per row with standard quota cancellation options Cancels via backend
⬜ Generic Quota section: show Petrol quotas read-only with "Managed in Petrol section →" link Mutations disabled from generic list
⬜ Generic Create Quota form: reject / redirect if Petrol type picked Blocked with redirect
⬜ Restrict Petrol section access to ROLE_MATCH_MANAGER 403 for other roles
⬜ Wire audit events on Petrol quota create / cancel through backend Audit entries present in Loki

Phase 6: Settings & System

6.1 User Management (Super Admin)

Status Task Verification
✅ Create admin users page (/admin/settings/users) Page renders
✅ List admin users with roles Users listed
✅ Add user form (email, role) Form works
✅ Edit user role Edit works
✅ Deactivate user Deactivation works
✅ View user audit log Audit shown

6.2 Audit Trail (via Grafana)

Architecture

Audit logs are stored in Grafana Loki. The admin audit page provides access via embedded Grafana dashboards. See Audit Logging Infrastructure.

Status Task Verification
⬜ Create audit log page (/admin/settings/audit) with Grafana embed Page renders Grafana dashboard
⬜ Configure Grafana viewer access for embedded dashboards Embed loads without separate login
⬜ Filter by user (Grafana variable) Filter works
⬜ Filter by action type (Grafana variable) Filter works
⬜ Filter by date range (Grafana variable) Filter works
⬜ Filter by entity (match, ticket, quota) Filter works
⬜ Show action details in drill-down panel Details displayed
⬜ Export audit log via Grafana CSV export Export works

6.3 System Settings

Status Task Verification
✅ Create settings page (/admin/settings) Page renders
✅ Configure cart timeout (minutes) Setting saved
✅ Configure queue window (minutes) Setting saved
✅ Configure QR visibility hours before match Setting saved
✅ Configure ticket limit per transaction Setting saved
✅ Configure support window cutoff (hours before match) Setting saved

Testing Checklist

Functional Testing

Status Task Verification
⬜ Test all CRUD operations for matches All operations work
⬜ Test stadium configuration workflow Workflow completes
⬜ Test quota creation and claiming simulation Quota workflow works
⬜ Test bulk seat operations Bulk ops complete
⬜ Test search and filtering All filters work
⬜ Test export/import functionality Files generate correctly

Access Control Testing

Status Task Verification
⬜ Test role-based menu visibility Menu items correct per role
⬜ Test route protection by role Unauthorized returns 403
⬜ Test action buttons hidden for unauthorized Buttons hidden
⬜ Test Super Admin bypass Super Admin sees all

Browser Testing

Status Task Verification
⬜ Test in Chrome (latest) All features work

Last Updated: February 2026