AAYMA
RU
Войти

SmartMatch

Сервис подбора подрядчиков для мероприятия по описанию на русском: извлекает условия, фильтрует каталог из 66 профилей, ранжирует и показывает до…

Рабочий MVP
Команда «ChezaurodynaHackathone» 3💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: ChezaurodynaHackathone
Кейс HackAlem.ai: Креативные индустрии — Firebird
Стадия: Рабочий MVP

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

Суть

Сервис подбора подрядчиков для мероприятия по описанию на русском: извлекает условия, фильтрует каталог из 66 профилей, ранжирует и показывает до трёх кандидатов с объяснением выбора и причинами исключения остальных.

Как устроено

brief.py (или OpenAI) разбирает свободное описание в поля: город, категория, дата, бюджет, формат, язык, длительность; пользователь их проверяет. hard_filter.py применяет жёсткие ограничения и сохраняет причины отказа. engine.py считает взвешенный балл: соответствие описанию 34% (LLM или локальный текстовый индекс), бюджет 30%, язык 12%, длительность 10%, происхождение данных 14%. Затем весь допустимый список сортируется и берутся первые три. Объяснения сервер собирает из фактов профиля и проверенной цитаты. Запросы, результаты и отмеченные кандидаты сохраняются в SQLite.

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

  • hard filtering
  • weighted scoring
  • local text index
  • LLM brief extraction
  • response validation
  • in-memory LRU cache

Особенности

LLM видит только профили, прошедшие фильтры, и не может снять ограничение или поменять цену. Бюджетная эвристика максимальна, когда стартовая цена около 72% верхней границы бюджета. Различаются три исхода: кандидаты есть; категория есть, но никто не подходит; категории нет. Синтетические профили и профили с восстановленными полями помечены и слегка штрафуются.

Стек

Python 3.11 · http.server · sqlite3 · HTML/CSS/JS · Docker · GitHub Actions

Модели

gpt-4.1-mini


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

README

README.md

SmartMatch — MVP подбора подрядчиков

1. Что делает проект

SmartMatch подбирает подрядчика для мероприятия по описанию на русском языке. Пользователь описывает задачу, проверяет заполненные условия и получает до трёх профилей из каталога HackAlem AI. Система объясняет выбор фактами из профиля и показывает причины исключения остальных кандидатов.

Репозиторий команды.

2. Что реализовано

  • Адаптивный сайт: описание, редактируемые параметры, примеры, карточки и подробности отбора.
  • Единая цепочка: разбор описания → проверка параметров → фильтры → ранжирование → объяснения → сохранение в SQLite.
  • Фильтры по городу, категории, дате, диапазону стартовой цены, формату, языку, длительности и происхождению профиля.
  • Сортировка по соответствию, возрастанию или убыванию цены. Сначала сортируются все допустимые кандидаты, затем выбираются первые три.
  • Серверное подключение OpenAI с проверкой ответа и локальным режимом при отсутствии ключа или ошибке API.
  • Постоянная база каталога, истории поисков и отмеченных кандидатов.
  • Три исхода: кандидаты найдены; категория есть, но никто не подходит; категории нет в городе.
  • Общий пакет smartmatch/, автоматические тесты, единая конфигурация и архив ранних прототипов.

3. Технологии и архитектура

Python 3.11+, стандартные библиотеки http.server, sqlite3, urllib, unittest; HTML, CSS и JavaScript без сборщика. Сторонние Python-пакеты для запуска не нужны. SQLite встроена в Python: отдельный сервер базы данных не требуется.

Браузер: HTML / CSS / JavaScript
                  ↓ HTTP JSON
web.py → service.py: общий сценарий приложения
          ├─ brief.py: извлечение условий
          ├─ models.py: проверка запроса
          ├─ database.py + repository.py: каталог
          └─ hard_filter.py → engine.py: фильтры → оценка → сортировка
                                     ↕ ai.py: модель и проверка ответа
                  ↓
SQLite: запрос, снимок результата, выбор кандидата

ИИ получает только прошедшие фильтры профили. Он не может отменить ограничение, изменить цену или добавить подрядчика вне каталога. Объяснения собираются сервером из фактов и подтверждённой цитаты.

4. Порядок установки и запуска

  1. Установите Python 3.11+. В Windows включите добавление Python в PATH.
  2. Скачайте репозиторий либо клонируйте его с доступом к репозиторию команды.
  3. Откройте терминал в папке, где находится run.py, и выполните:
