Формат и проверки
Сделайте CLI-проверку CSV-табеля с заголовками employee_id, date, start, end, break_minutes, project. Порядок колонок произвольный, повторяющиеся и неизвестные названия заголовков запрещены. CSV использует запятую и стандартное экранирование двойными кавычками. employee_id и project — непустые строки; date — действительная YYYY-MM-DD; start и end — локальное время HH:MM без часового пояса; break_minutes — целое от 0 до 1440.
Одна строка описывает непрерывную смену в пределах одного календарного дня. Ночные смены через полночь не поддерживаются: end обязан быть позже start. Вычислите продолжительность как разницу минут за вычетом перерыва; она должна быть строго положительной. Продолжительность смены до перерыва не может превышать 16 часов, перерыв не может быть длиннее самой смены. Для каждого сотрудника и даты допускается ровно одна строка: повтор пары employee_id/date является ошибкой второй строки, даже если интервалы не пересекаются. На корректных строках посчитайте часы по сотрудникам и проектам, используя целые минуты; отчёт показывает часы с точностью до двух знаков и общее число смен.
Ошибки строк должны включать физический номер, сотрудника если он прочитан, дату если она прочитана, и понятную причину. Строки с ошибками не входят в агрегаты. После чтения печатайте отчёт по корректным строкам и диагностики; любой дефект строки даёт ненулевой код. Неверная схема, синтаксис CSV, ошибка чтения — фатальны, агрегации не публикуются. Сортируйте сотрудников и проекты лексикографически. Программа ничего не меняет во входном файле. README фиксирует локальное время и ограничение одной смены в день; тесты включают граничные интервалы.
Структура программы
В internal/timesheet вынесите разбор локального времени, проверку смены и расчёт минут по сотруднику и проекту. Отдельный CSV-reader отвечает за заголовки, номера строк и преобразование полей; main.go соединяет его с проверками и отчётом. Возвращайте ошибки и диагностики как значения. Core-тесты подают подготовленные строки без запуска CLI.