AAYMA
RU
Войти

Qala Lab

Городской симулятор: команда делает ровно пять решений из 14 мер и распределяет бюджет 100 между пятью направлениями и пятью районами Астаны…

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

О проекте

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

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

Суть

Городской симулятор: команда делает ровно пять решений из 14 мер и распределяет бюджет 100 между пятью направлениями и пятью районами Астаны, серверная модель считает Astana Quality of Life Score, AI объясняет компромиссы и генерирует новые варианты условий (зима, жара, рост).

Как устроено

Чистая доменная модель на TypeScript считает эффекты мер с лагом (8−лаг)/8 за восемь кварталов, фиксированные синергии, клиппинг 0–100 и Score = 0.7×взвешенное по населению среднее + 0.3×слабейший район − число показателей ниже 40. Route Handlers Next.js валидируют решения; AI-адаптер (NVIDIA NIM или OpenAI) генерирует только ограниченный blueprint кейса, который проверяется, восстанавливается по доверенному каталогу цен и подписывается HMAC, и пишет объяснение отчёта. Интерфейс на React с процедурной 3D-сценой Three.js, сохранением отчётов и сравнением.

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

  • deterministic scoring model
  • lag and synergy effects
  • HMAC-signed case generation
  • JSON validation
  • rate limiting

Метрики

Контрольный план: Score 56.54307 (база 52.55768), расход 95, критических показателей 0; 99 unit/integration-тестов и 8 E2E

Особенности

AI не может менять score, цены и бюджеты: сгенерированный кейс подписывается HMAC и перепроверяется сервером. Есть Docker, Kubernetes-манифесты с kubeconform и smoke-проверка развёртывания.

Стек

TypeScript · Next.js · React · Three.js · pnpm · Docker · Kubernetes · Playwright · GitHub Actions

Модели

NVIDIA NIM · OpenAI


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

README

README.md

Qala Lab

«Аким на 5 часов» — AI-симулятор управления городом от Qala Lab. За пять решений команда распределяет общий виртуальный бюджет между транспортом, зелёными зонами, социальной инфраструктурой, безопасностью и городскими сервисами.

Каждая команда начинает с одинаковых синтетических данных и бюджета. Система проверяет стоимость выбранных мероприятий, рассчитывает изменение показателей и формирует Astana Quality of Life Score (AQoL) с AI-объяснением сильных сторон, рисков и компромиссов.

Главная страница — Qala Lab: пять районов Астаны, десять показателей, 14 мер, ровно пять решений и бюджет 100. AI создаёт новые условия и объясняет последствия; численный результат считает серверная модель. Для честного сравнения команды выбирают один кейс и версию правил. Горизонт фиксирован: восемь кварталов.

РежимЧто проверяет
/ — Qala LabИсходный датасет Астаны и варианты зимы, жары, роста; лаги, синергии, критические показатели и рекомендации
/sandbox — базовый раундПять решений при общем бюджете 100 и контрольных исходных данных
/challenge — городское событиеИсходный план, воздействие события и ответное перераспределение

Qala Lab: каталог кейсов

Запуск

Требуется Node.js 22.x и pnpm 10.34.5. Версии зависимостей закреплены в package.json и lockfile.

corepack enable
pnpm install --frozen-lockfile
pnpm dev

Откройте http://localhost:3000.

Production-сборка:

pnpm build
pnpm start

Проверки модели, HTTP, AI-адаптеров и браузерного сценария:

pnpm test
pnpm lint
pnpm build
pnpm exec playwright install chromium
pnpm test:e2e

Браузерные тесты запускают production-сервер на порту 3210. Они используют подмену ответа AI и не расходуют ключи; реальный провайдер проверяется отдельно после настройки окружения.

Qala Lab: экономика и AI-кейсы

Основной кейс astana точно воспроизводит предоставленную таблицу: Есиль, Алматы, Сарыарка, Байконур и Нура. Дополнительные winter, heat, growth — учебные вариации. Во всех случаях одинаковы каталог мер и правила: 100 единиц, ровно 5 уникальных мер, максимум 2 одного направления. Районные меры требуют один район, городские действуют во всех пяти. Несовместимые сочетания отклоняются.

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

КонтрольРасходScoreКритических показателей
Исходные данные—52.557682
M7, M8, M10 в Нуре; M12 по городу; M5 в Сарыарке9556.543070

