Czego się nauczysz?
- Projektowania systemów z przepływem pracy (workflow)
- Zarządzania statusami i ich zmianami
- Pracy z priorytetami i sortowaniem
- Walidacji złożonych formularzy
- Tworzenia raportów i statystyk
Stworzysz Rejestr zgłoszeń serwisowych - aplikację umożliwiającą rejestrowanie problemów technicznych (np. awarie komputerów, drukarek, sieci) z możliwością śledzenia statusu i zarządzania priorytetami. To mini wersja systemu helpdesk/ticketowego.
Czego się nauczysz?
W prawdziwej pracy...
Systemy ticketowe i helpdesk to podstawa obsługi klienta w każdej firmie IT. Jira, Zendesk, Freshdesk - wszystkie działają na podobnej zasadzie. Umiejętność projektowania systemów z przepływem pracy, statusami i priorytetami jest fundamentem dla każdego programisty aplikacji biznesowych.
Formularz zgłoszenia Użytkownik opisuje problem: tytuł, szczegółowy opis, kategoria (np. sprzęt, oprogramowanie, sieć), priorytet i dane kontaktowe.
Walidacja danych System sprawdza poprawność wprowadzonych danych - czy tytuł nie jest pusty, czy kategoria jest wybrana, czy email ma poprawny format.
Zapis z numerem zgłoszenia Każde zgłoszenie otrzymuje unikalny numer (np. TKT-001) i jest zapisywane do pliku JSON że statusem “nowe”.
Lista zgłoszeń Użytkownik może przeglądać wszystkie zgłoszenia z ich statusami i priorytetami.
Przykładowa struktura pliku JSON:
{ "tickets": [ { "id": 1, "ticket_number": "TKT-001", "title": "Nie działa drukarka w pokoju 203", "description": "Drukarka HP LaserJet nie drukuje, świeci się czerwona kontrolka", "category": "sprzęt", "priority": "wysoki", "status": "w_realizacji", "reporter_name": "Jan Kowalski", "reporter_email": "jan.kowalski@firma.pl", "created_at": "2026-02-10 09:30:00", "updated_at": "2026-02-10 11:00:00" }, { "id": 2, "ticket_number": "TKT-002", "title": "Prośba o instalację programu Excel", "description": "Potrzebuję Microsoft Excel na stanowisku roboczym", "category": "oprogramowanie", "priority": "niski", "status": "nowe", "reporter_name": "Anna Nowak", "reporter_email": "anna.nowak@firma.pl", "created_at": "2026-02-11 14:20:00", "updated_at": "2026-02-11 14:20:00" } ]}Wymagane funkcje:
Przykładowy scenariusz:
Ocena: 3.0Użytkownik wypełnia formularz opisujący problem z drukarką. Po zapisie widzi komunikat “Zgłoszenie TKT-003 zostało utworzone”. Na liście pojawia się nowe zgłoszenie z czerwonym znacznikiem wysokiego priorytetu.
Wszystko z wariantu A, plus:
Przykładowy scenariusz:
Ocena: 4.0-5.0Administrator widzi listę zgłoszeń, klika na TKT-003 i zmienia status na “w realizacji”. Zgłoszenie zmienia kolor na żółty. Może też filtrować: “pokaż tylko nowe” lub “pokaż tylko sprzęt”.
Wszystko z wariantu B, plus:
Przykładowy scenariusz:
Ocena: 5.0-6.0Administrator widzi dashboard: “Nowe: 5, W realizacji: 3, Zamknięte: 12”. Klika na zgłoszenie i dodaje komentarz “Zamówiono nowy toner”. Może też wyszukać “TKT-003” lub “drukarka” i szybko znaleźć zgłoszenie.
Generowanie numeru zgłoszenia:
function generateTicketNumber(array $tickets): string { $lastNumber = 0;
foreach ($tickets as $ticket) { // Wyciągnij numer z TKT-XXX if (preg_match('/TKT-(\d+)/', $ticket['ticket_number'], $matches)) { $lastNumber = max($lastNumber, (int) $matches[1]); } }
return 'TKT-' . str_pad($lastNumber + 1, 3, '0', STR_PAD_LEFT);}Walidacja formularza:
$title = trim($_POST['title'] ?? '');$email = trim($_POST['reporter_email'] ?? '');$category = $_POST['category'] ?? '';
if (empty($title)) { $errors[] = "Tytuł jest wymagany";}
if (strlen($title) < 5) { $errors[] = "Tytuł musi mieć minimum 5 znaków";}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { $errors[] = "Nieprawidłowy format email";}
$validCategories = ['sprzęt', 'oprogramowanie', 'sieć', 'inne'];if (!in_array($category, $validCategories)) { $errors[] = "Wybierz poprawną kategorię";}Zmiana statusu:
function changeStatus(array &$tickets, int $ticketId, string $newStatus): bool { $validStatuses = ['nowe', 'w_realizacji', 'zamknięte'];
if (!in_array($newStatus, $validStatuses)) { return false; }
foreach ($tickets as &$ticket) { if ($ticket['id'] === $ticketId) { $ticket['status'] = $newStatus; $ticket['updated_at'] = date('Y-m-d H:i:s'); return true; } }
return false;}Mapowanie statusów na kolory:
function getStatusColor(string $status): string { $colors = [ 'nowe' => '#e74c3c', // czerwony 'w_realizacji' => '#f39c12', // pomarańczowy 'zamknięte' => '#27ae60', // zielony ];
return $colors[$status] ?? '#95a5a6';}
function getPriorityColor(string $priority): string { $colors = [ 'niski' => '#27ae60', // zielony 'średni' => '#f39c12', // pomarańczowy 'wysoki' => '#e74c3c', // czerwony ];
return $colors[$priority] ?? '#95a5a6';}Statystyki (wariant C):
function getStatistics(array $tickets): array { $stats = [ 'total' => count($tickets), 'by_status' => [], 'by_category' => [], 'by_priority' => [], ];
foreach ($tickets as $t) { $status = $t['status']; $category = $t['category']; $priority = $t['priority'];
$stats['by_status'][$status] = ($stats['by_status'][$status] ?? 0) + 1; $stats['by_category'][$category] = ($stats['by_category'][$category] ?? 0) + 1; $stats['by_priority'][$priority] = ($stats['by_priority'][$priority] ?? 0) + 1; }
return $stats;}Wykorzystaj lekcje!
Cotygodniowe spotkania podczas lekcji to idealny moment, by:
Pracuj iteracyjnie - lepiej mieć działający wariant A niż niedokończony C!