Podpora21.cz je zákaznická podpora EP21. Přistupují k ní dva různé typy uživatelů s odlišnými potřebami:
1. Agenti (interní EP21 pracovníci) — potřebují plný helpdesk backend s ticketingem, statistikami, správou
2. Klienti (zákazníci a studenti EP21) — potřebují jednoduchý portál pro podání požadavku a sledování stavu
Dosud (po bootstrapu) je aplikace čistě interní — bez veřejné landing page, bez klientského přístupu. Nepřihlášený uživatel vidí jen přihlašovací formulář.
Zároveň má podpora21 potenciál jako SaaS — EP21 by mohlo provozovat helpdesk i pro jiné zákazníky (multi-tenant). Tuto vrstvu je třeba architekturálně rozhodnout teď, aby budoucí rozšíření nevyžadovalo breaking changes.
Uvažované možnosti:
A) Shared single URL space — vše na jedné doméně, role řídí co vidíš
B) Subdomain separation — klienti na client.podpora21.cz, agenti na admin.podpora21.cz
C) Path-based separation — /portal pro klienty, /helpdesk pro agenty, / jako veřejná landing
D) Separate app — klientský portál jako samostatná Nette aplikace
Zvolena Option C (path-based separation) z těchto důvodů:
1. Jedna Nette aplikace, jeden deployment — minimální provozní overhead
2. Sdílené DI services, modely a databázové připojení — žádná duplicita
3. URL struktura jasně komunikuje kontext: / = veřejné, /portal = klient, /helpdesk = agent
4. RBAC řídí přístup — není třeba oddělovat subdomény
5. Konzistentní s existující architekturou (BasePresenter, RouterFactory)
6. Multi-tenant ready: path-based separation je kompatibilní s budoucím subdomain routingem — /portal URL zůstane stejná, jen TenantResolver přidá subdomain logiku (viz ADR-0002)
Proč ostatní odmítnuty:
A) Shared single space — matoucí UX, těžší RBAC bez jasné URL hranice
B) Subdomain separation — v první fázi zbytečná složitost; přidat ji jako rozšíření TenantResolveru je jednodušší než od začátku
D) Separate app — duplicita kódu, dva deployments, sharing session/auth je složité
Multi-tenant jako design constraint (ne afterthought):
Tenant izolace je constraint platný od fáze 1 — viz ADR-0002. tenant_id je přidán na všechny tenant-owned tabulky před prvním deploymentem. TenantResolverService je DI singleton injected do presenterů a modelů. V fázi 1 je resolver statický (TENANT_KEY=ep21 z .env). Přidání druhého tenanta nevyžaduje DB schema změny — pouze nový core_tenant řádek a nový TENANT_KEY (nebo subdomain v fázi 2). Viz DS-0003 pro technický detail.
Pozitivní:
Negativní / rizika:
Neutrální:
RouterFactory musí deklarovat public routes PŘED autentizovanými:
Public (bez autentizace):
GET / → Homepage:default
GET /portal → Portal:default
GET /portal/register → Portal:register
POST /portal/quick-ticket → Portal:quickTicket (signal nebo action)
GET /log/in → Log:in
POST /log/in → Log:in (login form)
GET /log/out → Log:out
Client (role: client):
GET /portal/dashboard → Portal:dashboard
GET /portal/ticket/<id> → Portal:ticket
Agent (role: agent, admin):
GET /helpdesk → Ticket:dashboard
/ticket/* → Ticket:*
/rbac-admin/* → RbacAdmin:*
/tek/* → Tek:*
| Version | Date | Author | Note |
|---|---|---|---|
| 1.0.0 | 2026-04-10 | david.sorf + claude-sonnet-4-6 | Initial accepted version — path-based separation, single-tenant fáze 1, multi-tenant fáze 2 future. |