AAYMA
RU
Войти

Event Match

Flask-приложение с веб-интерфейсом и JSON API для подбора до трёх event-подрядчиков с фактическими объяснениями, сравнением карточек, экспортом и…

Доведённый продукт
Команда «TTTU.py» 4💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: TTTU.py
Кейс HackAlem.ai: Креативные индустрии — Firebird
Стадия: Доведённый продукт

Задача кейса: «#79-lite»: подобрать до 3 подрядчиков для мероприятия и объяснить выбор

Суть

Flask-приложение с веб-интерфейсом и JSON API для подбора до трёх event-подрядчиков с фактическими объяснениями, сравнением карточек, экспортом и админкой каталога.

Как устроено

Запрос → валидация → город+категория → hard-фильтры в Python → детерминированное ранжирование → top ≤3 → evidence. Опциональный LLM (любой chat-completions провайдер, JSON-режим, temperature=0, дедлайн 3 с) получает только evidence выбранных кандидатов и возвращает пары candidate_id/reason_id; текст собирает Python, при любой ошибке работает детерминированный fallback. Каталог хранится в SQLite-снимке, замена CSV через аутентифицированную админку.

Ключевые решения

  • hard filtering
  • deterministic ranking
  • evidence-based explanations
  • LLM reason-ID selection
  • JSON response_format
  • SQLite snapshot
  • CSV formula injection protection
  • i18n RU/KZ/EN

Особенности

AI не пишет свободный текст: возвращает только ID причин, а Python проверяет их принадлежность и собирает объяснение. Также есть CONTRACT.md с DTO, трёхъязычный интерфейс, экспорт CSV с защитой от формул и разнесённые unit/integration/frontend тесты.

Стек

Python 3.13 · Flask · Jinja2 · Bootstrap · SQLite · httpx · Waitress · pytest · Ruff · Black


Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-55e98d47-tttu-py.

README

README.md

Event Match

До трёх подходящих подрядчиков из существующего каталога — с объяснением на основе фактов.

Введите город, дату, формат мероприятия, категорию и бюджет; при необходимости — длительность и язык общения. Event Match исключит неподходящих подрядчиков, сравнит оставшихся и покажет цену «от», причины выбора и признаки synthetic/imputed. AI помогает выбрать содержательный фрагмент описания; допуск и порядок определяет Python. Приложение полностью работает без AI-ключа.

Начать: установите Python 3.13, клонируйте репозиторий и выполните команды Quick Start. Откройте http://127.0.0.1:5000, заполните форму или запустите python -X utf8 scripts/demo.py из подготовленного окружения.

CONTRACT.md фиксирует поведение и DTO. Финальная проверка содержит выполненные проверки и ограничения.

Problem & Value

В каталоге сложно одновременно сравнить занятость, цену, формат, языки и содержание описаний. Event Match сокращает список до проверяемого shortlist: пользователь видит не только имена, но и факты, объясняющие каждый выбор. При отсутствии совпадений система показывает причины отказа, чтобы можно было осмысленно изменить запрос. Каталог не расширяется автоматически; бронирование и окончательная цена согласуются с подрядчиком.

How It Works

User Query → Validation → City + Category → Hard Filters
           → Deterministic Ranking → Top ≤ 3 → Evidence
           → AI / Fallback Explanation → Web / API

AI does NOT decide eligibility. Python проверяет город, категорию, занятость, бюджет, формат, опциональные длительность и язык. Модель получает только evidence уже выбранных кандидатов и не может добавить карточку или изменить её место.

FILTER WITH CODE.
RANK DETERMINISTICALLY.
EXPLAIN WITH EVIDENCE.
USE AI WHERE AI ADDS VALUE.
NEVER LET AI OVERRIDE FACTS.

