Přeskočit obsah

Support systém — Specifikace

Přehled

Každá firma má automaticky vytvořený support kanál pro komunikaci s Avaxis support týmem. Support agenti vidí POUZE zprávy adresované do support kanálu — nikdy interní firemní chat. Systém přiděluje tikety dle priority a dostupnosti, podporuje AI asistenta pro přípravu odpovědí a znalostní bázi budovanou z vyřešených tiketů.

Princip izolace

Co support agent VIDÍ:
  ✓ Support kanál dané firmy (conversations.type = 'support')
  ✓ Historii své vlastní komunikace s firmou
  ✓ Fronta nových tiketů (nepřiřazených)
  ✓ Interní poznámky týmu k tiketu
  ✓ Znalostní bázi a FAQ

Co support agent NEVIDÍ:
  ✗ Interní firemní chat (type = 'internal')
  ✗ Cross-company konverzace uživatelů
  ✗ Data aplikací uživatelů
  ✗ Support kanály jiných firem (pokud mu nejsou přiděleny)

Tikety a fronta

support_tickets (
  id                UUID PRIMARY KEY,
  conversation_id   UUID REFERENCES conversations(id) UNIQUE,
  company_id        UUID REFERENCES companies(id),
  status            VARCHAR(30),
  -- 'new'          → čeká ve frontě
  -- 'assigned'     → přiřazen agentovi, zatím neodpověděl
  -- 'open'         → probíhá komunikace
  -- 'waiting'      → čeká na odpověď zákazníka
  -- 'resolved'     → vyřešeno agentem, zákazník může znovu otevřít
  -- 'closed'       → uzavřeno po 7 dnech bez odpovědi zákazníka
  priority          INTEGER DEFAULT 3,
  -- 1 KRITICKÁ / 2 VYSOKÁ / 3 NORMÁLNÍ / 4 NÍZKÁ
  category          VARCHAR(50),       -- 'technical'|'billing'|'general'
  assigned_to       UUID REFERENCES support_agents(id),
  assigned_at       TIMESTAMPTZ,
  first_response_at TIMESTAMPTZ,
  resolved_at       TIMESTAMPTZ,
  resolved_by       UUID REFERENCES users(id),
  csat_score        INTEGER,           -- 1–5, NULL dokud zákazník nehodnotí
  csat_comment      TEXT,
  created_at        TIMESTAMPTZ,
  updated_at        TIMESTAMPTZ
)

support_agents (
  id             UUID PRIMARY KEY,
  user_id        UUID REFERENCES users(id),
  is_available   BOOLEAN DEFAULT false,
  priority       INTEGER DEFAULT 5,
  max_tickets    INTEGER DEFAULT 10,
  specialization VARCHAR(100)[]        -- ['billing', 'technical', 'general']
)

Interní poznámky a eskalační řetězec

Interní poznámky agentů

Poznámky viditelné pouze support týmu — zákazník je nevidí nikdy.

V tiketu má agent dvě pole:
  [Odpověď zákazníkovi]  → vidí zákazník i agent
  [Interní poznámka]     → vidí pouze support tým

Příklady interních poznámek:
  "Čeká na vyjádření vývojáře, odhadem 2 dny"
  "Zákazník volal 21.4., domluveno řešení do pátku"
  "Předáno Martinovi — zná tuto firmu"

Datový model:
  ticket_notes (
    id          UUID PRIMARY KEY,
    ticket_id   UUID REFERENCES support_tickets(id),
    author_id   UUID REFERENCES users(id),
    content     TEXT,
    created_at  TIMESTAMPTZ
  )

Eskalační řetězec (předání tiketu s vyjádřením)

Tiket lze předat dalšímu členovi týmu — každý přidá své vyjádření. Tiket zůstane otevřený dokud ho někdo neuzavře jako vyřešený.

Tok eskalačního řetězce:

  Agent A obdrží tiket
    ├─ Přidá interní poznámku: "Potřebuji konzultaci se specialistou"
    ├─ Předá tiket Agentovi B (s poznámkou viditelnou jen týmu)
  Agent B obdrží tiket (notifikace)
    ├─ Přidá interní poznámku: "Problém je v konfiguraci modulu X"
    ├─ Napíše odpověď zákazníkovi NEBO předá dál (Agent C)
  [Kdokoli] → pošle odpověď zákazníkovi + uzavře tiket jako vyřešený
    → zákazník dostane výzvu k CSAT hodnocení

