Marine Edge
Edtech platform for Merchant Navy exam prep, on web and Android
A learning platform on web and Android: a Next.js web app with 4 role-based portals and free public tools, and an Angular Android app on Google Play, with live WebRTC classes, Razorpay checkout and lockdown exams.
- 140+ routes
- 49 mobile screens
- 14 Play Store builds
- 0% → 100% exam saves
§1
The problem
Merchant Navy aspirants needed one place for recorded lectures, live classes, study material and mock exams on any device. Exams had to be hard to cheat on, content hard to pirate, and purchases started in the app had to follow Google Play billing rules.
§2
My role
Front-end and mobile engineer in a three-person team: built the Android app end to end and its releases, and the public tools, student and staff portals and checkout on the web platform.
§3
Architecture
§4
Key decisions
D/01
TanStack Query as the data layer
22 hook modules with hierarchical cache keys, invalidated on mutation. Server state lives in one place; Zustand holds only true client state.
D/02
Don't retry what can't succeed
4xx responses are never retried (they used to spin for ~7 s). AbortController timeouts stop a stalled proxy from hanging the UI.
D/03
Uploads that bypass the API
Presigned direct-to-S3 uploads up to 2 GB, multipart above 100 MB with per-part ETags. XHR instead of fetch for real progress bars.
D/04
Checkout that respects Play policy
The app hands purchases to web checkout with the student already logged in. The handoff token is scoped to the API path and lives an hour, so it beats a stale web login without shadowing a later one.
D/05
Native where it matters
Capacitor plugins for offline downloads, push, deep links and a per-route privacy screen; everything else stays shared Angular code.
D/06
Tools before signup
A 4-step eligibility wizard, BMI calculator and colour-blindness test give aspirants a reason to visit before they pay, and feed SEO.
§5
Challenges
- 0 of 49 exam attempt IDs survived the native bridge: 18-digit IDs lost precision as JS numbers. Keeping IDs as strings end to end took exam saves from 0% to 100%.
- A 401 on /me redirected to login, which called /me again: an infinite loop that blanked the app. The error interceptor now leaves /me to the auth guards.
- Exam integrity: fullscreen lockdown, 7 tracked violation types, a soft warning, auto-termination after 3 strikes, and a staff dashboard to review violations.
- Screenshot blocking applied per route (videos, materials, exams, live classes) so the rest of the app behaves normally.
§6
Stack
- Next.js
- React
- TanStack Query
- Angular
- Ionic
- Capacitor
- NgRx
- LiveKit
- Razorpay
Next case study
Taska
Blockchain-backed wallet system built as event-driven microservices