Przejdź do treści
Artur Shaposhnyk
Studium przypadku

Organic Food Boutique Store

Bootcampowy sklep internetowy budowany przez dziewięć osób naraz, w którym ważne pytanie nie brzmi, co dowiózł zespół, tylko którą część napisałem ja — i ile kosztował mnie na końcu wybór elementu zależnego od wszystkich pozostałych.

Rola
Logika koszyka, sekcja hero, scrum master
Rok
2023
Stack
HTML · CSS · JavaScript · Vite
01

Kontekst

9
osób commitujących do jednego repozytorium
58
pull requestów, jedna gałąź na element

Organic Food Boutique Store to zespołowy projekt z bootcampu: witryna sklepu dla serwisu subskrypcji żywności, zbudowana na REST API dostarczonym przez kurs. W dziewięć osób commitowaliśmy do jednego repozytorium, które należy do innej osoby z zespołu, a nie do mnie — dlatego to studium przypadku zaczyna się od rysunku pokazującego, które obszary strony napisałem, zamiast od zrzutu ekranu całości.

Pracę podzieliliśmy według komponentów. Każdy wziął fragment strony — nagłówek, hero, filtry, listę produktów, popularne produkty, produkty z rabatem, okna modalne, koszyk — zbudował go na osobnej gałęzi i otworzył pull request do main; weszło ich w ten sposób pięćdziesiąt osiem, a tytuły mówią, kto zrobił co. Byłem scrum masterem sprintu: co wieczór prowadziłem stand-up i pilnowałem tablicy zadań.

Termin wynosił tydzień. Zrobiło się z niego dziesięć dni.

02

Ograniczenia

Żadne z nich nie pochodziło od klienta. To zwykłe warunki budowania jednej podstrony witryny, podczas gdy osiem innych osób buduje resztę — i każdy z nich przesądził o tym, co mogłem skończyć i kiedy.

Repozytorium nie jest moje
Jest na koncie innej osoby z zespołu. Z zewnątrz nie widać w nim nic z mojego wkładu — ani na moim profilu, ani w repozytorium, do którego mógłbym podlinkować jako do własnego — a każdy, kto ocenia tę pracę, przychodzi z dokładnie jednym pytaniem i bez wygodnego sposobu, żeby na nie odpowiedzieć. Po to jest rysunek poniżej i dlatego karta tego projektu ma linijkę o zakresie, której inne nie mają.
Wszystko, co zbudowałem, stało na cudzym kodzie
Koszyk czyta dane przez serwis API i wrapper na storage — oba napisane przez właściciela repozytorium, zanim zacząłem. Renderuje się w markupie, który napisała i ostylowała koleżanka z zespołu. Liczbę, którą wylicza, wyświetla nagłówek należący do dwóch innych osób. Napisałem środek tego łańcucha i żadnego z jego końców.
Tydzień, a potem dziesięć dni
Termin przesunął się raz, i to na naszą korzyść. Warto powiedzieć to wprost, bo wyklucza oczywiste wyjaśnienie tego, jak skończył się sprint: to nie harmonogram zawiódł.
03

Kluczowe decyzje

Dwie z nich podjąłem świadomie. Trzecia rzecz, którą zrobiłem, też była decyzją, ale wtedy jej za taką nie uznałem, więc jest w ostatniej sekcji, a nie tutaj.

Wziąć koszyk, bo wykorzystywał najwięcej z tego, czego nas uczono
Sprawdzał więcej materiału z kursu niż jakikolwiek inny element na tablicy — stan, storage, renderowanie z danych, komunikację z API — i wiązał się z realną odpowiedzialnością: to strona, na której zła liczba oznacza złe zamówienie, a nie kosmetyczną usterkę. Zależał też od pracy innych bardziej niż cokolwiek innego do wzięcia, a ja potraktowałem to jako argument za.
Renderować wiersze, zamiast wysyłać je gotowe
Strona koszyka przyszła jako statyczny markup z przykładowymi pozycjami wpisanymi w HTML. Usunąłem je i kazałem JavaScriptowi budować wiersze z zapisanego stanu, żeby strona pokazywała to, co jest w koszyku, a nie to, co akurat w nim było, gdy ktoś pisał markup. To jeden commit — i to ten, który zamienił layout w stronę.
Brać poprawki, zamiast zajmować czwarty element
Gdy pas hero był już zmergowany, zająłem się dwiema sekcjami należącymi do innych — poprawką w liście popularnych produktów i animacją w liście produktów z rabatem — zamiast zaczynać coś nowego, własnego. Przy tak krótkim projekcie pożyteczna praca na tym etapie to ta, która już jest w toku.
04

W szczegółach

Koszyk jest węzłem tej witryny. Wszystko inne na stronie to liść — filtr, karta, okno modalne — a koszyk jest jedynym miejscem, w którym API, zapisany stan, cudzy markup i cudzy licznik w nagłówku muszą się ze sobą zgadzać w tej samej chwili.

Co czyta. Produkty i ilości przychodzą przez serwis API i wrapper na storage; oba istniały, zanim otworzyłem plik. Nie napisałem transportu i nie napisałem zapisu danych. Napisałem część pomiędzy, która zamienia to, co zapisane, w to, co widać na ekranie.

