i18n: backend-localized lookups, suggestions, and static data (10 languages)
Backend CI / Test (push) Has been cancelled
Backend CI / Contract Tests (push) Has been cancelled
Backend CI / Lint (push) Has been cancelled
Backend CI / Secret Scanning (push) Has been cancelled
Backend CI / Build (push) Has been cancelled

- suggestion_service: fix scorer (stringList unmarshal accepts scalar|array;
  anchor scoring on base universal score so bool matches no longer tie); add
  localizeReasons for human-readable, Accept-Language-localized match reasons
- lookup_i18n: localize lookup display names, home-profile options, document
  types/categories via internal/i18n
- static_data_handler: per-locale seeded-data response (display_name, home
  profile options, document types/categories) with per-locale cache + ETag
- settings_handler: invalidate per-locale seeded-data cache on lookup change
  instead of pre-warming a single non-localized blob
- cache_service: per-locale seeded-data keys + ETag
- DTOs: add DisplayName fields (task/residence/contractor)
- translations: add suggestion.reason.* and lookup.* keys across all 10 langs
- cmd/api: extract startup helpers + tests

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Trey T
2026-06-04 20:54:54 -05:00
parent 25897e913e
commit 12de5a230a
23 changed files with 1671 additions and 703 deletions
+95 -39
View File
@@ -25,7 +25,6 @@
"error.google_signin_not_configured": "El inicio de sesion con Google no esta configurado",
"error.google_signin_failed": "Error en el inicio de sesion con Google",
"error.invalid_google_token": "Token de identidad de Google no valido",
"error.invalid_task_id": "ID de tarea no valido",
"error.invalid_residence_id": "ID de propiedad no valido",
"error.invalid_contractor_id": "ID de contratista no valido",
@@ -34,7 +33,6 @@
"error.invalid_user_id": "ID de usuario no valido",
"error.invalid_notification_id": "ID de notificacion no valido",
"error.invalid_device_id": "ID de dispositivo no valido",
"error.task_not_found": "Tarea no encontrada",
"error.residence_not_found": "Propiedad no encontrada",
"error.contractor_not_found": "Contratista no encontrado",
@@ -43,7 +41,6 @@
"error.user_not_found": "Usuario no encontrado",
"error.share_code_invalid": "Codigo de compartir no valido",
"error.share_code_expired": "El codigo de compartir ha expirado",
"error.task_access_denied": "No tienes acceso a esta tarea",
"error.residence_access_denied": "No tienes acceso a esta propiedad",
"error.contractor_access_denied": "No tienes acceso a este contratista",
@@ -52,10 +49,8 @@
"error.cannot_remove_owner": "No se puede eliminar al propietario de la propiedad",
"error.user_already_member": "El usuario ya es miembro de esta propiedad",
"error.properties_limit_reached": "Has alcanzado el numero maximo de propiedades para tu suscripcion",
"error.task_already_cancelled": "La tarea ya esta cancelada",
"error.task_already_archived": "La tarea ya esta archivada",
"error.failed_to_parse_form": "Error al analizar el formulario",
"error.task_id_required": "Se requiere task_id",
"error.invalid_task_id_value": "task_id no valido",
@@ -64,14 +59,12 @@
"error.invalid_residence_id_value": "residence_id no valido",
"error.title_required": "Se requiere el titulo",
"error.failed_to_upload_file": "Error al subir el archivo",
"message.logged_out": "Sesion cerrada correctamente",
"message.email_verified": "Correo electronico verificado correctamente",
"message.verification_email_sent": "Correo de verificacion enviado",
"message.password_reset_email_sent": "Si existe una cuenta con ese correo electronico, se ha enviado un codigo de restablecimiento de contrasena.",
"message.reset_code_verified": "Codigo verificado correctamente",
"message.password_reset_success": "Contrasena restablecida correctamente. Por favor, inicia sesion con tu nueva contrasena.",
"message.task_deleted": "Tarea eliminada correctamente",
"message.task_in_progress": "Tarea marcada como en progreso",
"message.task_cancelled": "Tarea cancelada",
@@ -79,46 +72,35 @@
"message.task_archived": "Tarea archivada",
"message.task_unarchived": "Tarea desarchivada",
"message.completion_deleted": "Finalizacion eliminada correctamente",
"message.residence_deleted": "Propiedad eliminada correctamente",
"message.user_removed": "Usuario eliminado de la propiedad",
"message.tasks_report_generated": "Informe de tareas generado correctamente",
"message.tasks_report_sent": "Informe de tareas generado y enviado a {{.Email}}",
"message.tasks_report_email_failed": "Informe de tareas generado pero no se pudo enviar el correo",
"message.contractor_deleted": "Contratista eliminado correctamente",
"message.document_deleted": "Documento eliminado correctamente",
"message.document_activated": "Documento activado",
"message.document_deactivated": "Documento desactivado",
"message.notification_marked_read": "Notificación marcada como leída",
"message.all_notifications_marked_read": "Todas las notificaciones marcadas como leídas",
"message.device_removed": "Dispositivo eliminado",
"message.subscription_upgraded": "Suscripción actualizada correctamente",
"message.subscription_cancelled": "Suscripción cancelada. Mantendrás los beneficios Pro hasta el final de tu período de facturación.",
"message.subscription_restored": "Suscripción restaurada correctamente",
"message.file_deleted": "Archivo eliminado correctamente",
"message.static_data_refreshed": "Datos estáticos actualizados",
"error.notification_not_found": "Notificación no encontrada",
"error.invalid_platform": "Plataforma no válida",
"error.upgrade_trigger_not_found": "Trigger de actualización no encontrado",
"error.receipt_data_required": "Se requiere receipt_data para iOS",
"error.purchase_token_required": "Se requiere purchase_token para Android",
"error.no_file_provided": "No se proporcionó ningún archivo",
"error.failed_to_fetch_residence_types": "Error al obtener los tipos de propiedad",
"error.failed_to_fetch_task_categories": "Error al obtener las categorías de tareas",
"error.failed_to_fetch_task_priorities": "Error al obtener las prioridades de tareas",
"error.failed_to_fetch_task_frequencies": "Error al obtener las frecuencias de tareas",
"error.failed_to_fetch_task_statuses": "Error al obtener los estados de tareas",
"error.failed_to_fetch_contractor_specialties": "Error al obtener las especialidades de contratistas",
"push.task_due_soon.title": "Tarea Proxima a Vencer",
"push.task_due_soon.body": "{{.TaskTitle}} vence {{.DueDate}}",
"push.task_overdue.title": "Tarea Vencida",
@@ -129,44 +111,38 @@
"push.task_assigned.body": "Se te ha asignado {{.TaskTitle}}",
"push.residence_shared.title": "Propiedad Compartida",
"push.residence_shared.body": "{{.UserName}} compartio {{.ResidenceName}} contigo",
"email.welcome.subject": "Bienvenido a honeyDue!",
"email.verification.subject": "Verifica Tu Correo Electronico",
"email.password_reset.subject": "Codigo de Restablecimiento de Contrasena",
"email.tasks_report.subject": "Informe de Tareas para {{.ResidenceName}}",
"lookup.residence_type.house": "Casa",
"lookup.residence_type.apartment": "Apartamento",
"lookup.residence_type.condo": "Condominio",
"lookup.residence_type.townhouse": "Casa Adosada",
"lookup.residence_type.mobile_home": "Casa Movil",
"lookup.residence_type.townhouse": "Casa adosada",
"lookup.residence_type.mobile_home": "Casa vil",
"lookup.residence_type.other": "Otro",
"lookup.task_category.plumbing": "Plomeria",
"lookup.task_category.electrical": "Electricidad",
"lookup.task_category.hvac": "Climatizacion",
"lookup.task_category.appliances": "Electrodomesticos",
"lookup.task_category.plumbing": "Fontanería",
"lookup.task_category.electrical": "Eléctrico",
"lookup.task_category.hvac": "Climatización",
"lookup.task_category.appliances": "Electrodomésticos",
"lookup.task_category.exterior": "Exterior",
"lookup.task_category.interior": "Interior",
"lookup.task_category.landscaping": "Jardineria",
"lookup.task_category.safety": "Seguridad",
"lookup.task_category.cleaning": "Limpieza",
"lookup.task_category.pest_control": "Control de Plagas",
"lookup.task_category.pest_control": "Control de plagas",
"lookup.task_category.seasonal": "Estacional",
"lookup.task_category.other": "Otro",
"lookup.task_priority.low": "Baja",
"lookup.task_priority.medium": "Media",
"lookup.task_priority.high": "Alta",
"lookup.task_priority.urgent": "Urgente",
"lookup.task_status.pending": "Pendiente",
"lookup.task_status.in_progress": "En Progreso",
"lookup.task_status.completed": "Completada",
"lookup.task_status.cancelled": "Cancelada",
"lookup.task_status.archived": "Archivada",
"lookup.task_frequency.once": "Una Vez",
"lookup.task_frequency.once": "Una vez",
"lookup.task_frequency.daily": "Diario",
"lookup.task_frequency.weekly": "Semanal",
"lookup.task_frequency.biweekly": "Cada 2 Semanas",
@@ -174,18 +150,98 @@
"lookup.task_frequency.quarterly": "Trimestral",
"lookup.task_frequency.semiannually": "Cada 6 Meses",
"lookup.task_frequency.annually": "Anual",
"lookup.contractor_specialty.plumber": "Plomero",
"lookup.contractor_specialty.plumber": "Fontanero",
"lookup.contractor_specialty.electrician": "Electricista",
"lookup.contractor_specialty.hvac_technician": "Tecnico de Climatizacion",
"lookup.contractor_specialty.hvac_technician": "Técnico de climatización",
"lookup.contractor_specialty.handyman": "Manitas",
"lookup.contractor_specialty.landscaper": "Jardinero",
"lookup.contractor_specialty.roofer": "Techador",
"lookup.contractor_specialty.painter": "Pintor",
"lookup.contractor_specialty.carpenter": "Carpintero",
"lookup.contractor_specialty.pest_control": "Control de Plagas",
"lookup.contractor_specialty.pest_control": "Control de plagas",
"lookup.contractor_specialty.cleaning": "Limpieza",
"lookup.contractor_specialty.pool_service": "Servicio de Piscina",
"lookup.contractor_specialty.general_contractor": "Contratista General",
"lookup.contractor_specialty.other": "Otro"
"lookup.contractor_specialty.pool_service": "Servicio de piscina",
"lookup.contractor_specialty.general_contractor": "Contratista general",
"lookup.contractor_specialty.other": "Otro",
"suggestion.reason.has_pool": "Tu casa tiene piscina",
"suggestion.reason.has_sprinkler_system": "Tu casa tiene sistema de riego",
"suggestion.reason.has_septic": "Tu casa tiene fosa séptica",
"suggestion.reason.has_fireplace": "Tu casa tiene chimenea",
"suggestion.reason.has_garage": "Tu casa tiene garaje",
"suggestion.reason.has_basement": "Tu casa tiene sótano",
"suggestion.reason.has_attic": "Tu casa tiene ático",
"suggestion.reason.heating_type": "Coincide con tu sistema de calefacción",
"suggestion.reason.cooling_type": "Coincide con tu sistema de refrigeración",
"suggestion.reason.water_heater_type": "Coincide con tu calentador de agua",
"suggestion.reason.roof_type": "Coincide con tu tejado",
"suggestion.reason.exterior_type": "Coincide con tu exterior",
"suggestion.reason.flooring_primary": "Coincide con tu suelo",
"suggestion.reason.landscaping_type": "Coincide con tu jardín",
"suggestion.reason.property_type": "Recomendado para tu tipo de propiedad",
"suggestion.reason.climate_region": "Recomendado para tu clima",
"lookup.residence_type.duplex": "Dúplex",
"lookup.residence_type.vacation_home": "Casa de vacaciones",
"lookup.task_category.general": "General",
"lookup.task_frequency.bi_weekly": "Quincenal",
"lookup.task_frequency.semi_annually": "Semestral",
"lookup.task_frequency.custom": "Personalizado",
"lookup.contractor_specialty.appliance_repair": "Reparación de electrodomésticos",
"lookup.contractor_specialty.cleaner": "Limpiador",
"lookup.contractor_specialty.locksmith": "Cerrajero",
"lookup.home_profile.gas_furnace": "Calefactor de gas",
"lookup.home_profile.electric_furnace": "Calefactor eléctrico",
"lookup.home_profile.heat_pump": "Bomba de calor",
"lookup.home_profile.boiler": "Caldera",
"lookup.home_profile.radiant": "Radiante",
"lookup.home_profile.other": "Otro",
"lookup.home_profile.central_ac": "AC central",
"lookup.home_profile.window_ac": "AC de ventana",
"lookup.home_profile.evaporative": "Evaporativo",
"lookup.home_profile.none": "Ninguno",
"lookup.home_profile.tank_gas": "Tanque (gas)",
"lookup.home_profile.tank_electric": "Tanque (eléctrico)",
"lookup.home_profile.tankless_gas": "Sin tanque (gas)",
"lookup.home_profile.tankless_electric": "Sin tanque (eléctrico)",
"lookup.home_profile.solar": "Solar",
"lookup.home_profile.asphalt_shingle": "Teja asfáltica",
"lookup.home_profile.metal": "Metal",
"lookup.home_profile.tile": "Teja",
"lookup.home_profile.slate": "Pizarra",
"lookup.home_profile.wood_shake": "Tablilla de madera",
"lookup.home_profile.flat": "Plano",
"lookup.home_profile.brick": "Ladrillo",
"lookup.home_profile.vinyl_siding": "Revestimiento de vinilo",
"lookup.home_profile.wood_siding": "Revestimiento de madera",
"lookup.home_profile.stucco": "Estuco",
"lookup.home_profile.stone": "Piedra",
"lookup.home_profile.fiber_cement": "Fibrocemento",
"lookup.home_profile.hardwood": "Madera dura",
"lookup.home_profile.laminate": "Laminado",
"lookup.home_profile.carpet": "Alfombra",
"lookup.home_profile.vinyl": "Vinilo",
"lookup.home_profile.concrete": "Hormigón",
"lookup.home_profile.lawn": "Césped",
"lookup.home_profile.desert": "Desierto",
"lookup.home_profile.xeriscape": "Xerojardinería",
"lookup.home_profile.garden": "Jardín",
"lookup.home_profile.mixed": "Mixto",
"lookup.document_type.warranty": "Garantía",
"lookup.document_type.manual": "Manual de usuario",
"lookup.document_type.receipt": "Recibo/Factura",
"lookup.document_type.inspection": "Informe de inspección",
"lookup.document_type.permit": "Permiso",
"lookup.document_type.deed": "Escritura/Título",
"lookup.document_type.insurance": "Seguro",
"lookup.document_type.contract": "Contrato",
"lookup.document_type.photo": "Foto",
"lookup.document_type.other": "Otro",
"lookup.document_category.appliance": "Electrodoméstico",
"lookup.document_category.hvac": "Climatización",
"lookup.document_category.plumbing": "Fontanería",
"lookup.document_category.electrical": "Eléctrico",
"lookup.document_category.roofing": "Tejado",
"lookup.document_category.structural": "Estructural",
"lookup.document_category.landscaping": "Jardinería",
"lookup.document_category.general": "General",
"lookup.document_category.other": "Otro"
}