Implemented

  • Единый подбор для HTML и JSON API, максимум три карточки, три явных исхода.
  • Диагностика причин отказа; deterministic ranking и объяснения без внешней модели.
  • Интерфейс и framing объяснений RU / ҚАЗ / EN; язык подрядчика — отдельный фильтр.
  • Смена языка сохраняет черновик и предыдущий результат без повторного AI-вызова.
  • Сравнение 2–3 карточек по фактическим публичным полям без выдуманного «победителя».
  • JSON/CSV-экспорт сохранённого результата; CSV защищён от формул электронных таблиц.
  • Светлый адаптивный интерфейс, synthetic/imputed-маркеры и предупреждение о цене «от».
  • Администратор может проверить CSV, увидеть preview и явно подтвердить полную замену каталога.
  • Отдельные CLI-команды validate/stage для доверенного локального оператора.

Architecture

Модульный монолит: один процесс, Flask routes, общие сервисы и локальная SQLite.

Browser → Web / Jinja2 ─┐
                       ├→ RecommendationService → Filters → Ranking → Evidence
JSON API ──────────────┘                                             ↓
                             CatalogManager ← SQLite       AI reason IDs / Fallback
                                   ↑                                  ↓
                      validated source / active CSV            factual explanation

create_app() создаёт приложение. CatalogManager сериализует чтение/активацию; каждая операция SQLite использует собственное соединение. Один и тот же RecommendationService обслуживает Web, API и экспорт нового запроса. Экспорт snapshot не запускает подбор повторно.

Technology & Project Structure

Python 3.13, Flask 3.1.3, Jinja2, Bootstrap 5.3.3, SQLite из стандартной библиотеки, httpx 0.28.1, Waitress 3.0.2. Проверки: pytest 8.4.2, Ruff 0.16.8, Black 26.5.1. Прямые зависимости закреплены в requirements; транзитивные зависимости разрешает pip. Bootstrap CSS загружается с CDN.

app/
  __init__.py, config.py    factory и runtime configuration
  models/, repositories/   DTO, CSV validation, SQLite
  services/                filtering, ranking, evidence, exports, catalog management
  ai/                      bounded chat-completions transport
  api/, web/               JSON / HTML / authenticated administration
  templates/, static/      Jinja2, CSS, JavaScript
 data/hackathon_dataset.csv исходный каталог: 66 профилей, 13 synthetic
 scripts/                  demo.py, product_qa.py, configure_admin.py
 tests/                    unit, integration, frontend, fixtures
 docs/                     текущий отчёт финальной проверки
 run.py                    development entry point
 requirements*.txt         runtime / development dependencies
 CONTRACT.md               behavioral and technical contract

Quick Start

Требуются Git и установленный Python 3.13. Команды выполняются из корня проекта. Для независимой проверки используйте новую папку clone: локально применённый каталог в instance/ меняет демонстрационные результаты.

Windows / PowerShell:

git clone --branch feature/jonas https://github.com/BAITC-Hacks/hack-55e98d47-tttu-py.git
cd hack-55e98d47-tttu-py
py -3.13 -m venv .venv
.venv/Scripts/python.exe -m pip install -r requirements.txt
Copy-Item .env.example .env
$env:LLM_API_KEY = ""
.venv/Scripts/python.exe run.py

macOS / Linux:

git clone --branch feature/jonas https://github.com/BAITC-Hacks/hack-55e98d47-tttu-py.git
cd hack-55e98d47-tttu-py
python3.13 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
cp .env.example .env
export LLM_API_KEY=""
.venv/bin/python run.py

Откройте http://127.0.0.1:5000; http://127.0.0.1:5000/api/v1/health возвращает {"status":"ok"}. Остановить сервер: Ctrl+C.

.env служит локальным шаблоном и автоматически не загружается. Передавайте значения через $env:NAME = "value" (PowerShell), export NAME="value" (POSIX) или secret manager. Для запуска без AI конфигурация сверх команд выше не нужна. При старте валидируется CSV и создаётся SQLite snapshot; миграции вручную не нужны. Отсутствующий или невалидный каталог останавливает запуск.

Environment Variables

