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> |
||
|---|---|---|
| android | ||
| backend | ||
| .env.example | ||
| .gitignore | ||
| docker-compose.yml | ||
| README.md | ||
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. Seebackend/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.