# Database Schema **Analysis Date:** 2026-04-26 ## Overview - Database: MySQL (`srv81099_brzez_ticket`) - ORM: Medoo query builder (`$mdb` global) for most queries; RedBeanPHP for cron tasks - No migration files — schema managed manually - No schema files checked into repo — tables inferred from code --- ## Tables ### `orders` Primary order records — one row per customer purchase. | Column | Type (inferred) | Notes | |--------|----------------|-------| | `id` | INT AUTO_INCREMENT PK | | | `name` | VARCHAR | Customer first name | | `surname` | VARCHAR | Customer last name | | `email` | VARCHAR | Customer email | | `zip_code` | VARCHAR | | | `city` | VARCHAR | | | `street` | VARCHAR | | | `order_price` | DECIMAL | Total order value | | `date_added` | DATETIME | Order creation timestamp | | `hash` | VARCHAR UNIQUE | Order identifier (used in URLs, QR codes) | | `payment_hash` | VARCHAR | Przelewy24 session/transaction ID | | `payment_status` | TINYINT | 0 = unpaid, 1 = paid | | `payment_date` | DATETIME | Timestamp of payment confirmation | | `invoice_status` | TINYINT | 0 = not generated, 1 = generated | | `invoice_url` | VARCHAR | URL to fakturowo.pl invoice/receipt | | `vat` | TINYINT | 0 = paragon, 1 = faktura VAT | | `company_name` | VARCHAR | For VAT invoice | | `nip` | VARCHAR | Polish tax ID for VAT invoice | | `gift_address` | TEXT | Gift ticket delivery address | | `used_ticket` | TINYINT | Whether QR has been scanned/used | | `informed_user` | TINYINT | Whether confirmation email was sent | **Key queries:** `autoload/controls/class.Tickets.php`, `autoload/controls/class.Apanel.php` --- ### `order_tickets` Line items — one row per ticket type per order. | Column | Type (inferred) | Notes | |--------|----------------|-------| | `id` | INT AUTO_INCREMENT PK | | | `order_id` | INT FK → orders.id | | | `product_id` | INT | Ticket product ID from `$settings['ticket']` | | `name` | VARCHAR | Ticket name (copied from config at time of order) | | `quantity` | INT | Number of tickets | | `price` | DECIMAL | Unit price at time of purchase | | `date_visit` | DATE | Intended visit date | | `date_added` | DATETIME | Row creation timestamp | **Key queries:** `autoload/controls/class.Apanel.php`, `autoload/factory/class.Tickets.php` --- ### `users` Staff/admin accounts for non-ticket modules. | Column | Type (inferred) | Notes | |--------|----------------|-------| | `id` | INT AUTO_INCREMENT PK | | | `email` | VARCHAR UNIQUE | Login identifier | | `password` | VARCHAR(32) | MD5 hash (insecure — see concerns.md) | | `name` | VARCHAR | First name | | `surname` | VARCHAR | Last name | | `default_project` | INT | Default project preference | | `pushover_api` | VARCHAR | Pushover API key for push notifications | | `pushover_user` | VARCHAR | Pushover user key | **Key queries:** `autoload/factory/class.Users.php` --- ### `ticket_calendar_availability` Controls which dates tickets can be purchased for. | Column | Type (inferred) | Notes | |--------|----------------|-------| | `ticket_group` | VARCHAR PK (composite) | e.g., `park-rozrywki`, `park-wodny` | | `available_date` | DATE PK (composite) | Date that is enabled for purchase | | `updated_at` | DATETIME | Last modification timestamp | **Notes:** - Created dynamically via `\factory\Tickets::ensureCalendarTable()` if missing - Admin manages via `/apanel/settings/` → calendar editor - Ticket groups: `park-rozrywki`, `park-wodny`, `all-open`, `bilety-rodzinne` - **Key file:** `autoload/factory/class.Tickets.php` --- ### `site_settings` Key-value store for runtime configuration (complements `config.php`). | Column | Type (inferred) | Notes | |--------|----------------|-------| | `setting_key` | VARCHAR PK | Setting name | | `setting_value` | TEXT | Setting value | **Notes:** - Created dynamically via `\factory\Apanel::getSetting()` if missing - `REPLACE INTO` for upserts - Used for admin-editable settings that don't require code deploy - **Key file:** `autoload/factory/class.Apanel.php` --- ## Relationships ``` orders (1) ──────< (N) order_tickets orders.id = order_tickets.order_id users — standalone (no FK to orders) ticket_calendar_availability — standalone lookup table site_settings — standalone KV store ``` ## Migration Approach - No migration tool (no Flyway, Phinx, Liquibase) - Schema changes applied manually via MySQL client - New tables created programmatically in application code when needed: - `ticket_calendar_availability` — `\factory\Tickets::ensureCalendarTable()` - `site_settings` — `\factory\Apanel::getSetting()` --- *Schema analysis: 2026-04-26* *Inferred from code — no authoritative schema file in repo* *Verify against production database for exact column types*