AAYMA
RU
Войти

Аким на 5 часов

Веб-симулятор управления Астаной: выбор 5 из 14 мероприятий по районам в бюджете 100, детерминированный расчёт Score до/после, альтернативные планы…

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

О проекте

Команда: Вайбкодеры
Кейс HackAlem.ai: Спецтрек — Astana Innovations
Стадия: Доведённый продукт

Задача кейса: «Аким на 5 часов»: городской симулятор, распределяющий бюджет по 5 направлениям и 5 районам

Суть

Веб-симулятор управления Астаной: выбор 5 из 14 мероприятий по районам в бюджете 100, детерминированный расчёт Score до/после, альтернативные планы, AI-объяснение и 3D-сцена города; задеплоен на NVIDIA Brev.

Как устроено

Next.js-фронт отправляет выбор в C# Minimal API, который валидирует правила (ровно 5 мер, ≤2 из направления, стоимость ≤100), применяет эффекты с долей реализации (8−лаг)/8 и бонусы синергии, считает Score = 0,7×средний балл + 0,3×худший район − число показателей ниже 40. Поиск альтернатив перебирает замены одной меры под цели. В режиме live OpenAI Responses API лишь ранжирует проверенные сервером утверждения, тексты формирует сервер; при ошибке — шаблонное объяснение.

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

  • детерминированная модель Score
  • перебор замен одной меры
  • ранжирование проверенных утверждений LLM
  • fallback mock

Особенности

LLM не генерирует факты: сервер формирует каталог проверенных утверждений, модель только выбирает их приоритет; процедурная 3D-модель Астаны на Three.js, локализация RU/KZ/EN и публичный деплой.

Стек

Next.js 16 · React 19 · TypeScript · Three.js · C# .NET 8 ASP.NET Core Minimal API · Swagger · Docker Compose · nginx · NVIDIA Brev

Модели

OpenAI Responses API (gpt-4o-mini)


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

README

README.md

Аким на 5 часов

Симулятор управления Астаной для спецтрека Astana Innovations: пять решений, бюджет 100, пять районов. Соберите план и узнайте, как он меняет качество жизни и положение самого слабого района.

Открыть демо · Swagger демо · Контракт API · Сторонние компоненты

Быстрый старт: после клонирования репозитория запустите docker compose up --build и откройте localhost:3000. По умолчанию используется mock: ключ OpenAI не нужен. Настройки и подробные команды — в разделах 4–7.

Документ описывает код репозитория, включая альтернативы, сравнение попыток и исправления клавиатурного фокуса из 7073164. Публичное демо может отставать: проверенная версия деплоя.

1. Описание и назначение

Пользователь выбирает ровно пять из 14 мероприятий на горизонте восьми кварталов. Все начинают с одного синтетического датасета организаторов: пять районов, доли населения и десять показателей по шкале 0–100. Большее значение всегда лучше.

Маршрут приложения:

  1. Обзор (/): исходные показатели, бюджет, правила и модель города.
  2. Решения (/decisions): каталог, выбор районов, стоимость и причины недоступности мер.
  3. Результат (/results): Score до/после, районные баллы, изменения показателей, расходы, сильные стороны и риски. Здесь же доступны альтернативные планы и сравнение двух последних успешных попыток.

Интерфейс доступен на русском, казахском и английском, с темами «День», «Ночь», «Бумага» и поддержкой уменьшенного движения. Трёхмерная сцена включает Байтерек, EXPO, Хан Шатыр, мечеть, монумент и мосты. Геометрия и размещение условные: это иллюстрация, а не географическая карта или источник числовых показателей.

На узком экране район выбирается через карточки и схему, колонка 3D скрыта. На широком экране при экономии трафика или недоступном WebGL показывается подписанный снимок модели. Черновик плана сохраняется в текущей вкладке. После полной перезагрузки результат нужно рассчитать снова — серверной истории и базы данных в MVP нет.

2. Архитектура и расчёт

Браузер: Next.js / React
  ├─ GET  /api/scenario
  ├─ POST /api/simulations/evaluate
  └─ POST /api/simulations/alternatives
           ↓
C# Minimal API: проверка → расчёт → объяснение
  ├─ единый датасет и детерминированная модель
  └─ mock или OpenAI Responses API с резервным mock

Браузер обращается к API через NEXT_PUBLIC_API_URL. Локально это прямые запросы на порт 8080 с CORS; на Brev nginx объединяет сайт и API под одним HTTPS-адресом. Next.js rewrites и отдельный API_INTERNAL_URL не нужны.