VariableRequiredPurposeSafe example / default
DATASET_PATHНетИсходный CSV и словарь допустимых значенийdata/hackathon_dataset.csv
DATABASE_PATHНетSQLite snapshot, каталог должен быть writableinstance/catalog.sqlite3
CATALOG_ACTIVE_PATHНетПрименённый через Web CSV; имеет приоритет при стартеinstance/catalog-active.csv
CATALOG_STAGING_PATHНетИзолированный CLI staging snapshotinstance/catalog-staged.sqlite3
LLM_API_KEYТолько для AIСекрет провайдера из secret managerПустая строка отключает AI
LLM_BASE_URLТолько для AIHTTPS base URL с version prefix, без /chat/completionshttps://provider.example/v1 — placeholder
LLM_MODELТолько для AIПоддерживаемая провайдером модельyour-model — placeholder
CATALOG_WEB_ADMIN_ENABLEDДля Web admin1 включает администратора при корректных hash и secret0; local setup включает автоматически
CATALOG_ADMIN_PASSWORD_HASHДля Web adminWerkzeug scrypt/pbkdf2 hashСоздаётся local setup; реального значения в Git нет
FLASK_SECRET_KEYДля Web adminСлучайный ключ сессии, минимум 32 символаГенерируется local setup / secret manager
SESSION_COOKIE_SECUREДля HTTPS adminSecure cookie при 10 локально, 1 для HTTPS
CATALOG_ADMIN_ENABLEDДля CLI adminЯвное разрешение validate/stage0; установить 1 оператору
HOSTНетАдрес только development runner127.0.0.1
PORTНетПорт только development runner5000

Пути по умолчанию вычисляются от корня проекта. Явные относительные пути из environment разрешаются от рабочего каталога процесса; для службы удобно использовать абсолютные пути. CSV, активный CSV, SQLite и staging должны быть отдельными файлами. CLI staging отклоняет совпадение с исходным/активным CSV, БД или входным файлом. Environment admin credentials имеют приоритет над локальной конфигурацией.

Without AI / With AI

Без LLM_API_KEY приложение фильтрует, ранжирует и строит конкретные объяснения из evidence. Отсутствие любого из трёх LLM_* значений также включает fallback.

Для AI передайте все три значения через защищённую конфигурацию процесса. Провайдер должен поддерживать chat-completions JSON endpoint, response_format=json_object и temperature=0. Один batch-вызов содержит evidence не более трёх кандидатов; общий deadline — 3 секунды, ответ — до 64 KiB, без повторов и переходов по redirect. AI возвращает только пары candidate_id / reason_id. Python проверяет их принадлежность и формирует текст из фактов и исходной цитаты. Timeout, недоступность, неподдерживаемые параметры, malformed JSON или чужие IDs дают deterministic fallback. AI не участвует в score.

Тесты выполняют AI success, invalid output, network errors и timeout через test doubles; реальный внешний провайдер и его качество/latency при финальной проверке не проверялись.

Usage

  1. Выберите город, дату, формат, категорию и бюджет; необязательно — часы и язык подрядчика.
  2. Нажмите кнопку подбора. Проверьте цену «от», цитату описания и synthetic/imputed-флаги.
  3. Для 2–3 карточек откройте сравнение; скачайте CSV или JSON текущего результата.
  4. Измените дату или бюджет и отправьте новый запрос, чтобы пересчитать подбор.
  5. RU / ҚАЗ / EN меняет интерфейс; прежнее объяснение сохраняет язык генерации.

Исходные описания и значения каталога не переводятся автоматически. При выключенном JavaScript смена locale сохраняет только последние отправленные серверу поля.

API

Method / pathНазначение
GET /api/v1/healthLiveness: 200 {"status":"ok"}; не проверяет провайдера и доступность диска
POST /api/v1/recommendationsПодбор; 200 для всех трёх продуктовых исходов
POST /api/v1/recommendations/exportJSON/CSV нового запроса или ранее сохранённого snapshot
GET /, POST /Форма, подбор и переключение locale
POST /recommendations/export/json, /csvWeb download с export_id в body
GET /admin/catalogВход/управление; без конфигурации — страница 503

