AAYMA
RU
Войти

ToiMatch

Сервис подбора до трёх event-подрядчиков: каждый факт в объяснении сверяется с каталогом.

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

О проекте

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

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

Суть

Сервис подбора до трёх event-подрядчиков: каждый факт в объяснении сверяется с каталогом. Есть рабочее место площадки с пошаговым стримом решений, чат-помощник для сборки пакета мероприятия, три языка и маскот.

Как устроено

NestJS-пайплайн состоит из четырёх частей. FilterService фильтрует по городу, категории, дате, формату, бюджету, языку и часам и строит воронку. RankingService задаёт детерминированный порядок с tie-break по id. ExplainerService собирает проверяемые варианты причин из полей каталога, отличий от других карточек и фрагментов анкет. LLM только выбирает вариант, свободный текст не пишет, затем код-критик сверяет факты, а результат кешируется в PostgreSQL. Шаги отдаются через SSE, чат работает через реестр инструментов, так что имена берутся из результатов инструментов. В режиме MOCK всё работает без сети.

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

  • детерминированная фильтрация с воронкой
  • выбор LLM из проверенных вариантов объяснений
  • fact-check критик
  • кеш объяснений
  • SSE стрим пайплайна
  • tool registry в чате
  • injection guard
  • MOCK LLM клиент

Метрики

время ответа 15–250 мс в режиме без ключа (MOCK)

Особенности

LLM не генерирует текст о подрядчике, а выбирает среди вариантов, собранных сервером из данных, поэтому галлюцинации исключены по построению. На экране /manager видна таблица «факт объяснения → поле каталога → ✓». Отдельный режим чата собирает пакет мероприятия с расчётом минимального бюджета. README на трёх языках, есть видео-демо.

Стек

Next.js 16 · React 19 · TypeScript · Tailwind CSS 4 · NestJS 11 · Prisma 6 · PostgreSQL 16 · Docker Compose

Модели

gpt-4o-mini · gpt-image-2


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

README

README.md

ToiMatch — подбор event-подрядчиков с доказательствами

