AAYMA
RU
Войти

Latitude 51

Городской симулятор на Next.js: пользователь выбирает 5 мер из каталога M1–M14 в пределах бюджета 100, видит последствия по 5 районам Астаны на 2D…

Рабочий MVP
Команда «Latitude51N» 14💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: Latitude51N
Кейс HackAlem.ai: Спецтрек — Astana Innovations
Стадия: Рабочий MVP

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

Суть

Городской симулятор на Next.js: пользователь выбирает 5 мер из каталога M1–M14 в пределах бюджета 100, видит последствия по 5 районам Астаны на 2D- и 3D-карте, ищет лучшую замену одной меры и получает AI-анализ плана.

Как устроено

Движок dataset.ts задаёт 5 районов, 10 показателей, доли населения, 14 мер, лаги, синергии и несовместимости. Эффект меры = эффект×(8−лаг)/8 на горизонте 8 кварталов. Score = 0.7×D_avg + 0.3×min(D_d) − N_crit. validate.ts проверяет план, improve.ts перебирает допустимые замены одной меры. Сервер /api/analyze заново считает план и передаёт в OpenAI только проверенные числа для объяснения.

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

  • weighted district scoring
  • lag/synergy model
  • single-swap improvement search
  • server-side revalidation

Метрики

Контрольные значения: базовый Score 52.55768; эталонный план организаторов (стоимость 95) даёт Score 56.54307.

Особенности

Движок проверен контрольными значениями из примера организаторов. Сервер не доверяет стоимости и Score, пришедшим из браузера, и пересчитывает их сам. Есть 3D-карта районов на GeoJSON и поиск лучшей замены одной меры.

Стек

TypeScript · React · Next.js · Tailwind CSS · MapLibre GL · Three.js · React Three Fiber · Vitest

Модели

GPT-4o-mini


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

README

README.md

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

HackAlem AI-симулятор управления городом от команды Latitude51N.

1. Назначение

Latitude 51 помогает пользователю в роли акима выбрать пять городских мер в рамках бюджета 100, увидеть последствия по пяти районам Астаны и сравнить компромиссы. Целевая аудитория текущей версии — участники демо и жюри хакатона: сценарий показывает, как ограниченный бюджет и лаг реализации влияют на качество решений.

Показатели районов в симуляторе синтетические и относятся к модели задачи, а не к официальному прогнозу города.

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

  • выбор ровно пяти разных мер из каталога M1–M14;
  • бюджет до 100 единиц, районные и городские меры;
  • валидация районов, направлений, бюджета и несовместимых сочетаний;
  • детерминированный расчёт Astana Quality of Life Score;
  • визуализация пяти районов на карте и отображение изменений показателей;
  • готовый сценарий организаторов стоимостью 95;
  • поиск лучшей допустимой замены одной выбранной меры;
  • серверный AI-анализ сильных сторон, рисков и компромиссов рассчитанного плана.

3. Пользовательский сценарий

  1. Открыть / и перейти в симулятор или сразу открыть /simulator.
  2. Выбрать район для районной меры и заполнить пять слотов. Городские меры применяются ко всем районам.
  3. Получить подсказки о недоступных мерах и увидеть стоимость, остаток бюджета и изменения районов.
  4. После заполнения пяти слотов получить Score и детализацию по районам.
  5. Запустить поиск одной замены, при необходимости применить её, затем запросить AI-анализ.

Score и все числовые последствия вычисляются кодом. LLM получает готовый результат и формулирует объяснение; она не является источником чисел.

4. Модель и данные

Движок использует пять районов, десять показателей, доли населения, 14 мер, веса, лаги, синергии и несовместимости, заданные в src/lib/engine/dataset.ts.

  • горизонт модели: 8 кварталов;
  • эффект меры: эффект × (8 − лаг) / 8;
  • после суммирования эффектов и синергий показатель ограничивается диапазоном 0–100;
  • районная мера действует в выбранном районе, городская — во всех пяти и оплачивается один раз;
  • D_d — взвешенная оценка района;
  • D_avg — оценка, взвешенная по доле населения;
  • N_crit — число значений показателей строго ниже 40;
  • Score = 0.7 × D_avg + 0.3 × min(D_d) − N_crit.

Данные и формула реализованы локально. Файл GeoJSON в public/geo/astana-districts.geojson используется для границ районов. Внешняя карта MapLibre может загружать картографическую подложку OpenFreeMap при наличии сети.

5. Технологии и интеграции

  • TypeScript и React 19;
  • Next.js 16 App Router;
  • Tailwind CSS 4;
  • MapLibre GL, Three.js, React Three Fiber и drei;
  • Motion и Phosphor Icons;
  • Vitest для тестов;
  • OpenAI Chat Completions API для /api/analyze.