Co zapisuje. Zmiana ilości, usunięcie pozycji i opróżnienie koszyka wracają do storage, a stamtąd czytają zarówno suma zamówienia, jak i znaczek w nagłówku. Dwie z trzech rzeczy czytających tę liczbę należały do innych osób, dlatego licznik jest na tej stronie wartością najbardziej narażoną na niezgodność między autorami.

Co renderuje. Wiersze są budowane z zapisanych pozycji, a nie wpisane w dokument, więc zmiana ilości renderuje wiersz i sumy na nowo z jednego źródła, zamiast aktualizować trzy miejsca z nadzieją, że będą się zgadzać.

Sekcja hero, na drugim arkuszu. Nagłówek, podtytuł i grafika hero na górze katalogu, z jednym słowem nagłówka zmieniającym kolor w pętli. To jedyna rzecz, jaką napisałem w tej witrynie, którą recenzent może zobaczyć w działaniu bez otwierania pliku.

Gdzie skończyła się moja praca. Koszyk wszedł jednym pull requestem pod koniec sprintu, a tego samego popołudnia przyszły po nim dwa commity właściciela repozytorium — jeden z nich naprawiał aktualizację koszyka przy zmianie ilości. Historia commitów jest uczciwym zapisem tej granicy, a studium przypadku, które przypisałoby mi tę stronę w całości, zostałoby przez nią obalone w mniej więcej minutę.

Która część jest moja

To projekt zespołowy, więc jedyne sensowne pytanie brzmi: które części napisałem ja. Podświetlone są obszary, które rysuje mój kod. W ramce, ale przygaszony: cudzy element z liczbą, którą wpisuje do niego mój kod — notka mówi, którą. Wszystko inne, przygaszone i bez ramki, nie jest moje w żadnym sensie. Każda notka wskazuje coś, co da się sprawdzić w repozytorium.

Katalog
Strona katalogu produktów: nagłówek i grafika hero są podświetlone, reszta strony przygaszona.
  1. hero.html4 commity
  2. rotateColor4s infinite
  3. hero.css6 commitów
Koszyk
Strona koszyka. Trzy wiersze pozycji są podświetlone; reszta strony jest przygaszona, a suma zamówienia i licznik koszyka w nagłówku są w ramkach jako elementy zbudowane przez inne osoby z zespołu, do których jego kod wpisuje liczbę.
  1. ich nagłóweklicznik ustawia cart.js
  2. cart.js4 commity · buduje wiersze
  3. jej panel zamówieniasumę liczy cart.js
  4. JS-Cart-Pagegałąź · kontrolka ilości
Scrum master · codzienny stand-up · tablica zadań
22 lis – 1 gru 2023 · 15 commitów
05

Wyniki

Witryna działa, a repozytorium jest publiczne. To, co napisałem, jest narysowane powyżej, obszar po obszarze, z plikiem, liczbą commitów albo gałęzią przy każdej notce — więc całe to twierdzenie może sprawdzić w historii commitów każdy, kto zechce poświęcić na to minutę.

Nie ma tu żadnej metryki rezultatu i nie będzie. Zespołowy projekt z bootcampu nie ma klienta, ruchu ani usługi w Search Console: nikt nigdy nie miał robić zakupów w tym sklepie, nic nie miało konwertować i nic nie było mierzone po prezentacji. Studium przypadku obdukcje podaje pozycje i wyświetlenia, bo wytworzyła je prawdziwa strona i mogę je co miesiąc sprawdzać. To podaje, co zostało wdrożone, bo to wszystko, co istnieje.

Co da się sprawdzić, jeśli ktoś ma ochotę: gałąź, na której powstawał koszyk, pull request, który go zmergował, commity każdego pliku wymienionego na rysunku oraz tytuły pull requestów, które przy każdym elemencie witryny wskazują osobę.

Ostatnia rzecz, jaka wydarzyła się w tym projekcie, była moja i była mała — poprawka stylu w formularzu koszyka, otwarta po zakończeniu sprintu i zmergowana ponad dwa tygodnie później.

06

Co zrobiłbym inaczej

Wybrałem koszyk, bo zależał od pracy innych bardziej niż cokolwiek innego na tablicy. Przez tę zależność na końcu czekałem.

Samo budowanie poszło dobrze. Ostatnie dni — nie: mieliśmy do przygotowania prezentację, a mojej części nie dało się skończyć, dopóki nie były skończone części, z których korzysta. Byłem scrum masterem. Przez cały czas miałem tablicę przed oczami, widziałem na niej każdą kartę, a i tak na końcu czekałem.

Lekcja nie polega na tym, że wybrałem zły element. Polega na tym, że wybrałem element z największą liczbą zależności, pełniąc jedyną rolę, która mogła ustawić ich kolejność — i traktowałem te dwa fakty tak, jakby nie miały ze sobą nic wspólnego.

Konkretna wersja na następny raz: części, z których korzystała moja strona, były interfejsem, zanim stały się kodem — mogłem spisać ten interfejs pierwszego dnia i zbudować koszyk na jego zaślepce. Wtedy ostatnie dni są integracją, która jest krótka, a nie czekaniem, które nie ma końca.