docs: map existing codebase

- 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>
This commit is contained in:
2026-04-26 22:15:02 +02:00
parent b6697352e9
commit 5bbec72b59
9 changed files with 989 additions and 0 deletions

144
.paul/codebase/db_schema.md Normal file
View File

@@ -0,0 +1,144 @@
# 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*