Prehľad
Táto stránka popisuje základný dátový model systému. Detaily budú spresnené počas vývoja.
Poznámka
Toto je vysokoúrovňový návrh. Implementačné detaily (typy stĺpcov, indexy) budú upresnené.
Hlavné entity
Organizácia
Organization
├── id
├── name
├── settings (JSON)
└── created_at
Pobočka
Branch
├── id
├── organization_id → Organization
├── name
├── address
├── phone
├── email
├── is_active
└── created_at
Miestnosť
Room
├── id
├── branch_id → Branch
├── name
├── capacity
├── description
└── created_at
Používatelia
User (základný účet)
User
├── id
├── email (unique)
├── password_hash
├── role (admin | instructor | parent)
├── name
├── phone
├── is_active
├── last_login_at
└── created_at
Instructor (rozšírenie pre lektora)
Instructor
├── id
├── user_id → User
├── bio
├── photo_url
└── created_at
Parent (rozšírenie pre rodiča)
Parent
├── id
├── user_id → User
├── address
├── billing_name
├── billing_ico
└── created_at
Child (dieťa)
Child
├── id
├── parent_id → Parent
├── name
├── birth_date (povinné, pre výpočet veku)
├── notes
└── created_at
Vek dieťaťa
Vek sa počíta z birth_date. Používa sa pre:
- UX navigáciu pri výbere termínu
- Odporúčania pre admina pri rozdeľovaní do skupín
Kurzy a triedy
Trimester
Trimester
├── id
├── organization_id → Organization
├── name (napr. "1. trimester 2025/26")
├── start_date
├── end_date
├── lesson_count (12 štandardne, 19 pre prípravu)
├── is_active
└── created_at
Slot (termín lekcie)
Slot
├── id
├── trimester_id → Trimester
├── branch_id → Branch
├── day_of_week (1-5, Po-Pi)
├── start_time
├── end_time
├── duration_minutes (60/90/120)
├── recommended_age_from (orientačné, napr. 7)
├── recommended_age_to (orientačné, napr. 9)
├── capacity (max detí na termín)
├── price (288 € štandardne)
└── created_at
Termíny vs Skupiny
Deti sa prihlasujú na termín (Slot). Admin ich potom rozdeľuje do skupín podľa veku. Vekové odporúčanie slúži pre UX navigáciu, nie je striktné.
Enrollment (zápis dieťaťa)
Enrollment
├── id
├── child_id → Child
├── slot_id → Slot
├── status (active | cancelled | moved)
├── enrolled_at
└── created_at
Sezónne campy (Art Camp)
Camp nie je zápis do trimestrového Slot. Samostatná ponuka (týždňové bloky, pobočka, kapacita) a registrácia dieťaťa s jednorazovou cenou.
CampSeason
├── id
├── organization_id → Organization
├── name (napr. "Letný Art Camp 2026")
├── age_from / age_to (napr. 7 / 14)
├── description (optional, pre verejný text)
├── price_amount (napr. 252)
├── vat_rate
├── is_active
└── created_at
CampWeek
├── id
├── camp_season_id → CampSeason
├── branch_id → Branch
├── starts_on / ends_on (kalendárny týždeň tábora)
├── capacity_total (max detí na týždeň)
├── instructor_id → Instructor (optional)
└── created_at
CampRegistration
├── id
├── camp_week_id → CampWeek
├── child_id → Child
├── parent_id → Parent (redundantné via Child, ale praktické pre fakturáciu a hostí)
├── source (public_web | parent_portal)
├── status (pending | confirmed | cancelled | waitlist)
├── invoice_id → Invoice (optional, keď vznikne dlh)
├── notes (alergie, spôsob odchodu z tábora, …)
└── created_at
Väzba na fakturáciu
Invoice / InvoiceItem odkazuje na camp rovnako ako na kurz — položka s popisom a väzbou na CampRegistration (implementačný detail: reference_type + reference_id alebo priamy foreign key na registráciu).
Dochádzka a náhrady
Attendance (dochádzka)
Attendance
├── id
├── enrollment_id → Enrollment
├── date
├── status (present | absent | excused)
├── note
└── created_at
LessonCredit (kredit — návrh pre nový model)
Po oprávnenom odhlásení alebo zrušení strany školy vzniká zápis kreditu. Čerpanie viaže rezerváciu na konkrétny session / výskyt hodiny s voľnou kapacitou, nie nutne na fixný „náhradný“ slot.
LessonCredit
├── id
├── child_id → Child
├── source (excused_absence | school_cancelled | manual)
├── units (typicky 1 hodina)
├── balance_remaining
├── related_attendance_id (nullable)
├── status (active | consumed | expired)
├── expires_at (nullable)
└── created_at
Substitute (náhradná hodina / spotreba kreditu)
V jednoduchom tvare je „náhrada“ buď pending kredit, alebo väzba minutia kreditu na konkrétny termín.
Substitute
├── id
├── child_id → Child
├── lesson_credit_id → LessonCredit (nullable, ak sa model zlúči)
├── original_class_id → Class
├── original_date
├── reason
├── status (pending | used | expired)
├── used_class_id → Class (nullable)
├── used_date (nullable)
├── expires_at
└── created_at
(Presné zlúčenie Substitute a LessonCredit sa doladí pri implementácii — dôležité je rozlíšiť stav kreditu a rezerváciu na voľný termín.)
Fakturácia
BillingCompany (fakturačná firma)
BillingCompany
├── id
├── organization_id → Organization
├── name
├── ico
├── dic
├── ic_dph (nullable)
├── is_vat_payer
├── address
├── iban
├── swift
├── logo_url
├── footer_text
└── created_at
Invoice (faktúra)
Invoice
├── id
├── billing_company_id → BillingCompany
├── parent_id → Parent
├── type (proforma | invoice)
├── number
├── variable_symbol
├── issue_date
├── due_date
├── subtotal
├── vat_amount
├── total
├── status (pending | paid | overdue)
├── paid_at (nullable)
├── pdf_url
└── created_at
InvoiceItem (položka faktúry)
InvoiceItem
├── id
├── invoice_id → Invoice
├── description
├── quantity
├── unit_price
├── vat_rate
├── total
└── created_at
PaymentReminder (pripomienka/výzva)
PaymentReminder
├── id
├── invoice_id → Invoice
├── type (reminder | warning1 | warning2)
├── sent_at
├── new_due_date
└── created_at
Vzťahy
Organization
│
├── Branches
│ └── Rooms
│
├── Trimesters
│
├── Slots (termíny)
│ ├── Branch
│ └── Enrollments
│ └── Child
│ └── Parent
│
├── CampSeasons
│ └── CampWeeks (Branch)
│ └── CampRegistrations → Child / Parent
│
└── BillingCompanies
└── Invoices
└── Parent
Indexy (návrh)
| Tabuľka | Stĺpce | Typ |
|---|---|---|
| User | UNIQUE | |
| Slot | trimester_id, day_of_week | INDEX |
| Enrollment | child_id, slot_id | UNIQUE |
| Invoice | parent_id, status | INDEX |
| Substitute | child_id, status | INDEX |
