Skip to content

2. Technická architektura

Stack

Ověřený fakt — ze package.json a zdrojových souborů:

Vrstva Technologie Verze
Frontend framework React 18.2
Build tool Vite 6.1
Styling Tailwind CSS 3.4
UI komponenty shadcn/ui (Radix UI primitives) viz package.json
Ikony lucide-react 0.475
Routing react-router-dom v6.26
Data fetching @tanstack/react-query v5.84
Animace framer-motion 11
Datum/čas date-fns 3.6
Drag & drop @hello-pangea/dnd 17
Rich text editor react-quill 2.0
PDF generování jsPDF 4.0
Backend runtime Deno (serverless, Base44 platform)
Databáze Base44 entities (NoSQL, proprietární)
E-mail Resend API
Platby Stripe (@stripe/react-stripe-js) připraveno
Autentizace admin Base44 Auth (session-based) + OTP přihlášení personálu
Autentizace klient OTP kód → localStorage session vlastní implementace
SMS SmsManager JSON API v2
Telefonie OptimCall (webhooky příchozích hovorů)
Účetnictví Pohoda mServer (dataPack XML přes REST)

Adresářová struktura

var/source/
├── base44/
│   ├── config.jsonc              # Název aplikace, build příkazy
│   ├── connectors/
│   │   └── outlook.jsonc         # MS Outlook OAuth scopes
│   ├── entities/                 # Schémata databázových entit (JSONC)
│   │   ├── CalendarEvent.jsonc
│   │   ├── Booking.jsonc
│   │   ├── Client.jsonc
│   │   └── ... (28 entit celkem)
│   ├── functions/                # Backend serverless funkce (Deno/TypeScript) — 18 funkcí
│   │   ├── clientAuth/entry.ts            # OTP klient + terapeut + personál
│   │   ├── clientBooking/entry.ts         # rezervace, storno, platby (1 484 ř.)
│   │   ├── sendNotification/entry.ts      # e-maily a SMS (1 491 ř.)
│   │   ├── checkAvailabilityConflicts/entry.ts
│   │   ├── reminderDispatcher/entry.ts
│   │   ├── syncToOutlook/entry.ts
│   │   ├── activityLogger/entry.ts
│   │   ├── assignClientNumber/entry.ts    # přidělení client_number (automat + backfill)
│   │   ├── generatePurchaseDocument/entry.ts  # doklad k nákupu balíčku/voucheru/kreditu
│   │   ├── getPublicInvoice/entry.ts      # veřejný výdej dokladu podle tokenu
│   │   ├── batchGenerateInvoices/entry.ts
│   │   ├── processExpiredPayments/entry.ts
│   │   ├── onPaymentConfirmed/entry.ts
│   │   ├── onServiceRealized/entry.ts     # automat: vznik výnosu po completed
│   │   ├── onLateCancellation/entry.ts    # automat: storno poplatek po cancelled_late
│   │   ├── processRefund/entry.ts         # vratky a dobropisy (308 ř.)
│   │   ├── syncPohodaExport/entry.ts      # dávkový export dokladů do Pohody
│   │   └── pohodaTestRun/entry.ts         # dry-run test účetních pravidel
│   │
│   └── shared/                   # Sdílené moduly backendu (nové)
│       ├── documentGeneration.ts # generování dokladů (555 ř.)
│       ├── pohodaXml.ts          # dataPack XML, dedup přes event_id (215 ř.)
│       ├── serviceRevenue.ts     # vznik výnosu při realizaci služby (186 ř.)
│       ├── cancellationAccounting.ts # storno poplatky a vratky (169 ř.)
│       └── accountingSource.ts   # odvození accounting_source
│
└── src/
    ├── App.jsx                   # Kořenový komponent: Router + Providers
    ├── Layout.jsx                # Top navbar (role-based navigace)
    ├── pages.config.js           # Registrace stránek + main page
    ├── index.css                 # CSS design tokeny (custom properties)
    │
    ├── pages/                    # 33 stránek aplikace
    ├── components/               # Sdílené komponenty
    │   ├── calendar/             # 21 komponent (vč. RefundDialog, PaymentMethodDialog, BookingLinkBox)
    │   ├── availability/         # 2 komponenty
    │   ├── clients/              # 8 komponent (vč. Consents, Packages tabů)
    │   ├── client/               # 6 komponent klientského portálu (onboarding, podpis, OTP, ServicePicker)
    │   ├── activitylog/          # 3 komponenty
    │   ├── notifications/        # 1 komponenta
    │   ├── demo/                 # 2 komponenty
    │   ├── optimcall/            # 2 komponenty (příchozí hovor)
    │   ├── services/             # 1 komponenta
    │   ├── settings/             # 3 komponenty (vč. SmsSettings, TelephonySettings)
    │   ├── staff/                # 1 komponenta (odznak přihlášeného zaměstnance)
    │   ├── therapists/           # 2 komponenty (admin správa)
    │   ├── therapist/            # 5 komponent portálu terapeuta (OTP login, kalendář, rezervace, export)
    │   └── ui/                   # shadcn/ui primitivy (~49 komponent)
    │
    ├── api/
    │   └── base44Client.js       # Inicializovaný Base44 SDK klient
    │
    └── lib/
        ├── AuthContext.jsx       # Admin auth stav
        ├── DemoAuthContext.jsx   # Demo user přepínač
        ├── query-client.js       # React Query konfigurace
        ├── permissions.js        # Role-based viditelnost navigace
        ├── NavigationTracker.jsx # Sledování navigace
        ├── StatusContext.jsx     # Globální stav aplikace
        └── utils.js              # Utility funkce

