AAYMA
RU
Войти

StikerAI

Городской симулятор «Аким на 5 часов»: план из 5 инициатив (из 14) в бюджете 100, детерминированный расчёт показателей 5 районов и Astana QoL Score.

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

О проекте

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

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

Суть

Городской симулятор «Аким на 5 часов»: план из 5 инициатив (из 14) в бюджете 100, детерминированный расчёт показателей 5 районов и Astana QoL Score. Дополнительно есть карта Астаны по OSM, демо-пространство для жителей и AI-объяснение результата.

Как устроено

Данные astana-v1.json. FastAPI проверяет план: ровно 5 разных мер, не больше двух на направление, соблюдение бюджета. Расчёт на Python: эффект × (8 − лаг)/8, оценка района — взвешенная сумма показателей, Score = 0,7·D_avg + 0,3·min(районы) − N_crit. Результаты сохраняются в PostgreSQL (SQLAlchemy/Alembic) с проверкой ревизии. OpenAI Responses API по желанию объясняет уже рассчитанный результат и не меняет числа. Фронтенд на React 19 с картой MapLibre/Leaflet: OSM-границы районов и школы из Overpass.

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

  • deterministic scoring model
  • lags/synergies/conflicts
  • OSM Overpass
  • MapLibre GL
  • Alembic migrations
  • Playwright E2E

Метрики

Контрольный план стоимостью 95: базовый Score 52,55768 → 56,54307, критические показатели 2 → 0

Особенности

Реальные геоданные OSM (границы районов, 171 школа) используются как контекст и сознательно не связываются с синтетической моделью по совпадению названий. Есть citizen workspace с петициями и голосами. Источники данных и их ограничения подробно задокументированы. Сборка фронтенда блокируется, если текущий checkout отстаёт от удалённых веток.

Стек

React 19 · TypeScript · Vite 7 · MapLibre GL · Leaflet · Python 3.12 · FastAPI · Pydantic · PostgreSQL 16 · SQLAlchemy 2 · Alembic · Docker Compose · GitHub Actions · pytest · Playwright

Модели

OpenAI


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

README

README.md

StikerAI — «Аким на 5 часов»

StikerAI — учебный симулятор городских решений и демонстрация взаимодействия администрации с жителями. Пользователь собирает план из пяти инициатив в рамках общего виртуального бюджета; backend проверяет план, детерминированно считает показатели районов и итоговый Astana Quality of Life Score. AI может объяснить уже рассчитанный результат, но не принимает решение и не меняет числа.

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

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

  • Akim workspace: портфель инициатив, общий бюджет 100 виртуальных единиц, выбор районов, проверка ограничений, предварительный расчёт и сохранённый результат.
  • Детерминированная модель: пять синтетических районов, десять показателей, 14 инициатив, лаги, синергии и конфликты. При отправке требуется ровно пять разных инициатив; допускается не более двух инициатив одного направления.
  • Citizen workspace: демонстрационные петиции, голоса, сообщения и проекты. Это вымышленные данные, хранящиеся локально в браузере; они не меняют государственный бюджет или Score.
  • Карта: шесть community-mapped границ районов и отдельный слой объектов OpenStreetMap с тегом amenity=school. Улицы загружаются отдельным слоем карты. География является контекстом, а не официальным кадастром и не связана с синтетическими показателями по неподтверждённому совпадению названий.
  • AI-объяснение: необязательный вызов OpenAI Responses API получает сохранённые результаты и отдельный явно вымышленный civic-снимок. AI не пересчитывает Score и не должен представлять вымышленные сигналы как мнение жителей.
  • Сохранение сценариев: PostgreSQL, анонимная браузерная сессия, проверка ревизии при записи, отправка и копирование сценариев.

Симулятор встроен в Akim workspace: откройте пункт Simulator или адрес /simulator. Общая оболочка объединяет выбор пяти мер, бюджет, карту, предварительный расчёт, сравнение показателей и AI-анализ. Сессия и каталог общие с обзором города.

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