python run.py --open-browser

В Linux/macOS команда может называться python3. В Windows также можно открыть Запустить SmartMatch.cmd двойным щелчком. Адрес сайта: http://127.0.0.1:8000. Терминал сервера оставьте открытым; Ctrl+C останавливает сервер.

При первом запуске создаётся runtime/smartmatch.sqlite3 и импортируется каталог. Без ключа доступны форма, фильтры, сортировка, локальный разбор и запись истории. ИИ подключается по инструкции ниже.

Двойной щелчок по smartmatch/static/index.html показывает оформление, но не запускает API, поиск или базу. Для полноценной работы используйте HTTP-адрес.

5. Пример проверки

Нажмите «Посмотреть на примере» — это локальный подбор без расходов API. Либо введите:

Нужен ведущий на корпоратив в Алматы 6 октября 2026 года. Бюджет до 1 млн тенге, русский язык, 5 часов. Интеллигентная подача для бизнес-аудитории, без навязчивых конкурсов.

Нажмите «Заполнить по описанию», проверьте форму, затем «Найти подрядчиков». Для исходного каталога, минимальной цены 0 и включённых синтетических профилей ожидаются 6 подходящих профилей, показаны 3. В карточках есть объяснение, язык, стартовая цена и календарь. Отметка кандидата сохраняется в БД и не является бронированием.

Автоматическая проверка без ключа:

python -m unittest discover -s tests -v
python scripts/evaluate.py

6. Используемые данные и внешние сервисы

Рабочий источник — data/contractors.csv: 66 анонимизированных профилей, из них 53 исходных и 13 синтетических. У 8 записей восстановлен город, у 18 — цена; метки сохранены в БД и видны на сайте. «Исходный» означает происхождение из предоставленного каталога, а не независимую проверку подрядчика.

OpenAI — необязательный сервис извлечения условий и оценки соответствия описаний. В коде по умолчанию задана модель gpt-4.1-mini; её можно заменить настройкой. Доступность, стоимость и ограничения зависят от вашего API-проекта. При отключённом ИИ внешних запросов нет.

SQLite сохраняет условия и пожелания, снимок ответа, фактический режим ИИ и отмеченных кандидатов. Подробности — в разделе базы данных.

7. Известные ограничения

  • Календарь: 23.09.2026–31.12.2026. Даты вне периода не принимаются; данные не обновляются автоматически.
  • Цена «от» не является коммерческим предложением. Диапазон бюджета сравнивается со стартовой ценой; окончательную стоимость нужно подтвердить.
  • Отсутствие занятой даты в выборке не гарантирует актуальную доступность. Нет оплаты, контактов, сообщений или бронирования.
  • У 9 строк max_hours не задан. В MVP это отсутствие применимого ограничения: такой профиль не исключается по длительности; время нужно подтвердить отдельно.
  • Форма поддерживает один обязательный язык. Запрос «русский и казахский» считается неоднозначным: выберите основной язык вручную; требование владеть обоими одновременно пока не реализовано.
  • Локальный текстовый поиск хуже понимает смысл и отрицания, чем языковая модель. Балл не является вероятностью успешного мероприятия.
  • Проверка цитат и ID не доказывает качество подрядчика. Распознанные условия пользователь подтверждает вручную.
  • Встроенный HTTP-сервер предназначен для локальной демонстрации и хакатона. Публичное размещение требует HTTPS, контроля доступа, лимитов API и правил хранения пользовательских данных.
  • Нет аккаунтов, административного редактора каталога, автоматического обучения на истории и многосерверной синхронизации.

8. Развёрнутая версия

Публичная версия пока не развёрнута. После запуска: http://127.0.0.1:8000. Текущий рабочий просмотр может использовать порт 8010. Оба адреса локальные: они не открывают сайт на компьютерах других участников сами по себе.


Работа с формой и фильтрами

  1. Укажите, кто нужен, город, полную дату с годом, формат и бюджет в тенге. Язык и длительность необязательны.
  2. Выполните разбор описания. Недостающие или неоднозначные условия не подставляются автоматически.
  3. Проверьте поля. Ручные изменения имеют приоритет при следующем разборе. Если текст ещё не разобран, первое нажатие поиска заполнит поля для проверки, второе выполнит подбор.
  4. Задайте минимальную цену, происхождение профилей и сортировку при необходимости.
  5. Получите карточки; раскройте «Как прошёл отбор» для причин исключения.
  6. Отметьте подходящих кандидатов: это сигнал интереса в истории, без отправки сообщения или бронирования.

