← indice note Lorenzo Trezza / blog tecnico NO. 01

HolySheet e la distanza tra feature complete e release ready

Portare una app di spartiti verso TestFlight significa rendere affidabile l'intero percorso: ricerca, scelta dell'edizione, importazione e lettura reale.

HolySheet aveva già autenticazione, libreria, setlist, ricerca, PDF, community, abbonamenti e funzioni AI. Sulla carta sembrava un prodotto completo. Su un telefono reale, però, una sola interruzione tra ricerca e lettura basta a renderlo inutilizzabile.

Il lavoro verso TestFlight mi ha costretto a distinguere due traguardi che spesso vengono confusi:

  • feature complete: le funzioni previste esistono nel repository;
  • release ready: il percorso principale è affidabile su dispositivi, account e servizi reali.

La prima condizione si può verificare in gran parte con codice e test. La seconda richiede hardware, configurazioni esterne e una disciplina diversa.

Il prodotto è un loop, non un elenco di schermate

HolySheet serve a trovare, conservare e usare spartiti. Il suo percorso essenziale è breve da descrivere:

cerca → confronta le edizioni → salva → leggi → porta in prova

Ogni freccia nasconde però un cambio di sistema. La ricerca interroga sorgenti differenti; la scelta dipende dalla qualità dei metadati; l’importazione deve sopravvivere a rete e autenticazione; il reader incontra memoria, gesture e rotazione; la pratica deve ritrovare il brano nello stato corretto.

La release non può quindi essere valutata contando le voci del menu. Va verificata attraversando il loop dall’inizio alla fine.

Cercare spartiti significa ricostruire opere ed edizioni

Le fonti musicali non espongono un catalogo uniforme. IMSLP è fondamentale per il repertorio di pubblico dominio, ma una singola opera può includere scansioni, arrangiamenti, parti, edizioni e qualità molto diverse. Altre sorgenti coprono segmenti differenti. La musica moderna introduce inoltre limiti legali e commerciali che non si possono risolvere fingendo che ogni risultato sia scaricabile.

La prima interfaccia mostrava i risultati quasi come elementi indipendenti. Era tecnicamente fedele alle risposte delle sorgenti, ma cognitivamente rumorosa. Il refresh ha spostato l’unità principale dalla singola risorsa all’opera, lasciando poi all’utente la scelta dell’edizione.

Questo cambia il compito dell’interfaccia:

PrimaDopo
Una lista di file similiUn’opera con edizioni confrontabili
Metadati esposti senza gerarchiaInformazioni ordinate per decidere
Download come esito implicitoProvenienza e disponibilità rese esplicite

La normalizzazione non deve cancellare le differenze. Deve renderle leggibili.

Il reader non è “aprire un PDF”

Su desktop un PDF è spesso delegato al browser. In una app mobile per musicisti, il documento è una superficie primaria: deve reagire bene mentre il dispositivo cambia orientamento, la memoria è limitata e le mani non sono sempre libere.

Il reader deve tenere insieme:

  • caricamento progressivo e gestione degli errori;
  • zoom, pan e cambio pagina senza gesture in conflitto;
  • stato del documento e ripresa del punto di lettura;
  • orientamento e dimensioni molto diverse tra telefono e tablet;
  • comportamento coerente tra iOS e Android;
  • passaggio sequenziale tra i brani di una setlist.

Un test automatico può dimostrare che lo stato cambia correttamente. Non può dimostrare da solo che un gesto sia naturale su un iPad o che una pagina complessa rimanga leggibile durante una prova. Per questo il redesign del reader è completo a livello di repository, mentre la validazione finale su dispositivi rimane un gate separato.

Separare stato locale, cloud personale e community

HolySheet combina superfici con aspettative differenti. Una setlist deve restare utilizzabile e reattiva; l’identità deve attraversare sessioni e dispositivi; i contenuti della community richiedono dati condivisi e regole di accesso.

La struttura usa Expo e React Native sul client, TanStack Query per lo stato server, store locali per autenticazione e UI, e Supabase per le parti cloud. Servizi come RevenueCat, notifiche e osservabilità aggiungono ulteriori confini esterni.

Il punto non è accumulare integrazioni, ma decidere chi possiede ogni dato:

  • lo stato effimero dell’interfaccia resta locale;
  • i dati recuperabili dal server seguono cache e invalidazione esplicite;
  • libreria e setlist devono gestire con cura transizioni e migrazioni;
  • community e identità applicano policy lato backend;
  • acquisti e restore vengono confermati dal servizio che ne detiene l’autorità.

Questa separazione riduce i casi in cui l’interfaccia sembra aver salvato qualcosa che il sistema reale non riconosce.

Il gate di rilascio vive anche fuori dal repository

La milestone corrente è repo-complete, release smoke pending. Build, tipi e test automatizzati possono essere verdi mentre restano controlli che nessuna pipeline locale può sostituire.

Verificabile nel repositoryDa verificare nel mondo reale
Typecheck, lint e testLogin Apple e Google su build native
Navigazione e stato delle schermateAcquisto e ripristino RevenueCat
Contratti dei providerLink legali e configurazioni store
Flussi del reader simulatiGesture, rotazione e memoria su device
Logica delle setlistPercorso sequenziale durante una prova
Build di sviluppoSmoke test completo in TestFlight

Chiamare “finita” la release prima di questi controlli produrrebbe una certezza falsa. Il codice è pronto a entrare nel gate; non significa che il gate sia già superato.

Cosa viene dopo

La ricerca deve estendersi verso pop e musica moderna attraverso fonti legittime, senza promettere accessi che il prodotto non può offrire. Android deve raggiungere la stessa affidabilità di iOS nelle superfici critiche. La pratica può evolvere da semplice consultazione a sistema capace di accompagnare brani, obiettivi e progressi.

Prima, però, serve chiudere il ciclo attuale su dispositivi reali. È meno spettacolare di aggiungere una nuova funzione AI, ma è il passaggio che trasforma un insieme di feature in uno strumento che un musicista può davvero portare sul leggio.