add kerio format support

This commit is contained in:
2026-07-17 11:42:12 +07:00
parent ccd8e8eb1b
commit 11175b4e31
4 changed files with 155 additions and 33 deletions
+22 -2
View File
@@ -43,7 +43,7 @@ gofmt -l . # список неотформатированных файл
- `POST /api/import` — создание ящиков, **потоковый NDJSON** (по строке результата на ящик, с `flusher.Flush()`).
Три конвейерных этапа обработки строки CSV, каждый меняет `Row.Status`
(`create``warn``exists``error`) и флаг `Importable`:
(`create``warn``exists``skip``error`) и флаг `Importable`:
1. `parseCSV``validateRow` — структурная проверка без сети (email, пароль, дубликаты в файле).
2. `enrichRow` — сверка с живым mailcow: несуществующий домен → `error`, существующий ящик → `exists` (пропуск). Работает только если заданы креды.
@@ -60,6 +60,21 @@ gofmt -l . # список неотформатированных файл
на практике используется `;`), снятие BOM, `LazyQuotes`, RU-алиасы заголовков
(`headerAliases` + `normHeader` игнорирует регистр/пробелы/подчёркивания).
`email` можно заменить парой `localpart`+`domain`.
- **Формат Kerio** (`isKerioHeader` + `kerioColumns`, `parseCSV` возвращает `format`):
экспорт Kerio Connect распознаётся по набору заголовков `kerioMarkers`
(`Name`+`FullName`+`MailAddress`+`DataSource`+`Authentication`) и разбирается
**отдельной таблицей колонок**, а не через `headerAliases`: у Kerio `Name` — это
логин, а `FullName` — отображаемое имя, т.е. ровно наоборот к алиасам. Маппинг:
`MailAddress`→логин (`localpart`, приоритет), `Name`→запасной логин (`email`),
`FullName``name`, **`Description``password`** (Kerio кладёт пароль туда),
`Enable``active`, `DiskSizeLimit (kB)`→квота с делением на 1024 (kB→МиБ),
`Role`→пропуск служебных учёток. Логины в экспорте **без домена**, поэтому
Kerio без выбранного домена в UI отклоняется с явной ошибкой.
- **Статус `skip`** — строка сознательно не мигрируется (`Importable=false`):
Kerio-роль содержит `admin` (консольная учётка, не почтовый ящик). `enrichRow`
такие строки не трогает, как и `error`. Отличается от `exists` (ящик уже в mailcow).
- `normActive` сводит `Yes/No`, `true/false`, `да/нет`, `1/0` к mailcow-флагу `active`;
пустое значение → `1`. Применяется к обоим форматам.
- **Режим override-домена** (`parseCSV(..., overrideDomain)`): если домен выбран в UI
и передан form-полем `domain`, колонка логина (`email`/`login`/`localpart`)
трактуется как localpart без домена, email собирается как `localpart@overrideDomain`.
@@ -79,7 +94,12 @@ gofmt -l . # список неотформатированных файл
`importResults` — идемпотентно, т.к. упавшие ящики не создались, успешные не трогаются.
При добавлении полей ящика править **три места синхронно**: заголовки/алиасы CSV
(`headerAliases`), структуру `Row` + `validateRow`, и `payload` в `handleImport`.
(`headerAliases`, при необходимости `kerioColumns`), структуру `Row` + `validateRow`,
и `payload` в `handleImport`.
При добавлении нового статуса `Row.Status` править `index.html` в четырёх местах:
CSS `.pill.<st>`/`.st.<st>`, `labels` и список ключей в `renderPreview`, `statusText`.
Ключи `summary` в `handlePreview` должны совпадать со списком в `renderPreview`.
## Требования на стороне mailcow