HackAlem AI 2026 · трек 06 «Креативные индустрии» · задача Firebird «Умный подбор подрядчиков» (#79-lite) · команда Code & Design (Ян Пинчук, Никита Костров, Иван Лысов)

Русский · Қазақша · English

Запасное видео демо (2:36): docs/demo/toimatch-demo.mp4 — весь сценарий проверки с подписями.

Как запустить

Нужен только Docker (с Docker Compose v2). Ключи не нужны.

git clone https://github.com/BAITC-Hacks/hack-cf5b3e57-code-design.git
cd hack-cf5b3e57-code-design
docker compose up --build

Одна команда поднимает PostgreSQL, применяет миграции, загружает сид (66 подрядчиков), запускает API и фронт. Первая сборка занимает несколько минут.

Остановить и очистить базу: docker compose down -v.

Пример переменных окружения

Всё работает без файла .env. Для живой модели скопируйте .env.example в .env в корне проекта (файл в .gitignore), впишите ключ и поставьте MOCK=0. Команда та же: docker compose up --build.

# .env.example (корень проекта, для Docker Compose)
MOCK=1                      # 1 — без модели; 0 — OpenAI (нужен ключ)
OPENAI_API_KEY=             # необязательно
MODEL_MAIN=gpt-4o-mini
CORS_ORIGIN=http://localhost:3000
NEXT_PUBLIC_API_URL=http://localhost:3001

Для запуска без Docker есть отдельные примеры: back/.env.example и front/.env.example.

# back/.env.example
DATABASE_URL="postgresql://postgres:postgres@localhost:5433/hackaton?schema=public"
PORT=3001
MOCK=1
OPENAI_API_KEY=
MODEL_MAIN=gpt-4o-mini

# front/.env.example
BACKEND_URL=http://localhost:3001
NEXT_PUBLIC_API_URL=http://localhost:3001

Docker по умолчанию работает без ключа (MOCK=1): объяснения строятся из тех же проверенных фактов детерминированно, сеть не нужна. Для живой модели передайте OPENAI_API_KEY через окружение и установите MOCK=0; ключ не записывайте в репозиторий.

Запуск с живой моделью (по желанию)

Нужен Node.js 22+. База остаётся в Docker, бэк и фронт запускаются локально:

docker compose up -d postgres
cd back
cp .env.example .env        # вписать OPENAI_API_KEY и установить MOCK=0
npm install
npx prisma migrate deploy
npx prisma db seed
npm run start:dev           # API на http://localhost:3001

Во втором терминале:

cd front
cp .env.example .env.local
npm install
npm run dev                 # http://localhost:3000

Переменные окружения

ПеременнаяГдеЗачемОбязательна
DATABASE_URLback/.envподключение к PostgreSQLда, значение из back/.env.example
PORTback/.envпорт APIнет, 3001
OPENAI_API_KEYback/.env / окружение Composeживые объяснения и чат моделью при MOCK=0нет — без ключа работает MOCK
MODEL_MAINback/.envмодель OpenAIнет, gpt-4o-mini
MOCKback/.env / compose1 — принудительно без модели; 0 с ключом — OpenAIнет; в Docker по умолчанию 1
BACKEND_URLfront/.env.localадрес API для сервера Next.jsнет, http://localhost:3001 (в Docker — http://backend:3001)
NEXT_PUBLIC_API_URLfront/.env.localадрес API для браузера (стрим на /manager)нет, http://localhost:3001

Настоящих ключей в репозитории нет: .env и .env.local в .gitignore, в репозитории только .env.example, back/.env.example и front/.env.example.

Проблема и для кого

Заказчик мероприятия в Казахстане открывает каталог подрядчиков своего города и тонет в похожих профилях: описания одинаковые («харизма», «топ-10»), непонятно, чему верить и на что смотреть. Менеджер площадки вручную собирает клиенту 3 варианта и объясняет выбор.

Ценность в цифрах.

  • Время. Сейчас менеджер на один запрос открывает 10–50 профилей категории в городе и сверяет по каждому календарь, цену, формат и язык. По нашей оценке это десятки минут. ToiMatch отвечает за 15–250 мс (замер в режиме без ключа) и сразу показывает, почему выбран каждый вариант и кто отсеян.
  • Кому. Выгоду получают заказчик, который быстрее выбирает, и площадка или агентство, которые встраивают подбор как услугу для клиентов. Каталог получает честную выдачу: недоступных и неподходящих подрядчиков сервис не показывает.

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

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

  • Подбор POST /api/v1/match: фильтр по фактам, детерминированное ранжирование, объяснения, три явных исхода: found, no_category_in_city, all_filtered_out.
  • Пошаговый стрим пайплайна GET /api/v1/match/stream (SSE) для экрана площадки.
  • Каталог GET /api/v1/contractors с фильтрами и профиль GET /api/v1/contractors/:id.
  • Кеш объяснений в PostgreSQL: тот же запрос — тот же текст и порядок.
  • Чат с режимами поиска и полного пакета мероприятия: перед сборкой пакета считает минимальный бюджет, честно показывает пустые категории, а итоговые имена и причины берёт из результатов инструментов, а не из свободного текста модели.
  • Режим без ключа (MOCK): весь сценарий работает без сети и без наших аккаунтов.
  • Фронт (Next.js): каталог /, подбор /match, рабочее место площадки /manager (старый адрес /admin перенаправляет туда), профиль /contractor/[id], чат-помощник /chat; интерфейс на русском, казахском и английском; маскот-помощник Нурлан.

Как работает — от запроса до результата

  1. Заказчик выбирает, кто нужен (категория), город, дату, событие и бюджет; можно указать длительность и язык.
  2. Фильтр (код): город → категория → свободен в эту дату → берёт этот формат → в бюджете → язык → часы. На каждом шаге считается, сколько кандидатов выбыло и почему (воронка).
  3. Ранжирование (код): детерминированный порядок по измеримым критериям запроса, при равенстве — по id.
  4. Объяснения: сервер собирает проверяемые варианты причин из полей каталога, отличий от других карточек и точных фрагментов анкет. OpenAI выбирает подходящий вариант, но не пишет свободный текст о подрядчике; без ключа выбор детерминированный.
  5. Проверка фактов (код): причина сверяется с выбранной карточкой до показа и кеширования. Цена с подстановкой и цитаты из описания явно помечены; неподтверждённое объяснение заменяется безопасным вариантом.
  6. Ответ: исход, до трёх карточек, воронка и человеческая фраза «почему столько».

Технологии, модели и API

  • Frontend: Next.js 16 (App Router), React 19, TypeScript, Tailwind CSS 4, шрифт Onest.
  • Backend: NestJS 11, Prisma 6, PostgreSQL 16, Docker Compose.
  • LLM: OpenAI gpt-4o-mini (переменная MODEL_MAIN) выбирает вариант объяснения и участвует в проверке; без ключа — детерминированный клиент (back/src/matching/llm/mock-llm.client.ts). Итоговый текст всегда строит сервер из проверенных данных.
  • Изображения: фото подрядчиков и маскот сгенерированы OpenAI gpt-image-2; анимация маскота — fal.ai (Kling v3); логотип — fal.ai (Recraft V4.1, SVG).
  • Общий контракт типов фронта и бэка: shared/contract.ts.

Архитектура

Браузер (Next.js: /, /match, /manager, /contractor/[id], /chat)
   │  POST /api/v1/match          GET /api/v1/match/stream (SSE)      GET /api/v1/contractors
   ▼
NestJS (back/src/matching)
   ├─ FilterService     — фильтр и воронка (детерминированно)
   ├─ RankingService    — порядок, tie-break по id
   ├─ ExplainerService  — проверяемые варианты объяснений, критик, кеш
   └─ LlmClient         — OpenAI или MockLlmClient (без ключа)
   ▼
PostgreSQL (Prisma): contractors · enrichments · explanation_cache

Экраны

Подбор /match — запрос 1: три карточки, у каждой своё объяснение и проверенные факты.

Результат подбора на /match

Рабочее место площадки /manager — тот же запрос: поток решений по шагам и воронка отсева.

Поток решений и воронка на /manager

Как проверить (сценарий для жюри)

Все запросы работают без ключа. Кнопки с этими примерами есть на странице /match.

#ЗапросОжидаемый результат
1Ведущий · Алматы · корпоратив · 16.10.2026 · до 1 000 000 ₸found: 3 карточки из 4 подходящих; воронка 10 → 5 свободны → 5 берут корпоратив → 4 в бюджете
1бТо же на 23.10.2026Другая тройка: часть ведущих занята 23.10
2Флорист · Алматы · свадьба · 15.10.2026 · до 300 000 ₸found, меньше трёх: в Алматы всего 2 флориста
3аЛайв-бэнд · Астана · свадьба · 14.11.2026 · до 1 500 000 ₸no_category_in_city: в Астане нет лайв-бэндов
3бДекоратор · Алматы · той · 14.11.2026 · до 3 000 000 ₸all_filtered_out: все 3 заняты 14.11 и ни один не оформляет той

Повторный запуск того же запроса в MOCK-режиме даёт тот же порядок и те же тексты. У каждой показанной карточки причина индивидуальна и содержит проверяемую информацию о дате и цене; фрагмент анкеты помечен «со слов подрядчика», а подставленная цена — «ценовой ориентир». Пустой город/категория и отсеивание после фильтров различаются в outcome и тексте ответа.

Экран площадки /manager показывает тот же подбор пошагово (воронку в реальном времени) и таблицу: каждый факт объяснения → поле каталога → ✓.

Данные и интеграции

  • Каталог: датасет организаторов — 66 анонимизированных профилей, из них 13 синтетических (synthetic: true), календарь занятости 23.09–31.12.2026. Загружается сидом из back/prisma/seed-data/contractors.csv. В карточках помечены синтетические профили и проставленные при подготовке датасета цены и города.
  • Внешний API: только OpenAI (если задан ключ). Пример запроса:
POST /api/v1/match
Content-Type: application/json

{"city":"Алматы","date":"2026-10-15","eventType":"свадьба","category":"Флорист","budgetKzt":300000}

Ответ содержит outcome, summary, criteria, до трёх cards с индивидуальными reason, factsUsed и флагами достоверности данных, а также funnel с причинами отсева на каждом шаге.

Что взяли готовым

  • Библиотеки с открытыми лицензиями: Next.js (MIT), React (MIT), Tailwind CSS (MIT), NestJS (MIT), Prisma (Apache-2.0), class-validator (MIT), Onest (SIL OFL).
  • Датасет подрядчиков — от организаторов (Firebird).
  • Фото подрядчиков — сгенерированы ИИ (OpenAI gpt-image-2), люди вымышленные; на сайте каждое фото помечено «Фото: ИИ-иллюстрация».
  • Маскот Нурлан — сгенерирован ИИ (gpt-image-2), анимация — fal.ai (Kling v3); логотип — fal.ai (Recraft V4.1).
  • ИИ-инструменты разработки: Claude Code и OpenAI Codex. Весь код решения написан 23.09.2026 с 13:00 — это видно по истории коммитов.

Ограничения

  • Без ключа объяснения выбираются детерминированно из проверенных вариантов; с ключом OpenAI помогает выбрать вариант, при сбое — откат на безопасный выбор.
  • Интерфейс полностью на русском, казахском и английском. Объяснения полностью готовы на русском. На казахском и английском в итоговых фразах пока остаются русские названия категорий и городов и даты в формате ГГГГ-ММ-ДД.
  • Docker по умолчанию работает без модели; для живой модели передайте ключ через окружение и установите MOCK=0.
  • Нет бронирования, оплаты, авторизации и уведомлений — это вне задачи.
  • Каталог маленький (66 профилей), поэтому в редких категориях честно показываем меньше трёх.

Рабочая версия

Развёрнутой версии нет: жюри запускает проект локально одной командой docker compose up --build (см. «Как запустить»).

Звёзды
⭐ 0
Форки
0
Язык
TypeScript
Последний push
в прошлом месяце
Коммиты
88
Авторы
4
Файлы
358
Ветки
14

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

Nikita1658 34ivanlyssov 33Pinchuk Yan 20YPNM 1

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

  • 2026-09-23 18:01Handle keep-only bundle category requestsPinchuk Yan
  • 2026-09-23 17:54Fix bundle category questions and removalsPinchuk Yan
  • 2026-09-23 17:53Add backup demo video and link it from README (RU/KK/EN)ivanlyssov
  • 2026-09-23 17:45Слить последние изменения main перед публикациейNikita1658
  • 2026-09-23 17:44Merge chat dialogue fixes into mainPinchuk Yan
  • 2026-09-23 17:43Слить актуальный main перед публикациейNikita1658
  • 2026-09-23 17:43Исправить открытие календаря подбораNikita1658
  • 2026-09-23 17:42Добавить управление лентой категорийNikita1658
Все коммиты (88)
  • 2026-09-23 17:41Fix conversational bundle matching and chat presentationPinchuk Yan
  • 2026-09-23 17:37Оформить hero и блок категорий на главнойNikita1658
  • 2026-09-23 17:36Merge remote-tracking branch 'origin/nikita_develop' into ivan/nikita-tryivanlyssov
  • 2026-09-23 17:36README in Kazakh and English; fix section pointerivanlyssov
  • 2026-09-23 17:34README: run instructions first with env examples; add root .env.example for Docker Composeivanlyssov
  • 2026-09-23 17:33Chat remembers city/budget/guests across turns; compare any two dates; /match prefill from links; /admin redirect; UX copy fixesivanlyssov
  • 2026-09-23 17:32промежуточный коммит.Nikita1658
  • 2026-09-23 17:24README: value in numbers, honest limitations, screenshots from the final buildivanlyssov
  • 2026-09-23 17:07Use the shared site header and footer on /match and /managerivanlyssov
  • 2026-09-23 17:05Merge remote-tracking branch 'origin/main' into ivan/polishivanlyssov
  • 2026-09-23 17:05Polish front: SEO, icons, manifest, OG image, /match and /manager redesign detailsivanlyssov
  • 2026-09-23 16:57Sync back/package-lock.json with package.json (csv-parse) so npm ci in Docker worksivanlyssov
  • 2026-09-23 16:56Integrate evidence-grounded matching with team frontendPinchuk Yan
  • 2026-09-23 16:51Fix chat session cleanupPinchuk Yan
  • 2026-09-23 16:46Implement evidence-grounded matching and demo workflowPinchuk Yan
  • 2026-09-23 16:35Merge remote-tracking branch 'origin/main' into nikita_developNikita1658
  • 2026-09-23 16:31Merge remote-tracking branch 'origin/nikita_develop' into ivan/polishivanlyssov
  • 2026-09-23 16:30Update remaining interface stylesNikita1658
  • 2026-09-23 16:29Refine matching form controlsNikita1658
  • 2026-09-23 16:28Update contractor photo stylesNikita1658
  • 2026-09-23 16:27Restore contractor card stylesNikita1658
  • 2026-09-23 16:27Remove obsolete contractor card stylesNikita1658
  • 2026-09-23 16:26Sync current interface stylesNikita1658
  • 2026-09-23 16:26Refine match component stylesNikita1658
  • 2026-09-23 16:25Update matching interface controlsNikita1658
  • 2026-09-23 16:23README: add /match and /manager screenshotsivanlyssov
  • 2026-09-23 16:19README: one-command Docker run, env vars, real API responsesivanlyssov
  • 2026-09-23 16:15Fix build after merging Nikita's branch: restore i18n keys, one mascotivanlyssov
  • 2026-09-23 16:12Merge remote-tracking branch 'origin/nikita_develop' into ivan/integrateivanlyssov
  • 2026-09-23 16:11Fix budget input: allow round amounts like 1 000 000ivanlyssov
  • 2026-09-23 16:09Слить срочное обновление mainNikita1658
  • 2026-09-23 16:08Добавить полный запуск проекта через DockerNikita1658
  • 2026-09-23 16:07Подключить чат к API ЯнаNikita1658
  • 2026-09-23 16:07Обновить интерфейс под бренд ToiMatchNikita1658
  • 2026-09-23 16:06Map the new date fact key in the manager fact tableivanlyssov
  • 2026-09-23 16:05Merge branch 'ivan/merge-front' into ivan/restyleivanlyssov
  • 2026-09-23 16:04Restyle front to the approved ToiMatch designivanlyssov
  • 2026-09-23 16:01Merge main into Nikita's front: resolve conflicts with the matching backendivanlyssov
  • 2026-09-23 15:56Слить свежий main и backend ЯнаNikita1658
  • 2026-09-23 15:52Merge develop_yan: matching pipeline + chat assistant + Ivan block 1 + enrichmentPinchuk Yan
  • 2026-09-23 15:51back: chat assistant + swap NVIDIA for OpenAI; front: dev harnessPinchuk Yan
  • 2026-09-23 15:51match: Ivan's copy spec (block 1) + few-shot + offline enrichmentPinchuk Yan
  • 2026-09-23 15:46Merge remote-tracking branch 'origin/main' into ivan/restyleivanlyssov
  • 2026-09-23 15:44Слить актуальный main с дизайном и текстамиNikita1658
  • 2026-09-23 15:41Add localized conversational matching assistantNikita1658
  • 2026-09-23 15:40Replace admin auth with matching workspaceNikita1658
  • 2026-09-23 15:40Build localized matching experienceNikita1658
  • 2026-09-23 15:40Build localized contractor catalogNikita1658
  • 2026-09-23 15:40Add localized frontend foundationNikita1658
  • 2026-09-23 15:38Merge pull request #5 from BAITC-Hacks/ivan/copyivanlyssov
  • 2026-09-23 15:37Merge pull request #4 from BAITC-Hacks/ivan/frontivanlyssov
  • 2026-09-23 15:36Add ToiMatch logo files and faviconivanlyssov
  • 2026-09-23 15:36Finalize DESIGN.md: ToiMatch brand, palette, logo, mascot and routesivanlyssov
  • 2026-09-23 15:36Add README draft for the juryivanlyssov
  • 2026-09-23 15:23Add contractor photos, Nurlan mascot and approved design mockupsivanlyssov
  • 2026-09-23 15:08Restore backend production entry pointNikita1658
  • 2026-09-23 15:08Honor locale in matching requestsNikita1658
  • 2026-09-23 15:08Add copy spec for explanations, criteria and summariesivanlyssov
  • 2026-09-23 15:02Remove out-of-scope admin authenticationNikita1658
  • 2026-09-23 14:59Merge remote-tracking branch 'origin/main' into nikita_developNikita1658
  • 2026-09-23 14:55chat infra: contract types, prisma models, locale in cache, /admin renamePinchuk Yan
  • 2026-09-23 14:55Add role-protected contractor admin APINikita1658
  • 2026-09-23 14:51Merge pull request #3 from BAITC-Hacks/develop_yanYPNM
  • 2026-09-23 14:49организовал систему входа для админа.Nikita1658
  • 2026-09-23 14:49Merge pull request #2 from BAITC-Hacks/ivan/designivanlyssov
  • 2026-09-23 14:46back: matching pipeline + catalog endpointsPinchuk Yan
  • 2026-09-23 14:36wip: matching module skeleton (filter, ranking, explainer, mock llm)Pinchuk Yan
  • 2026-09-23 14:36docs+contract: add catalog page and endpointsPinchuk Yan
  • 2026-09-23 14:35Add DESIGN.md draft with agreed UI decisionsivanlyssov
  • 2026-09-23 14:35Fix demo date pair in SCOPE: use 16.10 vs 23.10ivanlyssov
  • 2026-09-23 14:33Merge branch 'main' of https://github.com/BAITC-Hacks/hack-cf5b3e57-code-design into nikita_developNikita1658
  • 2026-09-23 14:29docs: AGENTS.md at root/back/frontPinchuk Yan
  • 2026-09-23 14:25seed: load 66 contractors from CSV via PrismaPinchuk Yan
  • 2026-09-23 14:13shared: API contract + seed CSVPinchuk Yan
  • 2026-09-23 13:58создал фалй начального экрана проекта.Nikita1658
  • 2026-09-23 13:55prisma: replace User with Contractor/Enrichment/ExplanationCachePinchuk Yan
  • 2026-09-23 13:51Merge pull request #1 from BAITC-Hacks/ivan/scopeivanlyssov
  • 2026-09-23 13:50SCOPE: задача, критерии, big idea, пайплайн и демо-запросыivanlyssov
  • 2026-09-23 13:24merge back/ into monorepoPinchuk Yan
  • 2026-09-23 13:19Init commitPinchuk Yan
Структура репозитория (358 файлов)
.claude/orchestration.md
.dockerignore
.env.example
.gitignore
AGENTS.md
DESIGN.md
README.en.md
README.kk.md
README.md
SCOPE.md
back/.dockerignore
back/.env.example
back/.gitignore
back/.prettierrc
back/AGENTS.md
back/Dockerfile
back/README.md
back/eslint.config.mjs
back/nest-cli.json
back/package-lock.json
back/package.json
back/prisma/migrations/20260923085538_contractors_initial/migration.sql
back/prisma/migrations/20260923095322_chat_and_locale/migration.sql
back/prisma/migrations/migration_lock.toml
back/prisma/schema.prisma
back/prisma/seed-data/contractors.csv
back/prisma/seed.ts
back/src/app.controller.spec.ts
back/src/app.controller.ts
back/src/app.module.ts
back/src/app.service.ts
back/src/chat/chat-intent.ts
back/src/chat/chat.controller.ts
back/src/chat/chat.module.ts
back/src/chat/chat.service.ts
back/src/chat/dto/create-session.dto.ts
back/src/chat/dto/send-message.dto.ts
back/src/chat/guards/injection.guard.ts
back/src/chat/openai-chat.client.ts
back/src/chat/tools/tools.registry.ts
back/src/chat/tools/tools.service.ts
back/src/contractors/contractors.controller.ts
back/src/contractors/contractors.module.ts
back/src/contractors/contractors.service.ts
back/src/contractors/dto/list-contractors.query.dto.ts
back/src/enrichment/enrich.ts
back/src/health/health.controller.ts
back/src/health/health.module.ts
back/src/main.ts
back/src/matching/copy/nouns.ts
back/src/matching/copy/reasons.ts
back/src/matching/criteria.ts
back/src/matching/dto/match-request.dto.ts
back/src/matching/evidence.ts
back/src/matching/explainer.service.ts
back/src/matching/filter.service.ts
back/src/matching/llm/llm-client.ts
back/src/matching/llm/mock-llm.client.ts
back/src/matching/llm/openai-llm.client.ts
back/src/matching/matching.controller.ts
back/src/matching/matching.module.ts
back/src/matching/matching.service.ts
back/src/matching/ranking.service.ts
back/src/matching/types.ts
back/src/prisma/prisma.module.ts
back/src/prisma/prisma.service.ts
back/test/app.e2e-spec.ts
back/test/chat-bundle.e2e-spec.ts
back/test/jest-e2e.json
back/test/match.e2e-spec.ts
back/tsconfig.build.json
back/tsconfig.json
docker-compose.yml
docs/copy-explanations.md
docs/demo/toimatch-demo.mp4
docs/design/NOTES.md
docs/design/admin.html
docs/design/contractor.html
docs/design/index.html
docs/design/match.html
docs/screenshots/manager.jpg
docs/screenshots/match.jpg
front/.env.example
front/.gitignore
front/AGENTS.md
front/CLAUDE.md
front/Dockerfile
front/README.md
front/app/admin/page.tsx
front/app/apple-icon.png
front/app/chat/api/[sessionId]/message/route.ts
front/app/chat/api/[sessionId]/route.ts
front/app/chat/api/session/route.ts
front/app/chat/page.module.css
front/app/chat/page.tsx
front/app/contractor/[id]/page.module.css
front/app/contractor/[id]/page.tsx
front/app/dev/page.tsx
front/app/globals.css
front/app/icon.svg
front/app/layout.tsx
front/app/manager/page.tsx
front/app/manifest.ts
front/app/match/api/route.ts
front/app/match/page.module.css
front/app/match/page.tsx
front/app/not-found.tsx
front/app/opengraph-image.alt.txt
front/app/opengraph-image.png
front/app/page.module.css
front/app/page.tsx
front/app/robots.ts
front/app/sitemap.ts
front/app/twitter-image.alt.txt
front/app/twitter-image.png
front/components/catalog/availability-calendar.module.css
front/components/catalog/availability-calendar.tsx
front/components/catalog/catalog-filters/catalog-filters.module.css
front/components/catalog/catalog-filters/catalog-filters.tsx
front/components/catalog/catalog-header/catalog-header.module.css
front/components/catalog/catalog-header/catalog-header.tsx
front/components/catalog/catalog-page.module.css
front/components/catalog/category-strip/category-strip.module.css
front/components/catalog/category-strip/category-strip.tsx
front/components/catalog/contractor-card/contractor-card.module.css
front/components/catalog/contractor-card/contractor-card.tsx
front/components/catalog/contractor-photo/contractor-photo.module.css
front/components/catalog/contractor-photo/contractor-photo.tsx
front/components/catalog/profile-page.module.css
front/components/chat/chat-attachment-results/chat-attachment-results.tsx
front/components/chat/chat-bundle-results/chat-bundle-results.module.css
front/components/chat/chat-bundle-results/chat-bundle-results.tsx
front/components/chat/chat-composer/chat-composer.module.css
front/components/chat/chat-composer/chat-composer.tsx
front/components/chat/chat-experience/chat-experience.module.css
front/components/chat/chat-experience/chat-experience.tsx
front/components/chat/chat-header/chat-header.module.css
front/components/chat/chat-header/chat-header.tsx
front/components/chat/chat-hero/chat-hero.module.css
front/components/chat/chat-hero/chat-hero.tsx
front/components/chat/chat-mode-switcher/chat-mode-switcher.module.css
front/components/chat/chat-mode-switcher/chat-mode-switcher.tsx
front/components/chat/chat-progress/chat-progress.module.css
front/components/chat/chat-progress/chat-progress.tsx
front/components/chat/chat-result-card/chat-result-card.module.css
front/components/chat/chat-result-card/chat-result-card.tsx
front/components/chat/chat-results/chat-results.module.css
front/components/chat/chat-results/chat-results.tsx
front/components/chat/chat-session-panel/chat-session-panel.module.css
front/components/chat/chat-session-panel/chat-session-panel.tsx
front/components/chat/chat-thread/chat-thread.module.css
front/components/chat/chat-thread/chat-thread.tsx
front/components/chat/format-dates.ts
front/components/chat/quick-replies/quick-replies.module.css
front/components/chat/quick-replies/quick-replies.tsx
front/components/manager/comparison-panel/comparison-panel.module.css
front/components/manager/comparison-panel/comparison-panel.tsx
front/components/manager/comparison-panel/index.ts
front/components/manager/criteria-panel/criteria-panel.module.css
front/components/manager/criteria-panel/criteria-panel.tsx
front/components/manager/criteria-panel/index.ts
front/components/manager/critic-panel/critic-panel.module.css
front/components/manager/critic-panel/critic-panel.tsx
front/components/manager/critic-panel/index.ts
front/components/manager/demo-presets/demo-presets.module.css
front/components/manager/demo-presets/demo-presets.tsx
front/components/manager/demo-presets/index.ts
front/components/manager/fact-table/fact-table.module.css
front/components/manager/fact-table/fact-table.tsx
front/components/manager/funnel-view/funnel-view.module.css
front/components/manager/funnel-view/funnel-view.tsx
front/components/manager/funnel-view/index.ts
front/components/manager/json-panel/index.ts
front/components/manager/json-panel/json-panel.module.css
front/components/manager/json-panel/json-panel.tsx
front/components/manager/manager-contractor-card/index.ts
front/components/manager/manager-contractor-card/manager-contractor-card.module.css
front/components/manager/manager-contractor-card/manager-contractor-card.tsx
front/components/manager/manager-header/index.ts
front/components/manager/manager-header/manager-header.module.css
front/components/manager/manager-header/manager-header.tsx
front/components/manager/manager-hero/index.ts
front/components/manager/manager-hero/manager-hero.module.css
front/components/manager/manager-hero/manager-hero.tsx
front/components/manager/manager-results/index.ts
front/components/manager/manager-results/manager-results.module.css
front/components/manager/manager-results/manager-results.tsx
front/components/manager/manager-shell/index.ts
front/components/manager/manager-shell/manager-shell.module.css
front/components/manager/manager-shell/manager-shell.tsx
front/components/manager/manager-workspace/index.ts
front/components/manager/manager-workspace/manager-workspace.module.css
front/components/manager/manager-workspace/manager-workspace.tsx
front/components/manager/match-request-form/index.ts
front/components/manager/match-request-form/match-request-form.module.css
front/components/manager/match-request-form/match-request-form.tsx
front/components/manager/pipeline-timeline/index.ts
front/components/manager/pipeline-timeline/pipeline-timeline.module.css
front/components/manager/pipeline-timeline/pipeline-timeline.tsx
front/components/manager/shared/contractor-photo.module.css
front/components/manager/shared/contractor-photo.tsx
front/components/manager/shared/format.ts
front/components/manager/shared/highlight.ts
front/components/manager/shared/icon.tsx
front/components/manager/shared/manager-data.ts
front/components/manager/shared/manager-types.ts
front/components/manager/shared/panel-heading.tsx
front/components/manager/shared/panel.module.css
front/components/match/category-picker/category-picker.module.css
front/components/match/category-picker/category-picker.tsx
front/components/match/compare-dates/compare-dates.module.css
front/components/match/compare-dates/compare-dates.tsx
front/components/match/criteria-list/criteria-list.module.css
front/components/match/criteria-list/criteria-list.tsx
front/components/match/demo-presets/demo-presets.module.css
front/components/match/demo-presets/demo-presets.tsx
front/components/match/format/format.ts
front/components/match/funnel-summary/funnel-summary.module.css
front/components/match/funnel-summary/funnel-summary.tsx
front/components/match/icons/icons.tsx
front/components/match/mascot-guide/mascot-guide.module.css
front/components/match/mascot-guide/mascot-guide.tsx
front/components/match/mascot/mascot.module.css
front/components/match/mascot/mascot.tsx
front/components/match/match-card/highlight-reason.ts
front/components/match/match-card/match-card.module.css
front/components/match/match-card/match-card.tsx
front/components/match/match-experience/match-experience.module.css
front/components/match/match-experience/match-experience.tsx
front/components/match/match-form/match-form.module.css
front/components/match/match-form/match-form.tsx
front/components/match/match-header/match-header.module.css
front/components/match/match-header/match-header.tsx
front/components/match/match-hero/match-hero.module.css
front/components/match/match-hero/match-hero.tsx
front/components/match/match-results/match-results.module.css
front/components/match/match-results/match-results.tsx
front/components/match/match-status/match-status.module.css
front/components/match/match-status/match-status.tsx
front/components/match/outcome-banner/outcome-banner.module.css
front/components/match/outcome-banner/outcome-banner.tsx
front/components/shared/brand-logo/brand-logo.module.css
front/components/shared/brand-logo/brand-logo.tsx
front/components/shared/custom-select/custom-select.module.css
front/components/shared/custom-select/custom-select.tsx
front/components/shared/locale-switcher/locale-switcher.module.css
front/components/shared/locale-switcher/locale-switcher.tsx
front/components/shared/status-icons/status-icons.tsx
front/components/site/site-copy.ts
front/components/site/site-footer.tsx
front/components/site/site-header.tsx
front/components/site/site.module.css
front/eslint.config.mjs
front/lib/catalog-api.ts
front/lib/chat/chat-api.ts
front/lib/chat/chat-assistant.ts
front/lib/chat/chat-proxy.ts
front/lib/chat/chat-storage.ts
front/lib/contractor-images.ts
front/lib/i18n/config.ts
front/lib/i18n/get-request-locale.ts
front/lib/i18n/locale-provider.tsx
front/lib/i18n/messages/catalog.ts
front/lib/i18n/messages/chat.ts
front/lib/i18n/messages/manager.ts
front/lib/i18n/messages/match.ts
front/lib/manager-stream.ts
front/lib/match-api.ts
front/next.config.ts
front/package-lock.json
front/package.json
front/postcss.config.mjs
front/public/brand/toimatch-logo-light.svg
front/public/brand/toimatch-logo.svg
front/public/brand/toimatch-mark.svg
front/public/contractors/HK-10990.webp
front/public/contractors/HK-11484.webp
front/public/contractors/HK-16628.webp
front/public/contractors/HK-19103.webp
front/public/contractors/HK-20640.webp
front/public/contractors/HK-23752.webp
front/public/contractors/HK-25279.webp
front/public/contractors/HK-26808.webp
front/public/contractors/HK-27222.webp
front/public/contractors/HK-29829.webp
front/public/contractors/HK-30583.webp
front/public/contractors/HK-31819.webp
front/public/contractors/HK-35215.webp
front/public/contractors/HK-35846.webp
front/public/contractors/HK-35913.webp
front/public/contractors/HK-36965.webp
front/public/contractors/HK-37181.webp
front/public/contractors/HK-39301.webp
front/public/contractors/HK-39372.webp
front/public/contractors/HK-42352.webp
front/public/contractors/HK-44733.webp
front/public/contractors/HK-44923.webp
front/public/contractors/HK-45928.webp
front/public/contractors/HK-46450.webp
front/public/contractors/HK-50695.webp
front/public/contractors/HK-53108.webp
front/public/contractors/HK-57480.webp
front/public/contractors/HK-58236.webp
front/public/contractors/HK-58385.webp
front/public/contractors/HK-60927.webp
front/public/contractors/HK-61323.webp
front/public/contractors/HK-62242.webp
front/public/contractors/HK-64395.webp
front/public/contractors/HK-68220.webp
front/public/contractors/HK-69010.webp
front/public/contractors/HK-72785.webp
front/public/contractors/HK-72938.webp
front/public/contractors/HK-74147.webp
front/public/contractors/HK-74914.webp
front/public/contractors/HK-75012.webp
front/public/contractors/HK-76268.webp
front/public/contractors/HK-76335.webp
front/public/contractors/HK-77793.webp
front/public/contractors/HK-77838.webp
front/public/contractors/HK-80581.webp
front/public/contractors/HK-83709.webp
front/public/contractors/HK-88430.webp
front/public/contractors/HK-90001.webp
front/public/contractors/HK-90002.webp
front/public/contractors/HK-90003.webp
front/public/contractors/HK-90004.webp
front/public/contractors/HK-90005.webp
front/public/contractors/HK-90006.webp
front/public/contractors/HK-90007.webp
front/public/contractors/HK-90008.webp
front/public/contractors/HK-90009.webp
front/public/contractors/HK-90010.webp
front/public/contractors/HK-90011.webp
front/public/contractors/HK-90012.webp
front/public/contractors/HK-90013.webp
front/public/contractors/HK-91112.webp
front/public/contractors/HK-92824.webp
front/public/contractors/HK-97041.webp
front/public/contractors/HK-97737.webp
front/public/contractors/HK-98562.webp
front/public/contractors/HK-99701.webp
front/public/file.svg
front/public/globe.svg
front/public/icons/icon-192.png
front/public/icons/icon-512.png
front/public/icons/maskable-512.png
front/public/mascot/nurlan-found.webp
front/public/mascot/nurlan-hello.mp4
front/public/mascot/nurlan-hello.webm
front/public/mascot/nurlan-hello.webp
front/public/mascot/nurlan-sorry.webp
front/public/mascot/nurlan-thinking.webp
front/public/next.svg
front/public/vercel.svg
front/public/window.svg
front/tsconfig.json
shared/README.md
shared/contract.ts
Ветки (14)

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

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

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