Завершить ETL-проект и документацию

This commit is contained in:
vladslav064 committed 2026-11-12 09:24:29 +03:00
1 parent 2ec0b38d95
commit 93b1478226
6 files changed
+669 -41

No files matched your search

+48 -40
View File
@@ -1,79 +1,87 @@
# Журнал работы с ИИ
# Отчёт о работе с ИИ
## 12 ноября 2026 — осмотр проекта
Работа велась по этапам 12 ноября 2026 года. ИИ помогал с планированием, кодом, тестами и документацией. Этот отчёт описывает фактический ход работы. Запросы ниже пересказаны; исходные тексты собраны в [prompts.md](prompts.md).
**Запрос пользователя.** Подготовить по этапам ETL-пайплайн для очистки CSV и агрегации выручки по дням и категориям в SQLite. Сохранять исходный CSV, учитывать причины отбраковки, проверить идемпотентность, подготовить три аналитических запроса с результатами, README и готовую базу. Вести журнал по фактически выполненной работе. Проверки писать на pytest. Оставить `main.py` в корне для объединения этапов, функции разместить в `src/`, пути вычислять от корня проекта.
## 1. План и правила обработки
**Проверки.** Осмотр корня проекта через PowerShell показал `.git/` и `.gitignore`. Прочитан `.gitignore`, проверено состояние Git. Исходный CSV, код и тесты отсутствовали. Файл `AGENTS.md` в корне проекта и родительских каталогах не обнаружен. Дополнительная команда `rg --files` завершилась ошибкой канала запуска. Список содержимого корня получен через `Get-ChildItem -Force`.
**Задача.** Разобрать требования и выбрать простое решение для CSV → очистка → SQLite → аналитика.
**Решение.** Первый этап реализации пользователь пока не указал. Работа ограничена осмотром и созданием журнала. Схема CSV и правила расчёта выручки пока не определены. Тесты не запускались.
**Решение.** Использовать стандартную библиотеку Python, SQLite и pytest. Оставить `main.py` точкой запуска, разделить чтение, очистку, отчёты и загрузку по модулям. Деньги хранить в копейках, а цену разбирать через Decimal. Подробные правила записаны в [плане](implementation_plan.md).
## 12 ноября 2026 — план реализации
До написания кода определили разницу между точными дублями, одинаковыми заказами после нормализации и конфликтами ID. Первоначальное описание одной причины отбраковки уточнили: у записи может быть несколько ошибок полей, но итоговый статус у неё один.
**Запрос пользователя.** Изучить проект и подготовить краткий план без кода пайплайна. Зафиксировать заданную модель заказа, денежные ограничения, порядок обработки дублей, нумерацию записей CSV, интерфейсы модулей, полную транзакционную перезагрузку, критерии готовности и неоднозначности.
## 2. Генерация исходных данных
**Принятые решения.** В [плане реализации](implementation_plan.md) описаны пять полей заказа, точный разбор цены через Decimal, хранение денег в копейках и проверка диапазона INTEGER. Точные дубли определяются по исходным полям до валидации. Конфликты ID проверяются по всей группе валидных заказов до выбора представителя. Для отчёта у каждой отброшенной записи одна причина и логический номер после заголовка, начиная с единицы.
**Задача.** Создать 1500 синтетических записей с гарантированными примерами ошибок.
**Разделение работы.** Чтение, очистка и загрузка распределены между тремя модулями в src/. Дневные агрегаты строятся в SQLite при полной перезагрузке двух таблиц в одной транзакции. В плане отдельно отмечены предлагаемые параметры CSV и определения аналитических запросов.
**Результат.** Генератор использует `Random(42)` и даты с 1 января по 31 марта 2024 года. В набор добавлены пропуски, неверные даты и числа, точный дубль, дубль с другим форматом даты и конфликт ID. Персональных данных нет.
**Фактические проверки и изменения.** Повторный осмотр через rg и Git показал только .gitignore и ранее созданный журнал. Прочитан журнал, проверено отсутствие AGENTS.md в каталогах проекта и документации и по пути к корню диска. Добавлен план и обновлён журнал. Код пайплайна не создавался, pytest не запускался.
**Проверка.** Два запуска дали одинаковый CSV. Первые два теста проверили количество записей и воспроизводимость. Для тестов создано виртуальное окружение; после неудачной попытки установки через настроенный источник pytest установлен из PyPI.
## 12 ноября 2026 — генератор синтетических заказов
## 3. Чтение и очистка
**Запрос пользователя.** Создать воспроизводимый CSV на 1500 записей с seed=42, заданными дублями и ошибками. Запустить генератор и тесты количества записей и воспроизводимости на временных файлах.
**Задача.** Сохранить исходные значения и номера записей, нормализовать поля и объяснить отбраковку.
**Решения.** В `src/generate_data.py` используется локальный `Random(42)`. Корректные даты выбираются из диапазона 01.01.2024–31.03.2024 включительно. Цены формируются из целых копеек, категории выбираются из фиксированного списка. Для трёх заказов добавляется по одной копии — точной, с другой записью той же даты и с изменённым количеством. Для остальных заданных случаев изменено по одному полю в отдельных заказах. Записи перемешиваются тем же генератором. CSV синтетический, без персональных данных. Кодировка UTF-8 и перевод строки LF заданы явно.
**Результат.** Читатель проверяет заголовок и структуру CSV. Очистка собирает ошибки независимых полей, проверяет деньги и обрабатывает дубли в два этапа. Конфликты определяются среди валидных записей; ошибочная строка сама по себе не делает корректный заказ конфликтным.
**Окружение.** В доступном Python 3.14.4 отсутствовал pytest. Создана локальная .venv. Первая попытка установки не нашла дистрибутив, затем из PyPI установлен pytest 9.2.0.
**Проверка.** Прошли 32 теста. Проверены даты, обязательные поля, деньги на границе SQLite INTEGER, переполнение выручки, дубли, конфликты и сохранность источника. Каждый исходный номер оказался ровно в одном результате: принятом или отброшенном.
**Проверки.** Команда `python -m src.generate_data` выполнена дважды. SHA-256 файла `data/raw_orders.csv` после обоих запусков совпал — `c4b9ffd2eb24c6c79b6a3e2436f3bd348ba86696a1aeb9b7e3083af65c799c67`. Чтение через csv.DictReader подтвердило пять заданных колонок, 1500 записей, один точный дубль и по одному пустому значению в каждом поле. ID 1, 2 и 3 встретились по два раза. Запуск `.\.venv\Scripts\python.exe -m pytest -q` завершился результатом `2 passed in 0.08s`. Оба теста используют tmp_path.
## 4. Дополнительная проверка предложений ИИ
## 12 ноября 2026 — чтение и очистка
**Задача.** Проверить крайние случаи и улучшить тесты без переписывания рабочей логики.
**Запрос пользователя.** Реализовать extract.py и transform.py, сохранить номер и исходные значения отклонённой записи, вернуть все обнаруженные ошибки полей, проверить дубли, конфликты, точность расчётов и сохранность CSV.
**Что изменилось.** Первоначальные тесты генератора проверяли размер и повторяемость файла, но не наличие всех запланированных ошибок. Добавлена такая проверка, а также тесты неверной UTF-8, отказа доступа, многострочных полей, порядка записей и большой суммы с точностью до копейки. Список полей CSV стал общим для генератора и читателя.
**Решения и изменения.** csv.reader в строгом режиме читает UTF-8 с поддержкой BOM и нумерует логические записи после заголовка. Нечитаемый файл, ошибка разбора CSV или неверный заголовок прерывают обработку. Для читаемой записи неверной ширины сохраняются все исходные поля. Точный дубль получает только причину повтора. Для остальных структурно корректных записей собираются ошибки независимых полей. Выручка проверяется при пригодных для расчёта цене и количестве. Среди валидных заказов сначала определяется наличие конфликта во всей группе ID. Номер источника сохраняется и у принятого заказа, но исключён из сравнения нормализованных значений. План обновлён согласно уточнению о нескольких причинах.
**Что не стали менять.** Другой ИИ предложил заменить расчёт через `as_integer_ratio()`, переименовать атрибут отбраковки и использовать `.get()` для категории. При разборе текущего кода эти замечания не подтвердились: расчёт точный, атрибуты согласованы, наличие колонки проверяет читатель. Предложения не приняли.
**Фактические проверки.** Полный запуск pytest дал 32 passed. На синтетическом raw_orders.csv обработаны 1500 записей, приняты 1482, отброшены 18. Из них 14 имели ошибки значений, одна оказалась точным дублем, одна — нормализованным, две отклонены из-за конфликта ID. Проверено, что номера от 1 до 1500 встречаются в совокупном результате ровно по одному разу. Байты CSV до и после обработки совпали, SHA-256 — `c4b9ffd2eb24c6c79b6a3e2436f3bd348ba86696a1aeb9b7e3083af65c799c67`.
**Проверка.** После расширения покрытия прошли 38 тестов. Ошибок существующей логики очистки новые тесты не выявили. Рабочий CSV не изменился.
## 12 ноября 2026 — дополнительные проверки генерации, чтения и очистки
## 5. Отчёт качества и экспорт
**Запрос пользователя.** Проверить запланированные примеры в CSV, обработку ошибок файла, нумерацию, деньги и приоритет причин отбраковки. Устранить повтор схемы CSV и уточнить план экспорта и аналитики.
**Задача.** Сохранить очищенные заказы, отклонённые записи и статистику.
**Изменения.** Генератор использует FIELDS из extract.py. Добавлено шесть тестов. Они проверяют содержимое созданного во временной папке CSV, неверную кодировку, отказ при открытии файла (подмена PermissionError), многострочное поле с CRLF и нумерацию после него, смешанную группу дублей и конфликтов с проверкой порядка обоих списков, расчёт большой суммы с точностью до копейки. Новые проверки прошли на существующей логике очистки.
**Результат.** Созданы `clean_orders.csv`, `rejected_rows.csv` и `quality_report.json` в `outputs/`. CSV записываются в UTF-8 с BOM. В отбраковке сохраняются исходные поля и все причины. Итоговая причина — первая по порядку проверок; отдельные счётчики проблем могут пересекаться.
**План.** Уточнены состав clean_orders.csv и учёт нескольких причин у одной отброшенной записи. Для будущих отчётов принят календарь между крайними датами принятых заказов. Для аномалий каждой категории учитываются нулевые дни, используется стандартное отклонение генеральной совокупности и строгий двусторонний порог 2σ. При периоде короче семи дней или нулевой дисперсии результат пуст.
**Проверка.** Прошли 40 тестов. Проверены баланс строк, несколько ошибок у записи, обратное чтение исходных значений, повторный экспорт и пустой результат.
**Проверки.** Через существующую .venv выполнен полный pytest до изменений (32 passed) и после (38 passed). На исходном CSV принято 1482 заказа, отклонено 18. SHA-256 перед работой и после проверок совпал — `c4b9ffd2eb24c6c79b6a3e2436f3bd348ba86696a1aeb9b7e3083af65c799c67`. Повторно сгенерированный во временной папке CSV побайтово совпал с исходным.
## 6. SQLite и полный запуск
## 12 ноября 2026 — уточнение аналитики и пути экспорта
**Задача.** Объединить обработку в `python main.py` и обеспечить безопасный повторный запуск.
По запросу пользователя в плане закреплён путь `outputs/clean_orders.csv` относительно корня проекта. Динамику показываем по общей дневной выручке всех категорий, одной строкой на дату. Аномалии ищем отдельно по дневной выручке каждой категории, используя её собственные среднее и стандартное отклонение.
**Результат.** Заказы и дневные агрегаты полностью заменяются в одной транзакции. Агрегация выполняется в SQLite. При ошибке загрузки предыдущие данные сохраняются. Отчёты записываются после фиксации базы; при сбое программа сообщает, что база уже обновлена.
## 12 ноября 2026 — статистика и экспорт результатов
**Проверка.** Прошли 45 тестов. Интеграционные проверки запускали копию проекта во временной папке: повторная загрузка, совпадение CSV с базой, откат при переполнении суммы, повреждённый вход и набор без принятых заказов. Отдельно проверен сбой экспорта после обновления базы.
**Запрос пользователя.** Создать quality.py, выгрузить два CSV в UTF-8 с BOM и отчёт JSON, проверить баланс, повторный запуск и пустой снимок. Предусмотреть сохранение после успешной загрузки БД.
## 7. SQL-аналитика
**Решения.** Модуль принимает результаты очистки и отдельное число исходных записей. Проверяет сумму статусов и покрытие всех исходных номеров без повторов. Итоговая причина — первая из обнаруженных в порядке проверок. Отдельные счётчики проблем включают все обнаруженные причины и могут пересекаться. В CSV отбраковки заголовок источника, исходные значения и причины представлены JSON-массивами. Так сохраняются порядок колонок, пустые и лишние поля. Состав чистого CSV уточнён в плане до шести запрошенных колонок. При сборке пайплайна save_outputs будет вызываться после успешного завершения транзакции БД.
**Задача.** Подготовить топ категорий, дневную динамику и поиск аномалий с сохранёнными результатами.
**Фактические проверки.** Через существующую .venv выполнен полный pytest — 40 passed. Временный пример проверил несколько причин у одной записи, порядок, кодировку, обратное чтение значений, побайтовое совпадение при повторном экспорте и замену снимка пустым с долей null. Проверено отклонение несогласованных количеств и повторяющихся номеров. Для текущего этапа три файла созданы прямым вызовом экспорта после очистки. Чтение результатов из outputs подтвердило 1482 принятых и 18 отброшенных из 1500, доля 0,988. Суммы обоих счётчиков на этом наборе равны 18. SHA-256 исходного CSV до и после совпал.
**Уточнение по ходу работы.** В раннем плане аномалией считался рост категории более чем вдвое к предыдущему наблюдению. Затем выбрали отклонение более чем на два стандартных отклонения. После обсуждения оставили отдельный расчёт для каждой категории, а динамику — общей по всем категориям. Путь чистого CSV уточнили до `outputs/clean_orders.csv`.
## 12 ноября 2026 — транзакционная загрузка и запуск пайплайна
**Результат.** Запросы используют календарь с нулевыми днями внутри периода. Аномалии не выдаются для периода короче семи дней и при нулевой дисперсии. Метод не учитывает сезонность и может выделять обычные продажи редкой категории, поэтому результат считается поводом для проверки, а не доказательством ошибки.
**Запрос пользователя.** Реализовать схему SQLite, полную загрузку заказов и дневных агрегатов и команду python main.py. Проверить повторяемость данных, согласованность CSV, обработку пустого снимка и сохранность предыдущих данных при сбое.
**Проверка.** Прошёл 51 тест. Проверены сортировка, пропущенные дни, рост и падение, постоянная выручка, короткий период, точная граница 2σ и пустая база. Тесты не изменили рабочую базу.
**Решения.** В sql/schema.sql заданы первичные ключи и ограничения значений. src/database.py открывает одну транзакцию до создания и очистки таблиц, вставляет заказы с параметрами, строит daily_category_revenue одним группирующим запросом и фиксирует обе таблицы вместе. main.py проверяет статистику до записи базы. После фиксации он передаёт готовый отчёт в save_reports. Если экспорт завершается ошибкой, CLI указывает, что база уже обновлена, и сохраняет исходную диагностику. Ранее использовавшийся интерфейс save_outputs сохранён.
## 8. Итоговые проверки и комплект сдачи
**Фактические проверки.** В существующей .venv прошли все 45 тестов. Пять новых интеграционных тестов запускали копию проекта во временном каталоге из другой рабочей папки. Переполнение суммы группы откатило изменения обеих таблиц. Испорченный CSV сохранил прежний снимок. Набор без принятых заказов очистил обе таблицы. Сбой экспорта после фиксации базы завершил CLI с ненулевым кодом и сообщением об обновлённой БД.
Подготовлены README, база, исходные и очищенные данные, отбраковка, отчёт качества, SQL-запросы и их результаты. В Git исключены окружение, кэши и секреты. Для исходного CSV закреплены окончания строк LF, база отмечена как двоичный файл.
На рабочем синтетическом CSV команда python main.py создала outputs/orders.db. Вход — 1500 записей, приняты 1482, отброшены 18. Получено 438 групп по дате и категории. Суммарная выручка в обеих таблицах составила 1 687 705 899 копеек. Содержимое обеих таблиц сравнили до и после повторного запуска, заказы сверили по всем шести полям с clean_orders.csv. SHA-256 исходного CSV совпал с исходным замером. Аналитические запросы остаются следующим этапом.
Проверка в новом окружении на Python 3.14.4 с SQLite 3.50.4 и pytest 9.2.0 воспроизвела генерацию и запуск с нуля. Все 51 тест прошли. В рабочем окружении повторные запуски дали те же строки таблиц и текстовые отчёты. `integrity_check` вернул `ok`; деньги дополнительно пересчитаны по исходным ценам через Decimal.
## 12 ноября 2026 — SQL-аналитика и Markdown-отчёт
| Результат | Значение |
|---|---:|
| Исходных записей | 1500 |
| Принято | 1482 |
| Отброшено | 18 |
| Ошибки значений | 14 |
| Точные / нормализованные дубли | 1 / 1 |
| Конфликтующие записи | 2 |
| Группы «дата + категория» | 438 |
| Выручка | 1 687 705 899 копеек |
| Строки результатов: топ / динамика / аномалии | 5 / 91 / 18 |
**Запрос пользователя.** Подключить три запроса к main.py, сохранить фактические результаты и пояснения в outputs/query_results.md, проверить запросы на временных базах.
Исходный CSV сохранил SHA-256:
`c4b9ffd2eb24c6c79b6a3e2436f3bd348ba86696a1aeb9b7e3083af65c799c67`.
**Решения.** Запросы читают дневную витрину. Рейтинг ограничен пятью категориями согласно плану. Динамика включает календарные пропуски и изменение общей выручки к предыдущему дню. Для аномалий календарь общий, среднее и дисперсия отдельные для каждой категории. Перед AVG вычитается минимум категории, чтобы лучше сохранять небольшие различия при большой выручке. Метод сравнивает квадрат отклонения с четырьмя дисперсиями. Все три результата получаются в одной транзакции чтения, денежные колонки отчёта выражены в копейках.
**Фактические проверки.** В существующей .venv прошёл 51 тест. На временных базах проверены сортировка при равной выручке, пропущенный день, рост и падение по отдельным категориям, постоянный ряд, короткий период, точная граница в два стандартных отклонения и пустой снимок. Контрольная сумма рабочей базы до и после тестов совпала.
**Запуск на данных проекта.** При первом запуске Windows отказала в замене clean_orders.csv после фиксации БД. После разрешённого повторного запуска python main.py завершился успешно. Для чтения созданного отчёта при проверке также потребовался доступ вне песочницы. Все строки трёх результатов сверены с Markdown. Получены 5 категорий, 91 календарный день и 18 аномальных пар «дата и категория». SHA-256 исходного CSV совпал с ранее зафиксированным.