Загрузка данных


Ты — senior C#/.NET разработчик, software architect и специалист по созданию Windows desktop-приложений.

Мне необходимо разработать полноценное Windows-приложение для автоматизированного поиска и обработки организаций из Яндекс Карт.

Я начинающий пользователь и не хочу вручную создавать файлы проекта, создавать классы и распределять код по файлам.

Твоя задача — самостоятельно создать весь проект, структуру папок, файлы, классы, код, конфигурацию и необходимые зависимости.

Я хочу получить в итоге готовое Windows-приложение, которое можно собрать в один запускаемый `.exe`.

========================

1. ОСНОВНАЯ ТЕХНОЛОГИЯ
   ========================

Используй:

* C#
* современный .NET (предпочтительно актуальный LTS .NET, совместимый с Windows)
* WPF для графического интерфейса
* MVVM для архитектуры интерфейса
* Microsoft.Extensions.DependencyInjection / подходящий DI при необходимости
* Microsoft.Extensions.Logging или другой нормальный механизм логирования
* Playwright for .NET для браузерной автоматизации, если он необходим
* HttpClient для обычных HTTP-запросов
* HtmlAgilityPack или AngleSharp для анализа HTML
* ClosedXML для экспорта в Excel
* System.Text.Json для JSON
* SQLite при необходимости для локального хранения данных
* dotnet publish для создания готового Windows-приложения

Не используй сторонние библиотеки без необходимости.

Перед добавлением новой зависимости оцени, действительно ли она нужна.

Проект должен быть построен модульно.

Основная логика не должна находиться непосредственно в коде окна WPF.

Предпочтительная структура:

* Presentation
* Application
* Domain
* Infrastructure

Либо другая эквивалентная чистая архитектура, если ты считаешь её более подходящей.

Главный принцип:

UI отдельно.
Логика парсинга отдельно.
Работа с Яндексом отдельно.
Работа с сайтами отдельно.
Поиск ИНН/ОГРН отдельно.
Excel отдельно.
Логирование отдельно.

Я хочу иметь возможность в будущем полностью изменить дизайн интерфейса, не переписывая парсер.

Также я хочу иметь возможность изменить источник организаций, не переписывая анализ сайтов и экспорт.

У меня уже существует другая программа-парсер.

Не анализируй её.
Не используй её код.
Не пытайся интегрироваться с ней.
Не пытайся выяснять, как она работает.

Этот проект должен быть полностью самостоятельным и написан с нуля.

Пользователь должен иметь возможность ввести:

Поисковый запрос:
например:
медцентр

Город:
например:
Пермь

Количество:
например:
200

После нажатия кнопки:

"НАЧАТЬ ПОИСК"

программа должна автоматически:

1. Найти организации в Яндекс Картах.
2. Ограничить поиск указанным городом.
3. Использовать поисковую фразу пользователя без самостоятельного изменения.
4. Получить карточки организаций.
5. Проверить наличие сайта непосредственно на карточке.
6. Пропустить организации без сайта.
7. Продолжать поиск следующих организаций, пока не будет найдено заданное количество подходящих организаций либо пока доступные результаты не закончатся.
8. Получить название организации.
9. Получить URL сайта.
10. Получить URL карточки Яндекс Карт.
11. Перейти на сайт организации.
12. Попытаться найти ИНН.
13. Попытаться найти ОГРН или ОГРНИП.
14. Отобразить результаты в таблице.
15. Позволить копировать отдельные значения одним нажатием.
16. Позволить открыть сайт.
17. Позволить открыть карточку Яндекс Карт.
18. Экспортировать результаты в Excel.

Пользователь самостоятельно вводит поисковую фразу.

Примеры:

медцентр

косметология

стоматология

ветеринарная клиника

Очень важно:

НЕ изменяй поисковую фразу автоматически.

Если пользователь ввёл:

медцентр

не превращай её автоматически в:

медцентры Пермь

Город является отдельным параметром географического ограничения.

Пример:

Запрос:
медцентр

Город:
Пермь

Должен выполняться поиск организаций по запросу "медцентр" в пределах города Пермь.

Если пользователь указал:

200

это означает:

"Найти 200 подходящих организаций, у которых на карточке Яндекс Карт указан сайт."

Это НЕ означает:

"Взять первые 200 сырых результатов."

Например:

найдено 100 карточек;
из них 40 имеют сайт.

Программа должна продолжить поиск следующих результатов.

Например:

найдено 250 карточек;
из них 180 имеют сайт.

Продолжить поиск.

Остановиться только когда:

* найдено 200 подходящих организаций;

ИЛИ:

* доступные результаты закончились.

Если доступно только 137 подходящих организаций, показать 137 и сообщить пользователю, что получить 200 не удалось.

