Skip to main content

Main Website - Documentation

πŸ”Ž Background

Overview​

Bikun Tracker Frontend V2 is the client-side web interface for the Universitas Indonesia shuttle bus tracking system. It consumes data from Backend V2 via WebSocket connections for live location updates, and utilizes REST APIs for static data and authentication.

Stakeholders​

  • Users: UI students and staff (monitoring real-time bus locations), Bikun Administrators (accessing reporting dashboards and schedules).
  • Upstream Dependencies: Bikun Tracker Backend V2 (providing REST API endpoints and /ws WebSocket), UI SSO (for authentication).
  • Downstream Consumers: End-user devices (Mobile and desktop web browsers).

Scope & Boundaries​

In Scope

  • Real-time interactive map rendering using Leaflet.
  • Maintaining continuous WebSocket connections to receive live bus GPS coordinates.
  • User interface for bus schedule management and reporting.
  • Client-side authentication integration utilizing UI CAS SSO.
  • Local state management for bus movement interpolation.

Out of Scope

  • Heavy computational processing for lane detection or lap history (strictly backend responsibility).
  • Relational data storage or direct interaction with PostgreSQL.
  • Ingesting raw hardware GPS data from Damri.

βš™οΈ Architecture & Design

System Diagram​

Architecture Decisions (ADRs)​

  • Language/Framework: React 19 + TypeScript built with Vite
  • Routing: TanStack React Router
  • State Management: Zustand
  • Styling & UI: Tailwind CSS v4
  • Map Visualization: Leaflet

πŸ’»Technical Specifications

API Documentation​

Data Model/Schema​

Project Structure​

bikuntracker-frontend-v2
┣ public
┃ ┣ assets
┃ ┣ favicon
┃ ┣ robots.txt
┃ β”— service-worker.js
┣ src
┃ ┣ assets
┃ ┃ ┣ bus-stops/
┃ ┃ β”— icons/
┃ ┣ common
┃ ┃ ┣ components/ (Reusable UI: map, modal, drawer, navbar)
┃ ┃ ┣ constants/ (Absolute static data: busSchedule, routes, map config)
┃ ┃ ┣ data/ (Bus stops and routes definitions)
┃ ┃ ┣ hooks/ (React logic hooks: useAnimatedBus, useWebsocket)
┃ ┃ ┣ schema/ (Zod type validation: auth, ws)
┃ ┃ β”— types/ (Global TypeScript interfaces)
┃ ┣ lib
┃ ┃ ┣ store/ (Zustand global state logic: auth, global, ref)
┃ ┃ ┣ busStopUtils.ts
┃ ┃ β”— utils.ts
┃ ┣ routes
┃ ┃ ┣ __root.tsx
┃ ┃ ┣ bus-schedule.tsx
┃ ┃ ┣ create-report.tsx
┃ ┃ ┣ index.tsx
┃ ┃ ┣ report.tsx
┃ ┃ β”— sso-login.tsx
┃ ┣ services
┃ ┃ ┣ auth.ts
┃ ┃ β”— util.ts
┃ ┣ index.css
┃ ┣ main.tsx
┃ β”— routeTree.gen.ts (Auto-generated by TanStack router)
┣ .env.example
┣ eslint.config.js
┣ package.json
┣ tsconfig.json
β”— vite.config.ts

Key Components​

main.go β€” Application Bootstrap

  • Reads config from .env via Viper
  • Creates pgxpool connection to PostgreSQL
  • Wires all handlers, services, repositories, and middlewares
  • Registers HTTP routes via utils.HandleRoute
  • Starts WebSocket broadcaster at /ws
  • Exposes webhook endpoint at /wh for GPS ingestion

app/bus/container.go β€” Runtime State Manager

  • Holds in-memory maps: busCoordinates, previousHalte, activeLaps, storedBuses, currentPlates

ApplyExternalCoordinates() β€” the main pipeline called by webhook: updates colours, detects lanes, tracks halte visits, detects lap start/end

  • DQ_SIZE = 50: rolling deque per bus for lane detection sampling

InitRuntimeState() β€” hydrates runtime caches from DB on startup

app/bus/halte.go β€” Geofence Proximity

  • 22 named haltes (bus stops) with fixed coordinates
  • nearestHalte(lat, lng) returns the closest halte name + distance in metres

Threshold: 45 metres β€” bus must be within 45m to register a halte visit

app/bus/route.go β€” Route Definitions

  • 4 route arrays: blueNormal, blueMorning, redNormal, redMorning
  • Pre-built halte-pair sets for O(1) lookup
  • detectRouteColorFromPair() returns blue / red / grey

app/auth/ β€” Authentication

  • SSO Login: validates CAS ticket with sso.ui.ac.id, auto-creates user in DB on first login
  • JWT pair (access + refresh) signed with HS256; expiry is configurable via env vars
  • Admin protection: API_KEY header is checked against ADMIN_API_KEY env var

☁️ Operational Playbook

Infrastructure​

  • Cloud Provider: AWS ECR + Pusilkom instance
  • Container Registry: 638207107223.dkr.ecr.ap-southeast-1.amazonaws.com
  • Image Name: bikun-tracker-v2-backend
  • Production Tag: stable (deployed from main branch)
  • Staging Tag: latest (deployed from staging branch)
  • Region: ap-southeast-1 (Singapore)

Environment Variables​

KeyDescriptionDefault (Dev)Sensitive?
DAMRI_APIDamri GPS API base URLhttps://api-damri.istsolutions.co.idNo
DAMRI_LOGIN_USERNAMEDamri API usernameβ€”Yes
DAMRI_LOGIN_PASSWORDDamri API passwordβ€”Yes
WS_URLExternal GPS WebSocket URLws://localhost:8000/statusNo
RM_APIRM lane-detection service URLhttps://eta-bikun-tracker-production.up.railway.appNo
PRINT_CSV_LOGSEnable CSV log POST to port 4040FALSENo
PORTPort the server listens on8080No
DB_HOSTPostgreSQL host addresslocalhostNo
DB_NAMEDatabase namebikun_trackerNo
DB_USERDatabase usernamepostgresNo
DB_PASSWORDDatabase passwordβ€”Yes
DB_PORTDatabase port5043No
WS_UPGRADE_WHITELISTAllowed WebSocket origins (comma-separated)localhost:5173No
JWT_EXPIRY_IN_DAYSAccess token validity in days1No
JWT_REFRESH_EXPIRY_IN_DAYSRefresh token validity in days30No
JWT_SECRET_KEYHMAC secret for JWT signingβ€”Yes
ADMIN_API_KEYAPI key for admin-protected endpointsβ€”Yes

πŸ™‹Questions

πŸ—’ List of frequently asked questions or question that need to be answered that is related to this initiative ..