Files
2022_oknardia/AGENTS.md

15 KiB
Raw Blame History

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

Импорт конфиденциальных данных:

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/              # загружаемые файлы

Отладка и команды

# Разработка
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