# AGENTS.md — Окнардия: Оконный Агрегатор **Версия**: 0.2.0 | **Язык**: Python 3.12+ + Django 6.0+ | **БД**: MariaDB/MySQL Этот документ обеспечивает AI-агентов (Copilot, Claude, Cursor и т.д.) контекстом для эффективной работы с проектом. ## Архитектура и назначение **Окнардия** — это агрегатор для сравнения цен на установку оконных конструкций в зданиях типового (серийного) строительства в России. Пользователи вводят адрес дома → система распознаёт серию строения → выдаёт типовые размеры оконных проемов → показывает предложения от поставщиков на установку (замену) окон. Архитектура двухуровневая: - **Основной проект**: `oknardia/` (Django settings, URL routing, models, templates) - **Приложение логики**: `web/` (views, вспомогательные функции, кеширование схем окон) ## Критические компоненты и модели данных ### Основные модели (oknardia/models.py) **Иерархия зданий:** - `Seria_Info` — серия типового строения (P-44, 5-этажка и т.п.), поддерживает self-referential FK для древовидной структуры - `Building_Info` — конкретный адрес с ссылкой на серию; содержит ~30 полей метаданных (площадь, износ, материалы) - `Apartment_Type` — типовой план квартиры в серии; содержит связь M2M с `Win_MountDim` - `MountDim2Apartment` — через-таблица между проёмами и квартирами **Каталог и цены:** - `PVCprofiles` — PVC-профили (окна), содержат рейтинг (0…+5) и tech-specs - `Glazing` — стеклопакеты с изоляционными параметрами и рейтингом - `SetKit` — готовый "набор" (профиль + стеклопакет + фурнитура + монтаж), связывает компоненты и хранит бизнес-условия - `PriceOffer` — финальная цена для конкретного проёма и набора от конкретного пользователя **Дополнительные сущности:** - `OurUser` — собственная система пользователей (расширение Django User) - `MerchantBrand` / `MerchantOffice` — организационная иерархия поставщиков - `BlogPosts` — универсальная таблица для блога и каталога (одна таблица, флаги `bCatalog`, `bPublished`) - Несколько LOG-таблиц: `LogMeasure`, `LogDemand`, `LogVisitPriceReport` **Именование полей** (обязательное соглашение): - `s*` = String/Char - `i*` = Integer - `f*` = Float/Decimal - `b*` = Boolean - `d*` = DateTime/Date - `k*` = Foreign Key (связь) - `p*` = Path/Media - Например: `sSetName` — название набора, `fSetRating` — рейтинг набора ### Кеширование и специфика 1. **Картинки схем окон** генерируются автоматически в: - `public/static/img/_flap.cfg` — большие картинки схем открывания - `public/static/img/_miniflap.cfg` — миниатюры для таблиц - **Важно**: не удалять просто так, они переиспользуются; если схема архивируется, картинка остаётся без явного удаления 2. **Pre-render HTML-шаблоны** для серий в `oknardia/templates/seria_info/prepared/` - Создаются при первом обращении к странице серии - **Требуют ручной очистки** при изменении цен/спецификаций или настройки cronjob на удаление 3. **Кольцевой буфер логирования** (настройка `MAX_LEN_RING_LOG_BUFFER=250` в settings) ## Workflow и точки входа ### Основной сценарий пользователя: 1. **Главная** (`/`) → `views.main_init()` — отслеживание кук посещений 2. **Автокомплит адреса** (`/autocomplete_addr`) → `autocomplete_addr.autocomplete_addr()` — подсказки при вводе 3. **Поиск по адресу** (`/get_address`) → `views.get_address()` — распознание серии здания 4. **Ценовая выдача** (`/{build_id}/{apart_id}/*`) → `prices.report_price()` — основной отчёт с фильтрацией и пагинацией по фреймам ### Каталоги и отчёты: - `catalog.py` — каталог профилей, производителей, серий (с методом `catalog_seria_info()`) - `report1.py` — сравнение наборов (`compare_offers()`) с расчётом рейтинговых компонент - `report2.py` — рейтинги и ранжирование (фильтрация по звёздочкам и весам) - `diagrams.py` — статистика и аналитика ### Система пользователей: - `user_manager.py` — регистрация, логин/logout, восстановление пароля, верификация email - Использует собственные таблицы `OurUser` + стандартный Django `User` ## Специфические технологии и паттерны ### Конфигурация через settings.py: - **Двойной хост** (DEV и PROD) по `socket.gethostname()` — разные БД, media-пути, сценарии отладки - Настройки ранжирования через веса (более 20 констант типа `RANK_STEP_*`, `RARING_*`) - Google Captcha и Yandex Maps API ключи из `my_secret.py` ### Импорт конфиденциальных данных: ```python from oknardia.my_secret import * # в settings.py и models.py ``` **⚠️ Важно**: `my_secret.py` содержит пароли БД, SECRET_KEY и должен быть в `.gitignore` ### Использование JSON в моделях: - Поле `sProfileDescription` (Profiles), `sGlazingDescription`, `sSetDescription` — JSON или HTML в TextField - Нет явной валидации структуры JSON при сохранении ### Система рейтинга и ранжирования: - Каждый компонент (профиль, стеклопакет, набор) имеет рейтинг - Веса рейтинга задают важность каждого атрибута (теплопередача, звукоизоляция и т.п.) - `report1.show_rating_components()` раскрывает формулу расчёта рейтинга ### Интернационализация: - `LANGUAGE_CODE = 'ru-RU'`, `TIME_ZONE = 'Europe/Moscow'` - `USE_I18N = True`, `FIRST_DAY_OF_WEEK = 1` (понедельник) - Все названия моделей и help_text на русском языке ## Конвенции кодирования Из `.github/copilot-instructions.md`: ✅ **Обязательные правила:** - **Язык**: отвечай на русском, комментарии кода на русском - **Стиль**: PEP 8 для Python, используй современные возможности (Python 3.12+, Django 6.0+) - **Управление зависимостями**: `poetry` (вместо pip/requirements.txt) - **Переменные окружения**: секреты в `.env`, не в коде - **Git коммиты**: - `add: <описание>` — новая функция/файл - `fix: <описание>` — баг - `mod: <описание>` — переработка кода - `minor: <описание>` — форматирование, опечатки, мелкие комменты - **Удаление старого кода**: помечать меткой `# Удалить:`, не стирать просто - **Тон**: неформальный, профессиональный, образность допускается (как с коллегой) ⚠️ **Исключения**: - Не удаляй старый код без явного указания - Всегда уточняй перед `git commit` / `git push` - Если модель требует миграций, опиши шаги для `python manage.py makemigrations/migrate` ## Типичные рабочие циклы ### Добавление нового фильтра в ценовую выдачу: 1. Добавить поле в модель (например, `SetKit`) → создать миграцию 2. Обновить фильтрацию в `prices.report_price()` → использовать Q-объекты 3. Обновить template для выбора фильтра (`templates/price/*.html`) 4. Проверить влияние на рейтинг в `report1.py` если нужно ### Обновление рейтинга и ранжирования: 1. Модифицировать вес в settings.py (RANK_STEP_*, RARING_*) 2. Пересчитать рейтинг в моделях через функцию `save()` или создать management-command 3. Проверить результаты в `report2.ratings()` и `report2.profiles_rating()` ### Кеширование и производительность: - Картинки схем кешируются автоматически; при добавлении новой схемы нужно явно вызвать функцию генерации - Pre-render HTML нужно чистить при обновлении ценовых данных (см. управление файлами в `seria_info/prepared/`) - БД индексирована на часто используемых полях (`db_index=True`) ### Разработка на macOS: - При установке `mysqlclient` может потребоваться `brew install mariadb-connector-c` - Подробнее см. README.md, раздел "Некоторые заметки относительно разработки" ## Структура папок ``` oknardia/ ├── manage.py ├── oknardia/ │ ├── models.py # ВСЕ модели (1900+ строк) │ ├── settings.py # конфиг, импорт my_secret.py │ ├── urls.py # маршруты (113 строк) │ ├── admin.py │ ├── views.py # главная, контакты, тариф │ └── my_secret.py # CONFIDENTIAL: пароли, ключи ├── web/ │ ├── views.py # основная логика │ ├── add_func.py # утилиты (геокод, расстояния) │ ├── prices.py # отчёты ценовой выдачи │ ├── report1.py # сравнение наборов │ ├── report2.py # рейтинги и ранжирование │ ├── catalog.py # каталоги │ ├── diagrams.py # статистика │ ├── blog.py # список и посты блога │ ├── autocomplete_addr.py # автокомплит адресов │ ├── user_manager.py # логин, регистрация │ └── service.py # служебные функции (sitemap, очистка) ├── templates/ # Django шаблоны (Jinja2-like) │ ├── base.html │ ├── index.html # главная │ ├── seria_info/prepared/ # пре-рендер кеш │ ├── price/ │ ├── catalog/ │ └── ... └── public/ ├── static/ │ ├── img/_flap.cfg/ # схемы окон (большие) │ ├── img/_miniflap.cfg/ # схемы окон (мини) │ ├── css/ │ ├── js/ │ └── ... └── media/ # загружаемые файлы ``` ## Отладка и команды ```bash # Разработка python manage.py runserver # локальный сервер python manage.py makemigrations # подготовить миграцию python manage.py migrate # применить миграцию # Администрирование python manage.py shell # интерпретатор с контекстом Django python manage.py createsuperuser # создать админа python manage.py collectstatic # собрать статику для продакшена # Служебные (см. service.py) # Находятся в urls.py: /service/make_sitemaps, /service/make_rating ``` ## Типичные ошибки и подводные камни 1. **Забывчивость миграций**: при добавлении полей в модель сразу создавай миграцию 2. **Нарушение именования полей**: новые поля должны начинаться с префикса (s, i, f, b, d, k, p) 3. **Незакешированные картинки**: если добавляешь новую схему открывания, вызови функцию генерации явно 4. **Неочищенные pre-render шаблоны**: могут вызвать устаревание данных на страницах серий 5. **Foreign Key ON_DELETE**: используется в основном `DO_NOTHING` и `SET_NULL`, будь осторожен при удалении 6. **Двойной хост**: убедись, что используешь правильные переменные из `my_secret.py` для текущей машины 7. **Индексирование БД**: большинство полей для поиска уже имеют `db_index=True`, но проверь при добавлении фильтров ## Реферальные ссылки (для более глубокого изучения) - **Django 6.0+ docs**: https://docs.djangoproject.com/en/stable/ - **MariaDB/MySQL**: Конфиг БД в settings.py, ENGINE = "django.db.backends.mysql" - **Система рейтинга**: см. functions в report1.py и constants в settings.py (RANK_*, RARING_*) - **Фронтенд**: Bootstrap 3.3.7 (в static/bootstrap-3.3.7-dist.zip), jQuery, Yandex Maps API --- **Автор инструкций**: проанализировано 16.04.2026 **Версия документа**: 1.0 **Последнее обновление**: инструкции в `.github/copilot-instructions.md`