No description
Find a file
vrubelroman 6e90956b3e Add logging throughout the Android app and unit tests
Log.d/i/w/e calls covering location resolution, TTS lifecycle and
errors, nearby/search network calls and their failure paths, and
screen-level state transitions. OkHttp's logging interceptor now
routes through Log (tag "OkHttp") instead of println for consistent
filtering. Enabled testOptions.unitTests.isReturnDefaultValues so
android.util.Log calls don't crash plain JVM unit tests.

Added mockk + kotlinx-coroutines-test and a GuideViewModelTest suite
covering the load-success, load-failure, and retry paths — including
a regression test for the infinite-spinner bug (isLoading must clear
and errorMessage must be set on a failed nearby-search call, not left
hanging). Verified: ./gradlew testDebugUnitTest passes (4/4).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 20:10:31 +00:00
android Add logging throughout the Android app and unit tests 2026-07-09 20:10:31 +00:00
backend Add structured logging throughout the backend 2026-07-09 20:10:10 +00:00
.env.example Add structured logging throughout the backend 2026-07-09 20:10:10 +00:00
.gitignore Initialize guideCity monorepo scaffolding 2026-07-09 18:19:47 +00:00
docker-compose.yml Add structured logging throughout the backend 2026-07-09 20:10:10 +00:00
README.md Document LAN-IP access for testing the backend from a physical device 2026-07-09 19:11:31 +00:00

guideCity

Android walking city-guide app. Detects the user's location, finds nearby landmarks, and narrates historical/architectural information about them by voice while showing a swipeable card stack. Starting city: Moscow.

Architecture

                 ┌────────────────────┐
                 │   Android app      │  Kotlin + Jetpack Compose
                 │  (android/)        │  2GIS map, on-device TTS,
                 └─────────┬──────────┘  location, Room favorites
                           │ HTTPS / REST (JSON)
                 ┌─────────▼──────────┐
                 │   FastAPI backend   │  Python, SQLAlchemy, Alembic
                 │   (backend/)        │  Dockerized
                 └─────────┬──────────┘
                           │ SQL
                 ┌─────────▼──────────┐
                 │ PostgreSQL+PostGIS  │  cities / places / place_content
                 └────────────────────┘
  • backend/ — FastAPI service exposing city/place/nearby-search endpoints, backed by PostgreSQL+PostGIS. See backend/ for details.
  • android/ — Kotlin/Compose app skeleton (MVVM, Hilt, Retrofit, Room, DataStore, 2GIS MapKit, on-device TextToSpeech).

Backend quickstart

cp .env.example .env
docker compose up -d db
docker compose exec api alembic upgrade head   # (once api image is built: docker compose up -d --build api adminer first)
docker compose exec api python -m seed.seed_loader --file seed/moscow_gorky_park.yaml
docker compose exec api python -m seed.seed_loader --file seed/moscow_red_square.yaml
docker compose exec api python -m seed.seed_loader --file seed/moscow_city.yaml
curl http://localhost:8000/api/v1/health
curl "http://localhost:8000/api/v1/nearby?lat=55.7525&lon=37.6231"

Swagger UI: http://localhost:8000/docs Adminer (DB inspection): http://localhost:8080

The api service binds 0.0.0.0:8000 (see docker-compose.yml), so it's also reachable from other devices on the same LAN at http://<this-machine's-LAN-IP>:8000/ — no extra config needed, just make sure nothing (firewall, VPN) blocks port 8000 on that interface.

Android quickstart

cp android/local.properties.example android/local.properties
# fill in sdk.dir and DGIS_API_KEY (test key: b4df01a8-61db-4cb9-8286-7e069495987d)
cd android && ./gradlew :app:assembleDebug

Point the app's API base URL (API_BASE_URL in local.properties) at http://10.0.2.2:8000/ for the emulator, or your machine's LAN IP (e.g. http://192.168.8.173:8000/) for a physical device on the same Wi-Fi/LAN.

Notes / current scope

This is iteration 1: Moscow only (Gorky Park, Red Square area, Moscow-City), no user accounts (favorites are local/Room-only), no speed/heading-aware auto content-length selection yet (reserved API params exist, unused).

The 2GIS API key above is used directly via local.properties/BuildConfig for development convenience — don't ship it as-is in a public repo.