Struttura: il sito esistente si sposta sotto apps/sito

Primo passo della separazione sito / piattaforme decisa da Adriano il 03/09:
due applicazioni autosufficienti, senza workspace di root, cosi' che ognuna
resti un progetto Astro completo ed estraibile.

Qui non cambia niente del codice: solo la radice. I pattern del .gitignore
che avevano una barra erano ancorati alla radice e dopo lo spostamento non
avrebbero piu' coperto niente (data/*.db*, uploads/*): resi validi a
qualunque profondita'.

Suite: 45 file, 347 test verdi prima e dopo lo spostamento.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EndnceRA5WnA6rvA5iV9WL
This commit is contained in:
AdrianoDev
2026-09-03 11:05:54 +00:00
parent c03edccd8e
commit 510d7ca4ec
551 changed files with 4 additions and 4 deletions
+86
View File
@@ -0,0 +1,86 @@
#!/usr/bin/env node
/**
* Porta nel database i testi decisi dal cliente il 17/08/2026 (MODIFICHE_PER_SITO.pdf).
*
* Perché serve uno script e non basta il deploy: i testi mostrati dal sito vivono in
* `content_blocks`, e `resolveContent` legge **prima** il database e solo dopo il seed nel
* codice. Un tag già presente in tabella continua quindi a mostrare il vecchio valore anche
* dopo che il seed è stato aggiornato — in produzione sono 19 righe.
*
* Perché una tantum e non una migrazione all'avvio: una riscrittura a ogni restart
* rimetterebbe le mani su testi che il cliente può cambiare dal pannello. Qui si passa una
* volta, si guarda cosa è cambiato, e poi quei testi tornano suoi.
*
* Uso: node scripts/testi-17-agosto.mjs [percorso.db] [--dry-run]
*/
import Database from 'better-sqlite3';
/**
* "Small Group" diventa "Personalized Training Group", **con gli articoli giusti**.
*
* Una sostituzione meccanica produrrebbe "Lo Personalized Training Group" e "gli
* personalized training group": le due frasi che portano un articolo si correggono per
* intero, prima. Il resto è la sostituzione del nome, che resta capitalizzato come nome
* proprio anche dove prima era minuscolo ("in formula small group" → "in formula
* Personalized Training Group").
*
* Idempotente: al secondo giro non c'è più niente da sostituire.
*/
export function rinominaSmallGroup(value) {
return value
.replace(/\bLo Small Group\b/g, 'Il Personalized Training Group')
.replace(/\bgli small groups?\b/gi, 'i Personalized Training Group')
.replace(/\bsmall groups?\b/gi, 'Personalized Training Group');
}
/**
* I testi riscritti per intero, tag per tag: il cliente ne ha dettato il contenuto nuovo,
* quindi non c'è una parola da sostituire ma una frase da rimpiazzare.
*
* Sono solo i tag che in produzione esistono già con il valore vecchio. Quelli nuovi (la
* sezione «Check-up Avanzato», gli eventi, la pagina di scelta) non stanno in tabella e li
* serve il seed dal codice, senza bisogno di scriverli qui.
*/
export const TESTI = {
'service.profilazione.title': 'Check-up',
'service.profilazione.subtitle': 'Base e avanzato',
'service.profilazione.excerpt':
'Il Check-up Base fotografa la tua condizione di partenza e rappresenta il punto di inizio del metodo InsanityLab. Attraverso la profilazione e la valutazione fisica definiamo lo stato di salute iniziale e le priorità del percorso.\n\nIl Check-up Avanzato va oltre: con macchinari di ultima generazione misuriamo composizione corporea, parametri vitali, spirometria, HRV — unanalisi completa e scientifica che guida le nostre scelte.',
'footer.services.4.label': 'Check-up',
'services.meta.description':
'I servizi InsanityLab: Personal Training, Class, Coaching, Check-up, Osteopatia e Nutrizione.',
};
/** I cambiamenti da fare, con il prima e il dopo. Non tocca niente. */
export function calcola(db) {
const righe = db.prepare('SELECT tag, value FROM content_blocks').all();
return righe
.map((r) => ({
tag: r.tag,
prima: r.value,
dopo: r.tag in TESTI ? TESTI[r.tag] : rinominaSmallGroup(r.value),
}))
.filter((c) => c.prima !== c.dopo);
}
export function applica(db, { dryRun = false } = {}) {
const cambi = calcola(db);
if (!dryRun && cambi.length) {
const upd = db.prepare(
"UPDATE content_blocks SET value = ?, updated_at = datetime('now'), updated_by = 'testi-17-agosto' WHERE tag = ?",
);
db.transaction(() => { for (const c of cambi) upd.run(c.dopo, c.tag); })();
}
return cambi;
}
if (import.meta.url === `file://${process.argv[1]}`) {
const args = process.argv.slice(2);
const dryRun = args.includes('--dry-run');
const path = args.find((a) => !a.startsWith('--')) ?? process.env.DB_PATH ?? 'data/insanitylab.db';
const db = new Database(path);
const cambi = applica(db, { dryRun });
for (const c of cambi) console.log(`${c.tag}\n - ${c.prima}\n + ${c.dopo}\n`);
console.log(`${cambi.length} contenuti ${dryRun ? 'da aggiornare (dry-run, niente scritto)' : 'aggiornati'} in ${path}`);
db.close();
}