2

Dzień 2 z 18

Projekt

Opublikowany

Zanim napiszemy pierwszą linię kodu funkcjonalnego, definiujemy co budujemy. Poznamy aktorów systemu, prześledzimy historie użytkownika (F1–F7 oraz B1–B3) i obejrzymy makiety kluczowych ekranów Jobeet.

Czego się nauczysz

  • Czym jest Jobeet i jakie problemy rozwiązuje
  • Aktorzy systemu: użytkownik, wystawiający, admin, partner
  • Jedna aplikacja z sekcją admina zamiast frontend + backend
  • Historie użytkownika F1–F7 (frontend)
  • Historie administratora B1–B3 (backend)
  • Makiety kluczowych ekranów
  • Reguły biznesowe: ważność 30 dni, tokeny, reaktywacja

Co zmieniło się w Symfony 8 vs 4.2

  • Jedna aplikacja zamiast osobnych frontend + backend
  • Bezpieczeństwo natywne (Security Bundle) zamiast FOSUserBundle
  • API na API Platform 3 zamiast JMSSerializer + FOSRestBundle
  • Panel admina na EasyAdmin 4 zamiast ręcznego CRUD

Dzień 2: Projekt

W Dniu 1 przygotowaliśmy środowisko i uruchomiliśmy pustą aplikację Symfony 8. Zanim napiszemy pierwszą linię kodu funkcjonalnego, musimy dokładnie wiedzieć co budujemy. Dzisiejszy rozdział nie zawiera kodu — to specyfikacja projektu: aktorzy systemu, historie użytkownika (user stories) i makiety kluczowych ekranów. Do tego dokumentu będziemy wracać przez cały kurs.

Jobeet to otwartoźródłowa tablica ogłoszeń o pracę, która robi jedną rzecz, ale robi ją dobrze. Jest prosta w użyciu, łatwa do dostosowania, rozszerzenia i osadzenia na własnej stronie. Obsługuje wiele języków, udostępnia kanały RSS oraz API do integracji programistycznej.


Aktorzy systemu

W Jobeet występują cztery typy użytkowników:

Aktor Rola
Admin jest właścicielem serwisu i nim zarządza
Użytkownik (kandydat) odwiedza serwis w poszukiwaniu pracy
Wystawiający (poster) odwiedza serwis, aby dodać ofertę pracy
Partner (affiliate) publikuje oferty Jobeet na własnej stronie przez API

Jedna aplikacja, nie dwie

W oryginalnym tutorialu (Symfony 1.x) budowano dwie osobne aplikacje: frontend dla użytkowników oraz backend dla administratorów. W Symfony 8 tego nie robimy — tworzymy jedną aplikację z wydzieloną, zabezpieczoną sekcją administracyjną (firewall + role, np. /admin).

