Files
2026-04-21 11:43:31 +02:00

317 lines
8.4 KiB
Markdown

# 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`