Ошибки запроса: 422 с error.code=VALIDATION_ERROR и details. Неожиданная ошибка: generic 500 INTERNAL_ERROR, без исключений и секретов. Полный контракт, включая административные POST-операции и snapshot schema: §13 и §23.

Пример запроса (UTF-8 JSON):

{
  "city": "Астана",
  "event_date": "2026-10-15",
  "event_format": "свадьба",
  "category": "Ведущий",
  "budget_kzt": 1000000,
  "duration_hours": 10,
  "language": "казахский"
}

Фактически полученный ответ исходного каталога без AI:

{
  "status": "matched",
  "count": 1,
  "message": "Найдено подходящих подрядчиков: 1. На выбранную дату заняты 2 подрядчика этой категории; они исключены из подбора. Показаны все подрядчики города и категории, прошедшие условия заказа; их меньше трёх.",
  "recommendations": [{
    "id": "HK-97041",
    "anon_name": "Тэнъя Иида",
    "category": "Ведущий",
    "city": "Астана",
    "price_from_kzt": 1000000,
    "synthetic": false,
    "city_imputed": false,
    "price_imputed": false,
    "explanation": "Цена от 1 000 000 ₸ при бюджете 1 000 000 ₸; категория «Ведущий», город — Астана, формат — «свадьба», дата 2026-10-15 свободна; поддерживаемый язык — казахский; длительность 10 ч не превышает лимит 10 ч. В описании: «Тэнъя ведёт 12 лет на каз/рус языках , современно, интеллигентно , с юмором»."
  }]
}

locale принимает ru (default), kk, en. communication_language — alias language; если переданы оба, их нормализованные значения должны совпадать. Бюджет — целое число от 0 до 10^15, дата — существующая YYYY-MM-DD, длительность — положительное конечное число до 10^6. Optional поля можно опустить или передать null.

Для экспорта нового запроса: {"format":"json","request":{...}} либо csv. Для точного snapshot добавьте X-Enable-Export: true к обычному подбору; ответный X-Recommendation-Export-Token передайте в body {"format":"csv","export_token":"..."}. Отсутствующий/истёкший token даёт 404 EXPORT_NOT_FOUND. Token — bearer capability, его нельзя помещать в URL или журналы. Необязательный сбой snapshot не отменяет подбор.

Snapshots живут 15 минут в памяти процесса, до 128 записей по 256 KiB в каждом Web/API store; возможны вытеснение и потеря при перезапуске. JSON/CSV сохраняют исходные запрос, результат, locale и UTC timestamp. CSV использует UTF-8 BOM, фиксированные колонки и защиту формул. Экспорты формируются в памяти.

Recommendation Logic

  1. Точное совпадение города и вхождение категории в multi-category профиль.
  2. Дата отсутствует в busy_dates; цена «от» не превышает бюджет; формат поддерживается.
  3. Если заданы часы, они не превышают max_hours; null означает, что услуга не привязана к присутствию на площадке. Если задан язык — он входит в languages.
  4. Для допустимых профилей: score = 35B + 45S + 10L + 10D, затем score DESC, id ASC.

B — доля использования бюджета (price/budget, при нулевом бюджете и цене — 1). S — среднее долей совпавших основ слов формата и категории в описании, [0, 1]. L — 1 при явно запрошенном совпадающем языке, иначе 0. D — requested_hours/max_hours; при max_hours=null — 1; без запроса часов — 0. Fraction исключает дрейф floating-point ties. Более высокая цена среди допустимых может повышать budget signal: это использование бюджета, а не рейтинг качества.

Это bounded lexical proxy, а не embedding search. Сначала применяются фильтры, потом score; хороший текст никогда не компенсирует занятость или превышение бюджета. Для top ≤3 Python собирает evidence, затем AI выбирает допустимую цитату либо fallback выбирает первый содержательный фрагмент. При отсутствии такого фрагмента объяснение содержит только структурированные факты.

Outcomes