СлойТехнологииОтветственность
FrontendReact 19, TypeScript, Vite 7, CSS, Lucide ReactРабочие пространства, локальная civic-демонстрация и отображение результатов
КартаMapLibre GL, Leaflet, GeoJSONOSM-границы районов, контекстные school POI и необязательная подложка улиц
APIPython 3.12, FastAPI, Pydantic, UvicornКаталог, сессии, проверка и сохранение решений, расчёт, карта и объяснения
ХранениеPostgreSQL 16, SQLAlchemy 2, psycopg 3, AlembicВерсии набора, сценарии, расчёты, AI-объяснения и миграции
Запуск / CIDocker Compose v2, GitHub Actions, pytest, PlaywrightПовторяемый локальный запуск, проверки backend/frontend и сборка
AIOpenAI Responses API; необязательный MiroFish gatewayКачественное объяснение рассчитанного backend результата

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

React UI → FastAPI → проверка бюджета/правил → Python scoring → сохранённый результат
                                                        └→ AI explanation (optional)

Основные файлы: frontend/src/App.tsx и frontend/src/SimulatorWorkspace.tsx — интерфейс; backend/app/api/simulator.py — сценарии и API; backend/app/services/scenarios.py — правила плана; backend/app/services/scoring.py и backend/app/services/results.py — численный расчёт; backend/app/services/llm.py — AI; backend/app/models.py и backend/migrations/ — хранение и схема БД.

Формула модели astana-qol-v1 описана в datadoc.md:

применённый эффект = полный эффект × (8 − лаг кварталов) / 8
оценка района = Σ(вес показателя × значение показателя)
D_avg = Σ(доля населения района × оценка района)
Score = 0.7 × D_avg + 0.3 × min(оценки районов) − N_crit

N_crit — количество значений «район × показатель» ниже 40. Показатели ограничиваются диапазоном 0–100; итоговый Score формулой снизу не ограничивается и теоретически может быть отрицательным. AI получает рассчитанные числа, компромиссы и решения; вычисления остаются в Python.

Установка и запуск

Нужны Git, Docker Engine/Desktop и Docker Compose v2.

git clone https://github.com/BAITC-Hacks/hack-3f85346f-stikerai.git
cd hack-3f85346f-stikerai
cp .env.example .env
docker compose up --build -d --wait

На Windows PowerShell вместо cp используйте Copy-Item .env.example .env. Compose запускает PostgreSQL, миграции и seed синтетического датасета, затем API и Vite frontend.

Для детерминированного расчёта ключи не нужны. Для AI-объяснения задайте OPENAI_API_KEY и OPENAI_MODEL в .env, затем пересоздайте backend:

docker compose up -d --force-recreate backend

OPENAI_BASE_URL и OPENAI_TIMEOUT_SECONDS настраивают API endpoint и timeout. VITE_MAP_STYLE_URL задаёт публичный стиль слоя улиц, VITE_MAP_TILE_URL — тайлы школьного контекста. Эти map-переменные видны браузеру; не размещайте в них секреты. MIROFISH_ENABLED по умолчанию false; для адаптера требуется отдельный защищённый gateway. Все параметры и локальные значения находятся в .env.example.

Логи и остановка:

docker compose logs backend frontend db migrate seed
docker compose down

PostgreSQL хранится в volume postgres_data; docker compose down сохраняет его. Для чистой локальной демонстрационной БД можно выполнить docker compose down -v — эта команда удаляет volume с данными.

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

Проверьте доступность API:

curl -fsS http://localhost:8000/api/health

Ожидаемый ответ:

{"status":"ok","service":"stikerai-backend"}

В интерфейсе нажмите Enter Command Center и соберите контрольный план из набора astana-synthetic-v1:

ИнициативаЦельСтоимость
M7 — школа и детсадНура24
M8 — семейный медцентрНура20
M10 — освещение и камерыНура12
M12 — платформа обращенийВесь город14
M5 — чистое топливоСарыарка25

Backend должен принять план стоимостью 95 из 100 и показать контрольный расчёт: базовый Score 52.55768, итоговый 56.54307, критические показатели — с 2 до 0. Это тестовый результат синтетической формулы, не оценка реального воздействия.

