AAYMA
RU
Войти

EventMatch

Сервис подбора до 3 подрядчиков для мероприятия по анонимизированному каталогу (66 профилей) с объяснениями, календарём доступности, подбором…

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

О проекте

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

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

Суть

Сервис подбора до 3 подрядчиков для мероприятия по анонимизированному каталогу (66 профилей) с объяснениями, календарём доступности, подбором команды из 1–5 ролей и планом Б на соседние даты.

Как устроено

CSV/JSON каталог загружается в память, затем обязательные фильтры (город, категория, дата, формат, цена, длительность, язык) формируют воронку отсева. Ранжирование детерминированное: соответствие пожеланиям (вес 80, по ключевым словам или по сходству embeddings) плюс запас бюджета (вес 20). Команду подбирают динамическим программированием по подмножествам ролей, O(N×R×2^R), с минимальной суммой цен и уникальными исполнителями. Модуль relaxation пересчитывает варианты с изменёнными условиями. Опциональный OpenAI используется только для разбора свободного описания события.

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

  • детерминированный скоринг с весами
  • embeddings-сходство
  • динамическое программирование по подмножествам ролей
  • релаксация ограничений
  • SQLite-кэш embeddings
  • воронка фильтров

Особенности

Подбор команды из нескольких ролей через DP по подмножествам ролей с условием уникальности исполнителей, а не жадный выбор самого дешёвого на каждую роль. Для даты вне календаря каталога API возвращает 422, неизвестная цена не приравнивается к нулю. Экспортирует бриф мероприятия в .txt.

Стек

Python · стандартная библиотека http.server · HTML/CSS/JS · SQLite

Модели

OpenAI (опционально)


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

README

README.md

EventMatch — умный подбор event-подрядчиков

MVP команды WESTcoder для HackAlem. Подбор подрядчиков и команды для мероприятия по анонимизированному каталогу хакатона.

Команда: Nurtilek Koblandy, Meirbek Arystanov, Nurkeldi Adilov.

Запуск

Нужен Python 3.11+. Backend использует стандартную библиотеку, установка пакетов не требуется.

Из корня репозитория:

python -m backend.server

Откройте http://127.0.0.1:8000. Остановка — Ctrl+C. Другой порт: python -m backend.server --port 8080.

Backend и frontend обслуживаются одним процессом. Сборка frontend не нужна. При изменениях Python перезапустите сервер; при изменениях HTML/CSS/JS обновите страницу.

После git pull также перезапустите уже работающий сервер. Если новые блоки появились без оформления или кнопки не работают, проверьте /studio.css и /planner.js: ответ 404 при наличии файлов означает, что старый процесс ещё использует прежний список маршрутов. Остановите его через Ctrl+C, запустите python -m backend.server --port 8765 (либо ваш порт) и обновите страницу через Ctrl+F5.

Рабочий интерфейс — frontend/index.html, его обслуживает Python-сервер. Открытие HTML напрямую или через обычный Live Server не запускает API. Корневой index.html содержит инструкцию запуска; about.html описывает проект. Untitled-1.html — статический предпросмотр каталога.

В VS Code выберите Run and Debug → EventMatch: Python server → F5. Также доступны задачи EventMatch: Run и EventMatch: Tests. Служебные папки .tools и .venv исключены из поиска и анализа. C/C++-исходники внутри этих папок открываются как текст: это код установленных зависимостей, а приложение использует готовые бинарные модули. Диагностика кода проекта остаётся включённой. Если вкладки зависимостей были открыты до изменения настроек, выполните Developer: Reload Window. Настройка основана на ассоциациях файлов VS Code и исключениях C/C++.

Расширение C/C++ Runner для этого Python-проекта не требуется: оно автоматически восстанавливает свои конфигурации при удалении. Если оно уже активно, выберите для него Disable (Workspace) и выполните Developer: Reload Window. Его автоматически созданный вариант запуска скрыт из списка; для приложения используется EventMatch: Python server. В конфигурации IntelliSense убрана ссылка на отсутствующий GCC и указан существующий каталог заголовков установленного Python (C:/Python314/Include на этом компьютере). На другой машине путь можно получить командой python -c "import sysconfig; print(sysconfig.get_path('include'))". Компиляция исходников зависимостей для запуска приложения не требуется.

