pd-diario

byANTONIO FRANCESCO PALA

voglio fare un'app web html js che mim consenta ogni ora con allarme di scrivere come mi sento fisicamente. una sorta di diario che alla fine della giornata o di un intervallo di tempo mi elabori un report

Landing
Landing

Comments (0)

No comments yet. Be the first!

System Requirements

System Requirements Document for pd-diario

1. Introduction

pd-diario è una web app in HTML e JavaScript che aiuta una persona a tenere un diario del proprio stato fisico. Ogni ora l'app invia un allarme: quando arriva, l'utente scrive come si sente fisicamente. Le annotazioni si accumulano in un diario consultabile e, alla fine della giornata o di un intervallo di tempo scelto, l'app elabora un report delle annotazioni raccolte.

Il pubblico è una singola persona che vuole osservare con regolarità e senza attrito come si sente il proprio corpo nel corso della giornata: un'abitudine personale e privata, non uno strumento clinico né condiviso.

Success Criteria

  • L'utente riceve un allarme ogni ora e, quando arriva, riesce a registrare come si sente fisicamente in pochi istanti.
  • Ogni annotazione registrata resta nel diario privato dell'utente e può essere riletta.
  • Alla fine della giornata o di un intervallo di tempo scelto, l'utente ottiene un report elaborato dalle proprie annotazioni.
  • Il diario resta privato: solo l'utente che lo possiede può riaprirlo dopo aver verificato la propria identità.
Page 1 of 18

2. System Overview

pd-diario è una web app HTML/JavaScript con un backend condiviso che conserva le annotazioni e genera i report. L'unico attore umano è il Diario utente, che registra lo stato fisico a ogni allarme orario e legge il report a fine giornata o su un intervallo.

Il flusso corrente è: la Landing spiega cosa fa l'app; l'utente crea un account e verifica l'identità per aprire il diario privato (Login); concede il permesso di notifica per ricevere l'allarme orario; a ogni allarme la pagina Check-in gli permette di scrivere come si sente fisicamente; le annotazioni salvate sono consultabili nella pagina Diario; la pagina Report permette di scegliere la fine della giornata o un intervallo di tempo e mostra il report elaborato.

L'elaborazione del report è affidata a un modello linguistico tramite il gateway LiteLLM del backend. I dati applicativi risiedono in MariaDB; PostgreSQL serve esclusivamente LiteLLM.

Removed from scope

  • Nessun concetto è stato rimosso dalla richiesta dell'utente.
Page 2 of 18

2a. Product Interpretation and Delivery Boundary

L'app è di proprietà dell'applicazione: l'identità dell'utente è gestita dall'app, perché il diario è uno stato privato e durevole che deve restare legato alla persona corretta e deve poter essere riaperto in sessioni successive. La Landing e la Login sono raggiungibili senza autenticazione; Check-in, Diario e Report richiedono l'accesso. Il permesso di notifica del browser è la condizione per ricevere l'allarme orario.

Il lavoro di generazione del report avviene nel backend tramite LiteLLM; l'utente interagisce con la pagina Report per scegliere l'intervallo e leggere il risultato. Non sono previste condivisione del diario, funzioni cliniche, integrazioni con dispositivi medici o funzionalità social: restano fuori dal perimetro corrente.

2c. Page Content and Component Coverage

Landing

  • Informazione/stato: cosa fa l'app, a chi serve, come funziona il ciclo allarme orario → annotazione → diario → report; stato anonimo.
  • Azioni primarie: avviare la creazione dell'account; passare alla Login per chi ha già un account.
  • Azioni di supporto: leggere la spiegazione del funzionamento.
  • Entità di dominio: nessuna entità persistita; solo contenuto esplicativo.
  • Responsabilità dei componenti: hero con titolo VT323 e banda ink con cinque icone pixel degli stati fisici; sezione "come funziona" in pannelli outlined; invito all'accesso.
  • Stati: caricamento (scheletro dei pannelli), vuoto (non applicabile), successo (contenuto completo), errore (messaggio con retry se il contenuto non si carica), recupero (link diretto alla Login).
Page 3 of 18

