#!/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 — un’analisi 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(); }