Возможности

  • EventMatch Studio: адаптивный интерфейс с последовательностью «идея → подрядчики → команда → следующий шаг».
  • Описание события своими словами: редактируемый черновик, опциональный OpenAI и явно обозначенный локальный разбор без ключа.
  • До трёх подрядчиков по городу, дате, категории, формату, бюджету, часам работы и языку.
  • Пожелания к стилю: «спокойная подача, без конкурсов» или «живая музыка, джаз».
  • Сортировка по пожеланиям либо по стартовой цене.
  • Объяснения, цитаты, неподтверждённые пожелания и возможные противоречия.
  • Календарь числа подходящих профилей на каждый из 100 дней. Нажатие на дату запускает подбор. Изменение формы помечает старый календарь неактуальным.
  • Избранное в localStorage, сравнение двух–четырёх профилей, повторная проверка сохранённого запроса. При недоступном хранилище список работает до закрытия страницы.
  • Проверяемые подсказки с изменением от одного до трёх условий, применяемые только по нажатию.
  • Команда из одной–пяти ролей: общая дата и бюджет, отдельные часы для каждой роли, разные подрядчики. При нехватке бюджета показывается минимальная сумма полной команды, если она существует.
  • План Б: до трёх полных команд на соседние даты в пределах ±7 дней. Резерв 0–30% вычитается из общего бюджета до подбора. При выборе варианта бюджет команды уменьшается на резерв; повторно он не вычитается.
  • Бриф мероприятия в UTF-8 .txt: условия, состав команды, стартовые цены и вопросы подрядчикам. Изменение условий скрывает экспорт устаревшего подбора.

Сценарий для жюри, анализ аналогов и следующие продуктовые шаги: PRODUCT_PLAN.md. Проверка требований кейса #79-lite, критерии на 100 баллов и оставшиеся риски: HACKATHON_CHECKLIST.md.

Архитектура

CSV / JSON / JSONL
  → dataset.py: загрузка и нормализация в памяти
  → models.py: проверка запроса и правил датасета
  → filters.py: обязательные ограничения и воронка
  → preferences.py / semantic.py: локальная проверка пожеланий или embeddings описаний
  → scoring.py: детерминированная оценка
  → service.py: сортировка по баллу или цене, максимум 3; календарь
  → team.py: команда с минимальной общей ценой и уникальными исполнителями
  → explanations.py: объяснения из фактов
  → relaxation.py: пересчёт альтернативных условий
  → server.py: REST API
  → frontend/: HTML, CSS, JavaScript

Все ограничения и числовые оценки считаются локально. Для 66 записей достаточно последовательного прохода; отдельные БД каталога и векторное хранилище не требуются. SQLite используется только для опционального кэша embeddings.

Алгоритмы

Фильтры: город → категория → доступность → формат → цена → длительность → язык. Сравнение строк без учёта регистра и лишних пробелов. Бюджет и часы проверяются включительно.

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

В режиме пожеланий балл состоит из соответствия описанию (вес 80) и запаса бюджета (20). Без анализа описания учитывается только запас бюджета. В режиме цены порядок определяется стартовой ценой. В режиме пожеланий сортировка — score DESC → id ASC; в режиме цены — price_from_kzt ASC → id ASC. Балл не является вероятностью или рейтингом качества.

ФакторВесБалл 0–100
Запас бюджета20100 × (1 − price_from_kzt / budget_kzt)
Соответствие описанию80Локальная проверка пожеланий или сходство embeddings

Итог — сумма балл × вес, делённая на сумму активных весов, с округлением до двух знаков. При нулевых бюджете и цене бюджетный компонент равен 100. Если анализ описания недоступен, его вес исключается. Формат, язык и длительность проверяются обязательными фильтрами.

В деталях карточки видны компоненты оценки, веса и факты из профиля. Объяснения рекомендаций строятся локально. Опциональная генеративная модель применяется только для разбора черновика события. Воронка считает каждый профиль на первом непройденном условии; подробный список показывает все нарушения. Прошедшие фильтры кандидаты ниже топ-3 указаны отдельно.

Без внешнего API используется проверка ключевых слов, небольшого словаря близких выражений и простых отрицаний. Это не полноценное понимание произвольного текста. Отсутствие слова не доказывает отсутствие услуги; такие пожелания помечаются как неподтверждённые.

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

Для команды выбирается минимальная сумма стартовых цен. Динамическое программирование по наборам ролей проверяет уникальность исполнителей, а не выбирает по одному самому дешёвому независимо. Сложность: O(N × R × 2^R), где R ≤ 5. Один профиль не может выполнять две роли одновременно.