Product outcomeAPI statusЧто видит пользователь
MATCHEDmatched1–3 карточки; объяснение малого числа результатов и занятости
CATEGORY_NOT_FOUNDcategory_not_foundВ этом городе нет указанной категории
NO_ELIGIBLE_CANDIDATESno_eligible_candidatesКатегория есть; причины отказа по ограничениям

Диагностика учитывает все нарушения каждого профиля: суммы причин могут превышать число профилей. Коды busy, over_budget, wrong_format, duration_too_long, language_mismatch не переводятся; пользовательские подписи локализованы.

Demo Scenarios

Все сценарии используют исходные 66 профилей, без optional полей, бюджет 6 000 000 ₸, город Алматы, формат свадьба, дату 2026-10-15, если не указано изменение. Даты фиксированы для воспроизводимости; система не запрещает исторические даты.

СценарийКатегория / изменениеОжидаемый результат
A: denseВедущий3 карточки: HK-35215, HK-27222, HK-77838
RareФлорист2 карточки, включая synthetic-профиль
B: date sensitivityВедущий; дата 2026-10-16Другой shortlist; занятые исключены
C: emptyВедущий; бюджет 0no_eligible_candidates, причины отказа
Category absentФлорист; город Зарубежьеcategory_not_found
D: AI failureКоманда теста нижеСбой/timeout AI сохраняет eligibility и порядок, включает fallback
E: productRU/ҚАЗ/EN, сравнение, JSON/CSVТе же IDs и сохранённый результат

В другом терминале при запущенном приложении:

.venv/Scripts/python.exe -X utf8 scripts/demo.py
.venv/Scripts/python.exe -X utf8 scripts/product_qa.py

Первый скрипт печатает пять реальных HTTP-ответов с карточками, объяснениями, диагностикой и временем. Второй проверяет API/Web/export, одинаковый порядок для трёх locale, alias языка, сравнение и возвращает краткий JSON. Оба принимают --base-url http://127.0.0.1:8080 для production. Демонстрация контролируемого отказа без ключей и внешних запросов:

.venv/Scripts/python.exe -m pytest -q tests/unit/test_ai_client.py tests/integration/test_ai_pipeline.py --basetemp=.pytest-ai-temp

Catalog Administration

Опционально, для локальной настройки пароля:

.venv/Scripts/python.exe scripts/configure_admin.py

Команда запрашивает пароль дважды и сохраняет только Werkzeug hash и случайный session secret в игнорируемом instance/catalog-admin-auth.json. Перезапустите приложение, откройте /admin/catalog, войдите, скачайте шаблон и загрузите CSV. Preview показывает SHA-256, число профилей/городов/категорий и пять фактических строк. Отдельная кнопка подтверждает полную замену каталога; отмена удаляет preview.

CSV: UTF-8/BOM, до 1 MiB и 1000 профилей, списки через |, колонки исходного dataset. Категории/форматы/языки должны принадлежать исходному словарю. Экспорт рекомендаций имеет другую схему и не предназначен для импорта. Исходный CSV остаётся неизменным; активный CSV сохраняется после перезапуска, прежние recommendation snapshots не меняются. Сессия — 30 минут, preview — 15; CSRF, ограничение входа, HttpOnly/SameSite cookies.

CLI-подготовка изолированного snapshot, без активации:

$env:CATALOG_ADMIN_ENABLED = "1"
.venv/Scripts/python.exe -m flask --app app.admin:create_admin_app catalog-admin validate data/hackathon_dataset.csv
.venv/Scripts/python.exe -m flask --app app.admin:create_admin_app catalog-admin stage data/hackathon_dataset.csv

На POSIX используйте export CATALOG_ADMIN_ENABLED=1 и .venv/bin/python. CLI требует доверенного доступа к ОС; dedicated factory не инициализирует активную БД.

Testing

.venv/Scripts/python.exe -m pip install -r requirements-dev.txt
.venv/Scripts/python.exe -m pytest -q --basetemp=.pytest-release-temp
.venv/Scripts/python.exe -m ruff check .
.venv/Scripts/python.exe -m black --check app tests scripts run.py
.venv/Scripts/python.exe -m pip check