Только C# рассчитывает итоговые числа. Интерфейс предварительно считает стоимость и количество выбранных мер, а также вычитает полученные «после − до» для показа изменений.

Правила выбора: ровно пять уникальных мер, не более двух из одного направления, стоимость не выше 100, обязательный район для районной меры и отсутствие района для городской. Несовместимость проверяется сервером. Невалидный набор возвращает стабильный код ошибки без оценки.

Порядок расчёта:

  1. Применить эффекты мер с долей реализации (8 − лаг) / 8, затем фиксированные бонусы синергии.
  2. Ограничить показатели диапазоном 0–100.
  3. Рассчитать районные баллы по весам десяти показателей и средний городской балл по долям населения.
  4. Рассчитать Score = 0,7 × средний балл + 0,3 × балл худшего района − количество значений показателей ниже 40 по всем районам.

Промежуточные значения не округляются; API округляет числа ответа до двух знаков. Исходные данные находятся в ScenarioData.cs, алгоритм — в ScoreCalculator.cs.

Роль AI. В режиме live сервер отправляет проверенные утверждения в OpenAI Responses API. Модель определяет их приоритет; итоговые тексты, переводы и рекомендации формирует сервер. Модель не рассчитывает Score и не сочиняет показатели. В режиме mock, а также при ошибке или некорректном ответе модели, сервер возвращает шаблонное объяснение с теми же рассчитанными числами. UI различает «AI-анализ» и «Шаблонное объяснение». Свободный чат и поиск глобально оптимального плана в MVP не реализованы.

Язык объяснения задаётся Accept-Language: ru-RU / kk-KZ / en-US; фактический язык возвращается в explanationLocale и Content-Language. Смена языка интерфейса не вызывает платный запрос автоматически: объяснение обновляется отдельной кнопкой.

На результате кнопка поиска вызывает POST /api/simulations/alternatives: сервер перебирает замены одной меры по целям Score, помощь слабейшему району и экономия, проверяет допустимость и рассчитывает последствия. AI может выбрать вариант и аргументы из проверенного набора. Это ограниченный поиск, а не глобальная оптимизация. Совпавшие стратегии не выдаются за разные планы; отсутствие улучшения показывается явно. «Применить» переносит пять мер в конструктор, а повторная оценка выполняется отдельным нажатием. История двух успешных планов хранится в памяти вкладки и очищается при перезагрузке или сбросе.

backend/                .NET API, датасет, расчёт и серверные проверки
frontend/app/           страницы /, /decisions, /results
frontend/features/      обзор и 3D, конструктор, результат, альтернативы, состояние
frontend/components/    общие компоненты интерфейса
frontend/lib/           API-клиент, контракты, форматирование и локализация
frontend/public/        логотип, favicon, снимки модели
frontend/tests/         frontend-тесты
frontend/docs/reports/  отчёты UI, интеграции и готовности релиза
docs/api.md             сетевой контракт и примеры
docs/reference/         исходные материалы задания

3. Технологии и команда

ЧастьТехнологии
FrontendNext.js 16.3.6, React 19.2.8, TypeScript, CSS Modules
ВизуализацияThree.js 0.186, собственные процедурные модели и SVG
Backend.NET 8 / ASP.NET Core Minimal API, Swashbuckle / Swagger
ОбъяснениеOpenAI Responses API через HttpClient; необязательный внешний сервис
ЗапускDocker Compose, Node.js 22 и .NET 8 контейнеры
ПубликацияNVIDIA Brev, nginx, HTTPS Secure Link

Фронтенд и интеграция — Hizeshi; C# API — Тамерлан (TamerlanWebd); сервер и DevOps — Кирилл. Зависимости, лицензии и назначение компонентов раскрыты в THIRD_PARTY.md.

4. Требования

Для запуска достаточно Docker Engine / Docker Desktop и Docker Compose v2, доступа к интернету при первой сборке и свободных портов 3000 и 8080. На Windows используйте WSL Ubuntu с включённой интеграцией Docker Desktop. Команды ниже предназначены для Bash в WSL/Linux.

Установка Node.js и .NET на хост не требуется для Docker. Для разработки и тестов без контейнеров нужны Node.js 22, npm и .NET 8 SDK. Для серверного compose-файла требуется Compose 2.24.4+, поддерживающий !override.

5. Установка

git clone https://github.com/BAITC-Hacks/hack-4c816c70-team.git
cd hack-4c816c70-team
cp .env.example .env

