ArtAcademy ADocs
Návrh

Dátový model

Základná štruktúra databázy a vzťahy medzi entitami.

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ľkaStĺpceTyp
UseremailUNIQUE
Slottrimester_id, day_of_weekINDEX
Enrollmentchild_id, slot_idUNIQUE
Invoiceparent_id, statusINDEX
Substitutechild_id, statusINDEX