Модель OpenAI задаётся переменной OPENAI_MODEL; по умолчанию используется gpt-4o-mini. API-ключ используется только серверным route handler. Статического AI-fallback в текущей версии нет: без ключа endpoint возвращает ошибку 503.

6. Архитектура

src/lib/engine/dataset.ts  данные, веса, меры и ограничения
src/lib/engine/validate.ts правила допустимости плана
src/lib/engine/score.ts    расчёт Score и районных результатов
src/lib/engine/improve.ts  перебор допустимых замен одной меры
src/lib/engine/engine.test.ts контрольные и поведенческие тесты

src/app/page.tsx            лендинг
src/app/simulator/page.tsx  страница симулятора
src/components/Simulator.tsx состояние пользовательского сценария
src/components/PlanBuilder.tsx выбор мер и районов
src/components/CityMapPanel.tsx карта и визуализация районов
src/components/ResultsPanel.tsx Score, ошибки, улучшение и AI-анализ
src/app/api/analyze/route.ts серверная валидация, расчёт и запрос OpenAI

Клиент отправляет в /api/analyze только список решений. Сервер заново вызывает валидатор и движок, рассчитывает улучшение и формирует prompt из проверенных данных. Стоимость, эффекты и Score из браузера не принимаются.

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

Требуется Node.js 20 или новее.

npm install
cp .env.local.example .env.local
# при необходимости отредактируйте .env.local и добавьте OPENAI_API_KEY
npm run dev

Откройте http://localhost:3000. Симулятор находится по адресу http://localhost:3000/simulator.

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

OPENAI_API_KEY=ключ OpenAI для серверного анализа
OPENAI_MODEL=gpt-4o-mini

.env.local исключён из Git, а .env.local.example содержит только шаблонные значения.

8. Как проверить

Автоматические команды:

npm test
npm run lint
npm run build

Повторяемый демо-сценарий:

  1. Откройте /simulator?plan=reference или нажмите «Загрузить пример организаторов».
  2. Проверьте пять решений: M7 в Нуре, M8 в Нуре, M10 в Нуре, M12 для города, M5 в Сарыарке.
  3. Убедитесь, что стоимость равна 95, а Score после округления до пяти знаков равен 56.54307.
  4. Нажмите «Найти лучшую замену», затем при наличии ключа — «Объяснить сценарий».
  5. Нажмите «Начать заново» и проверьте, что план и производные результаты сбрасываются.

Контрольные значения движка: базовый Score без действий — 52.55768; тесты также проверяют правила, лаг, городские меры, порядок решений и улучшение одной замены.

9. Ограничения текущей версии

  • модель использует синтетические показатели и не является прогнозом реальных городских показателей;
  • полный план требует ровно пяти решений, хотя остаток бюджета может быть положительным;
  • поиск улучшения проверяет только замены одной меры и не доказывает глобальный оптимум;
  • AI-анализ требует OPENAI_API_KEY, сетевого доступа к OpenAI и доступной модели;
  • карта с внешней подложкой зависит от сети; локальный GeoJSON является частью репозитория;
  • автоматические браузерные E2E-тесты в репозитории не настроены.

10. Deployed-версия

В текущем репозитории ссылка на deployed-версию не указана. Для проверки используется локальный запуск npm run dev.

11. Официальные материалы

HACKALEM_BRIEF.md находится в корне репозитория и содержит рабочую сводку требований. Каталог docs/ с официальными PDF и DOCX в текущем checkout отсутствует; README не делает утверждений о содержимом этих файлов.

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

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

Diyarsh 7

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

  • 2026-09-23 18:09Rename project from QALA to Latitude 51Diyarsh
  • 2026-09-23 18:02Simulator: interactive district schematic, richer decision slots, results revealDiyarsh
  • 2026-09-23 17:37UX polish: touch targets, press feedback, a11y landmarks, glass nav, 404 and iconDiyarsh
  • 2026-09-23 17:27Add scroll-driven 3D landing and move simulator to /simulatorDiyarsh
  • 2026-09-23 16:40Add 3D Astana map, hero model and 21st.dev componentsDiyarsh
  • 2026-09-23 16:24Harden rules, server-side scoring and plan builder UXDiyarsh
  • 2026-09-23 15:34Add QALA simulator with verified score engine and AI explainDiyarsh