После изменения условий предыдущий список помечается как устаревший — выполните поиск снова. Один профиль может не пройти несколько условий, поэтому сумма причин отказа может превышать число исключённых кандидатов.

ПараметрПравило
Город, категорияСовпадение с каталогом без учёта регистра; у профиля возможны несколько категорий
ДатаВ пределах календаря и отсутствует в занятых датах
Максимальный бюджетЦелое число 1–1 000 000 000 ₸; стартовая цена не выше
Минимальная ценаЦелое число от 0 до максимального бюджета; стартовая цена не ниже
ФорматВходит в поддерживаемые форматы
ЯзыкЕсли выбран, входит в языки профиля; пустое значение — любой
ДлительностьВ форме 0,5–24 часа с шагом 0,5; API принимает любое конечное число больше 0 и не выше 24; не превышает заданный max_hours
Синтетические профилиПри отключении исключаются все строки с synthetic=true
ПожеланияВлияют на оценку текста, не отменяют условия формы

Некорректные строки CSV изолируются до подбора. Метаданные содержат число и причины таких записей. Пустой корректный каталог останавливает запуск с ошибкой.

Оценка и сортировка

КомпонентВес
Соответствие описания: ИИ или локальный текстовый индекс34%
Соответствие бюджету30%
Язык12%
Длительность10%
Происхождение и восстановленные данные14%

Бюджетная эвристика достигает максимума при стартовой цене около 72% верхнего бюджета. Это выбранная формула, а не доказательство качества услуги. Синтетическое происхождение и восстановленные цена/город немного снижают составляющую качества данных. Формула находится в smartmatch/engine.py.

relevance сортирует по итоговому баллу, price_asc — по возрастанию цены, price_desc — по убыванию. При равенстве используется ID. Сортировка по цене может показать других кандидатов: она применяется ко всему допустимому списку до ограничения в три карточки.

Локальный режим воспроизводим при неизменных запросе и каталоге. Успешные ответы ИИ кэшируются в памяти (128 записей); одинаковые параллельные запросы синхронизированы. После перезапуска или вытеснения из кэша оценка модели может измениться. SQLite хранит прошлый результат, но не служит постоянным кэшем модели.

Настройка OpenAI

Создайте .env рядом с run.py на основе .env.example, не перезаписывая уже заполненный файл.

PowerShell:

if (-not (Test-Path .env)) { Copy-Item .env.example .env }
notepad .env

Linux/macOS:

test -f .env || cp .env.example .env

Впишите ключ после OPENAI_API_KEY= только в локальном .env:

SMARTMATCH_AI_PROVIDER=openai
SMARTMATCH_AI_MODEL=gpt-4.1-mini
OPENAI_API_KEY=
SMARTMATCH_AI_TIMEOUT=8

Сохраните файл и перезапустите сервер. Переменные окружения имеют приоритет над .env. Статус «OpenAI настроен» подтверждает конфигурацию, а не успешный вызов. Реальная проверка — подбор с включённым ИИ; поле ответа ai.used показывает, использовалась ли модель для ранжирования.

.env исключён из Git и Docker-образа. Не вставляйте ключ в HTML, JavaScript, README или .env.example. На хостинге задайте OPENAI_API_KEY в переменных окружения сервиса.

Запросы модели

При разборе передаются описание пользователя и допустимые значения каталога. При ранжировании — условия заказа, анонимные ID и описания только прошедших фильтры подрядчиков. Не вводите в пожелания секреты или ненужные персональные данные: текст передаётся модели и сохраняется в локальной истории.

OpenAI-адаптер вызывает /v1/responses, задаёт JSON Schema и store: false. Сервер проверяет полноту списка, ID, оценки 0–100 и буквальное присутствие цитат в исходных описаниях. Извлечённые числа и даты должны подтверждаться фрагментами пользовательского текста. Ошибка API или неподтверждённый ответ заменяются локальным результатом с явным пояснением.