Настройки из примера запускают mock без ключей. Файл .env не добавляется в Git. Не копируйте в него чужой ключ и не передавайте секреты через NEXT_PUBLIC_*: эти переменные доступны браузеру.

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

ПеременнаяЗначение по умолчанию / назначение
API_PORT8080, порт API на хосте
FRONTEND_PORT3000, порт сайта на хосте
GATEWAY_PORT8000, только для серверного nginx
FRONTEND_ORIGINПусто: http://localhost:<FRONTEND_PORT>; разрешённые CORS origins через запятую
NEXT_PUBLIC_API_URLhttp://localhost:8080; адрес API для браузера, встраивается при сборке
ASPNETCORE_ENVIRONMENTProduction
LLM_MODEmock без внешних запросов; live для OpenAI
OPENAI_API_KEYПусто; нужен только для live, только на сервере
OPENAI_MODELПусто; для live укажите доступную модель, команда использует gpt-4o-mini
OPENAI_BASE_URLПусто: стандартный OpenAI API; можно задать совместимый адрес для тестирования

При изменении API_PORT обновите и NEXT_PUBLIC_API_URL. После изменения адреса API необходима пересборка frontend. Для включения модели заполните серверные LLM_MODE=live, OPENAI_API_KEY, OPENAI_MODEL и пересоздайте API: docker compose up -d api.

7. Запуск и публикация

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

docker compose up --build

После сборки откройте сайт, Swagger и health. Обе службы должны стать healthy:

docker compose ps
curl --fail http://localhost:8080/health
docker compose logs --tail=100 api frontend

Команды проверки выполняйте во втором терминале. Для фонового запуска: docker compose up --build -d --wait. Остановка: docker compose down. Базы данных и тома с результатами нет.

На сервере Brev из согласованной рабочей копии запускайте:

docker compose -f docker-compose.yml -f docker-compose.brev.yml up --build -d --wait

В Secure Link укажите HTTP-порт 8000. nginx направляет /api/, /health, /swagger в C# API, остальные запросы — во frontend. Серверный compose задаёт относительный NEXT_PUBLIC_API_URL=/; временный Cloudflare-туннель для такого запуска не нужен. Порты 3000 и 8080 привязаны к loopback, HTTPS обслуживает Brev.

docker compose -f docker-compose.yml -f docker-compose.brev.yml ps
curl --fail http://127.0.0.1:8000/health

Обновляйте только чистую согласованную копию: git fetch origin, проверка изменений, git pull --ff-only, затем сборка. Записывайте SHA исходников и фактически запущенных образов обоих сервисов; git push сам по себе сайт не обновляет. Сохраняйте действующую серверную конфигурацию и права доступа. На текущем стенде API и frontend запускались из разных каталогов — не выполняйте обновление из случайного старого checkout с тем же Compose project. Точное состояние и оставшиеся шаги — в отчёте готовности.

После обновления проверьте, что Swagger содержит /api/simulations/alternatives. Если там есть только scenario и evaluate, работает старая версия API; обновление только frontend не включит альтернативы.

Если запуск не удался:

  • Порт занят — измените порты в .env, согласуйте адрес API и повторите сборку.
  • Failed to fetch / CORS — проверьте API из браузера и точный FRONTEND_ORIGIN, включая схему и порт; localhost и 127.0.0.1 различаются.
  • Сайт показывает старую версию — проверьте SHA контейнера и пересборку, затем обновите страницу.
  • Вместо 3D виден снимок — прочитайте подпись и попробуйте «Запустить 3D»; ограничения WebGL не мешают оценке плана.
  • Модель недоступна — числовой результат сохраняется, источник объяснения меняется на mock.

8. Проверка и демонстрация

Контрольный план: M7 → Нура, M8 → Нура, M10 → Нура, M12 → город, M5 → Сарыарка. Ожидаемый результат: 52,56 → 56,54, расходы 95, остаток 5.

curl --fail-with-body http://localhost:8080/api/simulations/evaluate \
  -H 'Content-Type: application/json' \
  -H 'Accept-Language: ru-RU' \
  --data '{"choices":[{"measureId":"M7","districtId":"nura"},{"measureId":"M8","districtId":"nura"},{"measureId":"M10","districtId":"nura"},{"measureId":"M12"},{"measureId":"M5","districtId":"saryarka"}]}'

Повторите с kk-KZ и en-US: числа должны совпасть, язык объяснения — измениться. Невалидный набор:

curl -i http://localhost:8080/api/simulations/evaluate \
  -H 'Content-Type: application/json' --data '{"choices":[]}'

