Skip to main content

Contributing to Education Services

The Education module powers GhanaAPI's national directory of educational institutions. It aggregates official Ghana Education Service (GES) datasets into a searchable API backed by PostgreSQL and Prisma. This guide explains how the feature works and how you can contribute.

๐ŸŽ“ Current Education Featuresโ€‹

Implementedโ€‹

  • School Search API โ€“ Filter by region, district, category (SHS, JHS, University, TVET), grade (Aโ€“D), and free-text query
  • School Detail Endpoint โ€“ Retrieve full metadata including programs offered, residency type, and contact details
  • Regional & District Browsing โ€“ Dedicated routes for region/district listings
  • Statistics Endpoint โ€“ Aggregated counts by category, grade, and region for analytics dashboards
  • Swagger Documentation โ€“ Full OpenAPI coverage with request/response schemas and examples

Data Pipeline Featuresโ€‹

  • ๐ŸŒ Live scraping of SHS Select (paginated list + detail pages) using Cheerio and Axios
  • ๐Ÿงญ Region/district normalization against locations/data/regions.json
  • ๐Ÿซ School grading heuristic that maps Category A/B/C into SchoolGrade
  • ๐Ÿ” Built-in retry/resiliency for HTTP requests and graceful logging when upstream data is missing
  • ๐Ÿ“ฌ Contact enrichment (email, phone, postal box) plus optional metadata like nicknames, founding year, and population
  • ๐Ÿ“ฆ Export + seed workflow: npm run schools:export writes data/shs-select-schools.json, review it, then npm run schools:seed to merge SHS Select and public-universities.json into PostgreSQL
  • ๐Ÿ“ฆ Prisma seed script (npm run prisma:seed) is retained for backwards compatibility but the JSON-driven flow is recommended for verification

๐Ÿงฑ Architecture Overviewโ€‹

Key Filesโ€‹

backend/src/education/
โ”œโ”€โ”€ education.module.ts # Nest module wiring (HTTP + cache + Prisma)
โ”œโ”€โ”€ education.controller.ts # REST endpoints + Swagger annotations
โ”œโ”€โ”€ education.service.ts # Business logic and caching
โ”œโ”€โ”€ dto/ # Request/response DTOs
โ”‚ โ”œโ”€โ”€ school-search.dto.ts
โ”‚ โ”œโ”€โ”€ school-search-response.dto.ts
โ”‚ โ”œโ”€โ”€ school.dto.ts
โ”‚ โ””โ”€โ”€ create-school.dto.ts
โ”œโ”€โ”€ entities/
โ”‚ โ””โ”€โ”€ school.entity.ts # Shared enums and interfaces
โ”œโ”€โ”€ services/
โ”‚ โ”œโ”€โ”€ prisma.service.ts # Prisma client lifecycle wrapper
โ”‚ โ””โ”€โ”€ school-data-provider.service.ts
โ””โ”€โ”€ utils/
โ”œโ”€โ”€ ges-school-parser.ts # Legacy PDF parser (kept for cross-checking)
โ””โ”€โ”€ shs-select-scraper.ts # Primary SHS Select HTML scraper

backend/prisma/
โ”œโ”€โ”€ schema.prisma # `School` model + enums + indexes
โ””โ”€โ”€ seed.ts # Seeds database with scraped SHS Select data

Data Flowโ€‹

  1. Seed Script (prisma/seed.ts)
    • Crawls every page of the SHS Select list to gather school slugs
    • Fetches each detail page (programmes, contact info, map coordinates, metadata)
    • Normalizes region/district names and converts Category A/B/C โ†’ SchoolGrade
    • Stores the schools via Prisma createMany
  2. SchoolDataProviderService
    • Caches the scraped dataset (1-hour TTL) and exposes it to the main service
  3. EducationService
    • Executes Prisma queries with filtering, pagination, and caching
  4. EducationController
    • Validates input via DTOs and exposes REST endpoints with OpenAPI metadata

๐Ÿš€ Getting Startedโ€‹

Local Database Setupโ€‹

# Generate Prisma client
npm run prisma:generate

# Run migration (if new fields were added)
npm run prisma:migrate

# Refresh data from GES PDFs
npm run prisma:seed

Running the APIโ€‹

npm run start:dev
# Swagger docs with Education tag available at http://localhost:3000/api/v1/docs

๐Ÿงญ Contribution Ideasโ€‹

Beginner-Friendlyโ€‹

  • Improve Swagger response examples for new education endpoints
  • Add unit tests for DTO validation edge cases
  • Expand sample requests/responses in docs/docs/api/education.md
  • Improve error messages when filters return zero results

Intermediateโ€‹

  • Enhance search relevance (e.g., fuzzy matching, multi-term queries)
  • Add pagination metadata (next/prev cursors) alongside offset/limit
  • Implement additional filters (programs offered, residency type)
  • Expose doubleTrack metadata in API responses with documentation

Advancedโ€‹

  • Support incremental data refresh instead of full re-seed
  • Integrate additional data sources (e.g., tertiary institutions directory)
  • Add job queue for scheduled PDF ingestion and change detection
  • Implement audit trails for data provenance and manual corrections

๐Ÿงช Testing Checklistโ€‹

# Run unit tests for education module
npm run test -- education

# Execute seed script in dry-run mode (coming soon) or manual verification
npm run prisma:seed

Recommended test cases when contributing:

  • Filters: combinations of region, district, category, grade, and text query
  • Pagination: limits, offsets, and hasMore flag accuracy
  • Stats endpoint: verify counts after seeding/reseding
  • Error handling: invalid enums, region/district typos, missing query parameters

๐Ÿ“š Documentation Updatesโ€‹

When adding features or schema changes, please update:

  • docs/docs/api/education.md โ€“ API reference and examples
  • docs/docs/contributing/education.md (this file)
  • docs/docs/api/IMPLEMENTATION_STATUS.md โ€“ Status tables
  • docs/docs/CHANGELOG.md โ€“ Include version bump summary
  • Swagger comments in education.controller.ts