feat(email-templates): seed missing locale translations + post-075 templates
This commit is contained in:
@@ -1,17 +1,27 @@
|
||||
/**
|
||||
* Migration: Auto-fill missing email-template translations for nl / pt /
|
||||
* ru / fr.
|
||||
* ru / fr — plus the en/de rows for templates that were seeded AFTER
|
||||
* migration 075 ran (customer_password_reset from 092, version_update_test
|
||||
* from 087). Those two carry their EN/DE content in the legacy
|
||||
* subject_en/body_html_en/... columns; without a row in
|
||||
* email_template_translations, the admin Templates UI shows them as
|
||||
* empty until an admin clicks save.
|
||||
*
|
||||
* Coverage going in:
|
||||
* - gallery_created / expiration_warning / gallery_expired /
|
||||
* archive_complete already had en/de/nl/pt/ru from migration 075
|
||||
* → this migration adds the missing `fr` row.
|
||||
* - All other templates (admin, customer, backup, restore, version)
|
||||
* had en/de only → this migration adds nl/pt/ru/fr.
|
||||
* - admin_*, backup_*, restore_*, database_backup_*, customer_invitation,
|
||||
* version_update_available had en/de only → this migration adds
|
||||
* nl/pt/ru/fr.
|
||||
* - customer_password_reset + version_update_test had legacy-column
|
||||
* EN/DE only (post-075 inserts) → this migration adds the full
|
||||
* en/de/nl/pt/ru/fr set, sourcing en/de from the legacy columns
|
||||
* when present and falling back to the curated copy below.
|
||||
*
|
||||
* The translations below were generated by an LLM and are flagged in
|
||||
* the PR description as needing native-speaker review before the next
|
||||
* stable release. en / de remain hand-translated and are untouched.
|
||||
* The non-EN/DE translations below were generated by an LLM and are
|
||||
* flagged in the PR description as needing native-speaker review
|
||||
* before the next stable release. en / de remain hand-translated.
|
||||
*
|
||||
* Idempotent: every insert checks (template_id, language) for an
|
||||
* existing row first and skips if present. Safe to re-run.
|
||||
@@ -228,6 +238,69 @@ const TRANSLATIONS = {
|
||||
},
|
||||
},
|
||||
|
||||
// Customer password reset (#354 follow-up). Seeded by migration 092
|
||||
// in the legacy columns with English-only copy (the EN string was
|
||||
// broadcast to every subject_*/body_html_* column to satisfy NOT
|
||||
// NULL on multi-locale schemas). Replacing here with a proper
|
||||
// per-locale set including hand-tuned EN/DE plus AI-generated
|
||||
// nl/pt/ru/fr.
|
||||
customer_password_reset: {
|
||||
en: {
|
||||
subject: 'Reset your customer account password',
|
||||
body_html: `<p>Hello,</p>
|
||||
<p>Your photographer has triggered a password reset for your customer account.</p>
|
||||
<p><a href="{{reset_link}}" class="button">Set a new password</a></p>
|
||||
<p>This link expires on {{expires_at}}.</p>
|
||||
<p>If you didn't expect this, you can ignore the message — your current password keeps working until you click the link.</p>`,
|
||||
body_text: `Reset your customer account password\n\nYour photographer has triggered a password reset for your customer account.\n\nSet a new password: {{reset_link}}\n\nThis link expires on {{expires_at}}.\n\nIf you didn't expect this, you can ignore the message — your current password keeps working until you click the link.`,
|
||||
},
|
||||
de: {
|
||||
subject: 'Passwort für dein Kundenkonto zurücksetzen',
|
||||
body_html: `<p>Hallo,</p>
|
||||
<p>Dein Fotograf hat einen Passwort-Reset für dein Kundenkonto ausgelöst.</p>
|
||||
<p><a href="{{reset_link}}" class="button">Neues Passwort festlegen</a></p>
|
||||
<p>Dieser Link läuft am {{expires_at}} ab.</p>
|
||||
<p>Wenn du diese Anfrage nicht erwartet hast, kannst du diese Nachricht ignorieren — dein aktuelles Passwort funktioniert weiter, bis du den Link anklickst.</p>`,
|
||||
body_text: `Passwort für dein Kundenkonto zurücksetzen\n\nDein Fotograf hat einen Passwort-Reset für dein Kundenkonto ausgelöst.\n\nNeues Passwort festlegen: {{reset_link}}\n\nDieser Link läuft am {{expires_at}} ab.\n\nWenn du diese Anfrage nicht erwartet hast, kannst du diese Nachricht ignorieren — dein aktuelles Passwort funktioniert weiter, bis du den Link anklickst.`,
|
||||
},
|
||||
nl: {
|
||||
subject: 'Wachtwoord van uw klantaccount opnieuw instellen',
|
||||
body_html: `<p>Hallo,</p>
|
||||
<p>Uw fotograaf heeft een wachtwoordreset voor uw klantaccount aangevraagd.</p>
|
||||
<p><a href="{{reset_link}}" class="button">Nieuw wachtwoord instellen</a></p>
|
||||
<p>Deze link verloopt op {{expires_at}}.</p>
|
||||
<p>Heeft u deze aanvraag niet verwacht? U kunt dit bericht negeren — uw huidige wachtwoord blijft werken totdat u op de link klikt.</p>`,
|
||||
body_text: `Wachtwoord opnieuw instellen\n\nUw fotograaf heeft een wachtwoordreset voor uw klantaccount aangevraagd.\n\nNieuw wachtwoord instellen: {{reset_link}}\n\nDeze link verloopt op {{expires_at}}.\n\nHeeft u deze aanvraag niet verwacht? U kunt dit bericht negeren — uw huidige wachtwoord blijft werken totdat u op de link klikt.`,
|
||||
},
|
||||
pt: {
|
||||
subject: 'Redefina a senha da sua conta de cliente',
|
||||
body_html: `<p>Olá,</p>
|
||||
<p>Seu fotógrafo iniciou uma redefinição de senha para sua conta de cliente.</p>
|
||||
<p><a href="{{reset_link}}" class="button">Definir nova senha</a></p>
|
||||
<p>Este link expira em {{expires_at}}.</p>
|
||||
<p>Se você não esperava esta solicitação, pode ignorar a mensagem — sua senha atual continuará funcionando até você clicar no link.</p>`,
|
||||
body_text: `Redefinir senha\n\nSeu fotógrafo iniciou uma redefinição de senha para sua conta de cliente.\n\nDefinir nova senha: {{reset_link}}\n\nEste link expira em {{expires_at}}.\n\nSe você não esperava esta solicitação, pode ignorar a mensagem — sua senha atual continuará funcionando até você clicar no link.`,
|
||||
},
|
||||
ru: {
|
||||
subject: 'Сброс пароля вашей клиентской учётной записи',
|
||||
body_html: `<p>Здравствуйте!</p>
|
||||
<p>Ваш фотограф инициировал сброс пароля для вашей клиентской учётной записи.</p>
|
||||
<p><a href="{{reset_link}}" class="button">Задать новый пароль</a></p>
|
||||
<p>Срок действия ссылки истекает {{expires_at}}.</p>
|
||||
<p>Если вы не ожидали этого письма, можете его проигнорировать — ваш текущий пароль продолжит работать, пока вы не перейдёте по ссылке.</p>`,
|
||||
body_text: `Сброс пароля\n\nВаш фотограф инициировал сброс пароля для вашей клиентской учётной записи.\n\nЗадать новый пароль: {{reset_link}}\n\nСрок действия ссылки истекает {{expires_at}}.\n\nЕсли вы не ожидали этого письма, можете его проигнорировать — ваш текущий пароль продолжит работать, пока вы не перейдёте по ссылке.`,
|
||||
},
|
||||
fr: {
|
||||
subject: 'Réinitialisez le mot de passe de votre compte client',
|
||||
body_html: `<p>Bonjour,</p>
|
||||
<p>Votre photographe a déclenché une réinitialisation de mot de passe pour votre compte client.</p>
|
||||
<p><a href="{{reset_link}}" class="button">Définir un nouveau mot de passe</a></p>
|
||||
<p>Ce lien expire le {{expires_at}}.</p>
|
||||
<p>Si vous n'attendiez pas cette demande, vous pouvez ignorer ce message — votre mot de passe actuel continue de fonctionner jusqu'à ce que vous cliquiez sur le lien.</p>`,
|
||||
body_text: `Réinitialiser le mot de passe\n\nVotre photographe a déclenché une réinitialisation de mot de passe pour votre compte client.\n\nDéfinir un nouveau mot de passe : {{reset_link}}\n\nCe lien expire le {{expires_at}}.\n\nSi vous n'attendiez pas cette demande, vous pouvez ignorer ce message — votre mot de passe actuel continue de fonctionner jusqu'à ce que vous cliquiez sur le lien.`,
|
||||
},
|
||||
},
|
||||
|
||||
// ────────────────────────────────────────────────────────────────
|
||||
// Database backups
|
||||
// ────────────────────────────────────────────────────────────────
|
||||
@@ -560,34 +633,112 @@ const TRANSLATIONS = {
|
||||
},
|
||||
},
|
||||
|
||||
// version_update_test was seeded by migration 087 in the legacy
|
||||
// subject_en / body_html_en / subject_de / body_html_de columns
|
||||
// AFTER migration 075 had already migrated existing rows into
|
||||
// email_template_translations — so this template has zero
|
||||
// translation rows even though the EN/DE content exists. The
|
||||
// Templates admin UI consequently shows it as empty. Seeding the
|
||||
// full set here (mirroring 087's curated EN/DE plus AI-generated
|
||||
// nl/pt/ru/fr) restores the editor.
|
||||
version_update_test: {
|
||||
en: {
|
||||
subject: '[TEST] PicPeak Update Notification — configuration check',
|
||||
body_html: `<h2>This is a test email</h2>
|
||||
<p>You are receiving this message because an administrator clicked
|
||||
<strong>Send Test Email</strong> on the Update Notifications page of your
|
||||
PicPeak installation.</p>
|
||||
<div style="background-color: #f0f8ff; border-left: 4px solid #5C8762; padding: 20px; margin: 20px 0; border-radius: 4px;">
|
||||
<p style="margin: 0;"><strong>Installed version:</strong> {{current_version}}</p>
|
||||
<p style="margin: 10px 0 0 0;"><strong>Channel:</strong> {{channel}}</p>
|
||||
<p style="margin: 10px 0 0 0;"><strong>Recipient address:</strong> {{recipient_email}}</p>
|
||||
</div>
|
||||
<p>If you can read this email, your SMTP configuration and the recipient
|
||||
list are working correctly. When a real new version becomes available,
|
||||
PicPeak will send a separate notification with release notes and update
|
||||
instructions.</p>
|
||||
<p style="color: #666; font-size: 13px; margin-top: 30px;">No action is required.
|
||||
You may safely delete this message.</p>`,
|
||||
body_text: `This is a test email\n\nYou are receiving this message because an administrator clicked "Send Test Email" on the Update Notifications page of your PicPeak installation.\n\nInstalled version: {{current_version}}\nChannel: {{channel}}\nRecipient address: {{recipient_email}}\n\nIf you can read this email, your SMTP configuration and the recipient list are working correctly. When a real new version becomes available, PicPeak will send a separate notification with release notes and update instructions.\n\nNo action is required. You may safely delete this message.`,
|
||||
},
|
||||
de: {
|
||||
subject: '[TEST] PicPeak Update-Benachrichtigung — Konfigurationsprüfung',
|
||||
body_html: `<h2>Dies ist eine Test-E-Mail</h2>
|
||||
<p>Sie erhalten diese Nachricht, weil ein Administrator auf der Seite
|
||||
„Update-Benachrichtigungen" Ihrer PicPeak-Installation auf
|
||||
<strong>Test-E-Mail senden</strong> geklickt hat.</p>
|
||||
<div style="background-color: #f0f8ff; border-left: 4px solid #5C8762; padding: 20px; margin: 20px 0; border-radius: 4px;">
|
||||
<p style="margin: 0;"><strong>Installierte Version:</strong> {{current_version}}</p>
|
||||
<p style="margin: 10px 0 0 0;"><strong>Kanal:</strong> {{channel}}</p>
|
||||
<p style="margin: 10px 0 0 0;"><strong>Empfänger-Adresse:</strong> {{recipient_email}}</p>
|
||||
</div>
|
||||
<p>Wenn Sie diese E-Mail lesen können, funktionieren Ihre SMTP-Konfiguration
|
||||
und die Empfängerliste korrekt. Sobald eine echte neue Version verfügbar
|
||||
ist, sendet PicPeak eine separate Benachrichtigung mit Versionshinweisen
|
||||
und Update-Anweisungen.</p>
|
||||
<p style="color: #666; font-size: 13px; margin-top: 30px;">Es ist keine Aktion
|
||||
erforderlich. Sie können diese Nachricht gefahrlos löschen.</p>`,
|
||||
body_text: `Dies ist eine Test-E-Mail\n\nSie erhalten diese Nachricht, weil ein Administrator auf der Seite „Update-Benachrichtigungen" Ihrer PicPeak-Installation auf „Test-E-Mail senden" geklickt hat.\n\nInstallierte Version: {{current_version}}\nKanal: {{channel}}\nEmpfänger-Adresse: {{recipient_email}}\n\nWenn Sie diese E-Mail lesen können, funktionieren Ihre SMTP-Konfiguration und die Empfängerliste korrekt. Sobald eine echte neue Version verfügbar ist, sendet PicPeak eine separate Benachrichtigung mit Versionshinweisen und Update-Anweisungen.\n\nEs ist keine Aktion erforderlich. Sie können diese Nachricht gefahrlos löschen.`,
|
||||
},
|
||||
nl: {
|
||||
subject: '[Test] PicPeak-update-meldingen werken',
|
||||
body_html: `<h2>Testmelding</h2>
|
||||
<p>Dit is een testmail om te bevestigen dat de PicPeak-update-meldingen correct zijn geconfigureerd.</p>
|
||||
<p>Geen actie vereist.</p>`,
|
||||
body_text: `Testmelding\n\nDit is een testmail om te bevestigen dat de PicPeak-update-meldingen correct zijn geconfigureerd. Geen actie vereist.`,
|
||||
subject: '[TEST] PicPeak-update-melding — configuratiecontrole',
|
||||
body_html: `<h2>Dit is een test-e-mail</h2>
|
||||
<p>U ontvangt dit bericht omdat een beheerder op de pagina
|
||||
"Update-meldingen" van uw PicPeak-installatie op
|
||||
<strong>Test-e-mail verzenden</strong> heeft geklikt.</p>
|
||||
<div style="background-color: #f0f8ff; border-left: 4px solid #5C8762; padding: 20px; margin: 20px 0; border-radius: 4px;">
|
||||
<p style="margin: 0;"><strong>Geïnstalleerde versie:</strong> {{current_version}}</p>
|
||||
<p style="margin: 10px 0 0 0;"><strong>Kanaal:</strong> {{channel}}</p>
|
||||
<p style="margin: 10px 0 0 0;"><strong>Ontvangeradres:</strong> {{recipient_email}}</p>
|
||||
</div>
|
||||
<p>Als u deze e-mail kunt lezen, werken uw SMTP-configuratie en de ontvangerslijst correct. Wanneer er een echte nieuwe versie beschikbaar komt, stuurt PicPeak een aparte melding met release-notities en update-instructies.</p>
|
||||
<p style="color: #666; font-size: 13px; margin-top: 30px;">Geen actie vereist. U kunt dit bericht veilig verwijderen.</p>`,
|
||||
body_text: `Dit is een test-e-mail\n\nU ontvangt dit bericht omdat een beheerder op de pagina "Update-meldingen" van uw PicPeak-installatie op "Test-e-mail verzenden" heeft geklikt.\n\nGeïnstalleerde versie: {{current_version}}\nKanaal: {{channel}}\nOntvangeradres: {{recipient_email}}\n\nAls u deze e-mail kunt lezen, werken uw SMTP-configuratie en de ontvangerslijst correct.\n\nGeen actie vereist.`,
|
||||
},
|
||||
pt: {
|
||||
subject: '[Teste] Notificações de atualização do PicPeak funcionando',
|
||||
body_html: `<h2>Notificação de teste</h2>
|
||||
<p>Este é um e-mail de teste para confirmar que as notificações de atualização do PicPeak estão configuradas corretamente.</p>
|
||||
<p>Nenhuma ação é necessária.</p>`,
|
||||
body_text: `Notificação de teste\n\nEste é um e-mail de teste para confirmar que as notificações de atualização do PicPeak estão configuradas corretamente. Nenhuma ação é necessária.`,
|
||||
subject: '[TESTE] Notificação de atualização do PicPeak — verificação',
|
||||
body_html: `<h2>Este é um e-mail de teste</h2>
|
||||
<p>Você está recebendo esta mensagem porque um administrador clicou em
|
||||
<strong>Enviar e-mail de teste</strong> na página "Notificações de
|
||||
atualização" da sua instalação do PicPeak.</p>
|
||||
<div style="background-color: #f0f8ff; border-left: 4px solid #5C8762; padding: 20px; margin: 20px 0; border-radius: 4px;">
|
||||
<p style="margin: 0;"><strong>Versão instalada:</strong> {{current_version}}</p>
|
||||
<p style="margin: 10px 0 0 0;"><strong>Canal:</strong> {{channel}}</p>
|
||||
<p style="margin: 10px 0 0 0;"><strong>Endereço do destinatário:</strong> {{recipient_email}}</p>
|
||||
</div>
|
||||
<p>Se você consegue ler este e-mail, sua configuração SMTP e a lista de destinatários estão funcionando corretamente. Quando uma nova versão real estiver disponível, o PicPeak enviará uma notificação separada com notas de versão e instruções de atualização.</p>
|
||||
<p style="color: #666; font-size: 13px; margin-top: 30px;">Nenhuma ação é necessária. Você pode excluir esta mensagem com segurança.</p>`,
|
||||
body_text: `Este é um e-mail de teste\n\nVocê está recebendo esta mensagem porque um administrador clicou em "Enviar e-mail de teste" na página "Notificações de atualização" da sua instalação do PicPeak.\n\nVersão instalada: {{current_version}}\nCanal: {{channel}}\nEndereço do destinatário: {{recipient_email}}\n\nSe você consegue ler este e-mail, sua configuração SMTP está funcionando corretamente.\n\nNenhuma ação é necessária.`,
|
||||
},
|
||||
ru: {
|
||||
subject: '[Тест] Уведомления об обновлениях PicPeak работают',
|
||||
body_html: `<h2>Тестовое уведомление</h2>
|
||||
<p>Это тестовое письмо для подтверждения корректной настройки уведомлений об обновлениях PicPeak.</p>
|
||||
<p>Никаких действий не требуется.</p>`,
|
||||
body_text: `Тестовое уведомление\n\nЭто тестовое письмо для подтверждения корректной настройки уведомлений об обновлениях PicPeak. Никаких действий не требуется.`,
|
||||
subject: '[ТЕСТ] Уведомление об обновлениях PicPeak — проверка',
|
||||
body_html: `<h2>Это тестовое письмо</h2>
|
||||
<p>Вы получили это сообщение, потому что администратор нажал
|
||||
<strong>Отправить тестовое письмо</strong> на странице
|
||||
«Уведомления об обновлениях» вашей установки PicPeak.</p>
|
||||
<div style="background-color: #f0f8ff; border-left: 4px solid #5C8762; padding: 20px; margin: 20px 0; border-radius: 4px;">
|
||||
<p style="margin: 0;"><strong>Установленная версия:</strong> {{current_version}}</p>
|
||||
<p style="margin: 10px 0 0 0;"><strong>Канал:</strong> {{channel}}</p>
|
||||
<p style="margin: 10px 0 0 0;"><strong>Адрес получателя:</strong> {{recipient_email}}</p>
|
||||
</div>
|
||||
<p>Если вы видите это письмо, значит ваша конфигурация SMTP и список получателей работают корректно. Когда станет доступна новая версия, PicPeak отправит отдельное уведомление с примечаниями к выпуску и инструкциями по обновлению.</p>
|
||||
<p style="color: #666; font-size: 13px; margin-top: 30px;">Никаких действий не требуется. Можете безопасно удалить это сообщение.</p>`,
|
||||
body_text: `Это тестовое письмо\n\nВы получили это сообщение, потому что администратор нажал «Отправить тестовое письмо» на странице «Уведомления об обновлениях» вашей установки PicPeak.\n\nУстановленная версия: {{current_version}}\nКанал: {{channel}}\nАдрес получателя: {{recipient_email}}\n\nЕсли вы видите это письмо, ваша конфигурация SMTP работает корректно.\n\nНикаких действий не требуется.`,
|
||||
},
|
||||
fr: {
|
||||
subject: '[Test] Les notifications de mise à jour PicPeak fonctionnent',
|
||||
body_html: `<h2>Notification de test</h2>
|
||||
<p>Ceci est un e-mail de test confirmant que les notifications de mise à jour PicPeak sont correctement configurées.</p>
|
||||
<p>Aucune action n'est requise.</p>`,
|
||||
body_text: `Notification de test\n\nCeci est un e-mail de test confirmant que les notifications de mise à jour PicPeak sont correctement configurées. Aucune action n'est requise.`,
|
||||
subject: '[TEST] Notification de mise à jour PicPeak — vérification',
|
||||
body_html: `<h2>Ceci est un e-mail de test</h2>
|
||||
<p>Vous recevez ce message parce qu'un administrateur a cliqué sur
|
||||
<strong>Envoyer un e-mail de test</strong> sur la page « Notifications
|
||||
de mise à jour » de votre installation PicPeak.</p>
|
||||
<div style="background-color: #f0f8ff; border-left: 4px solid #5C8762; padding: 20px; margin: 20px 0; border-radius: 4px;">
|
||||
<p style="margin: 0;"><strong>Version installée :</strong> {{current_version}}</p>
|
||||
<p style="margin: 10px 0 0 0;"><strong>Canal :</strong> {{channel}}</p>
|
||||
<p style="margin: 10px 0 0 0;"><strong>Adresse du destinataire :</strong> {{recipient_email}}</p>
|
||||
</div>
|
||||
<p>Si vous pouvez lire cet e-mail, votre configuration SMTP et la liste des destinataires fonctionnent correctement. Lorsqu'une nouvelle version réelle sera disponible, PicPeak enverra une notification distincte avec les notes de version et les instructions de mise à jour.</p>
|
||||
<p style="color: #666; font-size: 13px; margin-top: 30px;">Aucune action n'est requise. Vous pouvez supprimer ce message en toute sécurité.</p>`,
|
||||
body_text: `Ceci est un e-mail de test\n\nVous recevez ce message parce qu'un administrateur a cliqué sur « Envoyer un e-mail de test » sur la page « Notifications de mise à jour » de votre installation PicPeak.\n\nVersion installée : {{current_version}}\nCanal : {{channel}}\nAdresse du destinataire : {{recipient_email}}\n\nSi vous pouvez lire cet e-mail, votre configuration SMTP fonctionne correctement.\n\nAucune action n'est requise.`,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user