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)