AAYMA
RU
Войти

Akim for 5 Hours

Городской симулятор: 100 единиц бюджета распределяются по 5 направлениям и районам, считаются изменения индикаторов и индекс качества жизни, AI…

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

О проекте

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

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

Суть

Городской симулятор: 100 единиц бюджета распределяются по 5 направлениям и районам, считаются изменения индикаторов и индекс качества жизни, AI объясняет плюсы, риски и компромиссы, сценарии сохраняются и сравниваются.

Как устроено

Фронтенд на React/TS отправляет 5 решений в FastAPI. Бэкенд проверяет бюджет (превышение отклоняется с HTTP 422), применяет эффекты инициатив к индикаторам районов (0–100) и считает City Score как 0,8 × средневзвешенный по населению балл районов + 0,2 × минимальный балл района. Сценарии сохраняются в SQLite. AI-адаптер (OpenAI Responses API, gpt-4.1-mini) получает рассчитанные факты и проверенные альтернативы, возвращает структурированный JSON, числа в него подставляются из бэкенда. Без ключа работает явно помеченный rule-based режим.

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

  • rule-based simulation
  • population-weighted scoring with equity term
  • structured JSON output
  • grounding against fact catalog
  • scenario comparison

Особенности

В формулу индекса добавлен член справедливости: 20% веса у самого слабого района. Ответ LLM проверяется по схеме и каталогу рассчитанных фактов, а числовые плейсхолдеры заполняются значениями бэкенда, поэтому модель не может исказить цифры. Проект с CI, e2e-тестами на Playwright и воспроизводимым тест-планом (итоговый балл 49.819).

Стек

React · TypeScript · Vite · Zod · Pydantic · Python 3.12 · FastAPI · SQLite · Docker Compose · Nginx · Pytest · Vitest · Playwright · GitHub Actions

Модели

gpt-4.1-mini-2025-04-14


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

README

README.md

Akim for 5 Hours

An AI-assisted city-management simulator for the Astana Innovations hackathon.

1. What the product does

Akim for 5 Hours helps users explore how a limited city budget can affect quality of life across hypothetical districts.

Every user starts with the same 100 virtual budget units and the same synthetic dataset. The user chooses a district and one initiative in each of five areas:

  1. Transport
  2. Greening
  3. Social infrastructure
  4. Safety
  5. City services

The application checks the budget, calculates changes in district indicators, and produces an Astana Quality of Life Score. With live AI enabled, it explains the strengths, risks, trade-offs and possible consequences of the plan. Users can refine decisions and compare saved scenarios.

Who it is for: city managers, analysts, students and anyone learning about urban budget decisions.

Important: the districts, costs and effects are synthetic educational assumptions. The score is not an official Astana index or a forecast of real city outcomes. The dataset contains no personal data.

Main features

  • A shared starting budget and dataset.
  • Exactly five decisions: one per development area.
  • Budget-overrun prevention in the interface and backend.
  • Immediate previews of modeled effects.
  • Before-and-after district indicators and city scores.
  • Saved scenarios that can be reopened and compared.
  • AI explanations and explanations of tested, affordable alternatives.
  • An explicitly labeled rule-based mode for running without an API key.

2. Technologies used

PartTechnologiesPurpose
FrontendReact, TypeScript, ViteSimulator interface and results pages
API validationZod, PydanticValidate data exchanged between frontend and backend
BackendPython 3.12, FastAPI, UvicornBudget rules, simulation, API and analysis coordination
DatabaseSQLiteStore scenarios and cached analysis
AIOpenAI Responses API, HTTPX, structured JSON outputGenerate explanations from calculated results
DeploymentDocker Compose, NginxRun both services and forward API requests
TestingPytest, Vitest, PlaywrightBackend, frontend and browser integration checks
AutomationGitHub ActionsRun verification and build a source release

The configured AI model is gpt-4.1-mini-2025-04-14. Provider access must be checked with the team's API key.

How the parts work together

The browser sends the five decisions to FastAPI. The backend validates them, calculates the cost and score, and saves the scenario in SQLite. The AI adapter receives the calculated facts and tested alternatives, then returns explanatory text. The frontend displays the results.

The language model does not calculate or change the official simulation score.

3. Project structure

Use the complete Person 4 package. It already includes the code from Persons 1–3; no additional merging is needed.

