namespace BulkArchiveMailer.Core { /// /// One configured mail template: which files it applies to (by file /// name suffix, "{login}_{FileSuffix}.7z"), plus its Subject/BodyHtml. /// Replaces the old fixed pair of named templates (ssh_access / /// config_update) with an arbitrary, operator-editable list - /// AppSettingsData.Templates now holds a List<MailTemplateDefinition> /// instead of two hard-coded slots. /// /// FileSuffix is the only identifier a template needs: it must be /// non-empty and unique (case-insensitively) among all configured /// templates for ArchiveScanner's suffix-to-template lookup to be /// unambiguous. Enforcing that (non-empty + unique) is SettingsForm's /// job at save time, not this class's - a plain data holder has no /// validation of its own. /// public sealed class MailTemplateDefinition { public string DisplayName { get; set; } = ""; /// /// Suffix of the file name this template renders for: matches /// files named "{login}_{FileSuffix}.7z" (case-insensitive; see /// FilenameParser/ArchiveScanner). Must be non-empty and unique /// among all configured templates - see class remarks. /// public string FileSuffix { get; set; } = ""; public string Subject { get; set; } = ""; public string BodyHtml { get; set; } = ""; /// /// Optional regular expression the parsed login (from /// "{login}_{FileSuffix}.7z") must match (case-insensitively) for /// this template to actually apply, checked by ArchiveScanner AFTER /// the file's suffix has already matched this template. Empty (the /// default) means "no restriction" - the original, pre-v1.2.0 /// behavior where suffix alone decides the match. Validated for /// compilability by SettingsForm at save time; ArchiveScanner /// itself treats an uncompilable pattern defensively as "does not /// match" rather than throwing, in case an operator hand-edits /// config.json with a broken regex. /// public string LoginPattern { get; set; } = ""; } }