Backend-проверки на запущенном Compose:

docker compose exec backend python -m pytest -q

Для browser E2E на хосте нужны Python 3.12, Node.js 22.12+ и Chromium. Команда запускает изолированный тестовый API и frontend; AI-запросы не требуются.

cd backend
python3 -m venv .venv
.venv/bin/python -m pip install -r requirements-dev.txt
cd ../frontend
npm ci
npx playwright install chromium
PATH="../backend/.venv/bin:$PATH" npm run test:e2e

Сборка frontend:

cd frontend
npm ci
npm run build

npm run build сначала запускает prebuild: скрипт получает историю веток с Git remotes и блокирует сборку, если текущий checkout отстаёт от какой-либо удалённой ветки. Для этого шага требуется Git remote и сеть. CI дополнительно проверяет генерацию типов, backend-тесты на SQLite/PostgreSQL, frontend build и Docker Compose.

Данные и внешние сервисы

ИсточникГде используетсяСтатус и границы
backend/data/astana-v1.json, datadoc.mdБюджет, районы, индикаторы, меры, эффекты и ScoreСинтетический учебный набор; не официальная статистика и не прогноз
OpenStreetMap relationsГеометрия шести районов на картеСнимок от 2026-09-23; community mapping, не кадастровая или официально подтверждённая граница. Лицензия ODbL и attribution показаны в UI
OpenStreetMap через Overpass171 точка в снимке объектов, помеченных amenity=schoolНа 2026-09-22; могут быть неполные, устаревшие или неверно размеченные записи, включая колледжи/дошкольные объекты. Только поиск кандидатов; не официальный реестр
OpenFreeMap и OSM tile serviceНеобязательные веб-подложки улицЗагружаются браузером; требуют сети и зависят от условий/доступности поставщика. Границы и интерактивные списки остаются полезны без подложки
OpenAI Responses APIНеобязательное текстовое объяснениеРеальный внешний запрос только с серверными OPENAI_API_KEY и OPENAI_MODEL; численная модель остаётся в backend
MiroFish gatewayНеобязательный адаптерВыключен по умолчанию; не собирает посты или сообщения из соцсетей
Citizen fixtures / localStorageПетиции, сигналы, community activityВымышленные локальные данные, не реальные голоса или финансирование
Open-Meteo fixture в backend/data/enrichment/Исследовательская фикстураСнимок прогноза хранится с provenance; текущий интерфейс не использует его для показателей или Score
YouTube livestreamВидеоконтекстЗагружается только по нажатию; видео не анализируется

Геоданные, происхождение карты и crosswalk описаны в docs/interactive-map.md, исследование источников — в sources.md и плане обогащения. Официальные источники по транспорту, школам, безопасности, воздуху и городским активам пока не подключены как проверенные слои показателей.

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

  • Реальные городские результаты нельзя выводить из синтетических метрик, условных цен и модельных эффектов.
  • Пять синтетических профилей не имеют подтверждённого crosswalk к шести картографическим районам; совпадение названий не используется для окрашивания районов по Score.
  • OSM не заменяет официальный перечень школ, полевую проверку или инженерный аудит. В текущем продукте нет дорожных замеров, аварийных точек, вместимости школ, локальных показателей воздуха или реальных данных обращений.
  • Civic workspace демонстрационный: действия жителей хранятся в браузере, не синхронизируются между людьми, петиции не имеют юридического эффекта, платежи не проводятся.
  • AI может быть не настроен; без ключа недоступно только внешнее текстовое объяснение. AI не подтверждает факты и не доказывает причинность.
  • Стандартные OSM/OpenFreeMap подложки зависят от внешней сети и политики поставщика; для production требуется выбранный провайдер или собственный tile-сервис. Публичный deployment в репозитории не указан.
  • Compose настроен для разработки: используются Vite dev server и auto-reload. Production-конфигурация, HTTPS, аутентификация пользователей и эксплуатационная поддержка не входят в этот прототип.

Развёрнутая версия и документация