Eskalační historie je viditelná v detailu tiketu:
  [Přijal: Agent A] → [Předal: Agent A → B] → [Předal: Agent B → C]
  → [Uzavřel: Agent C]
ticket_transfers (
  id          UUID PRIMARY KEY,
  ticket_id   UUID REFERENCES support_tickets(id),
  from_agent  UUID REFERENCES users(id),
  to_agent    UUID REFERENCES users(id),
  note        TEXT,          -- interní poznámka k předání
  transferred_at TIMESTAMPTZ
)

Přidělování tiketů

Nový tiket přišel:
  1. Najdi dostupné agenty (is_available = true)
  2. Filtruj dle specialization (kategorie tiketu)
  3. Seřaď: méně tiketů → vyšší priorita agenta
  4. Přiřaď prvnímu v seznamu
  5. Pokud nikdo dostupný → fronta 'new' + viz sekce Pracovní doba
  6. Notifikace přiřazenému agentovi

Priorita 1 (KRITICKÁ) → notifikace všem dostupným agentům okamžitě

Eskalace bez odpovědi

Priorita 1 → eskalace po  15 min
Priorita 2 → eskalace po  30 min
Priorita 3 → eskalace po   4 hod
Priorita 4 → eskalace po  24 hod

Eskalace = notifikace vedoucímu supportu + přiřazení volnějšímu agentovi

Automatické předání při odchodu agenta

Agent přepne dostupnost na OFFLINE nebo vyprší heartbeat (30 min):
  → Systém automaticky přiřadí jeho otevřené tikety dostupným agentům
    (stejný algoritmus jako nový tiket)
  → Každý přeřazený tiket dostane interní poznámku:
    "Automaticky přeřazeno — agent [jméno] přešel do offline"
  → Zákazník není informován (změna agenta je interní)
  → Nový agent dostane notifikaci pro každý přeřazený tiket

Pracovní doba a AI fallback

Indikátor dostupnosti supportu

V aplikaci zákazníka (tlačítko "Kontaktovat Support"):
  ● Zelená — "Support je online" (alespoň 1 agent je_available = true)
  ● Šedá   — "Support je offline — odpovíme v pracovní době"

Tento indikátor se aktualizuje real-time přes WebSocket.

Chování mimo pracovní dobu (žádný agent online)

Zákazník odešle zprávu do tiketu:

  Pokud ŽÁDNÝ agent není online:
    1. Tiket se uloží (status: 'new', ve frontě)
    2. AI agent okamžitě odpoví automatickou zprávou:

    ┌─────────────────────────────────────────────────────────┐
    │ Dobrý den, děkujeme za váš dotaz.                      │
    │                                                         │
    │ Náš support tým je momentálně offline.                  │
    │ Váš tiket byl přijat a budeme se mu věnovat             │
    │ jakmile budeme zpět online v pracovní době.             │
    │                                                         │
    │ [AI návrh řešení na základě znalostní báze:]           │
    │ Podobný problém byl vyřešen takto: ...                  │
    │ Odkaz na FAQ článek: [Jak nastavit tisk sestav]        │
    │                                                         │
    │ Pokud vám toto pomohlo, můžete tiket uzavřít.          │
    │ Jinak se vám ozveme osobně.                            │
    └─────────────────────────────────────────────────────────┘

    3. Agent při přihlášení vidí tiket ve frontě s AI odpovědí
       označenou jako "AI odpověď — zkontrolujte"

AI asistent pro support tým

Příprava odpovědí (AI draft)

Při otevření tiketu AI agent automaticky připraví návrh odpovědi na základě znalostní báze a historie podobných tiketů.

Agent otevře tiket → AI analyzuje zprávu zákazníka:
  1. Vyhledá podobné vyřešené tikety (RAG — viz Znalostní báze)
  2. Vyhledá relevantní FAQ články
  3. Připraví návrh odpovědi:

  ┌──────────────────────────────────────────────────────────────┐
  │  🤖 AI návrh odpovědi (zkontrolujte před odesláním)         │
  │                                                              │
  │  "Dobrý den, problém s tiskem sestav ve verzi 2.1.3 byl     │
  │   způsoben chybou v šabloně. Řešení:                        │
  │   1. Otevřete Nastavení → Tisk → Resetovat šablony          │
  │   2. Restartujte aplikaci                                    │
  │   Pokud problém přetrvá, prosím zašlete screenshot."        │
  │                                                              │
  │  Zdroj: Tiket #1234 (Firma ABC, 15.3.2026)                  │
  │  Relevantní FAQ: "Problémy s tiskem v 2.1.x"               │
  │                                                              │
  │  [Použít jako odpověď] [Upravit] [Ignorovat]                │
  └──────────────────────────────────────────────────────────────┘

