Generalize mail templates from a fixed pair to an operator-managed list
ArchiveKind was a hardcoded two-value enum (ssh_access/config_update),
wired through FilenameParser's regex, MailTemplateSet's two fixed
slots, and SettingsForm's two fixed tabs. Operators wanted arbitrary
custom templates (own file-name suffix, subject, body) without a code
change per new archive kind ssh-access-tui might start producing.
Replaced with MailTemplateDefinition (DisplayName/FileSuffix/Subject/
BodyHtml) in an open-ended list: FilenameParser now accepts any
"{login}_{suffix}.7z" and ArchiveScanner matches the suffix against
the configured list; SendJob.Kind/SendLogEntry.Kind became plain
strings; SettingsForm gained a template list (+/- buttons, editor
panel) replacing the two static tabs. ssh_access/config_update are now
just the two default entries in that list, not special-cased.
Handles the two backward-compat edges that matter for a tool already
in real use: old config.json's object-shaped "templates" migrates to
the new list shape transparently on first load (DataContractJsonSerializer
turned out to silently produce an empty list rather than throw on the
old shape, so detection is structural, not exception-based), and old
send-log.csv rows with PascalCase Kind values (SshAccess/ConfigUpdate)
still dedupe correctly against the new snake_case suffixes.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
cb3b273741
commit
804b9610ca
16 files changed
+904
-288
No files matched your search
@@ -48,22 +48,22 @@ BulkArchiveMailer **не порождает архивы и не знает па
|
||||
BulkArchiveMailer.sln
|
||||
BulkArchiveMailer.Core/ net48, class library, БЕЗ ссылок на Outlook/COM/реестр — можно
|
||||
собрать и протестировать без Windows/Office.
|
||||
FilenameParser.cs парсинг "{login}_(ssh_access|config_update).7z"
|
||||
FilenameParser.cs парсинг "{login}_{суффикс}.7z" (суффикс - любой, сверяется с шаблонами в ArchiveScanner)
|
||||
EmailAddressBuilder.cs login -> "login.with.dots@domain"
|
||||
SendJob.cs модель строки предпросмотра (Login/Email/Kind/ArchivePath/…/Status)
|
||||
ArchiveScanner.cs сканирование папки, группировка по логину, конфликт "оба архива сразу"
|
||||
ArchiveScanner.cs сканирование папки, сопоставление суффикса с шаблоном, конфликт "оба архива сразу"
|
||||
TemplateEngine.cs подстановка {Login}/{Email}/{Date} в шаблон
|
||||
MailTemplates.cs два именованных шаблона (ssh_access / config_update)
|
||||
MailTemplateDefinition.cs один шаблон (название, суффикс файла, тема, HTML-тело) - список произвольной длины
|
||||
SendLogStore.cs CSV-журнал отправок + дедуп по (Email, Kind, SHA-256 архива)
|
||||
AppSettings.cs %APPDATA%\BulkArchiveMailer\config.json, засев из config.default.json
|
||||
config.default.json шаблоны писем и домен по умолчанию (встроен как Embedded Resource)
|
||||
AppSettings.cs %APPDATA%\BulkArchiveMailer\config.json, засев из config.default.json, миграция старого формата шаблонов
|
||||
config.default.json шаблоны писем (список) и домен по умолчанию (встроен как Embedded Resource)
|
||||
BulkArchiveMailer.Core.Tests/ xUnit-заготовка (один smoke-тест) — полное покрытие добавляется отдельно
|
||||
BulkArchiveMailer.AddIn/ VSTO-плагин, net48, Windows-only, ссылается на Core
|
||||
ThisAddIn.cs / .Designer.cs запуск/остановка плагина
|
||||
Ribbon.xml + RibbonController.cs одна кнопка ленты "Массовая рассылка"
|
||||
SignatureReader.cs чтение подписи Outlook из %APPDATA%\Microsoft\Signatures через реестр
|
||||
MailSender.cs создание/отправка Outlook.MailItem, тестовый режим (Черновики)
|
||||
UI/SettingsForm.cs папка, домен, подпись, тестовый режим по умолчанию, оба шаблона
|
||||
UI/SettingsForm.cs папка, домен, подпись, тестовый режим по умолчанию, список шаблонов (добавление/удаление)
|
||||
UI/PreviewForm.cs таблица предпросмотра, баннер про пароль, отправка, итоговый журнал
|
||||
docs/BUILD.md как собрать и подключить плагин в Visual Studio на Windows
|
||||
```
|
||||
@@ -93,8 +93,16 @@ Outlook в принципе не запустить.
|
||||
(`Session.Accounts`), полезно, если у оператора несколько ящиков (например,
|
||||
отдельный служебный/shared-ящик именно для этой рассылки). Пункт
|
||||
"(по умолчанию Outlook)" — прежнее поведение без явного выбора аккаунта.
|
||||
- **Шаблоны писем** — тема и HTML-тело отдельно для `ssh_access` и
|
||||
`config_update`, с плейсхолдерами `{Login}`, `{Email}`, `{Date}`.
|
||||
- **Шаблоны писем** — вкладка "Шаблоны" со списком произвольного числа
|
||||
шаблонов (кнопки "+ Добавить"/"Удалить"). Каждый шаблон — это название,
|
||||
суффикс имени файла (`{login}_<суффикс>.7z`, по которому шаблон подбирается
|
||||
для конкретного архива), тема и HTML-тело с плейсхолдерами `{Login}`,
|
||||
`{Email}`, `{Date}`. Суффикс обязателен и должен быть уникальным среди всех
|
||||
шаблонов — по нему, а не по фиксированному перечислению видов архива,
|
||||
`ArchiveScanner` теперь сопоставляет файл с шаблоном. Два исходных шаблона
|
||||
(`ssh_access`/`config_update`) — обычные равноправные записи в этом
|
||||
списке, без особой защиты от переименования/удаления; кнопка "Сбросить
|
||||
шаблоны по умолчанию" восстанавливает их, если они были случайно удалены.
|
||||
- **Тестовый режим по умолчанию** — включён по умолчанию (письма сохраняются
|
||||
в Черновики, а не отправляются) до первого осознанного отключения
|
||||
оператором в окне предпросмотра.
|
||||
|
||||
Reference in new issue
Block a user