← Index

MEL Platform

Quality ownership on a tri-lingual, offline-capable platform that follows a person with a disability from first contact to settled employment.

Client
Codesage · EnAble India
Role
Senior QA Engineer — end-to-end quality owner, and contributing engineer
Period
Feb 2026 — Present
repositories in the system
4repositories in the system
test cases authored & owned
1,028test cases authored & owned
feature modules under test
22feature modules under test
languages (EN / HI / KN)
3languages (EN / HI / KN)
of my commits merged
206of my commits merged
lines of product code written
~50klines of product code written

Overview

Full-stack product · Web, Windows desktop, Android

MEL — Monitoring, Evaluation and Learning — is the operational backbone of EnAble India's grassroots programme. It tracks one candidate through a long, human journey: campaign or walk-in, registration, a seven-step profile, training, self-employment settlement, 45- and 90-day follow-ups, and finally settled. Field officers use it in Grassroots Service Centres on patchy connections, in three languages, on phones and laptops. I own quality across all of it.

ClientsWeb appReact 19 · ViteWindows desktopTauri 2AndroidTauri 2Local storeoffline-firstsyncAPIHono API · TypeScriptJWT + RBAC scoping · Zod validation · i18n (EN / HI / KN) · /sync compound cursorData & servicesPostgreSQLDrizzle ORMRediscache · queuesAWS S3documents · evidenceNATSevents22 feature modules · Candidates, Trainings, Courses, Centres, Campaigns, Settlements, Workplace Support, Committees, Master Data, ReportsEvery list endpoint is scoped by the caller's role before it returns a row.
MEL system architecture — three clients over one Hono API, with an offline sync path for field devices.

01

The testing problem

MEL is not one app. The same feature has to behave identically in a browser, in a Tauri desktop build, and in a Tauri Android build that may be offline for hours — then reconcile when it syncs. Every screen exists in English, Hindi and Kannada. Every record is scoped by role: a field officer sees only their own centre, a State Head sees their states, an admin sees everything. A single candidate-status change can be correct on web and wrong on the offline path.

  • Multiple role types with different visibility, each a separate data path to verify
  • Three languages, two of which produce longer strings that break tight layouts
  • Three runtime targets, one of which writes to a local store and syncs later
  • Users are people with disabilities — accessibility is a functional requirement, not a polish item

02

How I set quality up

  • Wrote the test suite module by module — Candidates, Trainings, Courses, Centres, Campaigns, Settlements, Workplace Support, Committees, Master Data, Reports and Notifications — to 1,028 cases with per-role variants.
  • Ran a wireframe-versus-build comparison for every Master Data entity, sub-view by sub-view, so specification drift was caught before UAT rather than during it.
  • Drove UAT cycles end to end and produced the sign-off packages, release notes and production readiness reports the client signs against.
  • Built role-and-data-path smoke suites so a scope-visibility regression fails fast instead of surfacing in the field.
  • Extended the same coverage onto Android through a self-contained Appium and emulator harness, with mobile UAT sheets mirroring the web ones.

03

Defects worth naming

The bugs I am proudest of are the quiet ones — the kind that pass a happy-path script and lose real data.

  • Offline sync silently dropped rows: the scoped sync cursor keyed on a timestamp alone, so records written in the same tick were skipped forever. Fixed with a compound cursor.
  • Duplicate-key failures surfaced as opaque 500s because the ORM wrapped the Postgres unique violation. Mapped to a proper 409 with a usable message.
  • Future dates were accepted as a candidate's date of birth. Caught in UAT and tracked as a fail across two runs until it was fixed.
  • A training could be archived while candidates were still on its roster — on the offline path as well as online.
  • Editing a GSC centre did not prefill its pincodes, so saving quietly narrowed the centre's coverage area.

04

Where I crossed into the codebase

On a small team, handing over a one-line fix costs more than writing it. Over six months, 206 of my commits were merged across the frontend and backend — roughly 50,000 lines added. Several shipped as matched frontend and backend pairs on the same ticket.

  • Settlement module and the 45- and 90-day follow-up scheduler, including sequence gating and draft persistence
  • An application-wide centre and state scope switcher — API and UI, one ticket
  • Server-side search, filtering, pagination and denormalised counts across every Master Data tab
  • Committee PDF export, end to end
  • English-only input validation enforced across the whole API and app
  • URL-backed list filters, so a filtered view can be shared as a link
  • The accessibility remediation sweep described in its own case study

Stack

Frontend

  • React 19
  • TypeScript
  • Vite
  • TanStack Router
  • TanStack Query
  • Tailwind v4
  • shadcn/ui + Radix
  • React Hook Form + Zod
  • Zustand
  • i18next (EN/HI/KN)
  • Recharts
  • Leaflet

Backend

  • Hono
  • Drizzle ORM
  • PostgreSQL
  • Redis
  • NATS
  • AWS S3
  • Firebase Admin
  • Sentry
  • pdfmake
  • OTP / MFA
  • JWT + RBAC

Clients

  • Web
  • Tauri — Windows desktop
  • Tauri — Android
  • Offline-first sync

Quality

  • Playwright
  • axe-core
  • Vitest
  • Appium
  • Jira
  • UAT sign-off