Основным источником организаций являются Яндекс Карты.

Необходимо получать как минимум:

* название организации;
* URL карточки Яндекс Карт;
* URL сайта, указанный непосредственно на карточке.

Желательно также получать:

* адрес;
* телефон.

Но эти дополнительные данные не должны становиться критическими для работы программы.

Это одно из главных условий.

В итоговую таблицу должны попадать только организации, у которых есть сайт, указанный непосредственно на карточке Яндекс Карт.

Если сайта нет:

пропустить организацию.

Не считать официальным сайтом:

* Яндекс Карты;
* страницы социальных сетей;
* каталоги организаций;
* агрегаторы;
* сторонние сервисы;
* страницы отзывов.

Если определить тип ссылки неоднозначно — реализуй отдельный метод/сервис определения официального сайта, чтобы это правило можно было изменить позже.

После получения сайта необходимо попытаться найти ИНН и ОГРН/ОГРНИП.

Не ограничивайся только главной страницей.

Сначала проверяй:

* главную страницу;
* контакты;
* реквизиты;
* о компании;
* о нас;
* сведения об организации;
* документы;
* пользовательское соглашение;
* политику конфиденциальности;
* footer;
* другие очевидные страницы сайта.

Также анализируй:

* обычный текст;
* HTML;
* JSON-LD;
* structured data;
* meta-информацию;
* ссылки в footer;
* доступные текстовые документы, если это возможно без чрезмерного усложнения.

Ищи:

ИНН
ИНН:
ИНН /
ИНН/КПП

и аналогичные варианты.

Для юридического лица обычно используется 10-значный ИНН.

Не считай любое случайное десятизначное число ИНН.

Используй контекст найденного значения.

По возможности реализуй проверку контрольных цифр ИНН.

Если ИНН не найден:

отобразить:

"Не найден"

и продолжить обработку.

Отсутствие ИНН не должно останавливать программу.

Ищи:

ОГРН
ОГРН:
ОГРНИП
ОГРНИП:

Для юридического лица искать ОГРН.

Для индивидуального предпринимателя искать ОГРНИП.

По возможности реализовать проверку контрольной цифры.

Если значение не найдено:

"Не найден"

Продолжить работу.

Очень важно:

одна ошибка НЕ должна ломать весь процесс.

Пример:

Организация №1:
сайт работает;
ИНН найден;
ОГРН найден.

Организация №2:
сайт не открывается.

Организация №3:
сайт работает;
ИНН найден;
ОГРН не найден.

Организация №4:
сайт работает;
ИНН не найден;
ОГРН найден.

Все организации должны корректно обрабатываться.

Для отсутствующих данных писать:

"Не найден"

Для ошибки сайта использовать понятный статус.

После этого переходить к следующей организации.

Некоторые сайты могут быть полностью или частично построены на JavaScript.

Для обычных HTML-сайтов предпочтительно использовать HttpClient + HTML parser.

Если нужная информация недоступна в обычном HTML, использовать Playwright.

Не использовать Playwright без необходимости для каждого сайта, если обычный HTTP-запрос значительно быстрее.

Цель:

минимизировать время обработки большого количества организаций.

Создай современную таблицу результатов.

Минимальные колонки:

№
Организация
ИНН
ОГРН / ОГРНИП
Сайт
Яндекс Карты
Статус

Дополнительно:

Адрес
Телефон

Но дополнительные колонки не должны ухудшать основной интерфейс.

Для каждого результата пользователь должен иметь возможность одним нажатием скопировать:

* название;
* ИНН;
* ОГРН/ОГРНИП;
* сайт;
* ссылку Яндекс Карт.

Можно использовать:

* кнопки в строке;
* контекстное меню;
* либо другой удобный механизм.

Главное — копирование должно быть максимально быстрым.

Для URL предусмотреть:

[Открыть]
[Копировать]

Добавить кнопку:

"Экспорт в Excel"

Использовать ClosedXML либо аналогичную библиотеку.

Excel должен содержать:

* Организация
* ИНН
* ОГРН/ОГРНИП
* Сайт
* Яндекс Карты
* Статус
* Адрес
* Телефон

URL должны по возможности быть кликабельными гиперссылками.

Пользователь должен видеть, что программа делает.

Например:

Поиск организаций...

Найдено карточек: 153

Подходящих с сайтом: 78

Обработано сайтов: 61

ИНН найден: 47

ОГРН найден: 42

Текущая организация:
ООО "Пример"

Прогресс:

78 / 200

Также показывать общий статус.

Во время парсинга WPF-интерфейс не должен зависать.

Не выполнять длительные операции в UI thread.

Использовать:

async/await;

