Projects

Zwift Data Viewer

Flutter Dart Riverpod Supabase Google Gemini AI SQLite Syncfusion Charts

Status: Production / Active

Problem

Cyclists using Zwift and Strava generate vast amounts of performance data, but analyzing this data to improve training and discover optimal routes is time-consuming. Athletes need intelligent insights that combine historical performance with AI-powered recommendations.

Technical Approach

Built a cross-platform mobile application (iOS, Android, Web) that integrates multiple data sources and provides intelligent analytics:

Architecture Highlights

Hybrid 3-Tier Data Architecture: Implements cache-aside pattern with Strava API as source, Supabase as cloud database, and SQLite for local caching. Intelligent sync strategy handles conflicts with last-write-wins, treating Supabase as source of truth.

AI Integration: Hybrid recommendation engine combines algorithmic analysis (performance matching, progressive challenge) with Google Gemini 2.5 AI for pattern recognition. Graceful fallback ensures functionality even when AI is unavailable.

State Management: Riverpod providers handle complex state across connectivity changes, with FutureProvider for async data loading and StateNotifierProvider for mutable state. Family providers enable parameterized queries.

Authentication Flow: Multi-stage auth using Strava OAuth as primary, then Supabase auth with automatic token refresh and secure storage.

Key Learnings

Offline-first architecture requires careful consideration of conflict resolution strategies. Connection pooling and lazy loading are essential for mobile performance. Combining algorithmic and AI recommendations provides better results than either alone - algorithms handle edge cases where AI may be unreliable.

Impact

Production app with active users. Demonstrates sophisticated mobile architecture, AI integration, and data synchronization at scale. Shows ability to build complex, data-intensive applications that work seamlessly across platforms.

Related Projects:

LEGO Train Controller

Flutter Dart Bluetooth LE REST API Provider IoT

Status: Production / Active

Problem

LEGO Powered Up trains and switches require proximity for manual control. Remote automation and multi-device coordination is challenging. Hobbyists need a system that bridges digital control with physical hardware.

Technical Approach

Built a Flutter mobile application that controls LEGO Powered Up hubs via Bluetooth Low Energy through a backend server:

Architecture Highlights

Hardware Integration: Communicates with LEGO Powered Up hubs using Bluetooth Low Energy protocol. Backend server handles BLE complexity, exposing simple REST API for train/switch control.

State Management: Provider pattern with specialized providers for trains and switches. Polling mechanism (configurable, default 1s) maintains current device status across UI.

REST API Design: Clean endpoint structure for train control (POST /train), switch management (POST /switch), autonomous mode (POST /selfdrive), status retrieval (GET /connected/*), and system reset.

Data Models: Uses Freezed and json_serializable for type-safe, immutable data models with JSON serialization.

Key Learnings

IoT projects require careful abstraction layers - separating BLE complexity from application logic makes the system more maintainable. Polling vs push notifications involves trade-offs; polling is simpler but less efficient. Physical hardware debugging is fundamentally different from software - Bluetooth signal strength and physical interference matter.

Impact

Demonstrates IoT and hardware integration skills rarely seen in typical software portfolios. Shows ability to bridge digital and physical worlds, handle real-time control systems, and design APIs for hardware abstraction. Production deployment on both iOS and Android.

Related Projects:

LEGO Track Designer

React JavaScript Vite Material-UI Tailwind CSS SVG

Status: Active

Problem

LEGO train enthusiasts need to plan complex track layouts before physical construction. Planning on paper lacks precision, while physical trial-and-error wastes time and pieces. Digital tools need to be intuitive, accurate, and support iterative design.

Technical Approach

Built a browser-based visual track designer with drag-and-drop interface:

Architecture Highlights

Component Architecture: Modular React design with TrackDesigner as main orchestrator, TrackPieces defining piece geometry and SVG paths, and specialized hooks for drag behavior, history management, and canvas navigation.

Custom Hooks: useTrackHistory implements undo/redo with immutable state operations, useTrackDragging handles complex drag-and-drop with collision detection, usePanZoom manages canvas transformations for smooth navigation.

Geometric System: Pure functions handle track piece transformations (rotation, flipping), connection point calculations, and automatic piece snapping. SVG-based rendering ensures crisp visuals at any zoom level.

State Management: Immutable state updates through history system enable reliable undo/redo. All track operations are pure functions, making behavior predictable and testable.

Key Learnings

Interactive canvas applications require careful separation between UI state (pan/zoom) and domain state (track layout). Custom hooks enable clean separation of concerns - drag behavior, history, and canvas navigation are independently testable. SVG coordinate systems need careful handling when combining transformations, rotations, and user interactions. Immutable state patterns make undo/redo trivial but require discipline in state updates.

Impact

Demonstrates advanced React patterns, geometric algorithms, and interactive UI design. Shows ability to build specialized design tools with complex user interactions. Clean architecture makes the codebase maintainable and extensible for future features like track validation and 3D preview.

Links: GitHub

← Back to Home