Aktuální ticket_number je sekvenční (T-00001, T-00002, ...). Klient vidí toto číslo při potvrzení odeslání požadavku a může z něj odvodit:
Toto je informační únik (enumeration attack) který nechceme.
Příklad: zákazník odešle ticket ráno (T-00050) a večer (T-00051) → ví, že za den přišel 1 ticket → odhadne kapacitu/objem supportu.
Zavést druhý identifikátor: ticket_code — veřejný, náhodný, pro klienty.
Vlastnosti ticket_code:
Dvojí terminologie:
Slovník:
ticket_number = interní sekvenční číslo (T-NNNNN), pouze agenti
ticket_code = veřejný kód (XXXXXX), pro klienty a e-maily
Znaková sada: A-Z (26) + 2-9 (8) = 34 znaků
Vyloučeny: 0 (zaměnitelné s O), 1 (zaměnitelné s I nebo L)
Formát: první znak A-Z (26 možností), zbývajících 5 znaků z 34 znaků
Počet kombinací: 26 × 34^5 = 26 × 45 435 424 = 1 181 320 624 (~1,2 miliardy)
Pravděpodobnost kolize (birthday problem, 10 000 ticketů):
p ≈ n² / (2 × N) = 100 000 000 / (2 × 1 181 320 624) ≈ 0,004 %
Akceptovatelné — při kolizi generovat znovu (retry loop, max 5 pokusů).
Příklady platných kódů: AB3K7X, FW9R2M, ZQ4DT8
Příklady zakázaných: 0B3K7X (začíná číslicí), AB0K7X (obsahuje 0), AB1K7X (obsahuje 1)
| Tabulka | Změna | Detail |
|---|---|---|
podpora21.support_ticket | ADD COLUMN ticket_code VARCHAR(6) | NOT NULL, UNIQUE per tenant, generován při INSERT |
podpora21.support_ticket | ADD INDEX | UNIQUE INDEX (tenant_id, ticket_code) pro rychlé vyhledání |
podpora21.support_ticket | ticket_number zůstává | Interní identifikátor se nemění, jen skryje před klienty |
Flash zpráva po odeslání Quick Ticket: zobrazí ticket_code místo ticket_number
Helpdesk detail ticketu: zobrazí obě hodnoty — Ticket Code (pro klienta) + Ticket Number (interní)
Helpdesk list: sloupec ticket_number zůstává, ticket_code přidán jako sekundární info
E-mailová potvrzení (budoucí): v předmětu a tělu zprávy ticket_code
Portal klientský dashboard (fáze 2): klient vyhledává a odkazuje přes ticket_code
Migrace: ADD COLUMN ticket_code VARCHAR(6) NOT NULL DEFAULT '' na support_ticket
Migrace: backfill existujících ticketů (generovat ticket_code pro každý existující řádek)
Migrace: DROP DEFAULT, ADD UNIQUE INDEX (tenant_id, ticket_code)
TicketModel::generateTicketCode() — statická metoda, crypto-random, retry na kolizi
TicketModel::create() — doplnit ticket_code při INSERT
HomepagePresenter: flash zpráva zobrazí ticket_code místo ticket_number
TicketPresenter detail.latte: zobrazit ticket_code jako 'Kód pro klienta'
TicketPresenter list.latte: přidat ticket_code do tabulky
| Version | Date | Author | Note |
|---|---|---|---|
| 0.1.0 | 2026-04-10 | david.sorf + claude-sonnet-4-6 | Initial draft — problém enumerace, ticket_code návrh, charset, DB změny, UI dopad. |