Исходный Score — справочная точка, а не допустимый пустой план. Отчёт показывает районные изменения, вклад мер с учётом лага, синергии, штраф и до трёх улучшений. Рекомендации пересчитываются с полной валидацией. До 12 сохранений доступны в этом браузере: после перезагрузки можно открыть полный отчёт. При восстановлении сохранённого отчёта та же чистая модель локально перепроверяет данные; новый расчёт и AI-разбор проходят через сервер. Сравнение требует одинакового кейса и версии. Доступны JSON-экспорт, печать и необязательная процедурная 3D-схема с HTML-альтернативой.

AI создаёт только ограниченный blueprint: тему, описание и исходные районные показатели. Сервер проверяет структуру, восстанавливает доверенный каталог цен и подписывает кейс HMAC. Подпись действует семь дней; изменение данных клиентом отклоняется. В production для генерации нужен постоянный CASE_SIGNING_SECRET длиной минимум 32 символа. Без AI-ключа все готовые кейсы и расчёты доступны.

Граница реализма: названия районов реальные, но входные индексы и коэффициенты — предоставленные условия учебной модели, не подтверждённая статистика и не прогноз Астаны. Доля населения затронутых районов не равна числу доказанных благополучателей. Методика, полный датасет и правила, контракт релиза.

Архитектура

flowchart LR
  UI[React: кейсы и решения] --> HTTP[Route Handlers: валидация]
  HTTP --> DOMAIN[Чистая модель: AQoL, сроки, бюджеты]
  HTTP --> CASES[Доверенный каталог / подписанный blueprint]
  HTTP --> AI[AI-адаптер NVIDIA / OpenAI]
  AI --> VALIDATE[Проверка JSON и ограничений]
  VALIDATE --> CASES
  DOMAIN --> REPORT[Факты и рекомендации]
  REPORT --> UI
  REPORT --> AI

src/domain не зависит от React, HTTP и провайдеров. src/data задаёт версионированные правила, src/application связывает исходный сценарий с моделью. src/infrastructure содержит HTTP-схемы, подпись и AI-адаптеры; src/app/api — транспорт, src/components — интерфейс. Секреты не попадают в клиент, AI не может менять score, цены или бюджеты.

Docker и Kubernetes

Production-образ использует Next.js standalone, работает от непривилегированного пользователя и слушает порт 3000. Проверка готовности: GET /api/health. Ключ AI передаётся при запуске контейнера.

docker build -t akim-city:local .
docker run --rm --name akim -p 3000:3000 akim-city:local

В другом терминале выполните pnpm smoke:deploy: проверяются health, страница, статический файл и контрольный расчёт /api/challenge. Для AI добавьте --env-file .env.local перед именем образа.

Для локального Kubernetes с доступом к образу akim-city:local:

pnpm check:k8s
kubectl apply -k deploy/k8s
kubectl -n akim rollout status deployment/akim --timeout=180s
kubectl -n akim port-forward service/akim 3000:80

Проверка манифестов требует kubectl, Go 1.24+ и сеть для kubeconform и схем. Для удалённого кластера требуется загрузить образ в registry и указать его адрес. Контракт образа, Secret, настройка registry и остановка описаны в docs/runtime-contract.md. CI проверяет схемы Kubernetes и запускает тот же smoke в собранном Docker-образе.

API Qala Lab

EndpointНазначение
GET /api/casesГотовые кейсы и доступность генерации
POST /api/cases/evaluateПроверка пяти решений и детерминированный отчёт
POST /api/cases/analyzeПовторный серверный расчёт и AI-объяснение
POST /api/cases/generateГенерация условий, валидация, подписанный кейс

Контрольный расчёт без ключа:

curl http://localhost:3000/api/cases/evaluate \
  -H 'Content-Type: application/json' \
  -d '{"caseId":"astana","decisions":[{"measureId":"M7","districtId":"nura"},{"measureId":"M8","districtId":"nura"},{"measureId":"M10","districtId":"nura"},{"measureId":"M12"},{"measureId":"M5","districtId":"saryarka"}]}'

Ожидаются evaluation.result.spent=95, finalAqol=56.54307 (с погрешностью машинной арифметики), criticalCount=0. Для сгенерированного кейса добавляется caseToken, возвращённый генерацией. Клиентские цены, эффекты, score и лишние поля не принимаются. Невалидный набор возвращает причину и не получает score.

Генерация принимает {"brief":"Описание условий нового кейса не короче 20 символов","theme":"winter"}. Возможные темы: baseline, winter, heat, growth, mobility. Полный датасет, веса и правила — в контракте astana-1. Дополнительные /sandbox, /challenge и их API описаны в учебных режимах; у них отдельная прежняя модель.

