- stack.md - Technologies and dependencies - architecture.md - System design and patterns - structure.md - Directory layout - conventions.md - Code style and patterns - testing.md - Test structure (none) - integrations.md - External services - concerns.md - Technical debt and issues - db_schema.md - Database schema and relationships Co-Authored-By: Claude <noreply@anthropic.com>
145 lines
4.7 KiB
Markdown
145 lines
4.7 KiB
Markdown
# 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*
|