PathContents
frontend/React application
backend/API, simulation, database, AI adapter and backend tests
data/v1/Shared synthetic districts, initiatives and scoring configuration
data/person3/Assumption ledger and repeatable evaluation cases
scripts/Development launcher, verification and release tools
docs/Deployment guide, demo script and verification record
.github/workflows/ci.ymlContinuous integration workflow
compose.yamlConfiguration for starting the complete application
.env.exampleExample Docker deployment settings

4. Run the whole project in VS Code

Use this method first. It starts both the frontend and backend.

Before starting

You need:

  • The extracted complete project folder, named akim-team in the supplied ZIP.
  • VS Code.
  • Docker Desktop installed and running, with Docker Compose available.
  • Internet access for the first build to download dependencies and images.

You do not need to install Python or Node.js on your computer for this Docker method.

Step 1 — Open the correct folder

In VS Code, select File → Open Folder → akim-team.

You are in the correct folder if the VS Code file panel shows compose.yaml, frontend and backend together.

Step 2 — Open the terminal

Select Terminal → New Terminal.

Run all commands in this section from the project root—the folder containing compose.yaml.

Step 3 — Check Docker

Run these commands one at a time:

docker --version
docker compose version

Both commands should print a version. If Docker is not recognized, install Docker Desktop and reopen VS Code. If Docker cannot connect to its engine, open Docker Desktop and wait until it is running.

Step 4 — Create the settings file

Windows PowerShell:

Copy-Item .env.example .env

macOS/Linux:

cp .env.example .env

Do this only during the first setup. If .env already exists, keep it and edit its values as needed.

The initial settings use rule-based explanations. This lets you check the simulator before adding an AI key.

Step 5 — Start everything

docker compose up --build

The first build may take several minutes. Leave this terminal open while using the application. You do not need to start either service separately.

Step 6 — Open the application

Open this address in your browser:

http://127.0.0.1:8080

Choose your initiatives and districts, then select “See my city’s future.”

Stop and start again

To stop the application, press Ctrl+C in the running terminal.

To start it again:

docker compose up

Saved scenarios remain in the named database volume. Do not run docker compose down -v unless you intentionally want to delete that stored data.

5. Enable real AI analysis

The default rule-based mode does not demonstrate the hackathon's live AI requirement. Complete this section before presenting the AI feature.

  1. Open the root .env file, next to compose.yaml.
  2. Set these values, replacing the API-key placeholder with your own key:
AKIM_ADVISOR_FACTORY=app.services.team_advisor:TeamAdvisor
AKIM_ANALYSIS_VERSION=person4-ai-v1
OPENAI_API_KEY=your_actual_api_key
OPENAI_MODEL=gpt-4.1-mini-2025-04-14
  1. Save the file. Open a second VS Code terminal in the project root and run:
docker compose up -d --force-recreate backend frontend
  1. Open the application and submit a scenario. A successful live assessment displays “Your AI city advisor.”

AI requests require working provider credentials and model access and may incur charges. Keep the key server-side; never put it in frontend code or commit .env.

If AI fails, the calculated score and saved scenario remain available. The backend does not silently replace a failed live AI response with a rule-based one.

After changing the model or prompt, change AKIM_ANALYSIS_VERSION so cached explanations from the earlier configuration are not reused.

6. How the score is calculated

Each district has five quality indicators on a 0–100 scale, with higher values meaning better quality. Initiatives change the targeted district's indicators according to the shared dataset. Resulting indicators are constrained to the 0–100 range.

The five indicators have equal weight in each district's score.

City Quality of Life Score =
    0.80 × population-weighted average district score
  + 0.20 × lowest district score

The lowest-district component makes the distribution of benefits matter, alongside the citywide average. These weights are explicit model design choices.

The starting city score is 47.1375, shown as 47.1 when rounded to one decimal. All users use the same starting configuration.

AI output is checked against a structured schema and a catalog of calculated facts. Numeric placeholders are filled with backend values. These checks constrain numeric errors, but they cannot prove every free-form statement is correct; explanations still need human review.

7. Verify the solution manually

Start the application, then perform the checks below.