Ожидается HTTP 400 с code: WRONG_CHOICE_COUNT, без Score. Остальные коды, схемы и примеры — в контракте API.

Для короткого демо откройте обзор, соберите контрольный план, покажите результат и изменения Нуры. Затем измените район M5 на Алматы и оцените заново: Score меняется на 56,58 при тех же расходах 95. Покажите переключение языка и честное обозначение источника объяснения.

Для демонстрации альтернатив вернитесь к исходному контрольному плану и выберите цель Score: лучшая найденная замена M5 Сарыарка → M3 Нура даёт 57,21 при расходах 100. Цель экономии предлагает M5 Сарыарка → M11 Нура: 56,69 при расходах 80, с потерями для Сарыарки. Примените вариант, явно оцените его и покажите сравнение попыток. Эти значения проверены на API из репозитория; доступность нового экрана на публичном демо зависит от версии деплоя.

ПланРасходыОстатокScore
Контрольный: M7, M8, M10 в Нуре; M12 город; M5 Сарыарка95556,54
В контрольном плане заменить M5 Сарыарка на M3 Нура100057,21
В контрольном плане заменить M5 Сарыарка на M11 Нура802056,69

Автоматические проверки frontend:

cd frontend
npm ci
npm run lint
npm test
npm run build
npm run typecheck
cd ..

Проверки backend:

dotnet run --project backend/CitySimulator.RegressionTests -c Release
node backend/tests/api-regression.mjs http://localhost:8080

HTTP regression требует отдельный запущенный тестовый API в режиме mock и делает более 500 запросов; не направляйте его на публичное демо с платной моделью. Подробности — в инструкции тестов.

ПроверкаПодтверждённый результат
Frontend на коде 707316474/74 теста, lint, production build и typecheck
Клавиатура на 7073164, локально, 390 pxДобавление/удаление сохраняют фокус; первая, последняя и единственная строки; Escape возвращает фокус на корзину. Повторно проверено Claude 2 без POST
Новый backend, Docker45/45 C# и 45/45 HTTP-проверок, 400 наборов и 120 перестановок; альтернативы включены
Чистый Compose на Brev6929bf4, оба контейнера healthy, без ключей; этот прогон предшествовал последнему UI альтернатив
Полный сценарий из чистого клона, отчёт Тамерлана88a0c8c: 110/110 браузерных проверок; план → результат → альтернативы → применение → отдельная оценка → сравнение; mock без ключа
Последующая приёмка, отчёт Тамерлана7c0570e: 31/31 проверка пустого HTTP 503, повторов и мобильного обзора; на 7073164 повторно прошла production-сборка Docker
Настоящий AI, отчёт ТамерланаОдин запрос альтернатив: HTTP 200, recommendation.source=llm, исходный план 56,54 / 95 → совет 57,21 / 100
Firefox 156 / Intel ArcЖивая 3D-сцена, выбор районов и возврат со страницы решений; публичный frontend 631efbb

Подробности и границы проверки — в независимом отчёте, приёмке отчётов и финальной интеграции Тамерлана, включая машинные отчёты и скриншоты. Интегратор проверял Docker на Brev, Тамерлан — отдельный локальный Docker-стек; это разные стенды. Физические мобильные устройства и скринридер не проверены. Локальная приёмка не подменяет проверку нового публичного деплоя.

Готовность релиза и ограничения проверок · Отчёт по 3D · Отчёт по сценарию · Серверная регрессия

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

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

Hizeshi 32Tamerlan 25Codex 18kilka165 3Hizeshi 2

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

  • 2026-09-23 17:40feat(frontend): style district and language dropdown menusHizeshi
  • 2026-09-23 17:35fix(frontend): increase alternative goal controls to 44pxHizeshi
  • 2026-09-23 17:27Merge final integration acceptance reportsHizeshi
  • 2026-09-23 17:27docs: finalize README with verified end-to-end workflow and release statusHizeshi
  • 2026-09-23 17:22test: record final clean-clone browser and live AI acceptanceTamerlan
  • 2026-09-23 17:16fix(frontend): preserve planner keyboard focus and review agent reportsHizeshi
  • 2026-09-23 17:09docs: update README and verify integrated alternatives releaseHizeshi
  • 2026-09-23 17:07Merge remote-tracking branch 'origin/main'Hizeshi
