collage-bus-tracking-app: BusTracker: The Campus Fleet System That Runs on a Browser

How a Flask app, SQLite, Leaflet, and zero-native-mobile assumptions combine into a surprisingly resilient transit tool for colleges.

9 min read • View on GitHub • More from suyog254

A campus bus sits at the curb while a smartphone browser sends a signal stream to a small server box, which then branches toward a student map screen and an admin console. The image explains how the driver phone becomes the tracking device and how one live signal supports both rider visibility and operational control.
BusTracker swaps the usual hardware stack for a browser-first telemetry loop, then routes that data to students and administrators.
Key Takeaways

Why this bus tracker feels different

Most transit systems start by assuming a dedicated driver app or a specialized GPS device. BusTracker starts somewhere simpler: a phone browser, the navigator.geolocation API, and a Flask backend that can store the latest position without asking anyone to install much of anything.

That constraint changes the whole product. The driver phone becomes the sensor, students get a live map, and administrators get a control surface for route changes and recovery. It is a small system, but it behaves like infrastructure rather than a demo.

The whole system depends on one idea: continuous trust in the latest timestamp, not permanent faith in a stale dot on a map.

Who this system is actually for

BusTracker is not a generic fleet platform wearing campus branding. It is built for three very specific users: students who want arrival confidence, drivers who need a frictionless way to publish location, and administrators who need to keep routes moving when something goes wrong.

UserNeedWhat BusTracker gives them
StudentsKnow whether the bus is actually liveA map, ETA context, and a freshness state that turns stale data into an obvious offline signal
DriversBroadcast location with minimal frictionA smartphone browser workflow instead of app-store installation or hardware provisioning
AdministratorsKeep service running through disruptionsRoute control, maintenance logging, deactivation handling, and alternate bus assignment

The driver phone is the sensor

The technical center of the project is the driver telemetry loop. A browser session starts GPS capture, watchPosition streams coordinates, and the backend writes the latest point into bus_live_location with an updated_at timestamp.

That is the important move. The system does not treat the phone as an accessory. It treats it as the fleet sensor, which means the entire deployment avoids app distribution, mobile device management, and a pile of brittle setup work.

navigator.geolocation.watchPosition(
  async (pos) => {
    await fetch('/update-location', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        lat: pos.coords.latitude,
        lng: pos.coords.longitude,
        updated_at: new Date().toISOString()
      })
    });
  },
  (err) => console.error(err),
  { enableHighAccuracy: true, maximumAge: 5000, timeout: 10000 }
);

Freshness matters more than perfect accuracy

The student dashboard makes a more honest promise than many tracking systems do. It does not imply that a bus is live forever once it has appeared on the map. It checks the timestamp and changes state when the feed gets stale.

That is a small design choice with a big effect. A live dot that is actually old data is worse than no dot at all, because it creates false confidence. BusTracker is careful enough to admit when it no longer knows.

StateUI behaviorOperational meaning
Fresh telemetryGreen live status and active map updatesThe driver phone is still reporting
Stale telemetryOffline or red statusThe tracker should not be trusted until updates resume
Recovered telemetryStatus flips back to liveThe system has re-established a current location feed

The admin panel is old-school on purpose

BusTracker leans on HTML and CSS patterns that fail gracefully. The admin interface uses CSS-driven tabs, notifications can be rendered with native disclosure elements, and the whole experience stays usable without a heavy JavaScript dependency.

That matters in the real world. If you are building for a constrained campus environment, simpler front-end behavior is not a retro flourish. It is a reliability strategy.

An admin hand stamps a route card as deactivated, then the card splits into two paths: one for an alternate bus assignment and one for student notification. The image explains that service interruption is treated as an operational workflow, not a dead end.
The most mature feature in the system is not tracking. It is what happens when tracking or service breaks down.

Bus deactivation is where the product gets real

The alternate bus workflow is the clearest sign that this was built from operations outward. Deactivating a bus is not just a status change. It is a decision that can trigger a replacement vehicle, a route reassignment, and a notification path for the students who are affected.

That is the difference between a CRUD form and a transit system. One records a change. The other keeps the service alive after the change.

Deactivation styleWhat it doesWhy it matters
CRUD-styleMarks a bus inactive and stops thereLeaves operations to figure out the rest
Operational flowCaptures the reason, assigns an alternate bus, and notifies ridersPreserves continuity when the service is disrupted

Why SQLite and CSV export are not throwaway choices

SQLite keeps the deployment zero-config, which is exactly what a smaller institution wants when the priority is getting a working system into production without a database team. CSV export then gives the institution a portable escape hatch for reporting, backups, and handoff into spreadsheets.

The schema logic also suggests a system that expects to live for a while. The app can add columns when needed, which is a practical way to keep an internal tool moving even as the data model evolves.

def export_to_csv():
    # Export operational tables without sensitive fields
    # Keep it simple for reporting and recovery
    pass

What this project is really competing with

BusTracker is not trying to beat a commercial campus transit platform on feature breadth. It is trying to beat them on deployability, cost, and clarity. That is a different contest.

ApproachStrengthCost to adapt
Commercial campus systemsPolished support and mature transit workflowsHigh
General-purpose fleet softwareBroad GPS and hardware compatibilityMedium to high
BusTrackerBrowser-native drivers and campus-specific operationsLow

That trade-off makes sense. For a college with a narrow route network and a need for dependable basics, simplicity is not a concession. It is the feature.

The trade-offs are the point

The project still reads like an internal tool, not a hardened public product. Plaintext passwords, one Flask app doing almost everything, and local storage all point to a system optimized for usefulness first.

But that is exactly why it is interesting. BusTracker shows how far you can get when you match the architecture to the problem instead of dressing the problem up for a platform demo.