CheckWhat to doExpected result
Same starting conditionsStart a new plan in two separate browser sessionsBoth receive 100 budget units and the same district data
All five areasInspect the decision tabs and build a complete planTransport, greening, social infrastructure, safety and city services are available
Five-decision ruleTry submitting before completing every areaAn incomplete plan cannot be submitted successfully
Budget controlBuild a 100-unit plan, then try a more expensive replacementAn over-budget selection/submission is prevented; backend tests also check HTTP 422 rejection
Indicator changesSubmit the repeatable plan belowThe district indicators and final city score change
Saved resultsReload the results pageThe saved scenario remains available
Different choicesRefine the plan with a cheaper transport measure and submit againThe resulting score changes
ComparisonOpen “Compare plans” after saving two plansBoth plans can be compared
Live AIEnable AI, submit a plan and inspect its reportA successful AI report includes a summary, strengths, risks and trade-offs grounded in the scenario

Repeatable test plan

Select these exact initiatives and districts:

AreaInitiativeDistrictCost
TransportBus-priority lanesDistrict A20
GreeningNeighborhood pocket parkDistrict B20
Social infrastructureLocal clinic upgradeDistrict C20
SafetySafer pedestrian crossingsDistrict D20
City servicesDistrict maintenance crewDistrict E20

Expected results for the unchanged v1 dataset:

  • Total cost: 100.
  • Remaining budget: 0.
  • Final score: 49.819, displayed as 49.8.

This plan is stored as distributed_medium_cost in data/person3/evaluation_cases.json.

8. Automated verification

A. Check a running Docker deployment

In a second terminal at the project root:

docker compose ps

Both services should be running and become healthy. In your browser, open:

http://127.0.0.1:8080/api/health

The JSON response should include "status": "ok". Its analysis_source should be rules or ai, matching your configuration. Health alone does not confirm that a real provider request succeeds.

B. Run the full automated test suite

This method requires Python 3.12 and Node.js 24, in addition to the source files. Run from the project root.

Create a Python environment:

python -m venv .venv

If your system uses python3, use python3 -m venv .venv instead.

Activate it on Windows PowerShell:

.\.venv\Scripts\Activate.ps1

Or activate it on macOS/Linux:

source .venv/bin/activate

Install the locked dependencies:

python -m pip install -r backend/requirements.lock
npm --prefix frontend ci

Run backend tests, dataset validation, frontend tests and the production build:

python scripts/verify.py

For browser integration, first install Chromium:

cd frontend
npx playwright install chromium
cd ..

Then run:

python scripts/verify.py --browser

Keep ports 8001 and 5182 free for the browser checks. These checks launch their own temporary services and database. They exercise rule-based analysis and the AI adapter with mocked provider responses; they make no live AI calls.

C. Run a deployment smoke check

With Python available and the Docker application running:

python scripts/smoke.py

This checks health and shared configuration without creating scenarios.

For scenario creation, persistence, overrun rejection, changed scores and analysis:

python scripts/smoke.py --write --analysis

This creates two scenarios and requests one assessment. In AI mode, the assessment may incur provider charges. The scenario checks use the included v1 dataset.

Recorded verification status

CheckRecorded result
Backend tests60 passed
Frontend model tests8 passed
TypeScript and production buildPassed
Browser integration with rule-based analysisPassed
Browser integration with mocked AI providerPassed
Direct API smoke checkPassed
Local development launcher on LinuxPassed
Docker/Nginx execution and GitHub ActionsSupplied but not executed in the development environment
Real provider callNot executed; requires the team's API key

These are results from the assembled project's prior verification, not a guarantee that a new machine is configured correctly. Run the checks again on the machine used for submission. See docs/VERIFICATION.md for details.

9. Optional: run without Docker

Follow the Python/Node dependency setup in Section 8B, then run from the project root with the virtual environment activated:

python scripts/dev.py

Open http://127.0.0.1:5173. The launcher starts the frontend and backend together. Press Ctrl+C to stop them.

For this local method, AI settings belong in backend/.env, following backend/person3.env.example. Docker uses the root .env instead. Do not confuse these two settings locations.

10. Common problems

ProblemWhat to check
docker is not recognizedInstall Docker Desktop, then reopen VS Code
Cannot connect to Docker engineOpen Docker Desktop and wait for it to start
No Compose configuration file foundOpen the terminal in the folder containing compose.yaml
.env.example cannot be foundYou are probably in the wrong folder; open akim-team
Port 8080 is occupiedSet AKIM_PORT=8081 in root .env, rerun Compose and open port 8081
Frontend opens but API failsCheck that both services are healthy and inspect their logs
AI report failsCheck the server-side key, model access, provider quota and backend logs
An old AI explanation appearsChange AKIM_ANALYSIS_VERSION and recreate the services