Фактический датасет

data/contractors.csv — побайтовая копия пользовательского файла hackathon dataset anonymized .csv. Исходный файл не изменялся, новые профили не добавлялись. Имеющийся Untitled-1.html сохранён.

SHA-256: 6a724b6b7dfb5973343e68ba18dadb60fc807d87e3d78f03ee86fb26cb089f7d.

ПолеCSV → приложение
id, anon_nameСтроковые ID и анонимное имя
categoriesСписок категорий, разделитель |
cityАлматы, Астана, Зарубежье
price_from_kztНачальная цена за мероприятие; пустая/невалидная → неизвестна
event_formats, languagesСписки, разделитель |
max_hoursМаксимум часов; пустая строка → None
busy_datesЗанятые даты ISO, разделитель |
descriptionИсходное описание
synthetic, city_imputed, price_imputedФлаги True/False

66 профилей, 17 категорий: Алматы — 50, Астана — 15, Зарубежье — 1. Синтетических профилей — 13; город проставлен у 8, цена у 18; пустой max_hours у 9. Цены: 100 000–6 000 000 ₸. Подробнее: анализ датасета.

Правила исходного каталога:

  • Календарь: 2026-09-23 — 2026-12-31. Вне окна API возвращает 422: отсутствие записи не подтверждает доступность за пределами известного календаря.
  • Для Флорист, Декоратор, Подарки и сувениры пустой max_hours означает работу без почасового присутствия и не препятствует подбору с длительностью.
  • Некорректный max_hours (-1, boolean, нечисловая строка) или отсутствующее поле не равны явно заданному null: при требовании часов профиль исключается с причиной duration_invalid.
  • Для остальных категорий неизвестный лимит не подтверждает запрошенную длительность и приводит к исключению. Без требования часов фильтр не применяется.
  • Пустой список занятых дат — отсутствие занятости в пределах окна. Отсутствующий, null или повреждённый календарь — неизвестная доступность, кандидат исключается.
  • Разделители без дат (|, ||), пустые элементы между датами и даты с завершающим | считаются повреждённым календарём. Явно пустая строка CSV и пустой массив остаются допустимыми.
  • Неизвестная цена не считается нулевой. Синтетические и проставленные значения помечены в интерфейсе.

Загрузчик поддерживает JSON (массив объектов) и JSONL. ID должны быть непустыми и уникальными. При замене DATASET_PATH нужно пересмотреть правила календаря и значение null, настроенные на исходный датасет.

HTML-preview содержит те же профили, что и исходный CSV.

  • Цена «от» не является окончательной стоимостью. Сумма команды — ориентир без дополнительных услуг, логистики и доплат.
  • Отсутствие даты в busy_dates означает отсутствие записи о занятости. Доступность нужно подтвердить; подбор не является бронированием.
  • Контакты, подтверждённые отзывы, фотографии портфолио и полная вместимость площадок не представлены и не выдумываются.
  • Избранное хранит снимок профиля и параметров запроса в конкретном браузере. После изменения каталога или условий используйте «Перепроверить подбор».

Настройки

Опциональный семантический путь использует OpenAI Embeddings API. Для внешнего анализа скопируйте .env.example в .env, задайте свой OPENAI_API_KEY и ENABLE_EMBEDDINGS=true. Не добавляйте .env в Git. Без этих настроек всё работает локально.

ПеременнаяПо умолчаниюНазначение
HOST127.0.0.1Адрес сервера
PORT8000Порт
ENABLE_EMBEDDINGSfalseВнешний анализ
OPENAI_API_KEYпустоКлюч внешнего API
EMBEDDING_MODELtext-embedding-3-smallМодель embeddings
ENABLE_AI_BRIEFfalseРазбор описания события через OpenAI Responses API
BRIEF_MODELgpt-4.1-miniМодель для структурированного черновика
DATASET_PATHdata/contractors.csvCSV, JSON или JSONL
CACHE_DIR.cacheКеш SQLite

Векторы кэшируются по модели и тексту. Ключ решения включает версию схемы, модель, SHA-256 датасета, точные параметры запроса и ID прошедших кандидатов. Близкие дробные бюджеты не смешиваются. Повреждённые векторы не используются. Обычный повтор сохраняет предыдущий результат, включая подбор без семантики после сбоя. Кнопка «Повторить AI-анализ» отправляет refresh_semantic: true и разрешает заменить неудачное решение после восстановления API; успешный ответ затем сохраняется. Это отдельное действие пользователя, которое может изменить порядок. Успешный кэш повторно к API не обращается. Новый CACHE_DIR для восстановления после обычной сетевой ошибки не нужен.

