projekt

Dołącz do CKZiU GitHub Classroom:

https://classroom.github.com/a/Birbt567

 

Rozkład jazdy na sprint 6 – CRUD

Zadanie 1 – Backend: model danych + endpointy

Osoba od backendu zaczyna od zaprojektowania głównego modelu aplikacji i dodania go do bazy danych obok istniejącej tabeli użytkowników.

Każdy zespół definiuje swój model w docs/api-contract.md:

Przykład dla aplikacji z ogłoszeniami:
{
  id, title, description, userId (klucz obcy!), createdAt
}

Przykład dla aplikacji z zadaniami:
{
  id, title, isDone, priority, userId, createdAt
}

Kluczowa zasada: każdy rekord musi być przypisany do użytkownika (userId). Bez tego każdy widzi dane wszystkich.

Następnie backend buduje endpointy – wszystkie wymagają tokenu JWT:

GET    /api/[zasób]        → lista rekordów zalogowanego użytkownika
POST   /api/[zasób]        → utwórz nowy rekord
PUT    /api/[zasób]/:id    → edytuj rekord (tylko właściciel!)
DELETE /api/[zasób]/:id    → usuń rekord (tylko właściciel!)

Priorytet to GET i POST

Zadanie 2 – Frontend i Mobile: Create + Read

Gdy backend ma działające GET i POST, frontend i mobile podłączają pierwsze dwa widoki.

Co musi działać po tym dniu:

Zalogowany użytkownik może dodać rekord i zobaczyć listę swoich rekordów – bez odświeżania strony po dodaniu.

javascript
// Wzorzec dla obu platform – zawsze z tokenem
const token = localStorage.getItem('token'); // lub SecureStorage

const res = await fetch('/api/[zasób]', {
  headers: { 'Authorization': `Bearer ${token}` }
});
const items = await res.json();

Ważne: lista odświeża się automatycznie po dodaniu nowego rekordu – bez ręcznego F5.

 

Zadanie 3 – Update i Delete

Backend dodaje PUT i DELETE z walidacją właściciela:

javascript
// Backend musi sprawdzić czy rekord należy do zalogowanego użytkownika
if (item.userId !== req.user.id) {
  return res.status(403).json({ error: "Brak dostępu" });
}

Frontend i mobile dodają:

  • Przycisk edycji → formularz z wypełnionymi danymi → zapis
  • Przycisk usunięcia → potwierdzenie („Czy na pewno?”) → usunięcie z listy

Zadanie 4 – Walidacja i obsługa błędów

Backend – walidacja wejścia:

javascript
// Przykład: tytuł nie może być pusty
if (!title || title.trim() === '') {
  return res.status(400).json({ error: "Tytuł jest wymagany" });
}

Frontend i Mobile – obsługa błędów:

  • Co gdy serwer nie odpowiada? → komunikat zamiast białego ekranu
  • Co gdy formularz jest pusty? → walidacja przed wysłaniem
  • Co gdy token wygasł? → przekierowanie na login

Trzy scenariusze błędów które muszą obsłużyć każdy ekran z formularzem.

 

Zadanie 5 – Testy manualne i porządki

Każdy zespół przechodzi przez scenariusz testowy i zapisuje wyniki w docs/test-scenarios.md:

1. Loguję się → widzę pustą listę ✓
2. Dodaję rekord → pojawia się na liście bez odświeżania ✓
3. Edytuję rekord → zmiany widoczne od razu ✓
4. Usuwam rekord → znika z listy ✓
5. Wylogowuję się → loguję jako inny użytkownik → nie widzę jego danych ✓
6. Próbuję usunąć cudzy rekord przez API → dostaję 403 ✓

 

Rozkład jazdy na sprint 5 – Figma -> Kod

Zadanie 1 – Ustalenie stylu

Zanim ktokolwiek napisze linijkę CSS/XAML, zespół ustala trzy rzeczy i zapisuje je w docs/design-tokens.md:

Kolory:
  --primary:     #[hex]    // główny kolor przycisków, linków
  --background:  #[hex]    // tło aplikacji
  --text:        #[hex]    // kolor tekstu
  --error:       #[hex]    // błędy, walidacja

Fonty:
  --font-main:   [nazwa]   // np. Inter, Roboto (z Google Fonts)
  --font-size:   16px      // bazowy rozmiar

Spacing:
  --radius:      8px       // zaokrąglenie przycisków i kart

 

Nie musi być piękne – ma być spójne. Wszystkie trzy osoby trzymają się tych wartości.

Dla Reacta – te tokeny lądują w jednym pliku src/styles/variables.css jako CSS custom properties. Każdy komponent importuje ten plik zamiast hardkodować kolory.

Dla MAUI – te same wartości lądują w Resources/Styles/Colors.xaml jako Color resources.

 

Zadanie 2 – Komponenty bazowe (Frontend + Mobile osobno)