Inspect logs with:

docker compose logs --tail=100 backend frontend

Do not share your API key when reporting an error.

11. Scope and further documentation

The simulator models immediate indicator effects; it does not model implementation timelines or recurring operating costs. Comparison is between saved plans available in the current browser, not an authenticated cross-team leaderboard. Random city events and automatic slide export are not implemented.

The Docker configuration binds to localhost by default. Public hosting requires additional access control and operational safeguards; this prototype does not implement user accounts or per-user authorization.

Further guides:

  • docs/DEMO.md — presentation walkthrough.
  • docs/DEPLOYMENT.md — persistence, backup and operations.
  • docs/RUBRIC.md — mapping to hackathon criteria.
  • docs/VERIFICATION.md — detailed test record.

To create a source release with checksums, run:

python scripts/package_release.py

The ZIP is written to artifacts/akim-team-release.zip.

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

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

robot 7asim 2Jamshid 1

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

  • 2026-09-23 17:42Remove root environment examplerobot
  • 2026-09-23 17:41Update project READMErobot
  • 2026-09-23 17:37Sync local project staterobot
  • 2026-09-23 16:59Merge remote project historyrobot
  • 2026-09-23 16:58Initial project importrobot
  • 2026-09-23 16:40Merge remote project historyrobot
  • 2026-09-23 16:39Initial commitrobot
  • 2026-09-23 16:09Merge remote-tracking branch 'origin/main'asim
Все коммиты (10)
  • 2026-09-23 16:07Initial backend projectasim
  • 2026-09-23 15:41feat(frontend): finalize simulator changes and test suiteJamshid
