βββ βββ ββββββ βββ βββ
βββ ββββββββββββββ βββ
βββ ββββββββββββββ βββ
ββββ βββββββββββββββ βββ
βββββββ βββ ββββββββββββββ
βββββ βββ ββββββββββββββ
CS undergrad at Lancaster University chasing a First β but more importantly, someone who actually ships things.
I build from first principles: no framework cargo-culting, no tutorial-driven code. Across ML systems, full-stack web apps, mobile platforms, and everything in between β I care about taking ideas all the way to deployed, working products.
Currently: building FightPicks π₯ β a full-stack MMA prediction platform I architected and engineered from the ground up.
Outside the terminal: I'm an MMA fan (Muay Thai & Kickboxing), which probably explains why I gravitate toward problems that require sustained effort and discipline.
Languages
Frontend / Mobile
Backend
Infra / DevOps
A 3D launch-window optimisation system built under hackathon pressure. Real-time satellite orbit and debris field visualisation powered by WebGL and Three.js. A custom risk engine calculates collision probabilities against live debris density data, while an ML-driven weather service generates automated Go/No-Go launch decisions.
A passion project that became a proper engineering challenge. Three decoupled services working in concert to bring ML-powered fight predictions and community analytics to MMA fans.
How it fits together:
Next.js Frontend ββREST/JWTβββΊ Spring Boot API ββJPA/HibernateβββΊ PostgreSQL
β
βββββββββ΄βββββββββ
βΌ βΌ
FastAPI ML Service Python Scraper
(Gradient Boosting (Playwright + BS4
on 7,000+ fights, Oracle VPS Β· cron
66.09% sym acc.) via APScheduler)
What's inside each service:
π Web App β Spring Boot + Next.js monorepo Β· π Code
Expand details
- JWT auth with HttpOnly cookies, refresh token rotation, BCrypt hashing, and JSoup XSS sanitisation
- Fight Simulator β pit any two fighters from across divisions against each other
- Community predictions, discussion forums, and fight card polling
- Real-time leaderboards tracking accuracy, win streaks, and total points
- Advanced user management: profile editing, 90-day username cooldowns, account deletion with data anonymisation
- Token-bucket rate limiting via Bucket4j + Caffeine to prevent abuse
- Admin dashboard for managing users, roles, fights, and ML pre-warming tasks
- Automated emails via Resend API in production; MailHog locally
- Schema migrations managed with Flyway
- Full CI/CD via GitHub Actions: prod deploy on push to
main, staging environments on PRs, manual rollback viaworkflow_dispatch - Fully containerised dev stack via Docker Compose β no local Java or Node needed
- Backend tested with JUnit 5 + Mockito (H2 in-memory DB); frontend with Jest + React Testing Library
π€ ML Service β Containerised prediction API Β· π Code
Expand details
- Gradient Boosting Classifier trained on 7,000+ historical bouts β 66.09% true symmetric accuracy
- Symmetrised inference: every fight is evaluated as A vs B and B vs A, then averaged to eliminate red-corner bias
- Per-corner feature engineering (striking rates, takedown defence, etc.) to capture non-linear relationships
- Hyperparameter-tuned (
max_depth=2,n_estimators=300,learning_rate=0.05) to handle skewed target data - Served as a containerised FastAPI microservice, deployed on AWS ECS
update_dataset.pyfor local manual dataset backfills; live production scraping handled by the dedicated scraper service
π·οΈ Scraper Service β Automated live data ingestion Β· π Code
Expand details
- Autonomous Python worker scraping live UFC fight cards, events, results, and fighter stats from ufcstats.com
- Cron-scheduled nightly via APScheduler;
/trigger/historicalendpoint for one-off backfills - Authenticated pushes to the Spring Boot API via
X-Scraper-Keyheader - Cached fighter roster (
fighters.json) with active/inactive classification by weight class - Deployed on Oracle VPS inside a Docker Compose environment
{
"building" : "FightPicks β full-stack AI prediction & community platform",
"studying" : "Computer Science BSc @ Lancaster University (Year 3)",
"exploring" : ["distributed systems", "ML serving", "system design"],
"open_to" : ["grad jobs", "internships", "interesting problems"]
}If you're building something ambitious β let's talk.