Zanim zbudujecie ekrany, każda osoba robi małe, wielokrotnego użytku komponenty na podstawie tego co widzi w Figmie:

Frontend (React):

src/components/
├── Button.jsx          // primary, secondary, disabled
├── Input.jsx           // z labelem i komunikatem błędu
├── Card.jsx            // kontener z cieniem
└── Navbar.jsx          // nawigacja

Mobile (MAUI):

Components/
├── PrimaryButton.xaml
├── InputField.xaml
├── CardView.xaml
└── BottomNav.xaml

Kluczowa zasada: jeden komponent = jeden plik. Jeśli ten sam przycisk pojawia się na trzech ekranach – nie kopiujemy kodu, używają komponentu.

Zadanie 3 – Ekrany ekran po ekranie

Każda osoba idzie przez swoje wireframy po kolei, ekran za ekranem. Proponowany priorytet:

Kolejność Ekran Dlaczego
1 Login / Rejestracja Już macie logikę z poprzedniego sprintu
2 Dashboard / Ekran główny Pierwszy ekran po zalogowaniu
3 Główna funkcja aplikacji Serce projektu
4 Pozostałe ekrany Uzupełnienie

 

Ekrany autoryzacji mają już działającą logikę z poprzedniego sprintu – tu chodzi tylko o nadanie im wyglądu z Figmy.

Zasada dla każdego ekranu:

  1. Zbuduj layout z komponentów
  2. Podłącz do istniejącej logiki (jeśli jest)
  3. Sprawdź na różnych rozmiarach ekranu
  4. Commit z nazwą ekranu w opisie, np: feat: implement dashboard screen

 

Zadanie 4 – Nawigacja i spójność

Gdy ekrany istnieją, trzeba je połączyć w całość.

Frontend – React Router:

javascript
<Routes>
  <Route path="/"          element={<LandingPage />} />
  <Route path="/login"     element={<LoginPage />} />
  <Route path="/dashboard" element={<PrivateRoute><Dashboard /></PrivateRoute>} />
</Routes>

PrivateRoute to wrapper który sprawdza token – niezalogowany użytkownik wraca na /login. Uczniowie mają już ten mechanizm z poprzedniego sprintu, tu go tylko wpinają w router.

Mobile – MAUI Shell:

xml
<Shell>
  <ShellContent Route="login"     ContentTemplate="{DataTemplate views:LoginPage}" />
  <ShellContent Route="dashboard" ContentTemplate="{DataTemplate views:Dashboard}" />
</Shell>

Zadanie 5 – przegląd spójności:

Każda osoba przechodzi przez całą aplikację i sprawdza czy wszystkie ekrany wyglądają jakby należały do tego samego projektu – te same kolory, te same fonty, te same odstępy.

 

Rozkład jazdy na sprint 4 – Autoryzacja

Uwaga – tu już musi być baza danych!

Zadanie 1 – Backend: endpointy autoryzacji

Osoba od backendu ma jeden priorytet – dwa endpointy i token JWT.

POST /api/auth/register   → tworzy użytkownika, zwraca token
POST /api/auth/login      → sprawdza hasło, zwraca token
GET  /api/auth/me         → zwraca dane zalogowanego użytkownika (wymaga tokenu)

Minimalny model użytkownika:

{
  id, email, password (zahashowane!), createdAt
}

Dwie zasady których nie można pominąć:

  • Hasła zawsze hashowane – bcrypt, nigdy plain text
  • Token JWT w nagłówku Authorization: Bearer <token> – nie w URL, nie w body

Do bazy danych wystarczy najprostsze rozwiązanie – SQLite lokalnie albo MongoDB Atlas (darmowy tier).

Dzień 2 – Frontend i Mobile podłączają formularze

Gdy backend ma działające endpointy, frontend i mobile podłączają swoje formularze.

Co musi działać:

Użytkownik wpisuje email + hasło → klika „Zaloguj” → aplikacja dostaje token → token jest zapisany lokalnie → użytkownik widzi inny ekran niż przed chwilą.

Gdzie przechowywać token:

  • Frontend: localStorage
  • Mobile: SecureStorage (MAUI) lub AsyncStorage (React Native)

 

Co sprawdzam na koniec sprintu

Co Gdzie Minimalny próg
POST /api/auth/login zwraca token Postman Działa
Hasła hashowane w bazie Podgląd bazy – brak plain text Nie widać haseł
Frontend przekierowuje niezalogowanych Demo / screenshot Działa
Mobile robi to samo Demo / screenshot Działa
Token przechowywany lokalnie DevTools / AsyncStorage Nie w kodzie
Scenariusz testowy w docs/ GitHub repo Istnieje
Commity od wszystkich trzech osób GitHub → Contributors Min. 2 na osobę

Rozkład jazdy na sprint 3 – Pierwsza integracja frontend – backend, mobile-backend

Zadanie 1 – Backend przygotowuje „most”

Osoba od backendu ma jeden cel: dwa działające endpointy które frontend i mobile mogą wywołać.

