← Back to work
Case StudyPostgreSQL · SQLPythonProduct Analytics

Pathsy: the data model and analytics behind a career-guidance platform

Solo project — schema design → data curation → weighted recommendation engine → SQL audits and Python validation against the production database. All numbers on this page come from live queries, and every artifact is public.

12
tables in schema
78
active courses
833
career roles
9/9
archetypes in top 3
01

Problem

Every year, millions of Indian students finish Class 10 and 12 with no structured way to compare what comes next. Guidance is fragmented across coaching-institute marketing (biased), word of mouth (narrow), and scattered blogs (unverified) — so demand hyper-concentrates into engineering and medicine while vocational and emerging paths stay invisible.

Pathsy structures the decision as data: every major path as comparable, queryable records — courses, entrance exams, specializations, career roles, salary progressions — plus a quiz that maps student preferences to streams. My question as the analyst: can a transparent, rules-based model (no black-box AI) give students a genuinely useful ranked recommendation?

02

The dataset

Curated reference data (supply side): 78 active courses, 288 specializations, and 833 career roles across 4 education stages and 30 streams, hand-researched from state board syllabi (BIEAP, TSBIE, CBSE) and exam-authority sources, normalized into a 12-table PostgreSQL schema — courses → specializations → career roles, entrance exams linked through a many-to-many junction table, and a 4-band salary progression (Fresher → Junior → Mid → Senior) per course.

Behavioral data (demand side): product events — quiz starts and completions, searches (including zero-result ones), path views, saves. The append-only events table is designed and the funnel/search-gap SQL is written; instrumentation is the current sprint (see 07).

03

Cleaning & assumptions

  • Naming normalization: AP/Telangana stream names (MPC, BiPC) unified with CBSE equivalents (PCM, PCB) — both always displayed; a synonym map handles search (“doctor” → MBBS).
  • Salary standardization: all sources converted to a common 4-band LPA progression; conflicting sources resolved to conservative midpoints and flagged with an on-page disclaimer.
  • Soft deletes: courses carry an is_active flag instead of being deleted, so saved-path references never break.
  • Stated assumptions: salary bands are indicative national medians, not offers; quiz weights are hand-assigned per path and validated by simulation (see 05).
04

SQL audit of my own data

A guidance product is only as trustworthy as its least-complete record, so the first analysis was an audit of the dataset I curated — run against production:

sql/02_data_completeness.sql (excerpt)
SELECT c.slug, c.name,
       COUNT(DISTINCT sr.id)      AS salary_bands,   -- expected: 4
       COUNT(DISTINCT ce.exam_id) AS linked_exams
FROM courses c
LEFT JOIN salary_ranges sr         ON sr.course_id = c.id
LEFT JOIN course_entrance_exams ce ON ce.course_id = c.id
WHERE c.is_active
GROUP BY c.id, c.slug, c.name
HAVING COUNT(DISTINCT sr.id) < 4
    OR COUNT(DISTINCT ce.exam_id) = 0;
FindingThe audit found 22 of 78 active courses missing the full 4-band salary progression, and 74 of 78 with zero rows in the exam junction table — exam data was living in a free-text column, which blocks exam-based filtering. I backfilled the junction: 46 exams added, ~100 course–exam links with mandatory flags. The backfill also corrected the metric itself: 23 of those "missing" courses are ITI trades and skill certifications with no entrance exam at all — a completeness metric needs a "not applicable" category before you treat every zero as missing data. Auditing your own curation is humbling; it is also the job.
05

Validating the recommendation engine (Python)

The quiz scores 9 answers against per-path JSONB weights. To test calibration, I defined 9 student archetypes — the answers a stereotypical aspirant of each path would pick, chosen from option text alone — and ran them through the live scoring matrix:

ArchetypeExpected pathRank before fixRank after fix
Engineering aspirantMPC / Engineering11
Medical aspirantBiPC / Medical11
Commerce aspirantCommerce11
Humanities aspirantArts / Humanities11
Law / professionalIntegrated law11
Pharmacy aspirantPharmacy22
Hands-on trade seekerITI trades21 *
Diploma-first studentPolytechnic22
Defence aspirantDefence prep4 ❌1 ✅
FindingThe first run exposed a real flaw: a Defence aspirant could never see Defence ranked first — its maximum achievable score was 6, vs. 24 for the engineering track, because only 2 of 32 quiz options carried any defence weight. My first rebalance fixed the ranks but overcorrected: ITI could suddenly outrank engineering for any tinkering-minded student, which is unrealistic in India, and Defence collected points from options unrelated to service. The final design is commitment-gated: a ninth question asks what the student has actually done (trained for NDA, visited an ITI centre, researched entrance exams), and high-stakes paths only rank first when that action signal is present. Result: 7/9 rank #1, 9/9 in top 3.* ITI ranks first only for a student who has actually visited a training centre and wants a 1–2-year route to income; a tinkering-profile student still gets engineering first. Calibration is a product decision, not just a math one.
06

Key metrics

Quiz completion ratestarts → 9/9 answered; per-question drop-off finds weak questions
Save ratesaves ÷ path views — the product's real conversion of interest into intent
Zero-result search rateshare of searches returning nothing; its top terms are the content roadmap
Demand concentrationshare of views in top-3 streams — quantifies the engineering/medicine bias
Recommendation diversitydistinct top-1 results ÷ paths — quiz calibration health
07

Dashboard & instrumentation plan

Behavioral events flow into a single append-only app_events table (anonymous session id, event name, JSONB payload — insert-only RLS for clients). The funnel and zero-result-search SQL is already written against it. The Power BI report has three pages:

  • Engagement overview: WAU, views by stage, top paths, save-rate trend
  • Quiz funnel: start → per-question → completion, top-1 result distribution
  • Content gaps: zero-result search terms, demand vs. supply per stream, saves-to-views ranking
08

What this project demonstrates

Relational modeling from a blank page (12 tables, junction tables, RLS, full-text search), disciplined data curation with documented assumptions, a transparent scoring model whose flaws I went looking for and found, and SQL/Python used the way analysts actually use them — to audit, validate, and decide what to fix next. The honest status: reference data and validation are live; behavioral instrumentation ships next, and this page will grow real funnel numbers when it does.