MobiShare
A smart bike & scooter sharing platform, built for the CINI IT Challenge — a national university competition judged live by an industry panel.
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
Related
A local-first, privacy AI second brain. Multi-agent RAG turns chaotic Markdown vaults into a queryable archive — and a navigable 3D galaxy of ideas.
Artificial Intelligence didn’t start with ChatGPT. From its origins in the 1950s to today’s deep learning models, let’s explore what AI really is, how it learns from data, and why it’s not just computer “magic.”
Predicting a speaker's emotion from the acoustic signature of their voice — five classifiers benchmarked in scikit-learn and cross-validated against WEKA.
Curious how this was built?
I write about the backend×AI wedge — wins and failures included. Follow along, or say hi.