На POSIX замените .venv/Scripts/python.exe на .venv/bin/python. --basetemp обходит ограничения системной temp-папки; pytest очищает эту специально выделенную папку, поэтому не указывайте вместо неё каталог с пользовательскими данными. Тесты покрывают каждый hard filter, deterministic ranking, evidence/AI, три исхода, CSV/SQLite, API/Web, locale/draft/snapshot/export, CSRF и активацию каталога. Запускайте проверки в свежем clone с незаданными операторскими environment overrides.

Финальная проверка на Python 3.13.15: 291 passed; Ruff, Black и pip check успешны. Подробности окружения и границы проверки — в отчёте.

Deployment

Development

python run.py в виртуальном окружении запускает Flask на 127.0.0.1:5000, debug выключен. Для другого адреса/порта задайте HOST и PORT. Flask development server не является production-сервером. Не используйте flask run --debug для размещения.

Production

Поддерживаемый способ — один процесс Waitress, 4 потока, factory app:create_app. Документация Flask описывает эту схему для Windows и POSIX.

.venv/Scripts/python.exe -m waitress --host=127.0.0.1 --port=8080 --threads=4 --max-request-body-size=1114112 --call app:create_app

На POSIX замените путь Python. Адрес и порт задаются --host / --port, health: http://127.0.0.1:8080/api/v1/health. Factory по умолчанию создаёт приложение с debug=False; команда не включает debugger/reloader. Лимит тела Waitress 1 MiB + 64 KiB допускает multipart overhead, Flask дополнительно ограничивает upload до 1 MiB, обычный API body — до 16 KiB.

Для внешнего HTTPS разместите TLS reverse proxy перед loopback Waitress и задайте SESSION_COOKIE_SECURE=1. Не запускайте приложение от root/Administrator. Настройте supervisor/service на рабочий каталог проекта и тот же Python/environment. Конкретный cloud/TLS/service deployment в финальной проверке не выполнялся.

Нужны readable source CSV, writable SQLite directory, writable active/staging directories при администрировании и системная временная папка для буферизации WSGI. Сохраните активный CSV на постоянном диске; SQLite восстанавливается из CSV при старте. Не редактируйте SQLite вручную. Резервируйте свой active CSV перед заменой. Несколько процессов, реплик или одновременный запуск dev и production на одних runtime-файлах не поддерживаются; используйте разные пути либо остановите первый процесс. AI-конфигурация та же, что при локальном запуске, и остаётся опциональной.

Production Readiness & Limitations

Проверяемые основы: environment secrets, валидация, общий deterministic core, ограниченный AI/fallback, защищённое управление каталогом, generic ошибки, health endpoint и автоматические тесты. Текущее состояние проверок — в финальном отчёте.

Ограничения: SQLite и in-memory snapshots/лимиты/preview рассчитаны на один процесс; нет load/SLA проверки, distributed activation, истории каталогов/rollback UI, многопользовательских аккаунтов или бронирования. Health — только liveness. Исходный каталог демонстрационный: synthetic/imputed-флаги не скрываются. Цены «от» и занятость не заменяют подтверждение подрядчика. Bootstrap CDN требует сети; полностью офлайн-визуальная проверка не заявляется. Внешний AI не проверялся live.

Rotate previously exposed credentials before public publication.

Future Development

  • Версионирование каталогов, аудит изменений и откат.
  • Сохранённые поиски и пользовательские аккаунты.
  • Улучшение переводов evidence и multilingual semantic ranking с оценкой качества.
  • Общие snapshots/администрирование для нескольких процессов после измерения нагрузки.
  • Метрики, трассировка отказов и rate limiting публичного API на уровне размещения.
  • Интеграции с актуальными календарями и каталогами при сохранении прозрачных constraints.

Это roadmap. Locale, CSV/JSON-экспорт, сравнение и одиночный администратор уже реализованы.

Reproducibility Checklist