Одновременно разрешены два сетевых вызова. SMARTMATCH_AI_TIMEOUT — время ожидания одного вызова, 1–30 секунд, по умолчанию 8. Это не пользовательская квота расходов.

В коде также сохранены адаптеры gemini и compatible. Совместимому сервису нужны SMARTMATCH_AI_PROVIDER=compatible, SMARTMATCH_AI_MODEL, SMARTMATCH_AI_BASE_URL и SMARTMATCH_AI_API_KEY либо OPENAI_API_KEY; он должен поддерживать используемую JSON Schema. Для Gemini задаются SMARTMATCH_AI_PROVIDER=gemini и GEMINI_API_KEY. Тестовые ответы проверяют адаптеры, но не доказывают совместимость любого внешнего провайдера.

База данных и сбор информации

Рабочая база создаётся автоматически: runtime/smartmatch.sqlite3. При первом запуске CSV проверяется и импортируется одной транзакцией. Повторный запуск не дублирует и не перезаписывает каталог или историю. Изменение CSV не обновляет уже созданную БД автоматически. Для отдельного нового каталога задайте новый путь через --db; сервер загружает каталог при запуске, поэтому после изменения БД нужен перезапуск.

ТаблицаСодержимое
profilesОсновные сведения, происхождение, цена, календарь
profile_categories, profile_event_formats, profile_languagesКатегории, форматы, языки
profile_busy_datesЗанятые даты
metadata, import_auditВерсия, первичный импорт, изолированные строки
searchesВремя UTC, нормализованный запрос, полный снимок ответа
search_resultsПоказанные подрядчики и порядок карточек
selectionsОтметки кандидатов, привязанные к конкретному поиску

У каждого поиска свой search_id. Сохраняются и поиски без результатов. Отметить можно только подрядчика, показанного в этом поиске. Повторная отметка той же пары не создаёт дубль; можно отметить несколько кандидатов. Система не определяет реального заказчика и не объединяет его действия между поисками.

Ключи API, IP-адреса и отпечатки браузера в таблицы не записываются. Веб-сервер ведёт обычный консольный журнал запросов, в котором присутствует сетевой адрес клиента. Текст пожеланий хранится как введён пользователем; автоматического удаления или обезличивания свободного текста нет.

База использует внешние ключи, транзакции, режим WAL и отдельное соединение для каждой операции. Запись истории — часть запроса: при недоступном хранилище сервер возвращает ошибку вместо ложного сообщения «сохранено». История не доступна через публичный HTTP-маршрут: выгрузку делает оператор локально.

Инициализация и выгрузка

Создать базу без запуска сайта или посмотреть количество записей:

python scripts/init_database.py
python scripts/init_database.py --db runtime/catalog-test.sqlite3 --csv data/contractors.csv

Выгрузить запросы, результаты и выбор кандидатов в UTF-8 JSON:

python scripts/export_history.py --output exports/history.json

Для другого файла базы добавьте --db путь/к/базе.sqlite3. Экспорт содержит текст пользовательских пожеланий; храните его с теми же ограничениями доступа, что и БД. Команда отказывается перезаписывать существующий файл: для повторной выгрузки задайте новое имя, например exports/history-2026-09-24.json.

Дополнительные синтетические профили

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

python scripts/init_database.py --db runtime/synthetic-demo.sqlite3 --generate 30
python run.py --db runtime/synthetic-demo.sqlite3 --port 8011

Получится 96 записей: 53 исходных, 13 синтетических из CSV и 30 новых тестовых. Генератор использует фиксированный seed и явные правила data/synthetic_profile_rules.json, не обращается к ИИ и помечает добавленные записи как синтетические. Другой файл правил задаётся --rules; допустимое количество — 0–10 000. Повторение той же генерации пропускает совпадающие ID, конфликтующие данные откатывают новую партию. Это число запрашиваемых образцов, а не команда уменьшения каталога; --generate 0 не удаляет уже добавленные записи. После изменения БД перезапустите сервер.

Файлы *.sqlite3, их журналы и папка exports/ исключены из Git. Перед переносом БД остановите сервер; для работающей базы используйте SQLite Backup API, а не копирование одного файла без WAL. Политики сроков хранения и удаления пользовательских запросов в MVP ещё нет.

HTTP API