CancellationToken;

подходящую background worker архитектуру.

Пользователь должен иметь возможность продолжать видеть прогресс и нажать "Остановить".

Добавить кнопку:

"Остановить"

Она должна корректно отменять процесс.

Если пользователь остановил работу после 73 организаций:

73 уже полученных результата должны остаться в таблице.

Не терять собранные данные.

Использовать CancellationToken.

Одна организация не должна появляться несколько раз.

Использовать URL карточки Яндекс Карт и/или другой устойчивый идентификатор.

Если одна организация встретилась несколько раз:

сохранить только один результат.

Создай систему логирования.

Например:

logs/app.log

Записывать:

* дату;
* время;
* уровень;
* организацию;
* URL;
* этап обработки;
* текст ошибки.

Пользователю не показывать огромные технические stack trace.

Но лог должен позволять разработчику понять причину ошибки.

Вынести изменяемые параметры в конфигурацию.

Например:

* timeout;
* количество retries;
* задержки;
* настройки браузера;
* параметры обработки сайтов.

Не разбрасывать магические числа по коду.

Использовать разумные:

* timeout;
* retry;
* cancellation;
* обработку исключений.

Один сайт не должен блокировать весь процесс.

Если сайт не отвечает после разумного количества попыток:

пропустить его.

Если Яндекс временно не отвечает:

показать понятную ошибку.

Не делать бесконечные retries.

Не пытаться обходить CAPTCHA, антибот-системы или ограничения доступа.

Не реализовывать обход блокировок.

Соблюдать применимые правила использования внешних сервисов.

Создай отдельный интерфейс/сервис для получения организаций.

Например концептуально:

IOrganizationSearchProvider

и реализацию:

YandexMapsProvider

Но названия можешь изменить, если архитектурно есть более правильный вариант.

Главное:

логика Яндекс Карт не должна быть смешана с UI и анализом сайтов.

Если для корректной работы нужен официальный API Яндекса:

НЕ выдумывай API key.

НЕ вставляй фиктивные ключи.

Сообщи мне, какие credentials необходимы.

Если используется браузерная автоматизация:

реализуй её аккуратно и без обхода CAPTCHA или антибот-защиты.

Основной способ:

официальный сайт организации.

Если данные не найдены, архитектура должна позволять позже подключить дополнительный источник.

Например:

официальные данные ФНС или другой легальный источник.

Но:

не выдумывай API;

не используй неизвестные endpoints;

не подключай сомнительные сервисы без необходимости.

Первая версия должна работать и без дополнительного источника.

Создай интерфейс, через который такой источник можно будет добавить позже.

Интерфейс должен выглядеть как нормальное современное Windows-приложение, а не как техническая форма из старой программы.

Предпочтительно:

* современный минималистичный стиль;
* хорошие отступы;
* понятная типографика;
* аккуратные кнопки;
* современная таблица;
* визуальный прогресс;
* понятные статусы;
* нормальная работа с длинными URL.

Но самое главное:

UI должен быть полностью отделён от бизнес-логики.

Я хочу в будущем иметь возможность попросить тебя:

"Полностью переделай дизайн программы, но не меняй логику парсера."

И это должно быть возможно без переписывания основных сервисов.

Поэтому не помещай бизнес-логику в code-behind окна.

Используй MVVM.

Архитектура должна позволять позже добавить:

* тёмную тему;
* светлую тему;
* изменение цветов;
* логотип;
* название программы;
* дополнительные фильтры;
* поиск по результатам;
* сортировку;
* дополнительные колонки;
* историю запусков;
* сохранение предыдущих результатов;
* кнопку "Копировать все ИНН";
* кнопку "Копировать все ОГРН";
* дополнительные источники данных;
* другие поисковые системы/источники организаций.

Не реализуй эти функции сейчас, если они не нужны для первой версии.

Но оставь архитектуру пригодной для расширения.

После завершения поиска пользователь должен иметь возможность сразу сделать новый.

Например:

Запрос:
стоматология

Город:
Пермь

Количество:
100

После этого:

Запрос:
косметология

Город:
Екатеринбург

Количество:
200

Добавить кнопку:

"Очистить результаты"

или автоматически очищать предыдущие результаты перед новым запуском с подтверждением.

Создай полноценный solution.

Например:

YandexOrganizationParser.sln

Структуру выбери сам, но она должна быть профессиональной и понятной.

Например:

src/
YandexOrganizationParser.App/
YandexOrganizationParser.Application/
YandexOrganizationParser.Domain/
YandexOrganizationParser.Infrastructure/

tests/
...

Не обязательно использовать именно эту структуру, если ты считаешь другую архитектуру более правильной.

Главное — разделение ответственности.