AI-анализ

Скопируйте .env.example в .env.local. Для NVIDIA задайте AI_PROVIDER=nvidia и NVIDIA_API_KEY, для OpenAI — AI_PROVIDER=openai и OPENAI_API_KEY. Настройки моделей — NVIDIA_MODEL / OPENAI_MODEL. Ключ читается только сервером. В production также задайте CASE_SIGNING_SECRET (например, результат openssl rand -hex 32); один секрет должен использоваться всеми репликами.

Без ключа, при таймауте или ошибке провайдера система показывает недоступность AI, сохраняя детерминированный AQoL. AI-вызовы ограничены по частоте и параллелизму внутри процесса; для публичного многорепличного сервиса нужны общая квота и контроль доступа на входе. Базовый /sandbox использует исходный NVIDIA-адаптер.

Статус

Проект реализуется спринтами. Спецификация находится в docs/design/, пошаговые планы — в docs/superpowers/plans/, параллельные дорожки команды — в docs/sprint-workstreams.md.

Релиз Qala Lab проверен 23 сентября 2026: 99 unit/integration-тестов, 8 Chromium E2E, lint, production build, Docker и локальный Kubernetes. Реальные генерация и анализ OpenAI прошли через браузер; NVIDIA проверен mock-тестами. Протокол проверки, демо на три минуты, структура презентации.

GitHub Actions пока не запускается из-за блокировки аккаунта организации по биллингу. После восстановления доступа нужно повторить CI; приведённые результаты получены локально.

Иконки — Lucide (ISC), процедурная сцена — Three.js (MIT). Внешние 3D-модели и изображения не загружаются; скриншот получен из работающего приложения.

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

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

CMPNION 32aiympangerey1703 1sabinazzz 1Sabina Zhumagaliyeva 1a1ymsss 1

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

  • 2026-09-23 16:46chore: name the project Qala LabCMPNION
  • 2026-09-23 16:35Merge pull request #3: release Astana City LabNorkin Dmitriy
  • 2026-09-23 16:34docs: record GitHub Actions billing limitationCMPNION
  • 2026-09-23 16:32test: verify release flows in Chromium Docker and KubernetesCMPNION
  • 2026-09-23 16:32docs: publish Astana methodology demo and release evidenceCMPNION
  • 2026-09-23 16:28feat: ship city lab workspace with restorable reports and comparisonCMPNION
  • 2026-09-23 16:25feat: render accessible procedural district sceneCMPNION
  • 2026-09-23 16:24feat: implement exact Astana scoring and validated case variantsCMPNION
Все коммиты (36)
  • 2026-09-23 16:24feat: generate signed city cases with OpenAI and NVIDIACMPNION
  • 2026-09-23 16:15build: pin dependencies and prepare release verificationCMPNION
  • 2026-09-23 16:15feat: define supplied Astana dataset and exact scoring contractCMPNION
  • 2026-09-23 15:58docs: define city lab release contracts and simulation scopeCMPNION
  • 2026-09-23 15:51merge: add interactive event challengeCMPNION
  • 2026-09-23 15:47merge: add Docker and Kubernetes runtimeCMPNION
  • 2026-09-23 15:41docs: document city challenge flow and control scenarioCMPNION
  • 2026-09-23 15:41feat: add interactive city event challenge workflowCMPNION
  • 2026-09-23 15:40feat: add standalone Docker and Kubernetes runtimeCMPNION
  • 2026-09-23 15:40ci: verify deployment manifests and container smokeCMPNION
  • 2026-09-23 15:26merge: integrate Ayim quality gates from mainCMPNION
  • 2026-09-23 15:26docs: assign sprint three release workstreamsCMPNION
  • 2026-09-23 15:25Merge pull request #2 from BAITC-Hacks/feat/ayim-quality-gatesaiympangerey1703
  • 2026-09-23 15:25merge: integrate sprint two city event simulationCMPNION
  • 2026-09-23 15:25feat: add deterministic city event challengesCMPNION
  • 2026-09-23 15:23merge: integrate Sabina district visualizationCMPNION
  • 2026-09-23 15:23merge: integrate Ayim quality gatesCMPNION
  • 2026-09-23 15:22Merge pull request #1 from BAITC-Hacks/feat/sabina-district-visualssabinazzz
  • 2026-09-23 15:17feat: visualize district score changes and document hackathon demoSabina Zhumagaliyeva
  • 2026-09-23 15:16test: add catalog quality gates and verification CIa1ymsss
  • 2026-09-23 15:03feat: complete five-decision simulation flowCMPNION
  • 2026-09-23 15:01docs: add three-way sprint workstreamsCMPNION
  • 2026-09-23 14:59feat: explain scenarios with NVIDIA NIMCMPNION
  • 2026-09-23 14:48feat: add validated scenario endpointCMPNION
  • 2026-09-23 14:42feat: add deterministic city scenario engineCMPNION
  • 2026-09-23 14:34feat: scaffold city simulation appCMPNION
  • 2026-09-23 14:18docs: plan sprint one implementationCMPNION
  • 2026-09-23 14:05docs: specify Akim city simulationCMPNION
