Design Documentation - snuhcs-course/swpp-2026-project-team-16 GitHub Wiki
Design Documentation
1. Document Revision History
| 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 |
2. System Design
System Architecture
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)
Architectural Rationale
- 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.
Prototype Findings (Iteration 1)
1. Attempted Features & Results
- 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.
2. Design Changes Based on Learnings
- 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.
3. Planned Features for Next Iteration
- 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.
3. Design Details
API Specification (JSON Schema)
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.
Register
POST /api/v1/auth/register/ returns 201 Created when registration succeeds:
{ "status": "success", "data": { "username": "runner1", "email": "[email protected]", "token": "your-token" } }
It returns 400 Bad Request if a required field is missing or the username already exists.
Login
POST /api/v1/auth/login/ returns 200 OK when login succeeds:
{ "status": "success", "data": { "username": "runner1", "email": "[email protected]", "token": "your-token" } }
It returns 400 Bad Request if username or password is missing, and 401 Unauthorized if the credentials are invalid.
Generate a Route
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.
Saved Routes
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.
Authentication Token Specification
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.
GeoJSON Schema
Coordinates use longitude first, latitude second, in decimal degrees.
GeoJSON Point
A starting or ending point is a GeoJSON Point:
{ "type": "Point", "coordinates": [126.9784, 37.5665] }
GeoJSON LineString
A route line is a GeoJSON LineString:
{ "type": "LineString", "coordinates": [ [126.9784, 37.5665], [126.9791, 37.5672] ] }
RunningRoute
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 Reference
| 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 |
Generate-route request example
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" }
Key Algorithms & Component Design
1. Geometric Waypoint Sampling
- 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.
2. Obstacle Parsing Pipeline
- 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.
3. LLM Briefing Pipeline
- 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.
Client UI Architecture (Android)
Screen Flow
[ SplashScreen ]
β (Auto Transition)
βΌ
βββββββββββββββββββΊ [ LoginScreen ] βββββββββββββββββββ
β β (On Login / Guest) β
β βΌ β
β [ RouteInputScreen ] β
β β (On Generate Click) β
β βΌ β
β [ GeneratingScreen ] β
β β (On API Success) β
β βΌ β
β [ RouteResultScreen ] β
β β β
β βΌ β
βββββββββββββββββΊ [ MyPageScreen ] ββββββββββββββββββββ
(View Saved Routes / Delete / Logout)
4. Design Patterns
(Will be documented in detail during Iteration 5)