MobiShare

A smart bike & scooter sharing platform, built for the CINI IT Challenge — a national university competition judged live by an industry panel.

Role

Full-Stack & AI Developer

Timeline

September 2025

Overview

Mobishare was built for the CINI IT Challenge (Smart Cities & Communities) — a national competition for university students organized by the National Interuniversity Consortium for Computer Science, judged by a panel of industry experts. Discover the CINI IT Challenge →

It's a smart mobility platform for sharing bikes and scooters: a live map updated over MQTT from real vehicle telemetry, and a local AI agent that answers user questions and automates tasks (bookings, tickets) through RAG and function calling — no cloud LLM API involved. View the source on GitHub →

The Problem

The exam brief fixed the domain (urban mobility) and forced three hard constraints to work together in a few weeks: real-time GPS ingestion from actual hardware, a genuinely useful (not gimmick) AI agent, and real auth/payments/secrets handling — all inside a multi-container deployment a panel of judges would poke at live.

Architecture

Mobishare.Core holds the domain logic, Mobishare.Infrastructure the data access and external services, Mobishare.App the Razor Pages web app, and Mobishare.Ai the agent — a clean layered split on .NET 8 with a dedicated Mobishare.Tests project. Persistence is SQLite; deployment is Docker Compose with separate mosquitto-config (MQTT broker) and ollama-docker (local LLM) services, so the AI agent never leaves the same box as the app. Every operation inside Mobishare.Core is its own MediatR command or query rather than a shared service layer — I wrote up whether that traded off well in CQRS with MediatR in a Real ASP.NET Core App. Vehicle reservations also surfaced a real concurrency bug in how their expiry was tracked, covered in Reservation State Can't Live in a UI Countdown.

Real-Time Tracking Over MQTT

Vehicle GPS is published by an Arduino (arduino_gps.ino) over MQTT and pushed to the browser via SignalR — the map updates the moment a bike moves, without polling. Running the broker in its own container kept the telemetry pipeline decoupled from the web app, so either could restart without dropping the other.

A Local AI Agent, Not a Cloud Wrapper

The agent runs on Ollama: qwen3:latest for reasoning and tool calls, nomic-embed-text for the RAG embeddings — both local, no API key, no per-token bill. It answers "how do I open a ticket" or "reserve a scooter near me" by retrieving relevant context and then executing the matching function call against the app's own services, rather than just talking about it. Full build writeup — OllamaSharp's native tool-calling, and the hand-rolled cosine-similarity RAG that skips a vector database entirely — in A Local LLM Chatbot with Tool-Calling and RAG (No Vector Database). The same agent also picks which technician gets a repair ticket, treating the LLM as a ranking heuristic rather than a chat feature — see Using an LLM as a Heuristic Dispatcher. I wrote more about the tradeoffs of this kind of local-only RAG setup — no cloud fallback, everything ships on your own hardware — in Building a Privacy-First Local RAG System; Cosmind is the other project built on the same local-first principle.

Security & Infrastructure

Google OAuth 2.0 handles authentication, the PayPal SDK (sandboxed) handles payments, and every secret — API keys, OAuth credentials, DB connection strings — is injected at the container level rather than committed to the repo. Five services (app, AI agent, MQTT broker, Ollama, SQLite volume) run side by side under one docker compose up --build.

Revisiting the code with a year more experience, I also found and fixed a real gap: the internal API had no endpoint-level authorization — app.UseAuthentication() was never wired in, so every controller was reachable anonymously regardless of the UI-level admin/staff checks. Fixed it with a global authorization filter plus cookie-forwarding for the Razor Pages and chatbot calls that hit the API internally. Details in the write-up.

Tech Stack

ASP.NET Core (.NET 8) · Razor Pages · SignalR · MQTT (Mosquitto) · Ollama (qwen3, nomic-embed-text) · SQLite · Docker Compose · Google OAuth 2.0 · PayPal SDK · Google Maps SDK · Arduino

Curious how this was built?

I write about the backend×AI wedge — wins and failures included. Follow along, or say hi.