Структура репозитория (103 файлов)
.dockerignore
.env.example
.github/workflows/verify.yml
.gitignore
.nvmrc
AGENTS.md
CLAUDE.md
Dockerfile
README.md
deploy/k8s/configmap.yaml
deploy/k8s/deployment.yaml
deploy/k8s/kustomization.yaml
deploy/k8s/namespace.yaml
deploy/k8s/service.yaml
docs/assets/city-lab.png
docs/demo-script.md
docs/design/akim-na-5-chasov.md
docs/design/astana-dataset.md
docs/design/release-city-lab.md
docs/legacy-demo-script.md
docs/legacy-simulator.md
docs/model-assumptions.md
docs/presentation.md
docs/release-verification.md
docs/runtime-contract.md
docs/sprint-workstreams.md
docs/superpowers/plans/2026-09-23-akim-sprint-1.md
docs/superpowers/plans/2026-09-23-akim-sprint-2.md
docs/testing.md
e2e/city-lab.spec.ts
eslint.config.mjs
next-env.d.ts
next.config.ts
package.json
playwright.config.ts
pnpm-lock.yaml
postcss.config.mjs
scripts/deploy-smoke.mjs
scripts/test.mjs
scripts/validate-k8s.sh
src/app/api/cases/analyze/route.ts
src/app/api/cases/evaluate/route.ts
src/app/api/cases/generate/route.ts
src/app/api/cases/route.ts
src/app/api/challenge/route.test.ts
src/app/api/challenge/route.ts
src/app/api/health/route.ts
src/app/api/scenario/route.test.ts
src/app/api/scenario/route.ts
src/app/challenge/page.tsx
src/app/globals.css
src/app/layout.tsx
src/app/page.tsx
src/app/sandbox/page.tsx
src/application/run-event-challenge.ts
src/application/run-scenario.ts
src/application/scenario-narrator.ts
src/components/city-lab/case-report.tsx
src/components/city-lab/case-workspace.tsx
src/components/city-lab/city-lab.module.css
src/components/city-lab/city-lab.tsx
src/components/city-lab/city-scene.tsx
src/components/city-lab/lab-state.test.ts
src/components/city-lab/lab-state.ts
src/components/city-lab/scene/city-scene.module.css
src/components/simulation/budget-meter.tsx
src/components/simulation/challenge-builder.tsx
src/components/simulation/challenge-report.tsx
src/components/simulation/challenge-state.test.ts
src/components/simulation/challenge-state.ts
src/components/simulation/challenge.module.css
src/components/simulation/district-score-bars.module.css
src/components/simulation/district-score-bars.tsx
src/components/simulation/initiative-picker.tsx
src/components/simulation/presentation.ts
src/components/simulation/scenario-builder.tsx
src/components/simulation/scenario-report.tsx
src/data/astana-catalog.ts
src/data/city-cases.ts
src/data/city-v1.test.ts
src/data/city-v1.ts
src/data/events-v1.ts
src/domain/astana-metrics.ts
src/domain/city-case.ts
src/domain/evaluate-city-case.test.ts
src/domain/evaluate-city-case.ts
src/domain/evaluate-scenario.test.ts
src/domain/evaluate-scenario.ts
src/domain/events.ts
src/domain/model.ts
src/domain/run-event-challenge.test.ts
src/infrastructure/cases/cases.test.ts
src/infrastructure/cases/handlers.ts
src/infrastructure/cases/http.ts
src/infrastructure/cases/limiter.ts
src/infrastructure/cases/provider.ts
src/infrastructure/cases/schemas.ts
src/infrastructure/cases/tokens.ts
src/infrastructure/http/challenge-schema.ts
src/infrastructure/http/scenario-schema.ts
src/infrastructure/nvidia-scenario-narrator.test.ts
src/infrastructure/nvidia-scenario-narrator.ts
tsconfig.json

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

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

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