Разные запросы не блокируют друг друга во время сетевого вызова. Для одинакового запроса используется отдельная блокировка, чтобы не выполнять дублирующие вызовы. SQLite-соединения закрываются до обращения к API; запись результатов выполняется короткой транзакцией. Изменение конфигурации, данных, алгоритма или явный повтор AI-анализа может изменить оценку; обычные повторы при неизменном состоянии воспроизводимы.

Сетевой таймаут — 6 секунд. При недоступности API, отсутствии ключа или ошибке кеша используется локальная проверка пожеланий; если пожеланий нет, остаётся бюджетный компонент. UI показывает фактический режим. При неизменных данных, настройках и кеше порядок воспроизводим. Реальный внешний провайдер без пользовательского ключа не проверяется; тесты используют подмену транспорта.

API

Включение AI-разбора

Создайте .env по .env.example, если файла ещё нет. Не перезаписывайте существующий файл с ключами. В своём локальном .env установите:

OPENAI_API_KEY=ваш_ключ
ENABLE_AI_BRIEF=true
BRIEF_MODEL=gpt-4.1-mini

Перезапустите python -m backend.server. В блоке описания появится «AI-разбор · OpenAI». Если виден локальный режим, проверьте флаг и наличие ключа на сервере. При ошибке провайдера черновик явно сообщает о переходе к локальным правилам. Наличие настроек не доказывает работоспособность ключа: проверьте один реальный черновик после настройки аккаунта.

AI-разбор и embeddings включаются независимо. API-ключ не нужно добавлять в HTML, JavaScript, чат или Git. Реальные запросы могут тарифицироваться аккаунтом OpenAI.

backend/brief.py отправляет текст описания в Responses API с Structured Outputs. Ответ дополнительно проверяется: только значения справочников, даты известного календаря, конечные числа и до пяти уникальных ролей. Неизвестные поля остаются незаполненными. Пользователь проверяет черновик до применения. Модель не управляет ранжированием, не придумывает исполнителей и не подтверждает бронирование.

Запросы используют store: false, таймаут 12 секунд, лимит 900 выходных токенов и максимум 10 внешних вызовов в минуту на процесс. Отказ, таймаут, неполный или некорректный ответ возвращают локальный результат с уведомлением. Исходные ошибки провайдера и ключ не выводятся пользователю. Поддержка реального провайдера проверена заглушками транспорта; для живой проверки нужен ваш ключ.

Локальный разбор распознаёт явные города, роли, суммы в тенге и даты YYYY-MM-DD / DD.MM.YYYY. Сложные формулировки и неоднозначность нужно исправить в черновике. Это разбор по правилам, а не языковая модель.

Маршруты

МетодПутьРезультат
GET/api/healthСостояние сервера
GET/api/metaСправочники, границы календаря и демо
POST/api/recommendТоп-3, объяснения, воронка, подсказки
POST/api/calendarЧисло кандидатов на каждый день
POST/api/teamПолная команда или причина отсутствия решения
POST/api/brief{ "text": "описание от 10 до 1500 символов" } → черновик, режим, незаполненные поля
POST/api/planЗапрос команды + reserve_percent (0–30, по умолчанию 10) → исходная дата и до трёх соседних вариантов

Content-Type: application/json, максимум 16 KiB. Ошибки: 400 — некорректный или чрезмерно вложенный JSON; 413 — пустое или слишком большое тело; 415 — неправильный Content-Type; 422 — неверные поля. Отрицательные и бесконечные числа, boolean вместо числа и несуществующие даты отклоняются. Неизвестный город/категория даёт category_not_found; отсутствие подходящих профилей — no_candidates; успешный подбор — matched.

Запрос подбора или календаря:

{
  "city": "Алматы",
  "date": "2026-09-26",
  "event_format": "свадьба",
  "category": "Фотограф",
  "budget_kzt": 600000,
  "duration_hours": 6,
  "language": "русский",
  "preferences": "репортаж, естественные эмоции",
  "sort_by": "style"
}

duration_hours и language могут быть null. preferences — до 1500 символов, по умолчанию пустая строка. sort_by — style или price.

Пример PowerShell:

$eventBody = @{
  city = 'Алматы'
  date = '2026-09-26'
  event_format = 'свадьба'
  category = 'Фотограф'
  budget_kzt = 600000
  duration_hours = 6
  language = 'русский'
  preferences = 'репортаж, естественные эмоции'
  sort_by = 'style'
} | ConvertTo-Json
Invoke-RestMethod http://127.0.0.1:8000/api/recommend -Method Post -ContentType 'application/json; charset=utf-8' -Body ([System.Text.Encoding]::UTF8.GetBytes($eventBody))

Ответ содержит status, message, request, total_candidates (в городе и категории), eligible_candidates, recommendations, filter_stats, excluded_reasons, excluded_candidates, suggestions, semantic_mode, semantic_retry_allowed, dataset_sha256. В рекомендации — поля профиля, name, category, score, score_breakdown, reasons, warnings, explanation. Основная карточка показывает именно explanation из API. Опциональное поле запроса refresh_semantic принимает только boolean и разрешает повтор неудачного AI-анализа.

Запрос команды (budget_kzt — общий бюджет):

{
  "city": "Алматы",
  "date": "2026-09-26",
  "event_format": "свадьба",
  "budget_kzt": 2000000,
  "language": "русский",
  "roles": [
    {"category": "Фотограф", "duration_hours": 6},
    {"category": "Ведущий", "duration_hours": 4}
  ]
}

Подсказки возвращают объект changes, например {"budget_kzt":190000,"duration_hours":12}. Для изменения одного поля также сохранены field и value.

Демо для жюри

Кнопки над результатами выполняют запрос. Результаты ниже — без пожеланий и embeddings, исходный CSV. Для другого каталога демо строятся по его данным.

СценарийУсловияРезультат
Популярная категорияАлматы, 26.09.2026, свадьба, фотограф, 600 000 ₸, 6 ч, русский4 подходят; топ-3: Рок Ли, Сацуки Кусакабэ, Альфонс Элрик
Редкая категорияАлматы, 23.09.2026, свадьба, флорист, 600 000 ₸, 6 ч, русский2 подходят: Тони Тони Чоппер и Тихиро Огино
Никто не подходитПервый запрос с бюджетом 50 000 ₸no_candidates, причины и подсказка по бюджету
Категории нетАстана, декоратор, 26.09.2026category_not_found

Поменяйте дату первого запроса на 27.09.2026: состав выдачи изменится. Откройте «Как мы выбрали?» и подробности карточки. Примените подсказку и сравните количество кандидатов. Каждая подсказка пересчитывается с изменением от одного до трёх параметров и предлагает только реальное увеличение числа совпадений.

Проверки

python -m unittest discover -v
node --check frontend/app.js
node --check frontend/features.js
node --check frontend/planner.js

Необязательный сквозной DOM-тест интерфейса (нужен Node.js 22+):

npm install jsdom --prefix .tools/ui-test --no-save --package-lock=false --ignore-scripts
node --test tests/frontend.test.mjs

Тест сам запускает локальный сервер на свободном порту. Он проверяет действия пользователя и сохранение состояния, но не заменяет визуальную проверку в браузере. Тестовая библиотека находится в игнорируемой папке .tools и не нужна приложению.

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

Ручная проверка: сохранить два профиля, открыть сравнение, обновить страницу и проверить избранное; выбрать дату в календаре; применить составную подсказку; собрать команду и проверить нехватку общего бюджета.

Полный сценарий Studio в установленном Google Chrome, адаптивность на 360/390/768/1024/1440 px и автоматический аудит WCAG A/AA:

npm install playwright @axe-core/playwright jsdom --prefix .tools/ui-test --no-save --package-lock=false --ignore-scripts
node --test tests/browser.test.mjs

Этот тест сам запускает сервер на свободном порту. Он проверяет черновик и его редактирование, подбор команды, резерв, смену даты, скачивание файла, блокировку устаревшего экспорта и восстановление после ошибки. Скриншоты и отчёт доступности сохраняются в игнорируемой папке artifacts/. Автоматический аудит не заменяет ручную проверку всех состояний и вспомогательных технологий.

Чтобы проверить именно уже открытый локальный сервер, включая загрузку CSS/JS и применение оформления:

$env:EVENTMATCH_TEST_URL = 'http://127.0.0.1:8765'
try { node --test tests/browser.test.mjs }
finally { Remove-Item Env:EVENTMATCH_TEST_URL }

Для этого теста используйте локальный сервер с выключенными ENABLE_EMBEDDINGS и ENABLE_AI_BRIEF, чтобы проверки не обращались к платному API.