Datový tok

Ověřený fakt:

Frontend (React)
  │
  ├── base44.entities.*           ← CRUD nad NoSQL databází (SDK)
  │     .list(), .filter(), .get(), .create(), .update(), .delete()
  │
  └── base44.functions.invoke()   ← Volání Deno serverless funkcí
        clientAuth, clientBooking, sendNotification, ...

Všechna komunikace probíhá přes @base44/sdk — neexistuje žádný vlastní REST API server.

Autentizace

Admin přihlášení:

  • Řeší Base44 platforma transparentně
  • AuthContext.jsx — stav: isLoadingAuth, authError, navigateToLogin
  • Chybové stavy: user_not_registered, auth_required

Přihlášení personálu (OTP) — nové:

  • Celé admin rozhraní je nově za StaffGate (layout route v App.jsx). Nepřihlášený zaměstnanec vidí StaffLogin, ne aplikaci.
  • Zaměstnanec zadá e-mail → clientAuth akce request_otp_staff, ověření přes verify_otp_staff, session v localStorage (neo_demo_user)
  • Při startu se session revaliduje proti DB (get_staff); neaktivní účet se odhlásí, při výpadku sítě zůstává cached přihlášení
  • Změna logiky: entita DemoUser přestala být jen přepínačem rolí pro demo a stala se účtem zaměstnance. Role určuje viditelnost navigace i oprávnění (admin, admin-klientske, klientske, nově finance). Veřejné routy (/client, /invoice, /redeem, /storno, /TherapistPortal) jsou mimo gate.

Klient přihlášení (OTP):

  • Klient zadá e-mail nebo telefon → backend clientAuth vygeneruje 6-místný kód (platný 10 min)
  • Kód se odešle e-mailem přes Resend API
  • Po ověření vrátí backend data klienta → session se uloží do localStorage
  • ClientAuthContext spravuje stav v klientském portálu

Terapeut přihlášení (OTP) — portál terapeuta:

  • Stejný OTP mechanismus (clientAuth akce request_otp), ověření přes akci verify_otp_therapist
  • Backend spáruje kód s terapeutem podle portal_user_email (jen portal_access_enabled = true)
  • Session v localStorage (neo_therapist); viz Portál terapeuta

Plánovaná automatizace

Ověřený faktreminderDispatcher je serverless funkce spouštěná každých 5 minut (Base44 scheduler):

  • Posílá připomínky 10 minut před termínem
  • Posílá připomínky 24 hodin před termínem
  • Deduplication přes NotificationLog entitu

Entitní automaty (nové) — dvě funkce nejsou volány z UI, ale spouští je změna stavu entity CalendarEvent:

Automat Spouštěč Co dělá
onServiceRealized status → completed Zaúčtuje vznik výnosu (shared/serviceRevenue.ts), případně vystaví doklad k dodávce nebo marketingový náklad
onLateCancellation status → cancelled_late Vytvoří storno poplatek (shared/cancellationAccounting.ts)
assignClientNumber vytvoření Client Přidělí client_number z čítače SystemSettings.client_number_seed

Změna logiky: účetní dopady se nově odvozují od stavu události, ne od akce v UI. Samotné storno ani označení výkonu se nezměnilo — účetní krok na ně jen navazuje. Export do Pohody běží odděleně (syncPohodaExport), takže selhání účetnictví neblokuje provoz kalendáře.

Účetní vrstva a export do Pohody

Ověřený fakt — export z 19. 8. 2026 obsahuje kompletní účetní vrstvu, která v předchozí verzi chyběla:

platba / realizace / storno
        │
        ├── shared/documentGeneration.ts   → Invoice (document_type, event_id)
        ├── shared/serviceRevenue.ts       → výnos při uskutečnění služby
        └── shared/cancellationAccounting.ts → storno poplatek / vratka
                    │
              syncPohodaExport  → dataPack XML → Pohoda mServer
                    │
              pohoda_export_status: pending → exported / failed

Export je dvoufázový v čase: doklad k přijaté platbě (accounting_phase = payment_receipt) vzniká při úhradě, doklad k dodávce / výnos (realization) až při uskutečnění služby. Deduplikace jde přes event_id, přepínač pohoda_new_rules_enabled drží nová účetní pravidla vypnutá do doby, než projde dry-run přes pohodaTestRun.