feat(templates): add localized push templates and actions

Share template keys across email and push with independent editors and revisions. Render localized actions and preserve version-one delivery.

Ref: IT-1627
This commit is contained in:
2026-10-31 09:38:05 +02:00
parent d4ee8fc0c8
commit aba4173827
79 changed files with 3906 additions and 104 deletions
@@ -0,0 +1,38 @@
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc.ModelBinding;
namespace HrynCo.NotificationService.Web.Controllers.Admin.ViewModels;
public sealed class PushTemplateLanguageEditViewModel : IValidatableObject
{
[Required, StringLength(10)]
public string LanguageCode { get; set; } = "";
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Title { get; set; } = "";
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Body { get; set; } = "";
[Required]
public string ActionsJson { get; set; } = "{}";
[BindNever]
public bool IsPresent { get; set; }
public bool HasContent => !string.IsNullOrWhiteSpace(Title) || !string.IsNullOrWhiteSpace(Body) || HasActions();
private bool HasActions()
{
try
{
var actions = DAL.Abstract.Templates.PushTemplateActionValidation.Parse(ActionsJson);
return actions.DefaultAction is not null || actions.Buttons.Count > 0;
}
catch (DAL.Abstract.Templates.EmailTemplateWriteException) { return true; }
}
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (!HasContent) yield break;
if (string.IsNullOrWhiteSpace(Title))
yield return new ValidationResult("Title is required for a populated language.", [nameof(Title)]);
if (string.IsNullOrWhiteSpace(Body))
yield return new ValidationResult("Body is required for a populated language.", [nameof(Body)]);
}
}