# Giampy Dog Service ## Cos'è questo progetto Questo repository contiene il sito di **Giampy Dog Service**, sviluppato con **SvelteKit**. Il progetto ha due parti principali: - **sito pubblico**: landing page con contenuti, immagini, testimonianze, mappa e form contatti - **area admin**: pannello interno per modificare testi, SEO, immagini, testimonianze, notifiche, richieste ricevute e utenti amministratori Non usa un database esterno: i dati vengono salvati in file JSON dentro la cartella `data/`. ## Linguaggi e tecnologie usate - **TypeScript**: logica server, validazioni, storage, autenticazione - **Svelte 5 / SvelteKit**: rendering delle pagine, routing e form actions - **CSS**: stile globale del sito e del pannello admin - **Node.js**: runtime server-side - **Vite**: build e sviluppo locale - **Leaflet**: mappa caricata lato client nella home page Dipendenze principali dichiarate in `package.json`: - `@sveltejs/kit` - `svelte` - `typescript` - `vite` - `@sveltejs/adapter-node` - `leaflet` - `@fortawesome/fontawesome-free` ## Come funziona il codice ### 1. Avvio globale Il punto importante è [`src/hooks.server.ts`](../src/hooks.server.ts). Qui succedono due cose: - viene creato automaticamente un admin di default se non esiste ancora - viene controllata la sessione per proteggere tutte le route `/admin` Se non esistono utenti admin, al boot viene creato: - username: `admin` - password: `changeme` oppure vengono usate le variabili ambiente: - `ADMIN_USERNAME` - `ADMIN_PASSWORD` ### 2. Sito pubblico La home è composta principalmente da: - [`src/routes/+page.svelte`](../src/routes/+page.svelte) - [`src/routes/+page.server.ts`](../src/routes/+page.server.ts) Il file server: - carica i contenuti con `getContent()` - gestisce l'action del form contatti - salva le richieste in `data/submissions.json` - crea una notifica in `data/notifications.json` Il file Svelte: - legge i testi e le immagini dal contenuto caricato dal server - costruisce tutte le sezioni della landing page - carica **Leaflet** solo nel browser tramite `onMount` - mostra la mappa di Sassari ### 3. Gestione contenuti La logica dei contenuti è centralizzata in: - [`src/lib/server/content.ts`](../src/lib/server/content.ts) - [`src/lib/content/defaults.ts`](../src/lib/content/defaults.ts) `defaults.ts` definisce: - tutti gli slot di testo modificabili - le immagini di default - le testimonianze iniziali - i valori SEO iniziali `content.ts` invece: - legge `data/content.json` - unisce i dati salvati con i valori di default - espone funzioni per aggiornare copy, immagini, SEO e testimonianze Questo significa che il progetto funziona anche senza `content.json`: se il file manca, usa i default. ### 4. Persistenza dati Il salvataggio su disco è gestito da [`src/lib/server/storage.ts`](../src/lib/server/storage.ts). Il meccanismo è semplice: - legge i file JSON dalla cartella `data/` - se un file non esiste, usa un fallback - quando scrive, salva prima su un file temporaneo e poi fa `rename`, riducendo il rischio di corruzione File dati attesi: - `data/content.json` - `data/submissions.json` - `data/notifications.json` - `data/admin.json` - `data/sessions.json` ### 5. Autenticazione admin La logica è in [`src/lib/server/auth.ts`](../src/lib/server/auth.ts). Funziona così: - gli admin sono salvati in `data/admin.json` - le password non sono in chiaro: vengono hashate con `scrypt` - le sessioni sono salvate in `data/sessions.json` - il cookie di sessione è `gds_admin` Operazioni supportate: - login - logout - creazione admin - eliminazione admin - cambio password ### 6. Area admin Le route admin si trovano in `src/routes/admin/`. Sezioni principali: - `copy/`: modifica testi e SEO - `images/`: upload o reset immagini - `testimonials/`: CRUD testimonianze - `submissions/`: elenco ed eliminazione contatti ricevuti - `notifications/`: lettura e gestione notifiche - `users/`: gestione amministratori - `login/` e `logout/`: autenticazione Il layout server admin in [`src/routes/admin/+layout.server.ts`](../src/routes/admin/+layout.server.ts) calcola anche: - numero richieste ricevute - numero notifiche non lette ### 7. SEO e GEO score Il progetto contiene una logica semplice di scoring in [`src/lib/seo.ts`](../src/lib/seo.ts). Analizza i testi per stimare: - leggibilità - presenza keyword primarie - punteggio SEO - punteggio GEO Quando i testi o i dati SEO vengono modificati da admin, il sistema confronta il punteggio prima/dopo. Se c'è un calo rilevante, genera una notifica. ## Struttura pratica del repository ```text src/ lib/ content/ defaults.ts # configurazione contenuti iniziali server/ auth.ts # login, sessioni, admin content.ts # lettura/scrittura contenuti notifications.ts # notifiche admin storage.ts # persistenza JSON su disco submissions.ts # richieste dal form health.ts # calcolo score SEO/GEO seo.ts # analisi testi routes/ +page.svelte # sito pubblico +page.server.ts # load + action form contatti admin/ # pannello amministrativo static/ img/ # immagini statiche data/ # dati runtime salvati su file ``` ## Come eseguire il progetto Installazione dipendenze: ```bash npm install ``` Avvio in sviluppo: ```bash npm run dev ``` Build produzione: ```bash npm run build ``` Preview della build: ```bash npm run preview ``` Controllo TypeScript/Svelte: ```bash npm run check ``` ## Se vuoi modificarlo, cosa devi fare ### Cambiare testi del sito Hai due strade: - usare il pannello `/admin/copy` - modificare i default in [`src/lib/content/defaults.ts`](../src/lib/content/defaults.ts) Regola importante: se cambi solo `defaults.ts`, i contenuti già salvati in `data/content.json` continuano ad avere priorità. ### Aggiungere una nuova sezione alla home Passi consigliati: 1. aggiungi i nuovi slot testuali in `src/lib/content/defaults.ts` 2. se servono immagini, aggiungi un nuovo image slot nello stesso file 3. usa quei valori in `src/routes/+page.svelte` 4. se la sezione deve essere modificabile da admin, assicurati che legga dagli stessi slot ### Modificare il comportamento del form contatti Devi intervenire in [`src/routes/+page.server.ts`](../src/routes/+page.server.ts). Qui puoi: - aggiungere campi - cambiare validazioni - cambiare il formato salvato in `submissions.json` - aggiungere invii email o integrazioni esterne Se aggiungi nuovi campi, aggiorna anche: - il form in `src/routes/+page.svelte` - il tipo `Submission` in [`src/lib/server/submissions.ts`](../src/lib/server/submissions.ts) ### Modificare login o utenti admin Lavora in: - [`src/lib/server/auth.ts`](../src/lib/server/auth.ts) - [`src/routes/admin/login/+page.server.ts`](../src/routes/admin/login/+page.server.ts) - [`src/routes/admin/users/+page.server.ts`](../src/routes/admin/users/+page.server.ts) Se vuoi maggiore sicurezza, i miglioramenti più sensati sono: - rate limit sul login - scadenza sessioni più aggressiva - rotazione sessioni al login - storage su database invece che file JSON ### Cambiare immagini o upload Controlla: - [`src/routes/admin/images/+page.server.ts`](../src/routes/admin/images/+page.server.ts) - [`src/routes/admin/testimonials/+page.server.ts`](../src/routes/admin/testimonials/+page.server.ts) Qui trovi: - tipi MIME ammessi - limiti dimensione file - percorso upload `static/img/uploads` ### Modificare i punteggi SEO/GEO Intervieni in [`src/lib/seo.ts`](../src/lib/seo.ts). Se cambi le regole di scoring, verifica anche: - [`src/lib/server/health.ts`](../src/lib/server/health.ts) - [`src/routes/admin/copy/+page.server.ts`](../src/routes/admin/copy/+page.server.ts) ## Limiti attuali del progetto - non c'è un database: tutto è su file JSON - non c'è un sistema di migrazione dati - la concorrenza multi-istanza non è gestita - gli upload finiscono su filesystem locale - l'admin di default viene creato automaticamente se mancano utenti Per un deploy piccolo o singola istanza va bene. Per un ambiente più strutturato conviene spostare dati, sessioni e upload su servizi dedicati. ## Nota importante In `package.json` è presente lo script: ```json "seed": "node scripts/seed.mjs" ``` ma nel repository attuale la cartella `scripts/` non esiste. Quindi: - o va aggiunto davvero il file `scripts/seed.mjs` - oppure lo script va rimosso da `package.json`