Repository navigation
Design Documentation
| Version | Date | Key Changes | Author |
|---|---|---|---|
| v0.1.0 | 2026-09-29 | Initial system architecture & API design for Iter1 | SoonYoung Park |
| v0.1.1 | 2026-10-06 | Updated backend stack (Django), routing module (TMAP API), UI architecture | SoonYoung Park |
| v0.1.2 | 2026-10-07 | Added full current JSON API | Anton |
| v0.1.3 | 2026-10-09 | Refined screen flow/LLM spec (Gemini), added Iteration 1 Prototype Findings | SoonYoung Park |
The RunTime platform follows a Client-Server architecture separating path generation, data parsing, and AI evaluation.
[ Android App ] │ (HTTP / REST API) ▼ [ Django Backend ] ├── 1. Waypoint Sampler Engine (OSM / NetworkX / Scikit-Learn) ├── 2. Routing Module (TMAP Pedestrian & Place Search API) ├── 3. Obstacle Parser (Open-Elevation API + OpenStreetMap Regex) └── 4. LLM Evaluation Engine (Google Gemini 3.1 Flash Lite API)
- Client-Server Model: Offloads heavy geometric sampling, OSM data parsing, and LLM API calls from the mobile device to the server, ensuring low mobile resource usage.
- REST API over WebSocket: Request-response style fits the workflow well (user submits parameters once, server computes and returns 2-3 route candidates).
- Django Backend Framework: Selected over lightweight frameworks to utilize built-in ORM for User/Route data management and structured REST API views.
- TMAP Pedestrian API & POI Integration: Chosen for superior pedestrian pathing (sidewalks, footpaths, crosswalks) and native place searching.
- OSM & TMAP Hybrid Routing: Successfully replaced mock routes with an OSM-based walking route algorithm combined with TMAP POI search.
- Gemini Briefing Integration: Integrated gemini-3.1-flash-lite to generate concise bilingual pre-run briefings (with template fallback logic).
- Public Map Server Latency: Identified that cold requests fetching fresh OSM map data can take time (~35s timeout limit handled with HTTP 503 response), whereas subsequent cached requests execute rapidly.
- Route Options Expansion: Evolved from simple loop generation (Start + Distance) to supporting flexible A-to-B point-to-point routes by introducing an optional end_point.
- Shortest Path Fallback Notice: Added an is_shortest_path boolean flag to notify users on the frontend whenever the routing algorithm falls back to the shortest path case (e.g., when requested distance exceeds available local network boundaries).
- Network Permission Handling: Added debug-specific ACCESS_LOCAL_NETWORK handling for Android 17 emulator/local server connectivity.
- Map Connection (UI Integration): Render interactive map views with polylines on the Android UI (connecting generated coordinate lists).
- Enhanced Obstacle Parsing: Wire up elevation profiles and crosswalk/traffic signal counters into user-facing route summaries.
Responses use JSON. Most custom error responses have this format:
{ "status": "error", "message": "Description of the error." }
Success responses vary by endpoint:
- Authentication endpoints return status and data.
- Route generation returns status and data.
- GET /api/v1/routes/saved/ returns an array directly.
- Saved-route detail endpoints return status and data.
POST /api/v1/auth/register/ returns 201 Created when registration succeeds:
{ "status": "success", "data": { "username": "runner1", "email": "runner@example.com", "token": "your-token" } }
It returns 400 Bad Request if a required field is missing or the username already exists.
POST /api/v1/auth/login/ returns 200 OK when login succeeds:
{ "status": "success", "data": { "username": "runner1", "email": "runner@example.com", "token": "your-token" } }
It returns 400 Bad Request if username or password is missing, and 401 Unauthorized if the credentials are invalid.
POST /api/v1/routes/generate/ returns 200 OK:
{ "status": "success", "data": { "temporary_route_id": 123, "is_shortest_path": false, "route": { "distance": 2500, "briefing": "Enjoy a flat 2.5 km loop along quiet neighborhood sidewalks.", "route": [ { "type": "LineString", "coordinates": [ [126.9784, 37.5665], [126.9791, 37.5672] ] } ] } } }
The returned distance is the generated route distance in meters. Invalid input returns 400 Bad Request. Public map data timeouts (>35s) return 503 Service Unavailable.
GET /api/v1/routes/saved/ returns 200 OK with an array of saved routes. If the user has no saved routes, it returns an empty array:
[ { "id": 45, "distance": 2500, "briefing": "Generated a running loop.", "route": [ { "type": "LineString", "coordinates": [ [126.9784, 37.5665], [126.9791, 37.5672] ] } ], "created_by": "runner1", "saved_at": "2026-10-07T02:00:00Z" } ]
POST /api/v1/routes/saved/ accepts either a route_id or a temporary_route_id.
- Saving a temporary route returns 201 Created, including the new saved route’s route_id.
- Saving an existing route returns 201 Created with a success message.
- Providing neither ID returns 400 Bad Request.
- An unknown route or temporary route returns 404 Not Found.
GET /api/v1/routes/saved/{route_id}/ returns 200 OK with the saved route inside data. DELETE on the same URL removes the route from the user’s saved routes and returns 200 OK. Both return 404 Not Found if the route is not saved by the current user.
The registration and login endpoints are public. Route generation allows requests with or without authentication. The profile and saved-route endpoints require authentication.
For authenticated requests, send the token in the HTTP header:
Authorization: Token your-token
Route generation is optional-authentication. If the request is authenticated, the temporary route is associated with that user.
Coordinates use longitude first, latitude second, in decimal degrees.
A starting or ending point is a GeoJSON Point:
{ "type": "Point", "coordinates": [126.9784, 37.5665] }
A route line is a GeoJSON LineString:
{ "type": "LineString", "coordinates": [ [126.9784, 37.5665], [126.9791, 37.5672] ] }
The Python RunningRoute dataclass contains:
| Field | Type | Description |
|---|---|---|
| distance | Integer | Route distance in meters; must be greater than zero. |
| briefing | String | Description/briefing of the generated route; cannot be empty. |
| route | List of GeoJSONLineString | One or more route lines. |
| Endpoint | Method | Request | Response | Authentication |
|---|---|---|---|---|
| /api/v1/auth/register/ | POST | JSON: username, email, password | 201 with user details and token; 400 for missing fields or existing username | No |
| /api/v1/auth/login/ | POST | JSON: username, password | 200 with user details and token; 400 for missing fields; 401 for invalid credentials | No |
| /api/v1/users/my_profile/ | GET | No body | 200 with current user's username and email; 401 if unauthenticated | Yes |
| /api/v1/routes/generate/ | POST | JSON: starting_point (GeoJSON Point), end_point (optional GeoJSON Point), distance (int, meters), language (ko/en) | 200 with temporary route ID, is_shortest_path, and route data; 400 for invalid input; 503 for map server timeout | Optional |
| /api/v1/places/search/ | GET | Query param: keyword, language | 200 with top 5 TMAP POI search results | No |
| /api/v1/routes/saved/ | GET | No body | 200 with an array of saved routes | Yes |
| /api/v1/routes/saved/ | POST | JSON with route_id or temporary_route_id | 201 with success message & new route_id; 400 if no ID provided; 404 if route not found | Yes |
| /api/v1/routes/saved/{route_id}/ | GET | Route ID in URL; no body | 200 with saved route in data; 404 if not saved by current user | Yes |
| /api/v1/routes/saved/{route_id}/ | DELETE | Route ID in URL; no body | 200 with deletion message; 404 if not saved by current user | Yes |
POST /api/v1/routes/generate/ Content-Type: application/json Authorization: Token your-token
{ "starting_point": { "type": "Point", "coordinates": [126.9784, 37.5665] }, "end_point": null, "distance": 2500, "language": "en" }
- Calculates radius R = D / (2π) based on target distance D.
- Samples 2–3 waypoints using bearing angle sets (e.g., 90°, 180°, 270°).
- Applies feedback scaling loops if returned API path length exceeds ±10% error margin.
- Elevation: Queries Open-Elevation API for coordinate lists with local SRTM fallback/caching.
- Signals: Parses guidance text regex and cross-references OSM crossing=traffic_signals nodes.
- Uses gemini-3.1-flash-lite to generate 2-3 sentence pre-run briefings in English or Korean based on route metrics.
- Employs structured fallback templates if the LLM API is unreachable.
[ SplashScreen ]
│ (Auto Transition)
▼
┌─────────────────► [ LoginScreen ] ◄─────────────────┐
│ │ (On Login / Guest) │
│ ▼ │
│ [ RouteInputScreen ] │
│ │ (On Generate Click) │
│ ▼ │
│ [ GeneratingScreen ] │
│ │ (On API Success) │
│ ▼ │
│ [ RouteResultScreen ] │
│ │ │
│ ▼ │
└───────────────► [ MyPageScreen ] ───────────────────┘
(View Saved Routes / Delete / Logout)
(Will be documented in detail during Iteration 5)