Agent může návrh:
  • Použít přímo → odeslat zákazníkovi
  • Upravit → editovat text a odeslat
  • Ignorovat → napsat odpověď ručně

Technická implementace AI asistenta

Model: Claude API (Anthropic) — claude-sonnet-4-6 nebo novější
Přístup: RAG (Retrieval-Augmented Generation)

Pipeline:
  1. Embeddings znalostní báze uloženy ve vektorové DB (pgvector)
  2. Nový tiket → embed dotaz zákazníka
  3. Vyhledej top-5 nejpodobnějších dokumentů (cosine similarity)
  4. Pošli do Claude: { system_prompt, kontext z KB, dotaz zákazníka }
  5. Claude vrátí návrh odpovědi
  6. Zobraz agentovi ke kontrole

System prompt obsahuje:
  • Instrukce pro tón (profesionální, přátelský, česky)
  • Kontext produktu AVAX
  • Instrukce: "Navrhni odpověď, neposílej ji přímo zákazníkovi"

Znalostní báze a FAQ

Budování znalostní báze z tiketů

Při uzavření tiketu jako 'resolved':
  Agent dostane výzvu: "Přidat řešení do znalostní báze?"
  [Ano — přidat článek] [Ne]

  Pokud ANO:
    → Předvyplněný formulář z obsahu tiketu:
      Název problému: [...]
      Příznaky:       [...]
      Řešení:         [...]
      Kategorie:      [Technical ▼]
      Verze aplikace: [2.1.4 ▼]
    → Agent upřesní, uloží → článek přidán do KB
    → Automaticky embedován pro RAG vyhledávání

Výsledek: KB se organicky buduje s každým vyřešeným tiketem.

FAQ — hybridní přístup

Struktura FAQ:
  1. Manuálně kurátorované články
     → Psané support týmem pro nejčastější problémy
     → Organizované do kategorií (Instalace, Fakturace, Tisk...)
     → Verzované (platné pro verzi 2.x, 3.x)

  2. RAG vyhledávání nad znalostní bází
     → Zákazník napíše dotaz volným textem
     → Systém najde nejrelevantnější články + vyřešené tikety
     → AI shrne odpověď + odkáže na zdroje

  3. Metriky úspěchu FAQ
     Pod každým článkem: "Pomohl vám tento článek?"
       👍 Ano  →  počítá se jako deflected_ticket
       👎 Ne   →  zákazník přesměrován na otevření tiketu

     Metriky per článek:
       • Počet zobrazení
       • Míra úspěchu (% "Ano")
       • Deflection rate (kolik tiketů artikel odvrátil)
       • Průměrné CSAT tiketů které přišly po zobrazení článku

     Metriky celé FAQ:
       • Celkový deflection rate (% uživatelů kteří neotvřeli tiket)
       • Nejhledanější dotazy bez odpovědi → náměty pro nové články
kb_articles (
  id          UUID PRIMARY KEY,
  title       VARCHAR(255),
  content     TEXT,               -- Markdown
  category    VARCHAR(100),
  app_slug    VARCHAR(100),       -- NULL = obecné
  app_version VARCHAR(50),        -- NULL = všechny verze
  embedding   vector(1536),       -- pgvector pro RAG
  author_id   UUID REFERENCES users(id),
  source_ticket_id UUID REFERENCES support_tickets(id),  -- NULL = manuální
  views       INTEGER DEFAULT 0,
  helpful_yes INTEGER DEFAULT 0,
  helpful_no  INTEGER DEFAULT 0,
  is_published BOOLEAN DEFAULT false,
  created_at  TIMESTAMPTZ,
  updated_at  TIMESTAMPTZ
)

CSAT hodnocení spokojenosti

Po uzavření tiketu agentem → zákazník dostane výzvu (e-mail + in-app):

  "Jak hodnotíte vyřízení vašeho požadavku?"
  ★ ★ ★ ★ ★  (1–5 hvězdiček)
  [Volitelný komentář: ................................]
  [Odeslat hodnocení]

Hodnocení je volitelné — zákazník může ignorovat.
Výzva se zobrazí maximálně jednou (no spam).

Agregace:
  • Průměrné CSAT per agent (vidí agent i vedoucí)
  • Průměrné CSAT celého týmu (dashboard)
  • Trend v čase (graf)
  • Nejhorší hodnocení → vedoucí dostane notifikaci (< 2 hvězdičky)