POST-запросам нужен Content-Type: application/json; тело ограничено 32 768 байтами. API принимает описание и пожелания длиной не более 6000 символов; поле описания на сайте ограничено 5000. Неверные типы, бесконечные числа, некорректная дата или диапазон цены отклоняются.

МаршрутНазначение
GET /api/healthДоступность сервера и БД
GET /api/metaВарианты фильтров, календарь, качество каталога, статус ИИ без ключа
POST /api/parse-briefИзвлечение редактируемых условий
POST /api/recommendПодбор и запись поиска
POST /api/selectionОтметка кандидата из конкретной выдачи

Для /api/parse-brief:

{
  "description": "Нужен ведущий на корпоратив в Алматы 6 октября 2026 года, до 1 млн тенге, 5 часов, русский язык.",
  "use_ai": false
}

Ответ: query, missing_fields, warnings, mode, message. Сам разбор не создаёт подбор и не бронирует услугу.

Для /api/recommend:

{
  "city": "Алматы",
  "event_date": "2026-10-06",
  "event_format": "корпоратив",
  "category": "Ведущий",
  "budget_kzt": 1000000,
  "min_budget_kzt": 0,
  "language": "русский",
  "duration_hours": 5,
  "preferences": "Интеллигентная подача для бизнес-аудитории",
  "include_synthetic": true,
  "sort_by": "relevance",
  "use_ai": false
}

status: success, no_eligible или no_market. results — карточки; pipeline — количество после каждого этапа; exclusions и rejected_candidates — причины отказа; eligible_count — число всех допустимых профилей; ai.used — фактический режим. search_id и saved: true подтверждают запись истории.

Сохраните показанный JSON в request.json. PowerShell:

$body = [System.IO.File]::ReadAllText((Resolve-Path request.json))
$result = Invoke-RestMethod 'http://127.0.0.1:8000/api/recommend' -Method Post -ContentType 'application/json; charset=utf-8' -Body ([System.Text.Encoding]::UTF8.GetBytes($body))
$result | ConvertTo-Json -Depth 10

Linux/macOS:

curl -s http://127.0.0.1:8000/api/recommend -H 'Content-Type: application/json' --data-binary @request.json

Для /api/selection подставьте search_id и ID из его results:

{"search_id": "ID_полученного_поиска", "contractor_id": "ID_показанного_подрядчика"}

Успешный ответ — {"saved": true, "created": true}; повторная отметка возвращает created: false. Неизвестная пара отклоняется. Проверка принадлежности карточки поиску не заменяет авторизацию пользователя: для публичного сервиса её нужно добавить.

Параметры запуска и Docker

python run.py --host 127.0.0.1 --port 8010 --open-browser
python run.py --data data/contractors.csv --db runtime/smartmatch.sqlite3
python run.py --help

По умолчанию --host 127.0.0.1, --port 8000. Для демонстрации в локальной сети используйте --host 0.0.0.0, затем IP-адрес компьютера. Участникам нужен сетевой доступ к этой машине.

Docker Compose:

docker compose up --build -d
docker compose logs -f smartmatch
docker compose down

Откройте http://127.0.0.1:8000. По умолчанию порт контейнера доступен только на локальном компьютере. Compose подставляет OpenAI-настройки из .env и сохраняет SQLite в именованном томе smartmatch-data, путь контейнера — /var/lib/smartmatch/smartmatch.sqlite3. Обычный docker compose down оставляет том. Не используйте down -v, если нужно сохранить собранные данные.

Вариант без Compose:

docker build -t smartmatch .
docker run --rm -p 127.0.0.1:8000:8000 --env-file .env -v smartmatch-data:/var/lib/smartmatch smartmatch python run.py --host 0.0.0.0 --port 8000 --db /var/lib/smartmatch/smartmatch.sqlite3

Для локального режима без файла настроек уберите --env-file .env. Сам контейнер не делает сайт публичным сервисом с HTTPS и авторизацией.

Проверки и диагностика

python -m unittest discover -s tests -v
python scripts/evaluate.py

Тесты покрывают фильтры и сортировку, границы значений, разбор текста, цитаты и ID, кэш, ошибки модели, HTTP и SQLite. Тестовый транспорт не обращается к API. scripts/evaluate.py выводит JSON со сценариями, временем и 100 повторами локального запроса; проверяйте all_checks_passed. Время зависит от машины.