Браузерная проверка требует Playwright и установленный Google Chrome:

python -m pip install playwright
# В другом терминале должен работать python -m backend.server
python scripts/browser_smoke.py

Проверяет четыре демо, соответствие текста карточек объяснениям API, подсказки, дробные значения, восстановление сети, повторную загрузку каталога, кнопку повторного AI-анализа, отсутствие JS-ошибок, desktop 1440 px и mobile 390 px без горизонтального переполнения. Скриншоты: artifacts/ (не включаются в git).

Ограничения MVP

  • Каталог статический, календарь заканчивается 31.12.2026. Отсутствие занятости не заменяет подтверждение подрядчиком.
  • Цена «от» не является сметой. Оценка не учитывает качество работы и отзывы, которых нет в данных.
  • Описания — заявления профиля, а не независимо проверенные факты. Синтетические записи помечены.
  • Нет бронирований, сообщений, платежей, регистрации и редактирования каталога.
  • Сервер стандартной библиотеки предназначен для локального демо. Для публичной эксплуатации нужны production-сервер, HTTPS и лимиты запросов.
Звёзды
⭐ 0
Форки
0
Язык
Python
Последний push
в прошлом месяце
Коммиты
24
Авторы
3
Файлы
44
Ветки
1

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

Nura007 14Meiirbek Arystanov 6nureeek 6

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

  • 2026-09-23 17:46Fix duplicate planner script and verify frontend asset loadingMeiirbek Arystanov
  • 2026-09-23 17:32Add EventMatch Studio planning workflow and hackathon documentationMeiirbek Arystanov
  • 2026-09-23 16:27Update project filesMeiirbek Arystanov
  • 2026-09-23 15:03Add about pageMeiirbek Arystanov
  • 2026-09-23 17:39Update README.mdnureeek
  • 2026-09-23 13:58Add initial HTML pageMeiirbek Arystanov
  • 2026-09-23 16:58Merge latest README update from origin/mainNura007
  • 2026-09-23 16:57Merge main: integrate event planning features and validation fixesNura007
Все коммиты (24)
  • 2026-09-23 16:55Update README.mdnureeek
  • 2026-09-23 13:54Update project statusMeiirbek Arystanov
  • 2026-09-23 16:52Refactor contractor availability and duration validationNura007
  • 2026-09-23 15:48Revise README for clarity and quick start sectionnureeek
  • 2026-09-23 15:12Merge branch 'main' of https://github.com/BAITC-Hacks/hack-949b5db0-westcoderNura007
  • 2026-09-23 15:12feat: enhance frontend validation and error handlingNura007
  • 2026-09-23 14:53Merge branch 'main' of https://github.com/BAITC-Hacks/hack-949b5db0-westcoderNura007
  • 2026-09-23 14:51first commitNura007
  • 2026-09-23 14:50Revise Project Status and add folder structurenureeek
  • 2026-09-23 14:49Merge branch 'main' of https://github.com/BAITC-Hacks/hack-949b5db0-westcoderNura007
  • 2026-09-23 14:452md stepNura007
  • 2026-09-23 14:00Update README with project planning detailsnureeek
  • 2026-09-23 13:56starterNura007
  • 2026-09-22 21:08Correct spelling of team member's namenureeek
  • 2026-09-22 17:48Update README.mdNura
  • 2026-09-22 17:47Update README with team members listNura
Структура репозитория (44 файлов)
.env.example
.gitattributes
.gitignore
README.md
Untitled-1.html
about.html
backend/__init__.py
backend/brief.py
backend/dataset.py
backend/demos.py
backend/embedding_cache.py
backend/explanations.py
backend/filters.py
backend/models.py
backend/planning.py
backend/preferences.py
backend/relaxation.py
backend/scoring.py
backend/semantic.py
backend/server.py
backend/service.py
backend/team.py
data/contractors.csv
docs/HACKATHON_CHECKLIST.md
docs/PRODUCT_PLAN.md
docs/dataset-analysis.md
frontend/app.js
frontend/favicon.svg
frontend/features.css
frontend/features.js
frontend/index.html
frontend/planner.js
frontend/studio.css
frontend/styles.css
index.html
scripts/browser_smoke.py
tests/__init__.py
tests/browser.test.mjs
tests/frontend.test.mjs
tests/test_api.py
tests/test_features.py
tests/test_planning.py
tests/test_recommendations.py
tests/test_semantic.py

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

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

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