Zmiana vs Symfony 4.2: rezygnujemy z podziału na aplikacje frontend/backend. Sekcję admina zabezpieczymy natywnym Security Bundle (firewall, #[IsGranted('ROLE_ADMIN')], Voters) — bez zewnętrznych bundli w stylu FOSUserBundle. Panel admina zbudujemy później jako ręczny CRUD na formularzach Symfony (bez EasyAdmin/Sonata — zgodnie z konwencją tego projektu).


F1: Na stronie głównej użytkownik widzi najnowsze aktywne oferty

Na stronie głównej Jobeet użytkownik widzi listę 10 najnowszych aktywnych ofert pogrupowanych według kategorii. Dla każdej oferty wyświetlamy tylko lokalizację, stanowisko i firmę. Przy każdej kategorii jest link pozwalający wyświetlić wszystkie oferty z tej kategorii. Użytkownik może też wyszukać oferty lub dodać nową.

Makieta: strona główna

F2: Użytkownik przegląda wszystkie oferty z danej kategorii

Użytkownik widzi listę wszystkich ofert z kategorii, posortowaną według daty i podzieloną na strony po 20 ofert na stronę (paginacja).

Makieta: strona kategorii

F3: Użytkownik zawęża listę słowami kluczowymi

Użytkownik może wpisać słowa kluczowe, aby zawęzić wyszukiwanie. Słowa kluczowe mogą pochodzić z pól: lokalizacja, stanowisko, kategoria lub firma.

F4: Użytkownik klika ofertę, aby zobaczyć szczegóły

Użytkownik może wybrać ofertę z listy, aby zobaczyć szczegółowe informacje.

Makieta: szczegóły oferty

F5: Użytkownik dodaje ofertę

Użytkownik może dodać ofertę pracy. Oferta składa się z kilku informacji:

  • Firma
  • Typ (pełny etat, część etatu lub freelance)
  • Logo (opcjonalne)
  • URL (opcjonalne)
  • Stanowisko
  • Lokalizacja
  • Kategoria (wybór z listy dostępnych kategorii)
  • Opis stanowiska (adresy URL i e-mail są automatycznie zamieniane na linki)
  • Jak aplikować (adresy URL i e-mail są automatycznie zamieniane na linki)
  • Publiczna (czy oferta może być publikowana także na stronach partnerów)
  • E-mail (adres wystawiającego)

Proces ma tylko dwa etapy: najpierw użytkownik wypełnia formularz, a następnie zatwierdza ofertę po obejrzeniu podglądu finalnej strony.

Nie trzeba zakładać konta, aby dodać ofertę. Ofertę można później edytować dzięki specjalnemu adresowi URL chronionemu tokenem, który użytkownik otrzymuje przy tworzeniu oferty.

Każda oferta jest wyświetlana przez 30 dni (wartość konfigurowalna przez admina). Użytkownik może wrócić, aby reaktywować lub przedłużyć ważność oferty o kolejne 30 dni — ale tylko gdy do wygaśnięcia zostało mniej niż 5 dni.

Makieta: dodawanie oferty

F6: Użytkownik zgłasza się jako partner

Aby korzystać z API Jobeet, użytkownik musi zgłosić się jako partner. Może wybrać podzbiór kategorii, z których chce otrzymywać oferty. Przy zgłoszeniu podaje:

  • Nazwę
  • E-mail
  • Adres URL strony

Konto partnera musi zostać aktywowane przez admina. Po aktywacji partner otrzymuje e-mailem token do korzystania z API.

F7: Partner pobiera aktualną listę aktywnych ofert

Partner pobiera aktualną listę ofert, wywołując API ze swoim tokenem. Może ograniczyć liczbę zwracanych ofert i zawęzić zapytanie do wybranej kategorii.

Zmiana vs Symfony 4.2: oryginał zwracał dane w formatach XML / JSON / YAML, składanych ręcznie (JMSSerializer + FOSRestBundle). W Symfony 8 zbudujemy API zgodnie z konwencją tego projektu — kontroler REST zwracający JSON z DTO i automatyczną dokumentacją OpenAPI (NelmioApiDoc + swagger-php), z uwierzytelnianiem tokenem w nagłówku.


B1: Admin konfiguruje serwis

Admin może edytować kategorie dostępne w serwisie.

B2: Admin zarządza ofertami

Admin może edytować i usuwać dowolną dodaną ofertę.

B3: Admin zarządza partnerami

Admin może tworzyć i edytować partnerów. Odpowiada za aktywację partnera, może go też dezaktywować. Gdy admin aktywuje nowego partnera, system generuje unikalny token do użycia z API.


Podsumowanie

Mamy komplet specyfikacji Jobeet:

  • ✅ czterej aktorzy: admin, użytkownik, wystawiający, partner,
  • ✅ jedna aplikacja z zabezpieczoną sekcją admina (zamiast dwóch aplikacji),
  • ✅ siedem historii frontendu (F1–F7) i trzy backendu (B1–B3),
  • ✅ makiety kluczowych ekranów,
  • ✅ reguły biznesowe: ważność 30 dni, reaktywacja < 5 dni, edycja przez token, API dla partnerów.

W Dniu 3 przekujemy tę specyfikację w model danych: zdefiniujemy encje Doctrine (Job, Category, Affiliate), relacje między nimi, uruchomimy pierwszą migrację i zasilimy bazę danymi testowymi.

Spis treści