Проверена работа локального сайта, фильтров и сохранения отметки в SQLite. Живой вызов OpenAI с действующим ключом и запуск контейнера Docker в текущей проверке не выполнялись; подготовленная конфигурация не означает, что они уже проверены в вашей среде.

Условия, ИИ выключенРезультат исходной выборки
Алматы / Ведущий / 06.10.2026 / корпоратив / до 1 млн / русский / 5 ч6 допустимых, 3 карточки
Алматы / Флорист / 04.10.2026 / свадьба / до 500 тыс. / русский2 карточки
Алматы / Флорист / 01.10.2026 / свадьба / до 500 тыс. / русскийno_eligible
Астана / Декоратор / 04.10.2026 / свадьба / до 1 млн / русскийno_market

Во всех примерах минимальная цена — 0, синтетические профили включены. После изменения каталога числа могут измениться.

ПроблемаРешение
HTML открылся, кнопки не работаютЗапустите сервер и откройте HTTP-адрес
python не найденУстановите Python 3.11+; попробуйте py -3 в Windows или python3 в Linux/macOS
Порт занятОстановите старый запуск или укажите другой --port
ИИ не включаетсяПроверьте файл .env рядом с run.py, затем перезапустите сервер
ИИ настроен, но ответ локальныйПроверьте доступ к модели, ключ, лимиты, сеть; возможен тайм-аут или отклонение ответа при валидации
Нет кандидатовОткройте причины исключения, проверьте диапазон цены, дату, длительность и остальные условия
База недоступнаПроверьте доступ на запись в папку --db и целостность файла
CSV изменён, а каталог прежнийИмпорт выполняется один раз; используйте отдельную новую БД или осознанную миграцию
CSS изменён, а автономный HTML прежнийВыполните python scripts/embed_styles.py и обновите страницу

Структура репозитория и анализ кода

run.py                         Единая точка запуска
Запустить SmartMatch.cmd       Запуск для Windows
README.md                      Общий гайд
.env.example                   Пустой пример серверной конфигурации
Dockerfile, compose.yaml       Контейнер и постоянный том
smartmatch/
  web.py, service.py           HTTP и общий сценарий приложения
  models.py                   Типы и проверка параметров
  repository.py               Импорт и проверка CSV
  database.py, schema.sql      SQLite, история и выбор
  hard_filter.py              Жёсткие условия
  engine.py                   Оценка, сортировка, объяснения
  ai.py, brief.py, text.py     ИИ, разбор и локальный индекс
  samples.py                  Общие демонстрационные запросы
  generate_profiles.py        Необязательные синтетические образцы
  static/                     HTML, CSS, JavaScript, значок
data/contractors.csv           Исходные 66 профилей
data/synthetic_profile_rules.json Правила необязательной генерации
runtime/smartmatch.sqlite3        Создаётся локально, не входит в Git
scripts/                      Проверки, обслуживание БД, обновление CSS
tests/                        Тесты рабочего MVP
docs/CODE_REVIEW.md            Анализ модулей и решений
archive/prototypes/           Исторические эксперименты команды
.github/workflows/tests.yml   Автоматическая проверка

Прежние second-layer, third-layer и Database описывали разные модели, переменные AI_PROXY_*, точки запуска и каталог на 96 профилей. Они не образовывали единого сайта: третий этап зависел от модуля из другой папки, а некоторые файлы базы отсутствовали.

Рабочая цепочка теперь находится в smartmatch/ и использует общий .env. Отдельный генеративный запрос прототипа объяснений не выполняется: проверенные цитаты и факты объединяются в объяснение на сервере. Дополнительные 30 синтетических записей не смешиваются с исходными 66 автоматически.

Оригинальные эксперименты сохранены в archive/prototypes/ranking, explanations и database. Они не импортируются сервером. Исторические DESIGN_NOTES.md, API_SETUP.md и DATABASE_GUIDE.md сохраняют контекст команды; их команды и модели не являются инструкцией запуска MVP. Единственный актуальный README — этот файл. Подробный результат анализа — docs/CODE_REVIEW.md.

Исходник оформления — smartmatch/static/styles.css. Его копия встроена в HTML для просмотра оформления без сервера. После правок выполняйте python scripts/embed_styles.py, чтобы копии совпадали.

Звёзды
⭐ 0
Форки
0
Язык
Python
Последний push
в прошлом месяце
Коммиты
20
Авторы
3
Файлы
68
Ветки
2

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