Структура репозитория (96 файлов)
.cursor/skills/frontend-design/LICENSE.txt
.cursor/skills/frontend-design/SKILL.md
.cursor/skills/ui-ux-pro-max/LICENSE
.cursor/skills/ui-ux-pro-max/SKILL.md
.cursor/skills/ui-ux-pro-max/data/app-interface.csv
.cursor/skills/ui-ux-pro-max/data/catalog-summary.json
.cursor/skills/ui-ux-pro-max/data/charts.csv
.cursor/skills/ui-ux-pro-max/data/colors.csv
.cursor/skills/ui-ux-pro-max/data/data-provenance.json
.cursor/skills/ui-ux-pro-max/data/google-font-licenses.json
.cursor/skills/ui-ux-pro-max/data/google-fonts.csv
.cursor/skills/ui-ux-pro-max/data/icons.csv
.cursor/skills/ui-ux-pro-max/data/landing.csv
.cursor/skills/ui-ux-pro-max/data/motion.csv
.cursor/skills/ui-ux-pro-max/data/phosphor-icons-upstream.json
.cursor/skills/ui-ux-pro-max/data/products.csv
.cursor/skills/ui-ux-pro-max/data/react-performance.csv
.cursor/skills/ui-ux-pro-max/data/stacks/angular.csv
.cursor/skills/ui-ux-pro-max/data/stacks/astro.csv
.cursor/skills/ui-ux-pro-max/data/stacks/avalonia.csv
.cursor/skills/ui-ux-pro-max/data/stacks/flutter.csv
.cursor/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv
.cursor/skills/ui-ux-pro-max/data/stacks/javafx.csv
.cursor/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv
.cursor/skills/ui-ux-pro-max/data/stacks/laravel.csv
.cursor/skills/ui-ux-pro-max/data/stacks/nextjs.csv
.cursor/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv
.cursor/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv
.cursor/skills/ui-ux-pro-max/data/stacks/react-native.csv
.cursor/skills/ui-ux-pro-max/data/stacks/react.csv
.cursor/skills/ui-ux-pro-max/data/stacks/shadcn.csv
.cursor/skills/ui-ux-pro-max/data/stacks/svelte.csv
.cursor/skills/ui-ux-pro-max/data/stacks/swiftui.csv
.cursor/skills/ui-ux-pro-max/data/stacks/threejs.csv
.cursor/skills/ui-ux-pro-max/data/stacks/uno.csv
.cursor/skills/ui-ux-pro-max/data/stacks/uwp.csv
.cursor/skills/ui-ux-pro-max/data/stacks/vue.csv
.cursor/skills/ui-ux-pro-max/data/stacks/winui.csv
.cursor/skills/ui-ux-pro-max/data/stacks/wpf.csv
.cursor/skills/ui-ux-pro-max/data/styles.csv
.cursor/skills/ui-ux-pro-max/data/typography.csv
.cursor/skills/ui-ux-pro-max/data/ui-reasoning.csv
.cursor/skills/ui-ux-pro-max/data/ux-guidelines.csv
.cursor/skills/ui-ux-pro-max/references/pro-rules.md
.cursor/skills/ui-ux-pro-max/references/quick-reference.md
.cursor/skills/ui-ux-pro-max/scripts/core.py
.cursor/skills/ui-ux-pro-max/scripts/design_system.py
.cursor/skills/ui-ux-pro-max/scripts/reasoning_contract.py
.cursor/skills/ui-ux-pro-max/scripts/search.py
.cursor/skills/ui-ux-pro-max/scripts/validate_data.py
.env.local.example
.gitignore
AGENTS.md
CLAUDE.md
HACKALEM_BRIEF.md
README.md
eslint.config.mjs
next.config.ts
package-lock.json
package.json
postcss.config.mjs
public/geo/astana-districts.geojson
scripts/copy-maplibre-worker.mjs
src/app/api/analyze/route.ts
src/app/globals.css
src/app/icon.svg
src/app/layout.tsx
src/app/not-found.tsx
src/app/page.tsx
src/app/simulator/page.tsx
src/components/CityMap3D.tsx
src/components/CityMapPanel.tsx
src/components/CityModel3D.tsx
src/components/DistrictSchematic.tsx
src/components/PlanBuilder.tsx
src/components/ResultsPanel.tsx
src/components/Simulator.tsx
src/components/landing/LandingStory.tsx
src/components/landing/Sections.tsx
src/components/landing/StartButton.tsx
src/components/ui/animated-tabs.tsx
src/components/ui/magnetic.tsx
src/components/ui/number-ticker.tsx
src/components/ui/text-effect.tsx
src/lib/engine/dataset.ts
src/lib/engine/engine.test.ts
src/lib/engine/improve.ts
src/lib/engine/index.ts
src/lib/engine/score.ts
src/lib/engine/types.ts
src/lib/engine/validate.ts
src/lib/geo.ts
src/lib/landing.ts
src/lib/utils.ts
tsconfig.json
vitest.config.ts

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

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

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