Публичная развёрнутая версия в репозитории не указана. Чтобы воспроизвести проект, используйте Docker Compose выше.

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

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

vasileyyy 11Aigerim Nurgaliyeva 11ieeelon 9

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

  • 2026-09-23 18:00Integrate city simulator into the Akim workspacevasileyyy
  • 2026-09-23 17:49Rewrite README for current projectieeelon
  • 2026-09-23 17:30Merge latest Madi school context into both city workspacesvasileyyy
  • 2026-09-23 17:19Merge latest Aigerim documentation into mainvasileyyy
  • 2026-09-23 17:18Merge Vasya map and localization with main command centervasileyyy
  • 2026-09-23 17:17Add real OSM school context mapieeelon
  • 2026-09-23 17:15docs: update command center READMEAigerim Nurgaliyeva
  • 2026-09-23 17:01Merge remote-tracking branch 'origin/Madi'vasileyyy
Все коммиты (31)
  • 2026-09-23 17:00Add Astana pilot data source leadsieeelon
  • 2026-09-23 16:53feat: add interactive Astana map and Kazakh localizationvasileyyy
  • 2026-09-23 16:41docs: map data requirements for Astana pilotieeelon
  • 2026-09-23 16:18feat: connect civic AI context and verify merged command centerAigerim Nurgaliyeva
  • 2026-09-23 16:09merge: preserve local command center while integrating latest mainAigerim Nurgaliyeva
  • 2026-09-23 16:08feat: add Astana command center and connected citizen workspaceAigerim Nurgaliyeva
  • 2026-09-23 16:03Merge origin/Madi into main with unified scenario workflowvasileyyy
  • 2026-09-23 15:43feat: wire deterministic civic scenario workflowieeelon
  • 2026-09-23 15:36fix: mount current migrations and dataset in development containersAigerim Nurgaliyeva
  • 2026-09-23 15:31feat: add public signals demo and civic contextieeelon
  • 2026-09-23 15:27merge: pull latest main into AigerimAigerim Nurgaliyeva
  • 2026-09-23 15:22Merge remote-tracking branch 'origin/Madi' into Vasyavasileyyy
  • 2026-09-23 15:20merge: incorporate latest branch updates into AigerimAigerim Nurgaliyeva
  • 2026-09-23 15:19build: check all remote branches before every frontend buildAigerim Nurgaliyeva
  • 2026-09-23 15:18docs: plan localized public opinion analysisieeelon
  • 2026-09-23 15:15merge: integrate latest branches into Aigerim with Astana designAigerim Nurgaliyeva
  • 2026-09-23 15:11docs: research Astana data enrichment sourcesieeelon
  • 2026-09-23 15:09feat: style mayor simulator with Astana blue and gold identityAigerim Nurgaliyeva
  • 2026-09-23 15:03feat: connect simulator UI to persistent scenarios and AI analysisvasileyyy
  • 2026-09-23 14:29Merge remote-tracking branch 'origin/Madi'vasileyyy
  • 2026-09-23 14:26docs: add QGIS district grid planieeelon
  • 2026-09-23 14:24feat: add mayor city simulator dashboardAigerim Nurgaliyeva
  • 2026-09-23 14:18wip: scaffold application and simulator data modelvasileyyy
