/** * Add Italian translations for client-facing email templates * * Translates authentication, ticketing, and billing email templates to Italian * for client portal users. */ exports.up = async function(knex) { console.log('Adding Italian email templates...'); // Get notification subtypes const subtypes = await knex('notification_subtypes') .select('id', 'name') .whereIn('name', [ 'email-verification', 'password-reset', 'portal-invitation', 'tenant-recovery', 'no-account-found', 'Ticket Assigned', 'Ticket Created', 'Ticket Updated', 'Ticket Closed', 'Ticket Comment Added', 'Invoice Generated', 'Payment Received', 'Payment Overdue' ]); const getSubtypeId = (name) => { const subtype = subtypes.find(s => s.name === name); if (!subtype) { throw new Error(`Notification subtype '${name}' not found`); } return subtype.id; }; // Insert Italian templates await knex('system_email_templates').insert([ // Authentication templates // NOTE: email-verification template is managed in migration 20251029100000 { name: 'password-reset', language_code: 'it', subject: 'Richiesta di reimpostazione della password', notification_subtype_id: getSubtypeId('password-reset'), html_content: ` Richiesta di reimpostazione della password

Richiesta di reimpostazione della password

Ripristino sicuro della password del tuo account

Ciao {{userName}},

Abbiamo ricevuto una richiesta di reimpostazione della password per l'account associato a {{email}}.

🔐 Verifica di sicurezza dell'account

Richiesta: Poco fa

Email dell'account: {{email}}

Valido per: {{expirationTime}}

Per creare una nuova password per il tuo account, fai clic sul pulsante qui sotto:

Reimposta password

Oppure copia e incolla questo link nel tuo browser:

⚠️ Informazioni di sicurezza importanti

Cosa succede adesso?

  1. Fai clic sul pulsante di reimpostazione oppure usa il link fornito
  2. Crea una password sicura e unica per il tuo account
  3. Verrai autenticato automaticamente dopo il ripristino
  4. Tutte le sessioni esistenti verranno chiuse per sicurezza
  5. Valuta l'attivazione dell'autenticazione a due fattori per maggiore protezione

Hai bisogno di aiuto?

Se riscontri problemi nel reimpostare la password, il nostro team di supporto è a tua disposizione.

Contatta il supporto: {{supportEmail}}

`, text_content: `Richiesta di reimpostazione della password Ciao {{userName}}, Abbiamo ricevuto una richiesta di reimpostazione della password per l'account associato a {{email}}. VERIFICA DI SICUREZZA DELL'ACCOUNT - Richiesta: Poco fa - Email dell'account: {{email}} - Valido per: {{expirationTime}} Per creare una nuova password, visita il seguente link: {{resetLink}} INFORMAZIONI IMPORTANTI: - Questo link scadrà tra {{expirationTime}} - Può essere utilizzato una sola volta - Se non hai richiesto questa operazione, ignora questa email - La tua password non verrà modificata finché non ne imposterai una nuova Cosa succede adesso? 1. Usa il link fornito qui sopra 2. Crea una password sicura e unica 3. Verrai autenticato automaticamente 4. Tutte le sessioni esistenti verranno chiuse 5. Valuta l'autenticazione a due fattori Hai bisogno di aiuto? Contatta il supporto: {{supportEmail}} --- Questa è un'email di sicurezza automatica inviata a {{email}}. © {{currentYear}} {{clientName}}. Tutti i diritti riservati.` }, // NOTE: portal-invitation template is managed in migration 20251029100000 { name: 'tenant-recovery', language_code: 'it', subject: '{{platformName}} - I tuoi link di accesso', notification_subtype_id: getSubtypeId('tenant-recovery'), html_content: `

{{platformName}}

Ciao,

Hai richiesto l'accesso al tuo{{#if isMultiple}}i{{/if}} portale{{#if isMultiple}}i{{/if}} clienti. {{#if isMultiple}}Abbiamo trovato {{tenantCount}} organizzazioni associate al tuo indirizzo email.{{else}}Ecco il tuo link di accesso:{{/if}}

{{tenantLinksHtml}}

Nota di sicurezza: Se non hai richiesto questi link di accesso, puoi ignorare questa email in tutta sicurezza. Il tuo account rimane protetto.

Se hai domande o hai bisogno di assistenza, contatta il team di supporto della tua organizzazione.

© {{currentYear}} {{platformName}}. Tutti i diritti riservati.

Questo è un messaggio automatico. Non rispondere a questa email.

`, text_content: `{{platformName}} - I tuoi link di accesso Ciao, Hai richiesto l'accesso al tuo{{#if isMultiple}}i{{/if}} portale{{#if isMultiple}}i{{/if}} clienti. {{#if isMultiple}}Abbiamo trovato {{tenantCount}} organizzazioni associate al tuo indirizzo email.{{else}}Ecco il tuo link di accesso:{{/if}} I tuoi link di accesso: {{tenantLinksText}} Nota di sicurezza: Se non hai richiesto questi link di accesso, puoi ignorare questa email in tutta sicurezza. Se hai domande o hai bisogno di assistenza, contatta il team di supporto della tua organizzazione. --- © {{currentYear}} {{platformName}}. Tutti i diritti riservati. Questo è un messaggio automatico. Non rispondere a questa email.` }, { name: 'no-account-found', language_code: 'it', subject: '{{platformName}} - Richiesta di accesso', notification_subtype_id: getSubtypeId('no-account-found'), html_content: `

{{platformName}}

Ciao,

Abbiamo ricevuto una richiesta di accesso al portale clienti utilizzando questo indirizzo email.

Se hai un account con noi, dovresti aver ricevuto un'email separata con i tuoi link di accesso.

Se non hai ricevuto l'email di accesso, potrebbe significare:

Hai bisogno di aiuto?

Se ritieni di dover avere accesso a un portale clienti, contatta il team di supporto del tuo provider di servizi per assistenza.

Nota di sicurezza: Se non hai richiesto l'accesso, puoi ignorare questa email in tutta sicurezza.

© {{currentYear}} {{platformName}}. Tutti i diritti riservati.

Questo è un messaggio automatico. Non rispondere a questa email.

`, text_content: `{{platformName}} - Richiesta di accesso Ciao, Abbiamo ricevuto una richiesta di accesso al portale clienti utilizzando questo indirizzo email. Se hai un account con noi, dovresti aver ricevuto un'email separata con i tuoi link di accesso. Se non hai ricevuto l'email di accesso, potrebbe significare: - Questo indirizzo email non è associato a un account del portale clienti - Il tuo account potrebbe essere inattivo - L'email potrebbe essere stata filtrata nella cartella spam Hai bisogno di aiuto? Se ritieni di dover avere accesso a un portale clienti, contatta il team di supporto del tuo provider di servizi per assistenza. Nota di sicurezza: Se non hai richiesto l'accesso, puoi ignorare questa email in tutta sicurezza. --- © {{currentYear}} {{platformName}}. Tutti i diritti riservati. Questo è un messaggio automatico. Non rispondere a questa email.` }, // Ticketing templates { name: 'ticket-assigned', language_code: 'it', subject: 'Ticket assegnato • {{ticket.title}} ({{ticket.priority}})', notification_subtype_id: getSubtypeId('Ticket Assigned'), html_content: `
Ticket assegnato
{{ticket.title}}
{{ticket.metaLine}}

Ti è stato assegnato un ticket per {{ticket.clientName}}. Consulta i dettagli qui sotto e procedi con le attività necessarie.

Ticket #{{ticket.id}}
Priorità {{ticket.priority}}
Stato {{ticket.status}}
Assegnato da {{ticket.assignedBy}}
Assegnato a
{{ticket.assignedToName}}
{{ticket.assignedToEmail}}
Richiedente
{{ticket.requesterName}}
{{ticket.requesterContact}}
Board {{ticket.board}}
Categoria {{ticket.categoryDetails}}
Sede {{ticket.locationSummary}}
Descrizione
{{ticket.description}}
Apri ticket
Powered by Alga PSA • Manteniamo i team allineati
`, text_content: ` Ticket assegnato a te {{ticket.metaLine}} Assegnato da: {{ticket.assignedBy}} Priorità: {{ticket.priority}} Stato: {{ticket.status}} Assegnato a: {{ticket.assignedDetails}} Richiedente: {{ticket.requesterDetails}} Board: {{ticket.board}} Categoria: {{ticket.categoryDetails}} Sede: {{ticket.locationSummary}} Descrizione: {{ticket.description}} Apri ticket: {{ticket.url}} ` }, { name: 'ticket-created', language_code: 'it', subject: 'Nuovo ticket • {{ticket.title}} ({{ticket.priority}})', notification_subtype_id: getSubtypeId('Ticket Created'), html_content: `
Nuovo ticket Creato
{{ticket.title}}
{{ticket.metaLine}}

È stato registrato un nuovo ticket per {{ticket.clientName}}. Consulta il riepilogo qui sotto e utilizza il link per intervenire.

Ticket #{{ticket.id}}
Priorità {{ticket.priority}}
Stato {{ticket.status}}
Creato {{ticket.createdAt}} · {{ticket.createdBy}}
Assegnato a
{{ticket.assignedToName}}
{{ticket.assignedToEmail}}
Richiedente
{{ticket.requesterName}}
{{ticket.requesterContact}}
Board {{ticket.board}}
Categoria {{ticket.categoryDetails}}
Sede {{ticket.locationSummary}}
Descrizione
{{ticket.description}}
Apri ticket
Powered by Alga PSA • Manteniamo i team allineati
`, text_content: ` Nuovo ticket creato per {{ticket.clientName}} {{ticket.metaLine}} Creato: {{ticket.createdAt}} · {{ticket.createdBy}} Priorità: {{ticket.priority}} Stato: {{ticket.status}} Assegnato a: {{ticket.assignedDetails}} Richiedente: {{ticket.requesterDetails}} Board: {{ticket.board}} Categoria: {{ticket.categoryDetails}} Sede: {{ticket.locationSummary}} Descrizione: {{ticket.description}} Apri ticket: {{ticket.url}} ` }, { name: 'ticket-updated', language_code: 'it', subject: 'Ticket aggiornato • {{ticket.title}} ({{ticket.priority}})', notification_subtype_id: getSubtypeId('Ticket Updated'), html_content: `
Ticket aggiornato
{{ticket.title}}
{{ticket.metaLine}}

È stato aggiornato un ticket per {{ticket.clientName}}. Consulta le modifiche riportate qui sotto.

Ticket #{{ticket.id}}
Priorità {{ticket.priority}}
Stato {{ticket.status}}
Aggiornato da {{ticket.updatedBy}}
Assegnato a
{{ticket.assignedToName}}
{{ticket.assignedToEmail}}
Richiedente
{{ticket.requesterName}}
{{ticket.requesterContact}}
Board {{ticket.board}}
Categoria {{ticket.categoryDetails}}
Sede {{ticket.locationSummary}}
Modifiche effettuate
{{ticket.changes}}
Apri ticket
Powered by Alga PSA • Manteniamo i team allineati
`, text_content: ` Ticket aggiornato {{ticket.metaLine}} Aggiornato da: {{ticket.updatedBy}} Priorità: {{ticket.priority}} Stato: {{ticket.status}} Assegnato a: {{ticket.assignedDetails}} Richiedente: {{ticket.requesterDetails}} Board: {{ticket.board}} Categoria: {{ticket.categoryDetails}} Sede: {{ticket.locationSummary}} Modifiche effettuate: {{ticket.changes}} Apri ticket: {{ticket.url}} ` }, { name: 'ticket-closed', language_code: 'it', subject: 'Ticket chiuso • {{ticket.title}}', notification_subtype_id: getSubtypeId('Ticket Closed'), html_content: `
Ticket chiuso
{{ticket.title}}
{{ticket.metaLine}}

È stato risolto e chiuso un ticket per {{ticket.clientName}}. Consulta i dettagli della risoluzione di seguito.

Ticket #{{ticket.id}}
Stato Chiuso
Chiuso da {{ticket.closedBy}}
Assegnato a
{{ticket.assignedToName}}
{{ticket.assignedToEmail}}
Richiedente
{{ticket.requesterName}}
{{ticket.requesterContact}}
Board {{ticket.board}}
Categoria {{ticket.categoryDetails}}
Sede {{ticket.locationSummary}}
Risoluzione
{{ticket.resolution}}
Apri ticket
Powered by Alga PSA • Manteniamo i team allineati
`, text_content: ` Ticket chiuso {{ticket.metaLine}} Chiuso da: {{ticket.closedBy}} Stato: Chiuso Assegnato a: {{ticket.assignedDetails}} Richiedente: {{ticket.requesterDetails}} Board: {{ticket.board}} Categoria: {{ticket.categoryDetails}} Sede: {{ticket.locationSummary}} Risoluzione: {{ticket.resolution}} Apri ticket: {{ticket.url}} ` }, { name: 'ticket-comment-added', language_code: 'it', subject: 'Nuovo commento • {{ticket.title}}', notification_subtype_id: getSubtypeId('Ticket Comment Added'), html_content: `
Nuovo commento aggiunto
{{ticket.title}}
{{ticket.metaLine}}

È stato aggiunto un nuovo commento a un ticket per {{ticket.clientName}}.

Ticket #{{ticket.id}}
Priorità {{ticket.priority}}
Stato {{ticket.status}}
Commento di {{comment.author}}
Assegnato a
{{ticket.assignedToName}}
{{ticket.assignedToEmail}}
Richiedente
{{ticket.requesterName}}
{{ticket.requesterContact}}
Board {{ticket.board}}
Categoria {{ticket.categoryDetails}}
Sede {{ticket.locationSummary}}
💬 Commento
{{comment.content}}
Apri ticket
Powered by Alga PSA • Manteniamo i team allineati
`, text_content: ` Nuovo commento aggiunto {{ticket.metaLine}} Commento di: {{comment.author}} Priorità: {{ticket.priority}} Stato: {{ticket.status}} Assegnato a: {{ticket.assignedDetails}} Richiedente: {{ticket.requesterDetails}} Board: {{ticket.board}} Categoria: {{ticket.categoryDetails}} Sede: {{ticket.locationSummary}} Commento: {{comment.content}} Apri ticket: {{ticket.url}} ` }, // Billing templates { name: 'invoice-generated', language_code: 'it', subject: 'Nuova fattura #{{invoice.number}}', notification_subtype_id: getSubtypeId('Invoice Generated'), html_content: `

Fattura {{invoice.number}}

È stata generata una nuova fattura da esaminare:

Numero fattura: {{invoice.number}}

Importo: {{invoice.amount}}

Data di scadenza: {{invoice.dueDate}}

Cliente: {{invoice.clientName}}

Apri la fattura `, text_content: ` Fattura {{invoice.number}} È stata generata una nuova fattura da esaminare: Numero fattura: {{invoice.number}} Importo: {{invoice.amount}} Data di scadenza: {{invoice.dueDate}} Cliente: {{invoice.clientName}} Apri la fattura: {{invoice.url}} ` }, { name: 'payment-received', language_code: 'it', subject: 'Pagamento ricevuto: Fattura #{{invoice.number}}', notification_subtype_id: getSubtypeId('Payment Received'), html_content: `

Pagamento ricevuto

È stato ricevuto il pagamento della fattura #{{invoice.number}}:

Numero fattura: {{invoice.number}}

Importo pagato: {{invoice.amountPaid}}

Data del pagamento: {{invoice.paymentDate}}

Metodo di pagamento: {{invoice.paymentMethod}}

Apri la fattura `, text_content: ` Pagamento ricevuto È stato ricevuto il pagamento della fattura #{{invoice.number}}: Numero fattura: {{invoice.number}} Importo pagato: {{invoice.amountPaid}} Data del pagamento: {{invoice.paymentDate}} Metodo di pagamento: {{invoice.paymentMethod}} Apri la fattura: {{invoice.url}} ` }, { name: 'payment-overdue', language_code: 'it', subject: 'Pagamento in ritardo: Fattura #{{invoice.number}}', notification_subtype_id: getSubtypeId('Payment Overdue'), html_content: `

Pagamento in ritardo

Il pagamento della fattura #{{invoice.number}} è in ritardo:

Numero fattura: {{invoice.number}}

Importo dovuto: {{invoice.amountDue}}

Data di scadenza: {{invoice.dueDate}}

Giorni di ritardo: {{invoice.daysOverdue}}

Apri la fattura `, text_content: ` Pagamento in ritardo Il pagamento della fattura #{{invoice.number}} è in ritardo: Numero fattura: {{invoice.number}} Importo dovuto: {{invoice.amountDue}} Data di scadenza: {{invoice.dueDate}} Giorni di ritardo: {{invoice.daysOverdue}} Apri la fattura: {{invoice.url}} ` } ]).onConflict(['name', 'language_code']).merge({ subject: knex.raw('excluded.subject'), html_content: knex.raw('excluded.html_content'), text_content: knex.raw('excluded.text_content'), notification_subtype_id: knex.raw('excluded.notification_subtype_id') }); console.log('✓ Italian email templates added (auth + notifications)'); }; exports.down = async function(knex) { // Remove Italian email templates // NOTE: email-verification and portal-invitation are NOT removed as they're managed by other migrations await knex('system_email_templates') .where({ language_code: 'it' }) .whereIn('name', [ 'password-reset', 'tenant-recovery', 'no-account-found', 'ticket-assigned', 'ticket-created', 'ticket-updated', 'ticket-closed', 'ticket-comment-added', 'invoice-generated', 'payment-received', 'payment-overdue' ]) .del(); console.log('Italian email templates removed'); };