VamoKora runs on a 34-model Postgres schema, 159 HTTP handlers, and 1,853 test blocks.
It organizes recurring pickup soccer for a real 29-player crew — RSVPs, team drafting, cost splitting, and player ratings.
- current release
- v2.160.0
- commits
- 1194
- building since
- Jun 2026
About
Amir Ibrahim
TIER — GOLD
- TypeScript
- 92
- React / Next.js
- 90
- PostgreSQL
- 84
- System design
- 82
- Testing
- 86
- Shipping
- 95
I'm a full-stack developer and a Computer Engineering graduate from York University (2025), based in the GTA. I work in TypeScript, Next.js, React, PostgreSQL, and Python, and I've shipped two products to people who aren't me: VamoKora, which I've been building since June 2026, and KonnectTaps, a digital business card platform I co-founded and built the frontend for. Most of what I care about as an engineer is in the decisions below — what I chose, and what it cost.
This page's stats are compiled by the thing it describes — VamoKora's own CI reads its source and reports back daily.
Flagship · 01
VamoKora
footpalfc.amiribrahim3000.comPickup-soccer coordination for my own 29-player crew — RSVPs, team drafting, cost splitting, and player ratings — running real weekly games since June 2026.
- Next.js 16
- TypeScript
- PostgreSQL (Neon)
- Prisma
- Web Push
- Sentry
- Vercel
- 34
- Postgres models
- 159
- HTTP handlers across 119 route files
- 1,853
- test blocks across 164 test files
- 1194
- commits
- v2.160.0
- current release
In the app



A matchday, start to finish
0'
Pick a time
The organiser offers a few days; the busiest time rises to the top.
20'
Lock it in
Kickoff is set. Everyone says in, maybe, late, or out — waitlist included.
45'
Draw the teams
Fair sides from the crew's own ratings, laid out on a pitch in a real shape.
70'
Split the pitch
The fee splits between the people who played, rounded to the nearest 50¢.
90'
Rate the game
Votes for player of the match. The only thing that moves a rating.
Decisions
Crew-scoped isolation enforced in the application layer
Independent crews share one database. Access is gated by explicit guard functions — canAccessGame, canManageGame, getUserCrew — invoked per route.
Tradeoff — No Postgres RLS and no Prisma middleware. Isolation depends on each crew-scoped route calling a guard, and nothing underneath catches one that skips it.
Session auth written from scratch, no auth library
The cookie carries the plaintext token; the database stores only the SHA-256 hash. Sessions are per-device. A three-tier resolution path — Session row, then legacy hash column, then legacy plaintext — migrated existing accounts on read, without logging anyone out.
Tradeoff — Three lookup paths to maintain instead of one.
Man-of-the-match awards that fire exactly once
The award can be triggered by the final vote or by a fallback cron. Both paths run one conditional update guarded on a null timestamp, and the affected-row count decides which trigger won.
Tradeoff — The guarantee lives in one UPDATE's WHERE clause and its affected-row count, so it holds only as long as that stays a single statement.
Batched the game page's reads, cutting load from ~3.3s to ~1.1s
Collapsed 8 sequential Prisma reads into one parallel fetch and moved stats computation off first paint, then added three indexes after EXPLAIN showed sequential scans.
Tradeoff — Measured by hand on the heaviest crew game. There is no benchmark harness, so this is a point measurement, not continuous tracking.
Kickoff times resolved to UTC without a date library
Crew-local kickoff times resolve to UTC instants through Intl.DateTimeFormat.formatToParts, so daylight-saving shifts land on the right instant. package.json contains zero date libraries.
Tradeoff — The conversion logic is mine rather than a library's, including the DST transition days when a local time either does not exist or happens twice.
Hand-written service worker serving a branded offline page
The service worker is written by hand rather than generated. It serves a branded offline page in place of the browser's error screen. It does not cache pages, API responses, or app JS.
Tradeoff — Deliberate. Caching rosters and costs would show people stale information, so there is no cached app to fall back on — offline gets a clear page, not a working one.
Ratings and cost settlement as pure, unit-tested modules
The rating engine is crew-relative: each stat scales against that crew's best player and decays with absence. The settlement module nets per-game cost shares down to a single balance per player pair. Both are pure functions covered by the test suites.
Tradeoff — Crew-relative ratings do not compare across crews — the same number means different things in different crews.
Every Sentry event through one PII-scrubbing chokepoint
All error reporting routes through a single scrubbing function before anything leaves the app.
Tradeoff — Centralizing the scrubbing means one place to audit, and one place every error path has to keep routing through.
Privacy page enforced by the build, not by memory
Every outside service the app talks to must be named on the privacy page, or the build fails. Deleting an account scrubs every personal field, and a test fails if a new field is missed.
Tradeoff — The privacy page is load-bearing now — a copy edit can break the build.
Counts read from VamoKora's source by its own CI, refreshed daily.
Also built
KonnectTaps
Next.js / React / JavaScript
Digital business card platform I co-founded and built the frontend for, working with two other developers. Reached 100+ signups. Wound down in May 2026.
CSA Capstone — SOSO
Python / FastAPI / PostgreSQL / RabbitMQ / Docker
Satellite telemetry visualization tool built for a Canadian Space Agency capstone project, turning operational scheduling constraints into readable technical workflows.
Experience
Co-Founder
Jan 2024 – May 2026
KonnectTaps — Remote
- Built the frontend for a digital business card platform in React and Next.js, from component work through to the shipped product.
- Worked alongside two other developers on scope and product direction.
- The platform reached 100+ signups. It wound down in May 2026.
Assistant Deli Manager
Jun 2025 – Present
Marché Adonis — Mississauga, ON
- Run daily operations and scheduling for a 13-person team, after a promotion from Clerk at the seven-year mark.
- Act as primary escalation contact through high-volume, time-sensitive shifts.
Clerk
Nov 2017 – Jun 2025
Marché Adonis — Mississauga, ON
- Ran inventory, customer service, and floor operations across seven years while completing a full-time engineering degree.
Education
B.Eng. Computer Engineering
Graduated Jun 2025
York University — Lassonde School of Engineering
Object-Oriented Programming (Java), Data Structures & Algorithms, Operating Systems, Communication Networks, Software Engineering Principles
Electromechanical Engineering Technician — Year 1
2022 – 2023
Humber College
Control Circuits, Robotics, Mechatronics, Industrial Pneumatics, Statics, Engineering Graphics, Engineering Materials
Stack
Languages
JavaScript (ES6+), TypeScript, Python, Java, SQL, Bash
Frontend
React, Next.js (App Router/RSC), Tailwind, PWA (Web Push, installable)
Backend
Node.js, FastAPI, PostgreSQL, Prisma, MySQL
Testing & observability
Vitest, Sentry
Infrastructure
Docker, GitHub Actions, Git/GitHub, Vercel, Linux/Ubuntu, Nginx
Currently learning: AWS, Kubernetes. Also familiar with Ladder Logic, IT/OT networking, and electromechanical systems from Computer and Electromechanical Engineering studies.
Contact
Open to full-stack and frontend roles.
- Roles
- Software Developer, Full-Stack Developer, Frontend Engineer
- Location
- Remote or hybrid — GTA, Ontario
- Availability
- Immediately