Sprint #2 - Pappol/UniBuk GitHub Wiki
Sprint goal
L'obiettivo che ci siamo prefissati in questo secondo sprint è riuscire a creare un prodotto che, pur essendo un MVP per via della UI minimale, sia sostanzialmente completo e stabile nelle sue funzionalità core e, nonostante conservi indubbiamente notevole margine di miglioramento nella UI, dia la possibilità di avere un'esperienza completa nella visualizzazione di libri e contenuti, e aver la possibilità, tramite login, di gestire cancellazione, aggiunta e rimozione di essi.
Sprint Planning
Sprint backlog
Analogamente a quanto scritto nel primo sprint report, alleghiamo qui un link drive allo sprint backlog che abbiamo compilato e corredato di burndown chart: link Si noti che questo Google Sheet contiene una pagina contenente lo sprint backlog #1 e una pagina separata per lo sprint backlog #2; per visualizzare l'uno o l'altro sarà sufficiente selezionare il foglio corrispondente.
Project board
Qui si può trovarey la project board del progetto: link
Sprint
Branching strategy
La strategia di branching è stata cambiata in alcuni aspetti a confronto della prima iterazione. Anziché creare branch diversi per tecnologia utilizzata, come api (branch frontend) e database (branch backend), abbiamo deciso di suddividere i branch per feature, in modo che in ognuno di questi branch fosse possibile lavorare contemporaneamente sia nel frontend o del backend. All'inizio dello sprint abbiamo pensato quale fosse il modo migliore per individuare una feature, e abbiamo capito che una corrispondenza 1 a 1 con le user stories ci avrebbe portati ad avere troppi branch, creando uno squilibro nella grandezza di essi, dato che saremmo andati a fare molti cambiamenti in user stories grosse, e piccoli cambiamenti in user stories più piccole, rendendo la lista di branch confusionaria dal punto di vista di un contributor esterno.
Abbiamo quindi deciso di raggruppare le varie user stories in cluster; questi ultimi sono contengono da una a tre user stories che comprendono feature logicamente collegate.
Cluster:
- search-engine: cerca e filtra risorse
- reviews: visualizzazione, filtraggio e gestione delle domande
- follow: gestione dei follow degli utenti
- save-resources: aggiungi ai preferiti una certa risorsa
- content-linking: upload e gestione contenuti utente
- analytics: visualizzazione analytics per risorsa
- collaboration: gestione dati relativi all'utente
Il risultato ha premiato il maggior lavoro e tempo impiegati in sede di progettazione, dal momento che il lavoro, la gestione e il mantenimento dei branches sono risultati notevolmente più semplici rispetto a quanto non fossero nella prima iterazione, e ci ha risparmiato le confusionarie sedute di merging che avevamo precedentemente affrontato.
Sprint Planning
La gestione del Github project è stata portata avanti in maniera molto simile a quanto avevamo fatto nella prima iterazione. Abbiamo concordato che il raggruppamento di user stories in cluster non fosse adatto alla gestione delle task nel project, e di scegliere la suddivisione delle issues per user story. Abbiamo anche avuto modo di impiegare un’interessante funzionalità di Github, ossia la possibilità di modificare lo stato delle issues inserendo delle specifiche keywords all’interno dei messaggi dei commit. Nonostante sia un dettaglio, poter chiudere delle issue semplicemente aggiungendo “Closes #[numero_issue]” si è rivelato molto comodo, specialmente nell’ottica di migliorare quanto più possibile efficienza e mantenibilità del progetto (si vedano ad esempio questo commit e questo commit).
Team organization
Considerato quanto emerso nella sprint retrospective della prima iterazione, abbiamo deciso di cambiare organizzazione in merito alla compilazione dello sprint backlog: anziché aggiornarlo ogni tre giorni, come avevamo fatto durante nel precedente sprint, abbiamo scelto di utilizzare le prescrizioni classiche di scrum e compilare gli aggiornamenti quotidianamente. Al pari della precedente iterazione, nessun membro del team ha ricoperto il ruolo di scrum master.
Considerate inoltre le inconsistenze che si sono create nel corso della precedente iterazione, abbiamo cercato di migliorare il nostro metodo di assegnazione delle user stories e dei task: abbiamo fatto in modo che ogni membro del gruppo, di volta in volta, scegliesse una user story e ci lavorasse individualmente fino al completamento; successivamente, il lavoro compiuto su ciascuna user story è stato revisionato dall’autore e da un altro membro del team. Questo ci ha aiutato in svariati modi:
- ha permesso di assicurarci che ogni membro del team avesse sempre modo di lavorare a tutte le fasi dello sviluppo, evitando la creazione di figure come potrebbero essere un esperto di backend o un esperto di UI;
- ha permesso ai membri del team di essere più focalizzati nella risoluzione di un certo task, dal momento che abbiamo limitato le situazioni in cui un membro del team si trovasse costretto a passare da una user story all’altra nel caso in cui fosse riscontrato un bug;
- ha permesso, sul lungo andare, di ottenere un codice più pulito e complessivamente di qualità migliore, grazie al continuo cross-checking e scambio di feedback che avevamo.
Test cases
Il Google Sheet in cui abbiamo inserito la descrizione dei test che abbiamo effettuato per il servizio è disponibile a questo link
Backlog grooming
Parlando del product backlog, la modifica più evidente risulta essere la nuova colonna che abbiamo inserito a sinistra della tabella. Questa serve per raggruppare le varie user stories in cluster, secondo i criteri e i motivi che abbiamo già illustrato qui sopra quando abbiamo parlato della strategia di branching che abbiamo deciso di adottare in questo sprint.
Inoltre, a confronto di quanto già avevamo fatto durante la prima iterazione, abbiamo subito provveduto a fornire delle stime più realistiche per i vari task all'interno delle user stories, dal momento che stime che avevamo assegnato nella prima compilazione del product backlog erano fin troppo conservative.
Il risultato si vede soprattutto per quanto concerne lo sviluppo del frontend. A differenza della prima iterazione, durante la quale l’apprendimento del framework ReactJS ha rallentato di molto i tempi di sviluppo e ci ha visti costretti ad aumentare le stime fatte inizialmente dei tempi di sviluppo UI, non abbiamo avuto sorprese notevoli in termini di stime residue. Si nota infatti dallo sprint backlog: non ci sono user story (o suddivisioni di user story) da cui si possa evincere un notevole divario rispetto ai tempi stimati.
Per quando riguarda il completamente di tutte le user story e delle loro funzionalità previste, delle 16 user story che avremmo dovuto completare nel secondo sprint, non siamo riusciti a portare a termine 1 user story, in particolare la user story numero 3. Questa user story infatti richiedeva di fare di permettere a un certo utente di consigliare agli admin di aggiornare il collegamento di una risorsa a una certa università. L'implementazione di questa user story in particolare avrebbe richiesto una differenziazione di un utente normale da un utente di admin, il ché avrebbe richiesto l'aggiunta di login e interfaccia dedicata all'admin, con relativi check di sicurezza per questi metodi (sia UI che API). Questa implementazione avrebbe richiesto un grosso cambiamento dei modelli e delle API che non avevamo previsto all'inizio dello sprint.
Demo #2
L’applicazione è disponibile sulla piattaforma Heroku cliccando sul seguente link, nella sezione README della repository, o anche sulla wiki.
È importante specificare che non la consideriamo ancora come una versione definitiva del processo di sviluppo: come già detto, non abbiamo portato a termine tutte le user story, e in generale crediamo che il servizio abbiamo un ampio margine di miglioramento quanto a interfaccia grafica ed esperienza dell'utente.
Funzionalità permesse
Ecco una breve lista di azioni concesse.
Utente anonimo:
- nella homepage è possibile cercare libri, contenuti e altri utenti
- nella pagina ‘risorse’ è possibile visualizzare l’elenco di tutte le risorse divise per tipologia e filtrarle per una certa Università a cui queste sono connesse; inoltre, è possibile accedere alla pagina dettaglio della risorsa
- nella pagina dettaglio della risorsa è possibile visualizzarne tutti i dettagli, così come visualizzare le recensioni e le domande veloci con relative risposte postate dagli utenti
- inoltre, se la risorsa è un contenuto, è possibile andare direttamente alla pagina dell’autore
- nella pagina signup è possibile inserire i propri dati e registrarsi al servizio
- nella pagina login è possibile inserire le proprie credenziali di accesso
- nella pagina dettaglio utente è possibile visualizzare i dettagli di un utente, in particolare la lista dei contenuti che questi ha caricato
Utente loggato (tutte le funzionalità sopra menzionate ovviamente continuano a essere disponibili):
- nella pagina risorsa è possibile salvare ogni risorsa tra i propri preferiti e accedere a una pagina che li mostra
- nella pagina dettaglio risorsa è possibile aggiungere domande anonime e fornire risposte anonime alle domande
- nella stessa pagina è possibile scrivere una recensione per la risorsa e, se il profilo ha un’università associata, è possibile visualizzare solo le recensioni fatte da utenti che frequentano la stessa università
- inoltre, se la risorsa è un contenuto ed è stato creato con il profilo in cui è stato fatto il login, è possibile modificarne i dettagli
- nella pagina dettaglio del nostro profilo utente, è possibile modificare le nostre credenziali e visualizzare le nostre analytics
Come testare in ambiente di sviluppo
È possibile testare il progetto in ambiente di sviluppo in due modi, con o senza l’utilizzo di Docker.
Per testare utilizzando il setup Docker + Docker-Compose:
- effettuiamo la build delle immagini lanciano
~/docker-compose build
nella root directory del progetto - facciamo partire i container con
~/docker-compose up
- aprire una tab del browser e andare nel link
localhost:3000
Se non si dispone di docker, è comunque possibile avviare l’app in development environment, utilizzando due terminali separati. Bisogna accedere nella root directory del progetto e per avviare le 2 componenti: - backend:
- si prenda il primo e ci si sposti nella cartella backend
cd backend
- si installino le dipendenze con
npm install
- si lanci il server di backend in development environment con
npm run dev
- si prenda il primo e ci si sposti nella cartella backend
- frontend:
- utilizzando il secondo terminale ci si sposti nella directory app
cd app
- si installino le dipendenze con
npm install
- si lanci il dummy server che gestisce il frontend con
npm start
- utilizzando il secondo terminale ci si sposti nella directory app
- dovrebbe aprirsi automaticamente una tab del browser con l’applicazione; se questo non succede, aprire una tab del browser e recarsi in
localhost:3000/
- per lanciare il batch dei test che abbiamo eseguito, si vada in backend e si lanci
npm test
Sprint retrospective
Durante la fase di sprint planning di questa seconda iterazione abbiamo ponderato attentamente quanto emerso durante la retrospective del primo sprint e ci siamo impegnati a implementare tutte le proposte che erano state avanzate, in modo da migliorare la nostra gestione dello scrum.
Ci sono stati infatti numerosi punti in cui il lavoro del team è risultato molto più efficiente rispetto alla prima iterazione. In questo senso è sicuramente notevole il maggior tempo impiegato nella fase preliminare di sprint planning, in cui abbiamo avuto modo di fare una più accurata stima dei tempi e in cui abbiamo deciso di implementare la nuova strategia di branching di cui abbiamo parlato sopra. Quest’ultima in particolare si è rivelata determinante per mantenere le contribuzioni all'interno repository rendendola molto più semplice da mantenere, evitando i merge confusionari che avevamo riscontrato durante la prima iterazione.
Il gruppo si ritiene complessivamente molto soddisfatto di come è stato gestito lo sprint, abbiamo voluto comunque raccogliere dei numerosi piccoli miglioramenti di cui fare tesoro in un ipotetico terzo sprint. Ad esempio abbiamo registrato che, a seguito di merge dei branches dei vari cluster nel default branch e della scrittura dei batch di testing, abbiamo trovato alcuni bugs di cui non abbiamo avuto modo di scoprire prima di fare il merge del branch in cui erano stati introdotti; per risolvere questi bug abbiamo fatto una serie di commit sul branch develop, quando invece sarebbe stato più ordinato isolare i vari bug in categorie e creare dei branches dedicati ad uno specifico hotfix.
Inoltre abbiamo dovuto ancora fare i conti con la grande stratificazione e complessità dello stack tecnologico che compone una web application; un mese di sprint non è stato certamente sufficiente a renderci degli esperti web developers, e purtroppo abbiamo dovuto nuovamente investire molto tempo ad approfondire concetti legati ai framework e alle varie tecnologie, che hanno rallentato lo sviluppo di alcune feature più di quanto ci aspettassimo; questo scoglio continua a essere ben visibile nell’andamento della burndown chart.
Infine abbiamo riscontrato che l’utilizzo di formattatori di codice diversi ha creato dei problemi nella ricerca di bug all'interno di uno specifico commit, rendendo difficile l'individuazione di pezzi di codice aventi problemi, ad esempio è capitato più di qualche volta di rendersi conto che un commit in particolare dava problemi, ma al suo interno ci fossero centinaia di righe cambiate per il formatter e fosse complicato andare a cercare la riga che effettivamente desse problemi. In un ipotetico terzo sprint si potrebbe utilizzare uno formatter in comune risolvendo problemi di questo tipo.