islamabdul 13Delta Greencheese 8yei48 1

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

  • 2026-09-23 17:44Add UI design specifications for frontendyei48
  • 2026-09-23 17:13Integrate SmartMatch MVP with unified filters, SQLite history and complete guideislamabdul
  • 2026-09-23 16:44Explain standalone HTML styling and full application launchislamabdul
  • 2026-09-23 16:44Add script to refresh embedded stylesheet from CSS sourceislamabdul
  • 2026-09-23 16:44Keep SmartMatch styling when index.html is opened without adjacent assetsislamabdul
  • 2026-09-23 16:36Add files via uploadDelta Greencheese
  • 2026-09-23 16:33Create welp.txtDelta Greencheese
  • 2026-09-23 16:21Preserve complete browser script and stabilize HTTP validation responsesislamabdul
Все коммиты (20)
  • 2026-09-23 16:15Add files via uploadDelta Greencheese
  • 2026-09-23 16:15Build description-first SmartMatch site with validated server-side OpenAI matchingislamabdul
  • 2026-09-23 16:13Create help.txtDelta Greencheese
  • 2026-09-23 15:56Add files via uploadDelta Greencheese
  • 2026-09-23 15:56Create help.txtDelta Greencheese
  • 2026-09-23 15:42Keep result cards scrollable within reference layoutislamabdul
  • 2026-09-23 15:41Match SmartMatch UI to approved referenceislamabdul
  • 2026-09-23 15:39Match SmartMatch UI to approved referenceislamabdul
  • 2026-09-23 15:17Add strict hard-filter gate and rejection diagnosticsislamabdul
  • 2026-09-23 14:40Added profile generator for test drive the systemDelta Greencheese
  • 2026-09-23 14:38Build deterministic explainable contractor matcherislamabdul
  • 2026-09-23 13:53Add project system filtering requirementsDelta Greencheese
Структура репозитория (68 файлов)
.dockerignore
.editorconfig
.env.example
.gitattributes
.github/workflows/tests.yml
.gitignore
Dockerfile
README.md
archive/original-plan.txt
archive/prototypes/database/DATABASE_GUIDE.md
archive/prototypes/database/DESIGN_NOTES.md
archive/prototypes/database/contractors.csv
archive/prototypes/database/generate_profiles.py
archive/prototypes/database/init_database.py
archive/prototypes/database/schema.sql
archive/prototypes/database/synthetic_profile_rules.json
archive/prototypes/database/test_profile_database.py
archive/prototypes/database/welp.txt
archive/prototypes/explanations/API_SETUP.md
archive/prototypes/explanations/DESIGN_NOTES.md
archive/prototypes/explanations/examples/selected_profiles.json
archive/prototypes/explanations/help.txt
archive/prototypes/explanations/profile_explanations.py
archive/prototypes/explanations/set_test_key.ps1.example
archive/prototypes/explanations/test_profile_explanations.py
archive/prototypes/explanations/verify_profile_explanations.py
archive/prototypes/ranking/DESIGN_NOTES.md
archive/prototypes/ranking/help.txt
archive/prototypes/ranking/set_test_key.ps1.example
archive/prototypes/ranking/smartmatch.py
archive/prototypes/ranking/test_smartmatch.py
archive/prototypes/ranking/verify_openai_proxy.py
compose.yaml
data/contractors.csv
data/synthetic_profile_rules.json
design
docs/CODE_REVIEW.md
pyproject.toml
requirements.txt
run.py
scripts/embed_styles.py
scripts/evaluate.py
scripts/export_history.py
scripts/init_database.py
smartmatch/__init__.py
smartmatch/ai.py
smartmatch/brief.py
smartmatch/database.py
smartmatch/engine.py
smartmatch/generate_profiles.py
smartmatch/hard_filter.py
smartmatch/models.py
smartmatch/repository.py
smartmatch/samples.py
smartmatch/schema.sql
smartmatch/service.py
smartmatch/static/app.js
smartmatch/static/favicon.svg
smartmatch/static/index.html
smartmatch/static/styles.css
smartmatch/text.py
smartmatch/web.py
tests/test_ai.py
tests/test_database.py
tests/test_engine.py
tests/test_repository.py
tests/test_web.py
Запустить SmartMatch.cmd
Ветки (2)

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

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

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