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.
// 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:
// 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:
// 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:
- Zbuduj layout z komponentów
- Podłącz do istniejącej logiki (jeśli jest)
- Sprawdź na różnych rozmiarach ekranu
- 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:
<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:
<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) lubAsyncStorage(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.mdo 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/healthzwraca{ 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!