Структура репозитория (194 файлов)
.dockerignore
.github/workflows/ci.yml
.gitignore
.nvmrc
Dockerfile
README.md
SHA256SUMS
backend/.env.example
backend/.gitignore
backend/Dockerfile
backend/app/__init__.py
backend/app/ai/__init__.py
backend/app/ai/evaluation.py
backend/app/ai/evidence.py
backend/app/ai/grounding.py
backend/app/ai/provider.py
backend/app/ai/schemas.py
backend/app/ai/settings.py
backend/app/config.py
backend/app/database.py
backend/app/errors.py
backend/app/main.py
backend/app/models.py
backend/app/prompts/person3_advisor.txt
backend/app/repositories/__init__.py
backend/app/repositories/scenarios.py
backend/app/routes/__init__.py
backend/app/routes/analysis.py
backend/app/routes/configuration.py
backend/app/routes/health.py
backend/app/routes/scenarios.py
backend/app/schemas.py
backend/app/services/__init__.py
backend/app/services/ai_advisor.py
backend/app/services/analysis.py
backend/app/services/dataset.py
backend/app/services/recommendations.py
backend/app/services/scenarios.py
backend/app/services/scoring.py
backend/app/services/simulation.py
backend/app/services/team_advisor.py
backend/app/services/validation.py
backend/docs/API-CONTRACT.md
backend/docs/ARCHITECTURE.md
backend/docs/PERSON-3-HANDOFF.md
backend/docs/VERIFICATION.md
backend/docs/openapi.json
backend/person3.env.example
backend/pyproject.toml
backend/requirements-person3.txt
backend/requirements.lock
backend/scripts/check-frontend.mjs
backend/scripts/export_openapi.py
backend/scripts/person3_evaluate.py
backend/scripts/person3_live_check.py
backend/scripts/person3_validate_data.py
backend/scripts/person4_backup.py
backend/tests/__init__.py
backend/tests/conftest.py
backend/tests/fixtures/analysis-response.json
backend/tests/fixtures/completed-scenario.json
backend/tests/fixtures/config-response.json
backend/tests/fixtures/preview-request.json
backend/tests/fixtures/preview-response.json
backend/tests/fixtures/scenario-request.json
backend/tests/person3/__init__.py
backend/tests/person3/test_advisor.py
backend/tests/person4/__init__.py
backend/tests/person4/mock_app.py
backend/tests/person4/test_backup.py
backend/tests/test_analysis.py
backend/tests/test_api.py
backend/tests/test_boundaries.py
backend/tests/test_simulation.py
backend/tests/test_storage.py
compose.yaml
contracts/analysis-response.json
contracts/completed-scenario.json
contracts/config-response.json
contracts/preview-request.json
contracts/preview-response.json
contracts/scenario-request.json
data/person3/evaluation_cases.json
data/person3/initiative_assumptions.json
data/v1/data_dictionary.md
data/v1/districts.json
data/v1/initiatives.json
data/v1/model_config.json
docs/API-CONTRACT.md
docs/DEMO.md
docs/DEPLOYMENT.md
docs/RUBRIC.md
docs/VERIFICATION.md
docs/team/PERSON-1.md
docs/team/PERSON-2.md
docs/team/PERSON-3.md
frontend/.dockerignore
frontend/.env.example
frontend/.gitignore
frontend/Dockerfile
frontend/contracts/analysis-response.json
frontend/contracts/completed-scenario.json
frontend/contracts/config-response.json
frontend/contracts/preview-request.json
frontend/contracts/preview-response.json
frontend/contracts/scenario-request.json
frontend/docs/API-CONTRACT.md
frontend/docs/VERIFICATION.md
frontend/index.html
frontend/nginx.conf
frontend/package-lock.json
frontend/package.json
frontend/playwright.config.ts
frontend/public/favicon.svg
frontend/scripts/generate-fixtures.mjs
frontend/src/App.tsx
frontend/src/api/client.ts
frontend/src/api/scenarios.ts
frontend/src/api/storage.ts
frontend/src/components/AIReport.tsx
frontend/src/components/BudgetBar.tsx
frontend/src/components/CategoryTabs.tsx
frontend/src/components/DecisionSummary.tsx
frontend/src/components/DistrictCard.tsx
frontend/src/components/DistrictSelector.tsx
frontend/src/components/Icon.tsx
frontend/src/components/IndicatorComparison.tsx
frontend/src/components/InitiativeCard.tsx
frontend/src/components/RecommendationCard.tsx
frontend/src/components/ScoreCard.tsx
frontend/src/demo/config.json
frontend/src/demo/engine.test.ts
frontend/src/demo/engine.ts
frontend/src/hooks/useRoute.ts
frontend/src/hooks/useScenario.ts
frontend/src/main.tsx
frontend/src/pages/ComparePage.tsx
frontend/src/pages/ResultsPage.tsx
frontend/src/pages/SimulatorPage.tsx
frontend/src/pages/WelcomePage.tsx
frontend/src/styles/global.css
frontend/src/types/simulation.ts
frontend/src/utils/decisions.ts
frontend/src/utils/format.ts
frontend/tests/e2e/api.spec.ts
frontend/tests/e2e/simulator.spec.ts
frontend/tsconfig.json
frontend/vite.config.ts
index.html
install_person3.py
nginx.conf
package-lock.json
package.json
playwright.config.ts
public/favicon.svg
scripts/check-stack.mjs
scripts/dev.py
scripts/generate-fixtures.mjs
scripts/package_release.py
scripts/smoke.py
scripts/verify.py
src/App.tsx
src/api/client.ts
src/api/scenarios.ts
src/api/storage.ts
src/components/AIReport.tsx
src/components/BudgetBar.tsx
src/components/CategoryTabs.tsx
src/components/DecisionSummary.tsx
src/components/DistrictCard.tsx
src/components/DistrictSelector.tsx
src/components/Icon.tsx
src/components/IndicatorComparison.tsx
src/components/InitiativeCard.tsx
src/components/RecommendationCard.tsx
src/components/ScoreCard.tsx
src/demo/config.json
src/demo/engine.test.ts
src/demo/engine.ts
src/hooks/useRoute.ts
src/hooks/useScenario.ts
src/main.tsx
src/pages/ComparePage.tsx
src/pages/ResultsPage.tsx
src/pages/SimulatorPage.tsx
src/pages/WelcomePage.tsx
src/styles/global.css
src/types/simulation.ts
src/utils/decisions.ts
src/utils/format.ts
tests/e2e/api.spec.ts
tests/e2e/simulator.spec.ts
tsconfig.json
vite.config.ts

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

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

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