Чеклист для самостоятельного запуска проверяющим; выполненные release-проверки записаны в отчёте.

  • Install dependencies
  • Configure environment
  • Start application
  • Open UI
  • Run recommendation
  • Check API health
  • Run demo scenarios
  • Run tests
Звёзды
⭐ 1
Форки
0
Язык
Python
Последний push
в прошлом месяце
Коммиты
15
Авторы
3
Файлы
69
Ветки
4

Авторы коммитов

hyphens-cell 11VafelkaSSiropom 2Kseniya 2

История коммитов

  • 2026-09-23 15:38Add localization, exports, and comparison viewsVafelkaSSiropom
  • 2026-09-23 14:18,VafelkaSSiropom
  • 2026-09-23 17:16release: final hackathon submissionhyphens-cell
  • 2026-09-23 17:14Update pytest temporary directories in READMEhyphens-cell
  • 2026-09-23 17:08Prepare reproducible Event Match release and protect active catalog staginghyphens-cell
  • 2026-09-23 16:49Add authenticated browser catalog upload and light frontend flowhyphens-cell
  • 2026-09-23 16:13Record final integration, demo and security verificationhyphens-cell
  • 2026-09-23 16:12Integrate localized snapshots and refine light-only recommendation UIhyphens-cell
Все коммиты (15)
  • 2026-09-23 15:39Merge remote-tracking branch 'origin/frontend/denis' into feature/jonashyphens-cell
  • 2026-09-23 15:28Add recommendation exports, localization and safe catalog stagingKseniya
  • 2026-09-23 14:57Merge branch 'feature/jonas'hyphens-cell
  • 2026-09-23 14:39Add contract-aligned test cataloghyphens-cell
  • 2026-09-23 14:35Integrate web recommendation flow and QAhyphens-cell
  • 2026-09-23 14:18Implement deterministic contractor recommendation backendKseniya
  • 2026-09-23 13:45starthyphens-cell
Структура репозитория (69 файлов)
.env.example
.gitignore
CONTRACT.md
README.md
app/__init__.py
app/admin.py
app/ai/__init__.py
app/ai/client.py
app/ai/prompts.py
app/api/__init__.py
app/api/errors.py
app/api/routes.py
app/config.py
app/localization.py
app/models/__init__.py
app/models/contractor.py
app/models/request.py
app/repositories/__init__.py
app/repositories/catalog.py
app/services/__init__.py
app/services/catalog_management.py
app/services/evidence.py
app/services/explanation.py
app/services/export.py
app/services/filters.py
app/services/ranking.py
app/services/recommendation.py
app/static/css/app.css
app/static/js/form.js
app/templates/base.html
app/templates/catalog_admin.html
app/templates/export_error.html
app/templates/index.html
app/web/__init__.py
app/web/catalog_admin.py
app/web/catalog_i18n.py
app/web/exports.py
app/web/i18n.py
app/web/routes.py
data/hackathon_dataset.csv
docs/FINAL_SUBMISSION_VERIFICATION.md
pyproject.toml
requirements-dev.txt
requirements.txt
run.py
scripts/configure_admin.py
scripts/demo.py
scripts/product_qa.py
tests/conftest.py
tests/fixtures/contract_scenarios.csv
tests/frontend/test_web_routes.py
tests/integration/test_ai_pipeline.py
tests/integration/test_api.py
tests/integration/test_catalog_web.py
tests/integration/test_contract_fixture.py
tests/integration/test_export_api.py
tests/integration/test_product_integration.py
tests/integration/test_real_pipeline.py
tests/integration/test_web_pipeline.py
tests/unit/test_ai_client.py
tests/unit/test_catalog_admin.py
tests/unit/test_catalog_management.py
tests/unit/test_explanation.py
tests/unit/test_export.py
tests/unit/test_localization.py
tests/unit/test_ranking.py
tests/unit/test_recommendation.py
tests/unit/test_repository.py
tests/unit/test_validation.py
Ветки (4)

Обсуждение 0 комментариев

Войдите, чтобы комментировать

Пока нет комментариев — будьте первым.