Структура репозитория (130 файлов)
.env.example
.gitattributes
.github/workflows/ci.yml
.gitignore
Data_Enrichment_Research_Plan.md
MiroFish_Local_Opinion_Plan.md
PRD.md
QGIS_Plan.md
README.md
backend/.dockerignore
backend/Dockerfile
backend/alembic.ini
backend/app/__init__.py
backend/app/api/__init__.py
backend/app/api/context.py
backend/app/api/health.py
backend/app/api/map.py
backend/app/api/mirofish.py
backend/app/api/public_signals.py
backend/app/api/scenarios.py
backend/app/api/simulator.py
backend/app/db.py
backend/app/domain.py
backend/app/main.py
backend/app/models.py
backend/app/schemas.py
backend/app/seed.py
backend/app/services/__init__.py
backend/app/services/llm.py
backend/app/services/mirofish.py
backend/app/services/openai_analysis.py
backend/app/services/results.py
backend/app/services/scenarios.py
backend/app/services/scoring.py
backend/data/astana-v1.json
backend/data/enrichment/astana-context-v1/manifest.json
backend/data/enrichment/astana-context-v1/osm/overpass-query.txt
backend/data/enrichment/astana-context-v1/osm/schools.geojson
backend/data/enrichment/astana-context-v1/urban-quality/README.md
backend/data/enrichment/astana-context-v1/weather/forecast-raw-response.json
backend/data/enrichment/astana-context-v1/weather/forecast-sample.json
backend/data/geography/astana-districts.geojson
backend/data/geography/crosswalk.json
backend/data/geography/sources.json
backend/migrations/env.py
backend/migrations/script.py.mako
backend/migrations/versions/0001_initial_simulator_schema.py
backend/migrations/versions/0002_scenario_sessions_and_durable_analysis.py
backend/pytest.ini
backend/requirements-dev.txt
backend/requirements.txt
backend/scripts/export_types.py
backend/scripts/import_osm_boundaries.py
backend/tests/conftest.py
backend/tests/serve_e2e.py
backend/tests/test_api.py
backend/tests/test_data_model.py
backend/tests/test_health.py
compose.yaml
datadoc.md
docs/data-model.md
docs/enrichment/BASELINE_LOCK.md
docs/enrichment/README.md
docs/enrichment/boundaries/README.md
docs/enrichment/boundaries/sources.csv
docs/enrichment/civic-evidence-map.md
docs/enrichment/population-terrain/research.md
docs/enrichment/public-signals/README.md
docs/enrichment/public-signals/language-evaluation-template.csv
docs/enrichment/public-signals/source-card-template.md
docs/enrichment/urban-quality/README.md
docs/enrichment/weather/README.md
docs/enrichment/weather/source-card.md
docs/i18n.md
docs/integration.md
docs/interactive-map.md
docs/mirofish-adapter.md
docs/openai-evaluation.md
frontend/.dockerignore
frontend/Dockerfile
frontend/e2e/civic-accounting.spec.ts
frontend/e2e/civic.spec.ts
frontend/e2e/i18n.spec.ts
frontend/e2e/map.spec.ts
frontend/e2e/simulator.spec.ts
frontend/e2e/workspaces.spec.ts
frontend/index.html
frontend/package-lock.json
frontend/package.json
frontend/playwright.config.ts
frontend/public/astana-emblem.svg
frontend/public/astana-flag.svg
frontend/scripts/check-branch-sync.sh
frontend/src/App.tsx
frontend/src/AstanaMap.tsx
frontend/src/AstanaMapCanvas.tsx
frontend/src/CityContextMap.tsx
frontend/src/CityLiveView.tsx
frontend/src/PublicSignalsPanel.tsx
frontend/src/SimulatorWorkspace.tsx
frontend/src/api.ts
frontend/src/astana-map.css
frontend/src/city-context-map.css
frontend/src/city-orbit.css
frontend/src/civic-context.css
frontend/src/command-center.css
frontend/src/components/CitizenPulse.tsx
frontend/src/components/CityMap.tsx
frontend/src/components/CivicForms.tsx
frontend/src/components/CivicPages.tsx
frontend/src/components/Government.tsx
frontend/src/components/UI.tsx
frontend/src/data/citizens.ts
frontend/src/data/crowdfunding.ts
frontend/src/data/issues.ts
frontend/src/data/petitions.ts
frontend/src/data/votes.ts
frontend/src/futuristic-light.css
frontend/src/futuristic.css
frontend/src/hooks/useCivic.ts
frontend/src/hooks/useSimulator.ts
frontend/src/i18n.tsx
frontend/src/locales/kk.ts
frontend/src/main.tsx
frontend/src/mapData.ts
frontend/src/styles.css
frontend/src/types/domain.ts
frontend/tsconfig.json
frontend/vite.config.ts
sources.md
Ветки (4)

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

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

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