modulo 06 di 24 / Ore 0-20
Moduli 1-8 / Checkpoint 20 ore
Regola: uno strumento già in prestito non può essere prestato di nuovo
Evitare doppi prestiti dello stesso strumento distinguendo stato dello strumento e prestiti aperti.
Regola: uno strumento già in prestito non può essere prestato di nuovo
La seconda regola centrale e:
Uno strumento già in prestito non può essere prestato di nuovo.
Sembra identica alla regola sul guasto, ma contiene una difficolta in piu.
Qui non basta guardare una etichetta. Dobbiamo capire il rapporto tra:
- stato dello strumento;
- prestiti aperti;
- operazione di registrazione del prestito.
Obiettivo
Alla fine devi avere:
- una regola che impedisce il doppio prestito;
- uno scenario di violazione;
- una distinzione chiara tra controllo sullo stato e controllo sui prestiti aperti;
- un primo ragionamento su cosa deve fare il caso d’uso.
Il problema
Immagina questi dati:
const strumento = {
id: "s-001",
nome: "Kit sensori",
categoria: "robotica",
stato: "in_prestito",
};
const prestiti = [
{
id: "p-001",
strumentoId: "s-001",
assegnatario: "Sara 3B",
stato: "aperto",
},
];
Se registriamo un nuovo prestito per s-001, creiamo un conflitto:
Lo stesso strumento risulta prestato a due persone.
Il registro perde affidabilita.
Primo controllo: stato dello strumento
Se usiamo StatoStrumento, possiamo scrivere:
export function verificaStrumentoPrestabile(strumento) {
if (strumento.stato !== StatoStrumento.DISPONIBILE) {
throw new Error("STRUMENTO_NON_PRESTABILE");
}
return true;
}
Questa funzione blocca:
- guasto;
- in manutenzione;
- in prestito.
Gia questo impedisce molti doppi prestiti.
Secondo controllo: prestiti aperti
Pero puo esistere un problema di coerenza:
const strumento = {
id: "s-001",
nome: "Kit sensori",
categoria: "robotica",
stato: "disponibile",
};
const prestiti = [
{
id: "p-001",
strumentoId: "s-001",
assegnatario: "Sara 3B",
stato: "aperto",
},
];
Qui lo strumento dice disponibile, ma esiste un prestito aperto.
I dati sono incoerenti.
Per questo il caso d’uso dovra controllare anche i prestiti aperti.
Funzione di dominio sui prestiti
Nel file:
src/domain/prestito.js
possiamo aggiungere:
export function isPrestitoAperto(prestito) {
return prestito.stato === "aperto";
}
export function esistePrestitoApertoPerStrumento(prestiti, strumentoId) {
return prestiti.some(
(prestito) =>
prestito.strumentoId === strumentoId && isPrestitoAperto(prestito)
);
}
Questa funzione non legge localStorage. Riceve dati e risponde.
Regola nel caso d’uso
La regola completa verra coordinata nel caso d’uso:
export function registraPrestito({ strumento, prestiti, datiPrestito }) {
verificaStrumentoPrestabile(strumento);
if (esistePrestitoApertoPerStrumento(prestiti, strumento.id)) {
throw new Error("STRUMENTO_GIA_IN_PRESTITO");
}
const prestito = apriPrestito(datiPrestito);
return {
prestito,
strumento: {
...strumento,
stato: StatoStrumento.IN_PRESTITO,
},
};
}
Nota bene: il caso d’uso coordina dati diversi. Le funzioni di dominio esprimono regole piccole e verificabili.
Scenario 1: stato in prestito
## Scenario
Dato uno strumento con stato in_prestito,
quando provo a registrare un nuovo prestito,
allora il sistema rifiuta l'operazione con STRUMENTO_NON_PRESTABILE.
Scenario 2: prestito aperto incoerente
## Scenario
Dato uno strumento marcato come disponibile,
ma con un prestito aperto collegato,
quando provo a registrare un nuovo prestito,
allora il sistema rifiuta l'operazione con STRUMENTO_GIA_IN_PRESTITO.
Questo scenario e piu avanzato, ma utile. Mostra che non sempre un solo campo basta a proteggere il sistema.
Perche non basta nascondere lo strumento dalla lista
Potremmo dire:
Mostro solo gli strumenti disponibili, cosi l'utente non puo sbagliare.
Va bene per la UI, ma non basta.
La UI puo aiutare, ma la regola deve essere verificata quando l’operazione viene eseguita.
Una lista filtrata non e una protezione architetturale.
Esercizio
Parti da questi dati:
const strumenti = [
{ id: "s-001", nome: "Arduino Uno", stato: "disponibile" },
{ id: "s-002", nome: "Kit sensori", stato: "in_prestito" },
];
const prestiti = [
{ id: "p-001", strumentoId: "s-002", stato: "aperto" },
];
Scrivi:
- quale strumento puo essere prestato;
- quale strumento non puo essere prestato;
- quale errore ti aspetti;
- quale funzione dovrebbe bloccare l’operazione.
Poi aggiungi questo caso:
const strumentoIncoerente = {
id: "s-003",
nome: "Multimetro",
stato: "disponibile",
};
const prestiti = [
{ id: "p-002", strumentoId: "s-003", stato: "aperto" },
];
Che cosa deve succedere?
Cosa produrre
Alla fine della lezione devi avere:
- funzione per riconoscere prestiti aperti;
- scenario sullo stato
in_prestito; - scenario sul prestito aperto gia esistente;
- nota sulla differenza tra stato dello strumento e storico prestiti;
- controllo previsto nel futuro caso d’uso
RegistraPrestito.
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 regola: uno strumento già in prestito non può essere prestato di nuovo, il punto centrale è questo: Il dominio contiene il significato del problema: strumenti, prestiti, stati ammessi e regole che devono valere anche se cambia la UI o il modo in cui salviamo i dati.
Il rischio tipico è confondere un controllo di schermata con una regola del progetto. Se una regola protegge il senso del Registro, deve vivere nel dominio o vicino al caso d’uso. 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.
- Scrivi la regola in linguaggio naturale.
- Trasformala in una funzione o in un metodo con un nome leggibile.
- Verifica almeno un caso valido e un caso non valido.
- Controlla che la regola non sia duplicata nella UI.
- 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 verificaStrumentoPrestabile(strumento) {
if (strumento.stato === "guasto") {
throw new Error("STRUMENTO_GUASTO_NON_PRESTABILE");
}
if (strumento.stato === "in_prestito") {
throw new Error("STRUMENTO_GIA_IN_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:
- so perche il doppio prestito e un problema di dominio;
- controllo lo stato dello strumento;
- controllo anche i prestiti aperti quando serve;
- non mi affido solo alla lista filtrata nella UI;
- so spiegare il ruolo del caso d’uso in questa regola.
Nella prossima lezione lavoriamo sul ciclo di vita del prestito: un prestito chiuso non si chiude due volte.