Есть исторические данные которые ранее хранились в другой системе, Заказчик предоставил нам выгрузку данных в файлах TSV, теперь требуется их хранить в БД PostgreSQL 14 версии.
Нужна утилита импорта данных из файлов в БД.
Пример данных в каталоге data.
Текущая схема классов для использования из нашего приложения:

- Импорт данных производится из TSV (tab separated) файла. Данные могут быть частично некорректными (регистр символов, пробелы по краям и в середине), в этом случае требуется их базовая очистка.
- Повторный импорт не должен дублировать записи (для подразделения - уникальный признак "название подразделения + название его родителя", для сотрудника - ФИО, для должности - название), при этом по сотрудникам, если в данных повторного импорта есть изменения, например смена пароля, должности или подразделения у сотрудника - записи обновляются с новыми значениями, а для подразделений может смениться руководитель.
- Возможна неограниченная вложенность подразделений, проверку на закольцованность не делать, доверяем исходным данным.
- При импорте не должно падать на битых записях, они пропускаются c детальным сообщением - в какой строке исходного файла ошибка, желательно сообщением в stderror.
- Допустимо добавлять дополнительные столбцы в БД.
- Настройки доступа в БД должны храниться в файле конфигурации.
- Учитывать возможные массовые загрузки до 500к сотрудников по подразделениям (не грузим всё в память, ленивые варианты загрузки).
- Родительскими подразделениями в БД считаются те, у которых ParentID=0, нумерация ID начинается с 1.
- Допустимы подразделения без руководителя.
- Список должностей является приоритетным, считаем, что в списке сотрудников могут быть невалидные должности, если импортируется сотрудник с некорректной должностью - считаем его сотрудником без должности.
- Рекомендуемый инструментарий - C#, .Net/.NetCore, LINQ, EF.
Режимы работы утилиты:
- Импорт. Утилите передаётся имя файла и тип импорта (подразделение/сотрудник/должность). После импорта в консоль выводится полное текущее состояние БД.
- Вывод. Просим утилиту вывести текущую структуру данных, вторым параметром можно передавать ID подразделения, тогда выводится только цепочка родительских подразделений (без сотрудников) до него, само подразделение и его сотрудники.
Названия параметров и формат вызова - полностью на усмотрение разработчика.
- Подразделения выводятся по алфавиту с соблюдением иерархии
- Префикс подразделения "=", их количество отражает уровень вложенности
- Руководитель подразделения выводится с префиксом "*", перед ним количество " " = уровню вложенности подразделения
- Сотрудники выводятся после подразделения с префиксом "-", перед ним количество " " = уровню вложенности подразделения, в котором они состоят)
- Подразделения могут быть как без руководителя, так и без сотрудников
- Сотрудники без корректной должности или подразделения считаются неактивными и не участвуют в выводе
Пример:
= Подразделение ID=1
* Сотрудник ID=1 (должность ID=56)
- Сотрудник ID=2 (должность ID=99)
== Подразделение ID=2
=== Подразделение ID=4
- Сотрудник ID=5 (должность ID=4)
== Подразделение ID=3
- C# проект с исходными кодами (ссылка на репозиторий).
- SQL скрипт для создания структуры БД (если требуется).
- Краткая инструкция - как запускать, как настроить.
- Дополнительные вопросы и предложения, если возникли в процессе реализации.