#!/usr/bin/env node /** * Run: node patch-i18n-admin-health.mjs * Adds health/spend keys to all 4 message files. * Run from the pieced-portal root. */ import { readFileSync, writeFileSync } from "fs"; const newKeys = { en: { health: "Health", serviceHealth: "Service Health", vllmDescription: "GPU inference engine", litellmDescription: "LLM proxy & spend tracking", tenantOverview: "Tenant Overview", spendOverview: "Spend Overview", globalSpend: "Global Spend (CHF)", activeTenants: "Active Tenants", tenantsWithSpend: "tenants with recorded spend", refresh: "Refresh", healthUnavailable: "Health data unavailable.", loadingHealth: "Loading health data…", statusHealthy: "Healthy", statusDown: "Down", spendChf: "Spend (CHF)", }, de: { health: "Status", serviceHealth: "Dienststatus", vllmDescription: "GPU-Inferenz-Engine", litellmDescription: "LLM-Proxy & Kostenerfassung", tenantOverview: "Mandanten-Übersicht", spendOverview: "Kostenübersicht", globalSpend: "Gesamtkosten (CHF)", activeTenants: "Aktive Mandanten", tenantsWithSpend: "Mandanten mit erfassten Kosten", refresh: "Aktualisieren", healthUnavailable: "Statusdaten nicht verfügbar.", loadingHealth: "Statusdaten werden geladen…", statusHealthy: "OK", statusDown: "Ausgefallen", spendChf: "Kosten (CHF)", }, fr: { health: "Santé", serviceHealth: "Santé des services", vllmDescription: "Moteur d'inférence GPU", litellmDescription: "Proxy LLM & suivi des coûts", tenantOverview: "Aperçu des locataires", spendOverview: "Aperçu des coûts", globalSpend: "Coûts globaux (CHF)", activeTenants: "Locataires actifs", tenantsWithSpend: "locataires avec dépenses enregistrées", refresh: "Actualiser", healthUnavailable: "Données de santé indisponibles.", loadingHealth: "Chargement des données de santé…", statusHealthy: "OK", statusDown: "Hors service", spendChf: "Coûts (CHF)", }, it: { health: "Stato", serviceHealth: "Stato dei servizi", vllmDescription: "Motore di inferenza GPU", litellmDescription: "Proxy LLM & monitoraggio costi", tenantOverview: "Panoramica tenant", spendOverview: "Panoramica costi", globalSpend: "Costi globali (CHF)", activeTenants: "Tenant attivi", tenantsWithSpend: "tenant con spese registrate", refresh: "Aggiorna", healthUnavailable: "Dati di stato non disponibili.", loadingHealth: "Caricamento dati di stato…", statusHealthy: "OK", statusDown: "Non disponibile", spendChf: "Costi (CHF)", }, }; for (const [lang, keys] of Object.entries(newKeys)) { const path = `src/messages/${lang}.json`; const json = JSON.parse(readFileSync(path, "utf8")); Object.assign(json.admin, keys); writeFileSync(path, JSON.stringify(json, null, 2) + "\n"); console.log(`Patched ${path} — added ${Object.keys(keys).length} keys`); }