Login

  • Informazione/stato: accesso anonimo alla verifica dell'identità; distinzione tra primo utilizzo (creazione account) e ritorno (verifica).
  • Azioni primarie: creare un account; verificare l'identità di un utente che ritorna.
  • Azioni di supporto: tornare alla Landing.
  • Entità di dominio: account utente (identificativo, credenziali/verifica).
  • Responsabilità dei componenti: form di creazione account; form di verifica per il ritorno; messaggi di errore inline.
  • Stati: caricamento (invio in corso), vuoto (campi non compilati), successo (accesso al diario privato), errore (credenziali non valide o account già esistente), recupero (correzione dei campi e nuovo invio).
Page 4 of 18

Check-in

  • Informazione/stato: allarme orario attivo; ora corrente in VT323; stato di permesso notifica; annotazione in corso.
  • Azioni primarie: scrivere come si sente fisicamente; salvare l'annotazione.
  • Azioni di supporto: concedere il permesso di notifica; selezionare un'icona pixel dello stato fisico.
  • Entità di dominio: annotazione (ora, testo, eventuale stato fisico selezionato, riferimento all'utente).
  • Responsabilità dei componenti: badge allarme con blink breve; orologio VT323 che avanza a frame; riga ledger con tile outlined e icona pixel; campo di testo; pulsante di salvataggio.
  • Stati: caricamento (recupero dell'allarme corrente), vuoto (nessuna annotazione ancora scritta), successo (annotazione salvata e confermata), errore (salvataggio non riuscito con retry), recupero (bozza mantenuta finché il salvataggio non riesce).

Diario

  • Informazione/stato: elenco delle annotazioni salvate, ordinate come ledger orario con icona, ora e nota.
  • Azioni primarie: consultare le annotazioni.
  • Azioni di supporto: passare al Report; tornare al Check-in.
  • Entità di dominio: annotazioni dell'utente autenticato.
  • Responsabilità dei componenti: righe ledger outlined; icone pixel degli stati; indicazione dell'ora.
  • Stati: caricamento (elenco in caricamento), vuoto (nessuna annotazione ancora registrata, con invito al primo check-in), successo (elenco completo), errore (caricamento fallito con retry), recupero (ricaricamento).
Page 5 of 18

Report

  • Informazione/stato: selettore tra fine giornata e intervallo di tempo; report elaborato dalle annotazioni; stato di generazione.
  • Azioni primarie: scegliere fine giornata o intervallo; generare e leggere il report.
  • Azioni di supporto: tornare al Diario.
  • Entità di dominio: report (intervallo, contenuto elaborato, riferimento alle annotazioni usate).
  • Responsabilità dei componenti: selettore intervallo; barre del report come blocchi pixel impilati; area di testo del report.
  • Stati: caricamento (generazione in corso), vuoto (nessuna annotazione nell'intervallo scelto), successo (report mostrato), errore (generazione fallita con retry), recupero (modifica dell'intervallo e nuovo tentativo).
Page 6 of 18

3. Functional Requirements

FR-1 — Web app HTML/JavaScript (explicit) As a Diario utente I should use pd-diario as a web app built in HTML and JavaScript, so that I can access it from a browser.

  • Trigger: apertura dell'app nel browser.
  • Risultato osservabile: l'interfaccia dell'app è servita e utilizzabile in HTML/JavaScript.
  • Accesso: la Landing è pubblica; le pagine protette richiedono l'accesso.
  • Fallimento/recupero: se l'app non si carica, l'utente ricarica la pagina.

FR-2 — Allarme ogni ora (explicit) As a Diario utente I should receive an alarm every hour, so that I am prompted to record how I feel physically.

  • Trigger: trascorrere di un'ora.
  • Risultato osservabile: l'allarme orario viene inviato e il badge dell'allarme si attiva con un blink breve.
  • Accesso: richiede login e permesso di notifica concesso.
  • Fallimento/recupero: se il permesso di notifica non è concesso, l'utente lo concede dalla pagina Check-in; l'allarme non viene ricevuto finché il permesso manca.
  • Continuazione: l'utente passa al Check-in per scrivere l'annotazione.
Page 7 of 18

FR-3 — Scrittura dello stato fisico a ogni allarme (explicit) As a Diario utente I should write how I feel physically when the hourly alarm arrives, so that each hour is recorded.

  • Trigger: arrivo dell'allarme orario.
  • Input: testo libero sullo stato fisico; eventuale icona pixel dello stato.
  • Risultato osservabile: l'annotazione viene salvata e confermata.
  • Accesso: login richiesto.
  • Fallimento/recupero: se il salvataggio fallisce, la bozza resta e l'utente riprova.

FR-4 — Diario delle annotazioni (explicit) As a Diario utente I should see my annotations collected as a diary, so that I can review what I recorded.

  • Trigger: apertura della pagina Diario.
  • Risultato osservabile: elenco delle annotazioni salvate con ora, icona e nota.
  • Accesso: login richiesto; l'utente vede solo le proprie annotazioni.
  • Fallimento/recupero: caricamento fallito → retry; nessuna annotazione → stato vuoto con invito al check-in.
Page 8 of 18

FR-5 — Report a fine giornata o su intervallo (explicit) As a Diario utente I should have the app elaborate a report of my annotations at the end of the day or for a time interval, so that I can read a summary of how I felt.

  • Trigger: scelta di "fine giornata" o di un intervallo di tempo e richiesta di generazione.
  • Risultato osservabile: report elaborato dalle annotazioni dell'intervallo, mostrato con barre a blocchi pixel.
  • Accesso: login richiesto.
  • Fallimento/recupero: nessuna annotazione nell'intervallo → stato vuoto; generazione fallita → messaggio con retry e possibilità di cambiare intervallo.

FR-6 — Creazione account (required_inference) As a Diario utente I should create an account to start, so that my diary is private and bound to me.

  • Trigger: primo utilizzo dalla Landing.
  • Risultato osservabile: account creato e accesso al diario privato.
  • Accesso: la Login è raggiungibile senza autenticazione.
  • Fallimento/recupero: dati non validi o account già esistente → errore inline e correzione.

FR-7 — Verifica dell'identità al ritorno (required_inference) As a Diario utente I should verify my identity to reopen my private diary, so that only I can access my annotations.

  • Trigger: ritorno dell'utente sulla Login.
  • Risultato osservabile: sessione autenticata e accesso a Check-in, Diario e Report.
  • Fallimento/recupero: credenziali non valide → errore e nuovo tentativo.
Page 9 of 18

FR-8 — Permesso di notifica per l'allarme orario (required_inference) As a Diario utente I should grant notification permission to receive the hourly alarm, so that the alarm can reach me.

  • Trigger: accesso al Check-in senza permesso concesso.
  • Risultato osservabile: permesso concesso e allarme orario attivo.
  • Fallimento/recupero: permesso negato → l'app resta utilizzabile ma l'allarme non arriva; l'utente può concederlo in seguito.

4. User Personas

Diario utente

  • Contesto di prodotto: una persona che vuole osservare il proprio stato fisico nel corso della giornata con un'abitudine oraria leggera e privata. Usa l'app da browser, in HTML/JavaScript, e tiene il diario solo per sé.
  • Obiettivo primario: registrare come si sente fisicamente a ogni allarme orario e leggere un report delle proprie annotazioni a fine giornata o su un intervallo scelto.
  • Responsabilità distinte: creare l'account e verificare l'identità al ritorno; concedere il permesso di notifica; scrivere l'annotazione quando arriva l'allarme; consultare il diario; scegliere l'intervallo e leggere il report.
  • Input e decisioni: testo dello stato fisico, eventuale icona pixel dello stato; scelta tra fine giornata e intervallo di tempo.
  • Interazioni con altri partecipanti: nessun altro attore umano; il backend conserva le annotazioni e LiteLLM elabora il report.
  • Successo osservabile: ogni ora registrata compare nel diario e il report riflette le annotazioni dell'intervallo scelto.
Page 10 of 18

5. Core User Flows

Flusso A — Primo utilizzo e creazione account

  1. Il Diario utente apre la Landing e legge cosa fa l'app e come funziona il ciclo allarme → annotazione → diario → report.
  2. Seleziona l'invito ad avviare la creazione dell'account e arriva alla Login.
  3. Compila i dati di creazione account e invia.
  4. In caso di dati non validi o account già esistente, vede un errore inline e corregge i campi.
  5. Al successo, l'account è creato e l'utente accede al diario privato.

Flusso B — Ritorno e verifica dell'identità

  1. Il Diario utente apre la Login.
  2. Inserisce le proprie credenziali e invia la verifica.
  3. In caso di credenziali non valide, vede un errore e riprova.
  4. Al successo, la sessione è autenticata e l'utente può aprire Check-in, Diario e Report.

Flusso C — Concessione del permesso di notifica

  1. Il Diario utente accede al Check-in.
  2. Se il permesso di notifica non è concesso, l'app lo richiede.
  3. L'utente concede il permesso: l'allarme orario diventa attivo.
  4. Se nega, l'app resta utilizzabile ma l'allarme non arriva; può concedere il permesso in seguito.
Page 11 of 18

Flusso D — Check-in orario

  1. Trascorsa un'ora, l'allarme arriva al Diario utente e il badge dell'allarme si attiva con un blink breve.
  2. L'utente apre il Check-in; l'orologio VT323 mostra l'ora corrente.
  3. Scrive come si sente fisicamente e, se vuole, seleziona l'icona pixel dello stato.
  4. Salva l'annotazione: riceve conferma del salvataggio.
  5. Se il salvataggio fallisce, la bozza resta e l'utente riprova.

Flusso E — Consultazione del diario

  1. Il Diario utente apre il Diario.
  2. Vede le annotazioni salvate come righe ledger con icona, ora e nota.
  3. Se non ci sono annotazioni, vede lo stato vuoto con l'invito al primo check-in.
  4. Se il caricamento fallisce, riprova.

Flusso F — Report di fine giornata o su intervallo

  1. Il Diario utente apre il Report.
  2. Sceglie "fine giornata" oppure un intervallo di tempo.
  3. Richiede la generazione: il backend elabora le annotazioni dell'intervallo tramite LiteLLM.
  4. Legge il report mostrato con barre a blocchi pixel.
  5. Se non ci sono annotazioni nell'intervallo, vede lo stato vuoto; se la generazione fallisce, vede un errore, riprova o cambia intervallo.
Page 12 of 18

6. Visuals Colors and Theme

Direzione creativa: Charming clarity after Susan Kare — un diario orario del corpo, privato e personale, che deve risultare calmo, amichevole e affidabile, non clinico.

Palette (light mode)

RuoloHexUso
Background#F4F0E6Terreno carta caldo, ~70% della superficie
Surface#FFFDF7Pannelli outlined
Text#1F1F1DTesto ink
Primary#1F1F1DRiempimento primario, ~20%
Accent#E4572ESolo allarme e ora attiva
Muted#7A7468Testi secondari

Tipografia

  • Heading: VT323 — display pixel in mixed case, grande e stretto, per numeri, ore e titoli brevi.
  • Body: Work Sans.
  • Scala: modulare 1.25 — 64/40/28/20/16; heading da 40px su mobile a 64px su desktop, con clamp() per restare interi nel viewport.
Page 13 of 18

Forma e spaziatura

  • Contorni ink spessi 2px; raggi 12px; tile icona quadrati; pittogrammi pixel per ogni stato fisico.
  • Ritmo di spaziatura regolare su una singola colonna centrata di pannelli outlined su carta.

Immagini

Solo icone pixel per testa, schiena, energia, stomaco e umore. Nessuna fotografia: i simboli portano tutta la voce visiva.

Da evitare

Grafici a gradiente morbido; pulsanti a pillola arrotondati con ombre morbide; hero fotografiche; accenti blu o indigo; divisori a filo sottile.

7. Signature Design Concept

La Landing è un foglio di carta a tutta larghezza: un titolo VT323 gigante impilato a sinistra sopra una banda ink solida. Sulla banda, una fila di cinque icone pixel degli stati fisici (testa, schiena, energia, stomaco, umore) in arancione accent si accende al passaggio del mouse. Sotto, il ciclo spiegato in pannelli outlined con contorni 2px. Il concetto ricompone solo contenuto accettato — spiegazione, invito all'accesso — e non introduce nuove azioni.

Page 14 of 18

8. Interaction Model & Motion Direction

Interaction Model: Animated Motion Tempo: restrained Hero Dimensionality: flat

Landing Hero Motion Brief

  • Soggetto focale: la banda ink con le cinque icone pixel degli stati fisici in accent orange.
  • Tesi input → trasformazione → risultato: hover su un'icona → l'icona si accende a frame → l'utente riconosce lo stato fisico che potrà registrare nel check-in.
  • Vocabolario di movimento: easing a scatti frame-by-frame per icone e numeri; blink breve sul badge dell'allarme; nessun rimbalzo morbido.
  • Primo frame composto: titolo VT323 impilato a sinistra, banda ink a tutta larghezza, cinque icone pixel allineate in arancione.
  • Stato reduced-motion: icone statiche, tutte visibili e leggibili, nessun blink; layout invariato.
Page 15 of 18

9. Non-Functional Requirements

  • NFR-1 — Privacy del diario (required_inference): le annotazioni e i report sono accessibili solo all'utente autenticato che li possiede; Check-in, Diario e Report richiedono login.
  • NFR-2 — Persistenza durevole (explicit, planning scope): annotazioni, account e report sono conservati in modo durevole in MariaDB, separata da PostgreSQL usato da LiteLLM.
  • NFR-3 — Affidabilità del salvataggio (required_inference): un salvataggio fallito non perde la bozza e consente il retry.
  • NFR-4 — Leggibilità responsive (explicit, design constraints): titoli, etichette, numeri, testi delle card e controlli restano interi nel viewport e nel contenitore a 375px, 768px e 1280px, con wrapping o clamp(); nessun elemento li copre.
  • NFR-5 — Accessibilità del movimento (explicit, design constraints): con prefers-reduced-motion è fornita una disposizione statica utilizzabile.
  • NFR-6 — Elaborazione del report (explicit, planning scope): la generazione del report usa un modello linguistico tramite il gateway LiteLLM del backend.
Page 16 of 18

10. Tech Stack

  • Frontend: React (applicazione UI), con la resa HTML/JavaScript richiesta dall'utente.
  • Backend: FastAPI condiviso per le API applicative e i moduli di dominio (annotazioni, account, report).
  • Database applicativo: MariaDB per i dati di proprietà dell'applicazione.
  • Gateway modelli: LiteLLM per le chiamate del backend ai provider di modello.
  • Database del gateway: PostgreSQL a supporto di LiteLLM, separato dallo storage applicativo.
  • Orchestrazione: docker-compose con i servizi backend, database, frontend, litellm, postgres.

11. Assumptions and Constraints

  • L'app è una web app HTML/JavaScript accessibile da browser; non sono richieste app native.
  • L'identità è di proprietà dell'applicazione: l'utente crea un account al primo utilizzo e verifica l'identità al ritorno.
  • L'allarme orario dipende dal permesso di notifica del browser concesso dall'utente.
  • Il report è elaborato dal backend tramite LiteLLM sulle annotazioni dell'intervallo scelto.
  • Non sono previste condivisione del diario, funzioni cliniche, integrazioni con dispositivi medici o funzionalità social.
  • [Default — not specified by user] La cadenza dell'allarme è esattamente oraria; non sono specificati orari di silenzio.
Page 17 of 18

12. Glossary

  • Allarme orario: notifica inviata ogni ora che invita l'utente a scrivere come si sente fisicamente.
  • Annotazione: testo (ed eventuale icona pixel di stato) che l'utente registra a un check-in.
  • Check-in: momento in cui l'utente, raggiunto dall'allarme, scrive il proprio stato fisico.
  • Diario: raccolta delle annotazioni salvate dell'utente.
  • Report: elaborazione delle annotazioni a fine giornata o su un intervallo di tempo scelto.
  • Intervallo di tempo: periodo scelto dall'utente su cui elaborare il report.
  • LiteLLM: gateway del backend per le chiamate ai provider di modello usato per generare il report.
Page 18 of 18
Live
Landing design preview
Landing: Read how it works
Login: Start account creation
Login: 1. Submit account details
Login: 2. Correct invalid fields
Login: 1. Verify returning identity
Login: 2. Retry invalid credentials
Check-in: 1. Grant notification permission
Check-in: 2. Defer permission grant
Check-in: 1. Write physical state
Check-in: 2. Select state icon
Check-in: 3. Save annotation
Check-in: 4. Retry failed save
Diario: 5. Review saved annotations
Diario: 6. Retry failed load
Diario: 7. Follow first check-in invite
Report: Choose end of day
Report: Choose time interval
Report: 1. Generate report
Report: Read pixel block report
Report: 2. Adjust interval after empty
Report: 3. Retry failed generation
Live
Landing design preview
Landing: Read how it works
Login: Start account creation
Login: 1. Submit account details
Login: 2. Correct invalid fields
Login: 1. Verify returning identity
Login: 2. Retry invalid credentials
Check-in: 1. Grant notification permission
Check-in: 2. Defer permission grant
Check-in: 1. Write physical state
Check-in: 2. Select state icon
Check-in: 3. Save annotation
Check-in: 4. Retry failed save
Diario: 5. Review saved annotations
Diario: 6. Retry failed load
Diario: 7. Follow first check-in invite
Report: Choose end of day
Report: Choose time interval
Report: 1. Generate report
Report: Read pixel block report
Report: 2. Adjust interval after empty
Report: 3. Retry failed generation