modulo 07 di 24 / Ore 0-20
Moduli 1-8 / Checkpoint 20 ore
RegistraPrestito: leggere, verificare, modificare, salvare
Costruire il caso d'uso RegistraPrestito coordinando archivio, dominio, creazione del prestito e aggiornamento dello strumento.
RegistraPrestito: leggere, verificare, modificare, salvare
RegistraPrestito e il caso d’uso piu importante della prima parte del corso.
Perche contiene quasi tutto:
- lettura da archivio;
- verifica di regole;
- creazione di un nuovo oggetto;
- modifica dello stato dello strumento;
- salvataggio di piu dati;
- gestione di errori comprensibili.
Se questo caso d’uso e chiaro, la struttura del corso inizia a prendere forma.
Obiettivo
Alla fine devi avere un caso d’uso che:
- riceve
strumentoId,assegnatarioe data; - trova lo strumento;
- verifica che possa essere prestato;
- controlla che non esista gia un prestito aperto;
- crea il prestito;
- cambia lo stato dello strumento in
in_prestito; - salva prestito e strumento;
- restituisce un risultato.
Il comando
const comando = {
prestitoId: "p-001",
strumentoId: "s-001",
assegnatario: "Luca 3A",
apertoIl: "2026-05-09",
};
La UI puo costruire questo comando da un form.
Il caso d’uso non deve leggere il form.
Dipendenze minime
Per registrare un prestito servono:
- archivio strumenti;
- archivio prestiti;
- funzioni del dominio.
Esempio:
export function creaRegistraPrestito({
archivioStrumenti,
archivioPrestiti,
}) {
return function registraPrestito(comando) {
// operazione
};
}
Questa forma rende chiaro che il caso d’uso non crea da solo gli archivi.
Li riceve.
Passo 1: trovare lo strumento
const strumento = archivioStrumenti.trovaPerId(comando.strumentoId);
if (!strumento) {
throw new Error("STRUMENTO_NON_TROVATO");
}
Questo e coordinamento applicativo.
Il caso d’uso deve recuperare cio che serve all’operazione.
Passo 2: verificare se lo strumento e prestabile
verificaStrumentoPrestabile(strumento);
Questa e una regola del dominio.
Il caso d’uso non riscrive:
if (strumento.stato === "guasto") ...
if (strumento.stato === "in_manutenzione") ...
Chiama il dominio.
Passo 3: controllare prestiti aperti
const prestiti = archivioPrestiti.tutti();
if (esistePrestitoApertoPerStrumento(prestiti, strumento.id)) {
throw new Error("STRUMENTO_GIA_IN_PRESTITO");
}
Questo protegge da dati incoerenti.
Anche se lo strumento risulta disponibile, un prestito aperto collegato e un segnale da bloccare.
Passo 4: creare il prestito
const prestito = apriPrestito({
id: comando.prestitoId,
strumentoId: strumento.id,
assegnatario: comando.assegnatario,
apertoIl: comando.apertoIl,
});
La funzione apriPrestito appartiene al dominio.
Controlla che il prestito abbia dati minimi validi.
Passo 5: aggiornare lo strumento
const strumentoAggiornato = {
...strumento,
stato: StatoStrumento.IN_PRESTITO,
};
Questo cambio rappresenta una conseguenza dell’operazione.
Piu avanti potremmo spostarlo in una funzione di dominio:
segnaComeInPrestito(strumento)
Per ora va bene tenerlo leggibile, purche non sia nella UI.
Passo 6: salvare
archivioPrestiti.salva(prestito);
archivioStrumenti.salva(strumentoAggiornato);
Il caso d’uso coordina il salvataggio.
L’archivio decide come salvare.
Con archivio in memoria, salva in array.
Con localStorage, salvera nel browser.
Il caso d’uso deve cambiare il meno possibile.
Implementazione completa
import { StatoStrumento } from "../domain/statoStrumento.js";
import { verificaStrumentoPrestabile } from "../domain/strumento.js";
import {
apriPrestito,
esistePrestitoApertoPerStrumento,
} from "../domain/prestito.js";
export function creaRegistraPrestito({
archivioStrumenti,
archivioPrestiti,
}) {
return function registraPrestito(comando) {
const strumento = archivioStrumenti.trovaPerId(comando.strumentoId);
if (!strumento) {
throw new Error("STRUMENTO_NON_TROVATO");
}
verificaStrumentoPrestabile(strumento);
const prestiti = archivioPrestiti.tutti();
if (esistePrestitoApertoPerStrumento(prestiti, strumento.id)) {
throw new Error("STRUMENTO_GIA_IN_PRESTITO");
}
const prestito = apriPrestito({
id: comando.prestitoId,
strumentoId: strumento.id,
assegnatario: comando.assegnatario,
apertoIl: comando.apertoIl,
});
const strumentoAggiornato = {
...strumento,
stato: StatoStrumento.IN_PRESTITO,
};
archivioPrestiti.salva(prestito);
archivioStrumenti.salva(strumentoAggiornato);
return {
prestito,
strumento: strumentoAggiornato,
};
};
}
Scenari fondamentali
Scrivi almeno questi:
## Scenario valido
Dato uno strumento disponibile,
quando registro un prestito,
allora viene creato un prestito aperto e lo strumento diventa in_prestito.
## Strumento non trovato
Dato un id inesistente,
quando registro un prestito,
allora ottengo STRUMENTO_NON_TROVATO.
## Strumento non prestabile
Dato uno strumento guasto,
quando registro un prestito,
allora ottengo STRUMENTO_NON_PRESTABILE.
## Prestito gia aperto
Dato uno strumento con un prestito aperto collegato,
quando registro un nuovo prestito,
allora ottengo STRUMENTO_GIA_IN_PRESTITO.
Esercizio
Disegna il flusso su carta:
comando
-> trova strumento
-> verifica regole
-> crea prestito
-> aggiorna strumento
-> salva
-> restituisce risultato
Poi scrivi accanto a ogni passaggio il livello coinvolto:
Application
Domain
Infrastructure
Cosa produrre
Alla fine della lezione devi avere:
- file
src/application/registraPrestito.js; - caso d’uso
RegistraPrestito; - almeno quattro scenari;
- controllo sullo strumento non trovato;
- controllo sulle regole di prestabilita;
- salvataggio di prestito e strumento;
- nessun riferimento alla UI.
Spiegazione guidata per studiare
Questa lezione va studiata su due piani. Il primo è il comportamento visibile del Registro del laboratorio: che cosa vede o fa l’utente quando registra uno strumento, cerca un dispositivo, apre un prestito o segnala un guasto. Il secondo è il confine architetturale: dove deve stare il codice che rende possibile quel comportamento.
Per registraPrestito: leggere, verificare, modificare, salvare, il punto centrale è questo: Un caso d’uso coordina un’operazione completa: riceve un comando, legge ciò che serve, applica regole, salva il risultato e restituisce un esito.
Il rischio tipico è far diventare il caso d’uso una seconda UI o un secondo database. Deve coordinare, non mostrare HTML e non conoscere dettagli tecnici di salvataggio. Per evitarlo, non partire dal file che hai già aperto nell’editor. Parti dalla domanda: “quale responsabilità sto modificando?”. Se la risposta riguarda una regola del laboratorio, guarda il dominio. Se riguarda una sequenza di operazioni, guarda i casi d’uso. Se riguarda salvataggio, file, localStorage, API o database, guarda l’infrastruttura. Se riguarda input, pulsanti, form e messaggi, guarda la Presentation.
Il tempo è sufficiente per alternare spiegazione, modifica guidata e revisione. Alla fine della lezione lo studente non deve ricordare una definizione a memoria: deve saper indicare un punto del progetto, spiegare perché quel codice sta lì e mostrare una verifica del comportamento.
Passo per passo nel progetto
- Rileggi il titolo della lezione e riscrivilo come domanda pratica. Per esempio: “dove deve stare questa regola?”, “chi deve salvare questo dato?”, “come verifico questo errore?”.
- Apri solo i file necessari. Se devi toccare più di tre file, fermati e scrivi prima una mini-mappa.
- Definisci input e output del caso d’uso.
- Leggi i dati attraverso un archivio o una dipendenza esplicita.
- Chiama le regole del dominio.
- Salva il risultato senza sapere come funziona la persistenza concreta.
- Aggiorna una nota breve nel README o negli appunti se hai cambiato un confine del progetto.
Esempio da leggere lentamente
Questo esempio serve a ragionare, non a incollare codice senza capire:
function registraPrestito(comando, archivioStrumenti, archivioPrestiti) {
const strumento = archivioStrumenti.trovaPerId(comando.strumentoId);
verificaStrumentoPrestabile(strumento);
const prestito = apriPrestito(strumento.id, comando.nomePersona);
archivioPrestiti.salva(prestito);
archivioStrumenti.salva({ ...strumento, stato: "in_prestito" });
return prestito;
}
Leggilo chiedendoti che cosa cambierebbe se domani sostituissimo la pagina web con una CLI, oppure localStorage con un’API. Se l’esempio continua ad avere senso senza riscrivere tutto, il confine è probabilmente buono. Se invece un dettaglio tecnico si propaga in molti file, il progetto sta tornando fragile.
Prova di comprensione
Prima di chiudere la lezione, rispondi per iscritto a queste domande:
- Qual è la responsabilità principale trattata in questa lezione?
- In quale livello del progetto dovrebbe stare?
- Quale errore faresti se cercassi la soluzione più veloce?
- Quale piccolo test, controllo manuale o esempio dimostra che hai capito?
- Che cosa deve restare facile da cambiare dopo questa lezione?
Una risposta accettabile non deve essere lunga. Deve però usare parole concrete del Registro: strumento, prestito, stato, archivio, caso d’uso, messaggio, test.
Controllo finale
La lezione e completata quando puoi rispondere si:
RegistraPrestitocoordina una operazione completa;- le regole restano nel dominio;
- il caso d’uso usa archivi invece di leggere dati globali a caso;
- lo strumento cambia stato dopo il prestito;
- il caso d’uso e testabile senza pagina web.
Nella prossima lezione completiamo il ciclo: ChiudiPrestito.