Все коммиты (80)
  • 2026-09-23 17:06feat(frontend): connect plan alternatives and compare successful attemptsTamerlan
  • 2026-09-23 17:06fix(frontend): refresh city previews and record final acceptanceHizeshi
  • 2026-09-23 17:05Merge remote-tracking branch 'origin/main' into integration/logo-cityHizeshi
  • 2026-09-23 17:05fix(frontend): preserve HTTP errors with empty response bodiesHizeshi
  • 2026-09-23 17:02docs: reconcile component disclosures after team mergeTamerlan
  • 2026-09-23 17:01feat(api): add validated alternative strategies and grounded adviceTamerlan
  • 2026-09-23 17:01Merge remote-tracking branch 'origin/main' into HEADTamerlan
  • 2026-09-23 16:58docs: prepare demo README and consolidate release checksHizeshi
  • 2026-09-23 16:49fix(frontend): keep API error details out of localized copyHizeshi
  • 2026-09-23 16:45fix(frontend): show city preview and recover 3D startupHizeshi
  • 2026-09-23 16:40Merge remote-tracking branch 'origin/main'Hizeshi
  • 2026-09-23 16:40fix(git): inspect pushes with unfetched remote baseHizeshi
  • 2026-09-23 16:39feat(frontend): integrate city polish and localized API errorsHizeshi
  • 2026-09-23 16:35Merge remote-tracking branch 'origin/main'Hizeshi
  • 2026-09-23 16:34fix(frontend): guard explanation renderingHizeshi
  • 2026-09-23 16:33Merge remote-tracking branch 'origin/main' into HEADTamerlan
  • 2026-09-23 16:33feat(api): explain negative measure effects and compensationTamerlan
  • 2026-09-23 16:24merge: sync latest team updates before publishing fixeskilka165
  • 2026-09-23 16:22fix: harden simulation responses and add regression coveragekilka165
  • 2026-09-23 16:21merge: include final localization browser checksHizeshi
  • 2026-09-23 16:21merge: publish city branding with localized explanation workflowHizeshi
  • 2026-09-23 16:17test: record localized explanation retry browser checksTamerlan
  • 2026-09-23 16:14feat(frontend): complete city landmarks and visual identityHizeshi
  • 2026-09-23 16:12feat(frontend): request localized explanations and preserve retry resultsTamerlan
  • 2026-09-23 16:09merge: synchronize origin mainHizeshi
  • 2026-09-23 16:06feat(frontend): negotiate explanation localeHizeshi
  • 2026-09-23 16:06chore: guard personal commit authorship and attributionTamerlan
  • 2026-09-23 16:06Merge remote-tracking branch 'origin/main'Hizeshi
  • 2026-09-23 16:05chore: require team synchronization before deliveryHizeshi
  • 2026-09-23 16:05feat(frontend): model Astana landmarks and river bridgesHizeshi
  • 2026-09-23 16:00fix(api): constrain claim counts and localize decimal textTamerlan
  • 2026-09-23 16:00feat(api): localize explanations with Accept-LanguageTamerlan
  • 2026-09-23 16:00chore: use each contributor own git identityTamerlan
  • 2026-09-23 15:59fix(frontend): keep locale when storage is unavailableHizeshi
  • 2026-09-23 15:55feat(frontend): localize simulator in ru kk enHizeshi
  • 2026-09-23 15:50chore: enforce repository owner attributionHizeshi
  • 2026-09-23 15:41Merge remote-tracking branch 'origin/main'Codex
  • 2026-09-23 15:40feat(frontend): harden demo flow and mobile polishCodex
  • 2026-09-23 15:36test: accept routed UI and document ranking fallbackTamerlan
  • 2026-09-23 15:32Merge remote-tracking branch 'origin/main'Codex
  • 2026-09-23 15:32feat(frontend): integrate 3d city and mobile polishCodex
  • 2026-09-23 15:30fix(api): rank verified claims instead of generating factsTamerlan
  • 2026-09-23 15:30docs: record claim catalog verification and frontend integrationTamerlan
  • 2026-09-23 15:27docs(frontend): record polish verificationCodex
  • 2026-09-23 15:23feat(frontend): prepare 3d city polishCodex
  • 2026-09-23 15:14Merge remote-tracking branch 'origin/main'Codex
  • 2026-09-23 15:13test: record live browser and tunnel acceptanceTamerlan
  • 2026-09-23 15:13Merge remote-tracking branch 'origin/main'Codex
  • 2026-09-23 15:13docs(frontend): record redesign verificationCodex
  • 2026-09-23 15:13chore: add verified NVIDIA Brev deploymentkilka165
  • 2026-09-23 15:12feat(frontend): redesign routed simulatorCodex
  • 2026-09-23 15:09fix(api): generate district-aware recommendations on serverTamerlan
  • 2026-09-23 15:01docs: clarify successful live check after browser testsTamerlan
  • 2026-09-23 15:00test: record browser acceptance and live AI verificationTamerlan
  • 2026-09-23 14:47chore: wire live AI configuration and document API tunnelTamerlan
  • 2026-09-23 14:43feat(frontend): support live explanation sourceCodex
  • 2026-09-23 14:41merge: update origin main before publishCodex
  • 2026-09-23 14:40fix(frontend): focus results and semantic page mainCodex
  • 2026-09-23 14:38merge: integrate origin mainCodex
  • 2026-09-23 14:38feat(frontend): add city overview and plannerCodex
  • 2026-09-23 14:36feat(api): add live AI explanation with safe fallbackTamerlan
  • 2026-09-23 14:34docs: complete README with launch checks and acceptance guideHizeshi
  • 2026-09-23 14:26docs(frontend): note integration blockersCodex
  • 2026-09-23 14:24docs(frontend): record integration verificationCodex
  • 2026-09-23 14:24feat(frontend): integrate simulator API and resultsCodex
  • 2026-09-23 14:08chore: add Docker Compose setup and integration guideHizeshi
  • 2026-09-23 14:07docs(frontend): exclude Intel Playground and local GPU inferenceHizeshi
  • 2026-09-23 14:06docs(frontend): align integration handoff with confirmed API contractHizeshi
  • 2026-09-23 13:57docs(frontend): define architecture, UI contracts and three-agent work splitHizeshi
  • 2026-09-23 13:53feat: implement scenario API and docker launchTamerlan
  • 2026-09-23 13:35chore: normalize documentation file modesTamerlan
  • 2026-09-23 13:34chore: scaffold backend and Next.js frontendTamerlan