Добавь разумное количество unit tests для критически важных частей.

В частности протестируй:

* распознавание ИНН;
* проверку ИНН;
* распознавание ОГРН;
* проверку ОГРН;
* распознавание ОГРНИП;
* дедупликацию;
* обработку отсутствующих данных;
* экспорт данных.

Не нужно писать огромное количество искусственных тестов.

Создай README.md.

В нём объясни:

* что делает программа;
* как открыть проект;
* как установить зависимости;
* как запустить;
* как установить Playwright browsers, если требуется;
* как собрать программу;
* как получить `.exe`;
* какие настройки доступны;
* где находятся логи.

Инструкции должны быть понятны начинающему пользователю.

Это один из главных результатов проекта.

Я хочу иметь возможность получить готовый Windows executable.

Используй:

dotnet publish

с подходящими параметрами для Windows.

Предпочтительно сделать self-contained publish, чтобы на компьютере пользователя не требовалось отдельно устанавливать .NET Runtime.

По возможности использовать single-file publish.

Например, целевой результат должен быть похож на:

dist/
YandexOrganizationParser.exe

Если какие-либо компоненты невозможно корректно упаковать в один файл, не скрывай это от меня.

Объясни, какие дополнительные файлы необходимы.

Создай удобный:

build.bat

или PowerShell-скрипт, который автоматически выполняет сборку.

После создания проекта:

не просто напиши код и остановись.

Проверь проект.

Порядок:

1. Создай solution.
2. Создай проекты.
3. Создай необходимые классы.
4. Настрой зависимости.
5. Реализуй базовый WPF интерфейс.
6. Собери проект.
7. Исправь ошибки компиляции.
8. Запусти приложение.
9. Проверь GUI.
10. Реализуй поиск организаций.
11. Реализуй фильтрацию по наличию сайта.
12. Реализуй анализ сайтов.
13. Реализуй ИНН.
14. Реализуй ОГРН/ОГРНИП.
15. Реализуй таблицу.
16. Реализуй копирование.
17. Реализуй открытие URL.
18. Реализуй Excel.
19. Реализуй прогресс.
20. Реализуй CancellationToken.
21. Реализуй логирование.
22. Добавь тесты.
23. Проверь сборку.
24. Выполни publish.
25. Проверь полученный `.exe`.

Если во время разработки появляется ошибка:

самостоятельно анализируй её и исправляй.

Не оставляй проект в заведомо некомпилируемом состоянии.

Не добавляй:

* регистрацию пользователей;
* авторизацию;
* облачный сервер;
* сложный backend;
* платежи;
* аккаунты;
* ненужную базу данных;
* сложную инфраструктуру.

Это локальная Windows-программа.

Приоритеты:

1. Корректность данных.
2. Надёжность.
3. Отсутствие зависания интерфейса.
4. Удобство использования.
5. Скорость.
6. Дизайн.

Не жертвуй корректностью ради максимальной скорости.

В конечном итоге я должен открыть программу и увидеть примерно:

---

ПАРСЕР ОРГАНИЗАЦИЙ

Поисковый запрос:
[ медцентр                         ]

Город:
[ Пермь                            ]

Количество:
[ 200 ]

[ НАЧАТЬ ПОИСК ]   [ ОСТАНОВИТЬ ]

Найдено подходящих: 84 / 200

Обработано сайтов: 61
ИНН найдено: 48
ОГРН найдено: 43

---

| № | Организация | ИНН | ОГРН | Сайт | Яндекс |
| - | ----------- | --- | ---- | ---- | ------ |
| 1 | ...         | ... | ...  | ...  | ...    |
| 2 | ...         | ... | ...  | ...  | ...    |

---

[ ЭКСПОРТ В EXCEL ]

---

Каждый результат должен позволять:

[Копировать ИНН]
[Копировать ОГРН]
[Копировать сайт]
[Открыть сайт]
[Копировать Яндекс]
[Открыть Яндекс]

============================================

НАЧНИ СЕЙЧАС.

Сначала внимательно проанализируй всё ТЗ.

Затем создай структуру проекта непосредственно в рабочей директории Cursor.

Не заставляй меня вручную создавать файлы.

Не выдавай мне огромные блоки кода с инструкцией "скопируй это в файл".

Создавай и редактируй файлы проекта самостоятельно.

После каждого существенного этапа проверяй компиляцию и исправляй найденные ошибки.

Если какое-либо требование технически невозможно реализовать именно так, как описано, НЕ выдумывай решение.

Сначала объясни проблему и предложи ближайший рабочий вариант.

Особенно важно не выдумывать API Яндекс Карт, API ФНС или любые другие внешние API.

Начни с создания solution и архитектуры проекта.