GET  /api/health       → { "status": "ok" }        (już działa)
GET  /api/hello        → { "message": "Cześć z backendu!" }

(Jeśli robisz w Node pamiętaj, że backend musi mieć włączony CORS, inaczej przeglądarka zablokuje każde zapytanie z frontendu.)

Backend deployuje lokalnie i wysyła zespołowi adres – np. http://localhost:3000. Frontend i mobile nie czekają na więcej.

Zadanie 2 – Frontend i Mobile dzwonią do backendu

Frontendowiec i backendowiec pracują równolegle, każdy na swoim ekranie.

Frontend (osoba B):

Jedna strona z przyciskiem „Ping backend” – po kliknięciu wywołuje GET /api/hello i wyświetla odpowiedź na ekranie. Zero stylowania, ma działać.

Mobile (osoba C):

Jedna strona z przyciskiem „Ping backend” – po kliknięciu wywołuje

Zadanie 3 – Weryfikacja i porządki

Każdy testuje u każdego:

  • Frontend odpala mobile i sprawdza czy widzi odpowiedź z backendu
  • Mobile sprawdza frontend
  • Backend patrzy na logi gdy oboje klikają

Commit i dokumentacja:

  • Każda osoba robi commit z opisem co zrobiła
  • Aktualizują docs/api-contract.md o nowe endpointy
  • Jeden screenshot działającej integracji ląduje w docs/

 

Rozkład jazdy na sprint 2 – Figma

Zadanie 1 – Wspólne ustalenie ekranów

Zanim odpalimy Figmę, zespół wypisuje w docs/screens.md listę wszystkich ekranów/widoków.

Przykład:

Web:
- Strona główna / landing
- Logowanie / rejestracja
- Dashboard użytkownika
- Widok funkcji cośtam

Mobile:
- Splash screen
- Logowanie
- Ekran główny
- Widok funkcji cośtam

To wymusza rozmowę – frontend i mobile nie mogą rysować niezależnie jeśli nie wiedzą jakie ekrany w ogóle istnieją.

Zadanie 2 – Wireframy w Figmie (frontendu + mobile)

Każda osoba rysuje wireframy swojej części. Zasady:

  • Używamy tylko szarości
  • Obrazki = prostokąt z X w środku
  • Tekst = prawdziwy tekst, nie „Lorem ipsum” – treść wpływa na układ
  • Każdy ekran = osobny Frame w Figmie (nie luźne elementy na canvasie)
  • Nazwy frame’ów = takie same jak w screens.md

Zadanie 3 – Wspólny plik Figma, nie osobne 

Jeden plik na zespół, dwie strony (Pages): Web i Mobile. Osoba od frontendu pracuje na stronie Web, osoba od mobile na stronie Mobile. Dzięki temu backend widzi całość i może dopasować API.

Zadanie 4 – Link do Figmy w README

Na końcu wklejamy link do pliku Figma w README.md w sekcji dokumentacji.T o punkt kontrolny. Przyjmijmy, że zrobi to backendowiec, bo w tym sprincie miał mniej pracy 🙂

Rozkład jazdy na sprint 1 – Fundamenty projektu

Zadanie 1 – Uzupełnienie README

  • Wypełnić wszystkie pola szablonu: nazwa projektu, opis, technologie, podział ról (chcę, żeby użytkownicy byli dla mnie identyfikowalni 🙂 )
  • Każda osoba commituje swoją sekcję (żeby od razu widać kto coś robi)

Zadanie 2 – API Contract

Stworzyć plik docs/api-contract.md z tabelą endpointów. Choćby wstępną – na przykład:

| Metoda | Endpoint        | Opis                  | Kto robi |
|--------|-----------------|-----------------------|----------|
| POST   | /api/auth/login | Logowanie             | Backend  |
| GET    | /api/items      | Lista elementów       | Backend  |
| POST   | /api/ai/query   | Zapytanie do modelu AI| Backend  |

Zadanie 3 – Hello World × 3

Każda osoba uruchamia swój fragment i robi pierwszy sensowny commit:

  • Backend → serwer działa na porcie 3000, endpoint GET /api/health zwraca { status: "ok" }
  • Frontend → aplikacja startuje, jedna strona z nagłówkiem projektu
  • Mobile → aplikacja odpala się na emulatorze/telefonie, jeden ekran powitalny

Zadanie 4 – Struktura folderów i .gitignore

Założyć foldery backend/, frontend/, mobile/, docs/ i dodać .gitignore (żeby node_modules i .env nie trafiły do repo itp.).

Uwaga – każdy musi mieć co najmniej po 2-3 commity!

 

wstecz

Kontakt



Centrum Kształcenia Zawodowego i Ustawicznego

 ul. Promienna 65, 43-600 Jaworzno

 sekretariat@ckziu.jaworzno.pl

 32 76 29 100

Używamy ciasteczek. Czytaj więcej.