Support dashboard (agent pohled)

┌────────────────────────────────────────────────────────────────────┐
│  FRONTA               MOJE TIKETY              MŮJ VÝKON          │
│  ──────               ───────────              ─────────          │
│  🔴 Kritická: 1       [open] Firma XYZ         CSAT: ★4.2/5      │
│  🟡 Vysoká:   2       poslední: 10 min         Tikety dnes: 8     │
│  ⚪ Normální: 5       [waiting] Firma DEF      Prům. odpověď: 23m │
│                       čeká: 2 hod                                  │
│                       [open] Firma GHI         DOSTUPNOST: ● ON   │
│                       poslední: 1 hod          [Přejít offline]   │
└────────────────────────────────────────────────────────────────────┘

Support API

GET  /support/queue
GET  /support/tickets?status=open&agent_id=me
GET  /support/tickets/{id}           ← detail + konverzace + poznámky + eskalace

POST /support/tickets/{id}/assign    Body: { agent_id }
POST /support/tickets/{id}/priority  Body: { priority: 1|2|3|4 }
POST /support/tickets/{id}/status    Body: { status, message_to_customer }
POST /support/tickets/{id}/transfer  Body: { to_agent_id, note }
POST /support/tickets/{id}/notes     Body: { content }   ← interní poznámka

GET  /support/tickets/{id}/ai-draft  ← AI návrh odpovědi pro agenta
POST /support/tickets/{id}/csat      Body: { score: 1-5, comment }  ← zákazník

PUT  /support/agents/me/availability Body: { is_available: bool }

GET  /support/stats?from=...&to=...

GET  /kb/articles?q={dotaz}&category={cat}&app={slug}
POST /kb/articles                    ← nový článek (agent)
PUT  /kb/articles/{id}
POST /kb/articles/{id}/helpful       Body: { helpful: true|false }  ← zákazník

Notifikace

Agent:
  → Nový tiket přiřazen
  → Zákazník odpověděl (waiting → open)
  → Tiket eskaluje
  → Tiket automaticky přeřazen (jiný agent šel offline)
  → Zákazník hodnotil < 2 hvězdičky

Vedoucí supportu:
  → Tiket eskaloval
  → Fronta > 10 tiketů bez přiřazení
  → Agent přešel offline se otevřenými tikety
  → CSAT < 2 hvězdičky

SLA metriky

Priorita Cíl první odpovědi Cíl vyřešení
Kritická 15 minut 4 hodiny
Vysoká 1 hodina 1 pracovní den
Normální 4 hodiny 3 pracovní dny
Nízká 1 pracovní den 7 pracovních dní

Rozhodnuté otázky

Otázka Rozhodnutí
CSAT 5 hvězdiček, volitelné, zákazník hodnotí po uzavření
CSAT — agent vidí Ano — průměr na dashboardu, vedoucí upozorněn při < 2
Interní poznámky Ano — vidí jen support tým, zákazník nikdy
Eskalační řetězec Předání s poznámkou, tiket otevřen dokud ho někdo neuzavře
Uzavření tiketu Agent odešle odpověď zákazníkovi + uzavře → zákazník dostane CSAT
Pracovní doba Indikátor online/offline v aplikaci zákazníka (real-time)
Mimo pracovní dobu AI automatická odpověď + návrh z KB, agent zkontroluje ráno
Předání tiketů (konec směny) Automatické přeřazení dostupnému agentovi
Znalostní báze Budovaná z vyřešených tiketů, agent přidá článek při uzavření
AI asistent Claude API + RAG (pgvector), návrh odpovědi ke schválení agentem
AI zdroje Ano — agent vidí které tikety/články Claude použil (transparentnost)
FAQ Hybridní: manuální články + RAG vyhledávání + metriky úspěchu
FAQ deflection Měří se "Pomohl článek?" + počet tiketů odvrácených FAQ
Pracovní doba Konfigurovatelná v portálu (Po–Pá 8–17 apod.)
Online indikátor Zelená pokud: pracovní doba AND alespoň 1 agent přihlášen
Mimo prac. dobu Zobrazí "Odpovíme [další pracovní den] od [čas]" + AI odpověď
KB schválení Agent napíše článek → vedoucí/senior agent schválí → teprve pak publikováno

Otevřené otázky

Všechny otázky k support.md jsou vyřešeny.


Poslední aktualizace: 2026-04-21