Структура репозитория (243 файлов)
.env.example
.githooks/check-personal-authorship.py
.githooks/commit-msg
.githooks/pre-commit
.githooks/pre-merge-commit
.githooks/pre-push
.gitignore
AGENTS.md
CLAUDE.md
README.md
THIRD_PARTY.md
backend/.dockerignore
backend/CitySimulator.Api/ApiExamplesFilter.cs
backend/CitySimulator.Api/CitySimulator.Api.csproj
backend/CitySimulator.Api/Features/Analysis/AlternativeAdviceService.cs
backend/CitySimulator.Api/Features/Analysis/AlternativeSelectionValidator.cs
backend/CitySimulator.Api/Features/Analysis/AnalysisFacts.cs
backend/CitySimulator.Api/Features/Analysis/ExplanationService.cs
backend/CitySimulator.Api/Features/Analysis/ExplanationValidator.cs
backend/CitySimulator.Api/Features/Analysis/LlmOptions.cs
backend/CitySimulator.Api/Features/Analysis/OpenAiExplanationClient.cs
backend/CitySimulator.Api/Features/Scenario/ScenarioData.cs
backend/CitySimulator.Api/Features/Scenario/ScenarioEndpoints.cs
backend/CitySimulator.Api/Features/Scenario/ScenarioModels.cs
backend/CitySimulator.Api/Features/Simulation/AlternativeModels.cs
backend/CitySimulator.Api/Features/Simulation/AlternativeSearch.cs
backend/CitySimulator.Api/Features/Simulation/ChoiceValidator.cs
backend/CitySimulator.Api/Features/Simulation/ExplanationBuilder.cs
backend/CitySimulator.Api/Features/Simulation/ExplanationLocales.cs
backend/CitySimulator.Api/Features/Simulation/ExplanationText.cs
backend/CitySimulator.Api/Features/Simulation/RecommendationBuilder.cs
backend/CitySimulator.Api/Features/Simulation/ReplacementAdvisor.cs
backend/CitySimulator.Api/Features/Simulation/ScoreCalculator.cs
backend/CitySimulator.Api/Features/Simulation/SimulationEndpoints.cs
backend/CitySimulator.Api/Features/Simulation/SimulationModels.cs
backend/CitySimulator.Api/Features/Simulation/TextNumberFormat.cs
backend/CitySimulator.Api/Program.cs
backend/CitySimulator.Api/Properties/launchSettings.json
backend/CitySimulator.Api/appsettings.Development.json
backend/CitySimulator.Api/appsettings.json
backend/CitySimulator.RegressionTests/CitySimulator.RegressionTests.csproj
backend/CitySimulator.RegressionTests/Program.cs
backend/CitySimulator.RegressionTests/README.md
backend/Dockerfile
backend/README.md
backend/scripts/verify-explanation-locales.py
backend/tests/api-regression.mjs
docker-compose.brev.yml
docker-compose.yml
docs/api.md
docs/reference/challenge-task.docx
docs/reference/district-dataset.docx
docs/reports/bugfix-regression.md
docs/reports/e2e.md
docs/reports/e2e/desktop-1440-overview.png
docs/reports/e2e/desktop-1440-result-llm.png
docs/reports/e2e/desktop-1440-result.png
docs/reports/e2e/desktop-evaluate-offline.png
docs/reports/e2e/desktop-planner.png
docs/reports/e2e/desktop-scenario-offline.png
docs/reports/e2e/final-desktop-ru-alternatives.png
docs/reports/e2e/final-mobile-kk-comparison.png
docs/reports/e2e/live-kk-desktop-results.png
docs/reports/e2e/locales-en-retry-error.png
docs/reports/e2e/locales-kk-mobile-390.png
docs/reports/e2e/mobile-390-overview.png
docs/reports/e2e/mobile-390-planner.png
docs/reports/e2e/mobile-390-result.png
docs/reports/e2e/mobile-390-tray.png
docs/reports/e2e/v3-desktop-decisions.png
docs/reports/e2e/v3-desktop-overview.png
docs/reports/e2e/v3-desktop-results.png
docs/reports/e2e/v3-mobile-390-decisions.png
docs/reports/e2e/v3-mobile-390-overview.png
docs/reports/e2e/v3-mobile-390-results.png
docs/reports/e2e/v3-mobile-390-tray.png
docs/reports/final-browser-summary.json
docs/reports/final-http503-summary.json
docs/reports/final-integration.md
docs/team.md
frontend/.dockerignore
frontend/.gitignore
frontend/AGENTS.md
frontend/Dockerfile
frontend/README.md
frontend/app/decisions/page.tsx
frontend/app/error.tsx
frontend/app/layout.tsx
frontend/app/loading.tsx
frontend/app/page.tsx
frontend/app/results/page.tsx
frontend/components/ui/AppHeader.module.css
frontend/components/ui/AppHeader.tsx
frontend/components/ui/Badge.module.css
frontend/components/ui/Badge.tsx
frontend/components/ui/BrandMark.tsx
frontend/components/ui/Button.module.css
frontend/components/ui/Button.tsx
frontend/components/ui/LanguageSwitcher.module.css
frontend/components/ui/LanguageSwitcher.tsx
frontend/components/ui/Metric.module.css
frontend/components/ui/Metric.tsx
frontend/components/ui/Panel.module.css
frontend/components/ui/Panel.tsx
frontend/components/ui/Reveal.module.css
frontend/components/ui/Reveal.tsx
frontend/components/ui/Select.module.css
frontend/components/ui/Select.tsx
frontend/components/ui/Skeleton.module.css
frontend/components/ui/Skeleton.tsx
frontend/components/ui/ThemeProvider.tsx
frontend/components/ui/ThemeSwitcher.module.css
frontend/components/ui/ThemeSwitcher.tsx
frontend/components/ui/cx.ts
frontend/components/ui/index.ts
frontend/components/ui/messages.ts
frontend/components/ui/theme-store.ts
frontend/docs/3d-and-polish.md
frontend/docs/START-HERE.md
frontend/docs/acceptance.md
frontend/docs/architecture.md
frontend/docs/backend-handoff.md
frontend/docs/demo.md
frontend/docs/design.md
frontend/docs/localization.md
frontend/docs/redesign.md
frontend/docs/reports/alternatives-handoff.md
frontend/docs/reports/architect-audit.md
frontend/docs/reports/architect.md
frontend/docs/reports/city-browser-fallback.md
frontend/docs/reports/city-model.md
frontend/docs/reports/claude-1.md
frontend/docs/reports/claude-2.md
frontend/docs/reports/clean-start.md
frontend/docs/reports/custom-select.md
frontend/docs/reports/deployment.md
frontend/docs/reports/gpt.md
frontend/docs/reports/localization-review.md
frontend/docs/reports/release-readiness.md
frontend/docs/reports/report-review.md
frontend/docs/reports/screenshots/claude-1-city-day-1440.png
frontend/docs/reports/screenshots/claude-1-city-night-1440.png
frontend/docs/reports/screenshots/claude-1-home-mobile-390.png
frontend/docs/tasks/claude-1-city-acceptance.md
frontend/docs/tasks/claude-1.md
frontend/docs/tasks/claude-2-release-acceptance.md
frontend/docs/tasks/claude-2.md
frontend/docs/tasks/gpt.md
frontend/docs/tasks/locale-final-pass.md
frontend/eslint.config.mjs
frontend/features/alternatives/AlternativesPanel.tsx
frontend/features/alternatives/alternatives-state.ts
frontend/features/alternatives/alternatives.module.css
frontend/features/alternatives/index.ts
frontend/features/alternatives/labels.ts
frontend/features/alternatives/loader.ts
frontend/features/alternatives/messages.ts
frontend/features/alternatives/plan-diff.ts
frontend/features/alternatives/types.ts
frontend/features/city-overview/AtlasSketch.tsx
frontend/features/city-overview/CityHome.tsx
frontend/features/city-overview/CityScene.tsx
frontend/features/city-overview/DistrictAtlas.tsx
frontend/features/city-overview/DistrictDetails.tsx
frontend/features/city-overview/DistrictExplorer.tsx
frontend/features/city-overview/atlas-layout.ts
frontend/features/city-overview/city-landmarks.ts
frontend/features/city-overview/city-overview.module.css
frontend/features/city-overview/city-scene-engine.ts
frontend/features/city-overview/city-scene.module.css
frontend/features/city-overview/district-summary.ts
frontend/features/city-overview/format.ts
frontend/features/city-overview/home.module.css
frontend/features/city-overview/index.ts
frontend/features/city-overview/messages.ts
frontend/features/city-overview/use-city-copy.ts
frontend/features/planner/BudgetRibbon.tsx
frontend/features/planner/DecisionTray.tsx
frontend/features/planner/DistrictChoice.tsx
frontend/features/planner/DistrictPicker.tsx
frontend/features/planner/MeasureCard.tsx
frontend/features/planner/Planner.tsx
frontend/features/planner/index.ts
frontend/features/planner/labels.ts
frontend/features/planner/localize.ts
frontend/features/planner/messages.ts
frontend/features/planner/planner.module.css
frontend/features/planner/selection-rules.test.ts
frontend/features/planner/selection-rules.ts
frontend/features/results/AttemptHistory.tsx
frontend/features/results/DistrictComparison.tsx
frontend/features/results/Explanation.tsx
frontend/features/results/Results.tsx
frontend/features/results/ScoreComparison.tsx
frontend/features/results/index.ts
frontend/features/results/messages.ts
frontend/features/results/results.module.css
frontend/features/simulator/AppShell.tsx
frontend/features/simulator/DecisionsPage.tsx
frontend/features/simulator/HomePage.tsx
frontend/features/simulator/ResultsPage.tsx
frontend/features/simulator/SimulationProvider.tsx
frontend/features/simulator/error-messages.ts
frontend/features/simulator/routes.module.css
frontend/features/simulator/simulator-reducer.ts
frontend/features/simulator/simulator.module.css
frontend/features/simulator/use-simulation.ts
frontend/lib/api/adapter.ts
frontend/lib/api/alternatives.ts
frontend/lib/api/client.ts
frontend/lib/api/errors.ts
frontend/lib/api/payload.ts
frontend/lib/api/request.ts
frontend/lib/contracts/api.generated.ts
frontend/lib/contracts/ui.ts
frontend/lib/format/numbers.ts
frontend/lib/i18n/LocaleProvider.tsx
frontend/lib/i18n/catalog.ts
frontend/lib/i18n/index.ts
frontend/lib/i18n/locale-store.ts
frontend/mocks/scenario.ts
frontend/next.config.ts
frontend/package-lock.json
frontend/package.json
frontend/public/city/akim-logo.png
frontend/public/city/akim-logo.svg
frontend/public/city/preview-day.png
frontend/public/city/preview-night.png
frontend/public/favicon.ico
frontend/styles/globals.css
frontend/styles/tokens.css
frontend/tests/alternatives-api.test.ts
frontend/tests/alternatives.test.ts
frontend/tests/api-contract.test.ts
frontend/tests/applied-effects.test.ts
frontend/tests/explanation-locale.test.ts
frontend/tests/i18n-catalog.test.ts
frontend/tests/locale-store.test.ts
frontend/tests/number-format.test.ts
frontend/tests/simulation-error-messages.test.ts
frontend/tests/simulator-reducer.test.ts
frontend/tsconfig.json
frontend/tsconfig.test.json

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

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

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