Skip to content

dhis2/certification-app

DHIS2 Certification App

DHIS2 certification assessments and W3C Verifiable Credential issuance.

Prerequisites

  • Docker and Docker Compose v2+
  • Node.js 24+ (for running tests or scripts outside Docker)

Architecture

graph TB
    User([User / Assessor / Admin])
    Public([Public Verifier])

    subgraph Traefik["Traefik (TLS + Routing)"]
        direction LR
        R1["Host + PathPrefix /api/v1, /health → API"]
        R2["Host + catch-all → Client"]
    end

    subgraph App["Application"]
        Client["Client<br/>React + nginx"]
        API["API<br/>NestJS"]
    end

    subgraph Data["Data Stores"]
        DB[(PostgreSQL)]
        Redis[(Redis)]
    end

    Vault["OpenBao Vault<br/>(optional)"]

    User --> Traefik
    Public --> Traefik
    Traefik --> Client
    Traefik --> API
    API --> DB
    API --> Redis
    API --> Vault
Loading

Development Setup

1. Create .env

cp .env.example .env

The defaults work as-is for local development. The seed creates an admin user with credentials printed to the migration container logs.

2. Start everything

docker compose up --build -d

This runs:

Service Port What it does
dhis2-cert-db 5432 PostgreSQL 18
dhis2-cert-redis 6379 Redis 7
dhis2-cert-migrations Runs TypeORM migrations + seeds, then exits
dhis2-cert-api 3001 NestJS API with hot reload (nest start --debug --watch)
dhis2-cert-client 3000 Vite dev server with HMR

The compose.override.yaml is auto-merged by Docker Compose — it swaps production images for local builds, mounts source code for hot reload, and exposes ports on 127.0.0.1.

3. Verify

# API health
curl http://localhost:3001/health/live

# Client
open http://localhost:3000

API docs (Swagger): http://localhost:3001/api/v1/docs

Vault (optional)

For testing Vault-backed signing instead of ephemeral keys:

docker compose --profile vault up --build -d

Set USE_VAULT=true in .env. The dev Vault runs in -dev mode with a root token of dev-root-token and auto-initializes the transit engine.

Running Without Docker

If you prefer running the API and client natively (DB and Redis still in Docker):

# Start only the infrastructure
docker compose up -d dhis2-cert-db dhis2-cert-redis

# API
cd api
npm ci
npm run migration:run
npm run seed
npm run start:dev

# Client (separate terminal)
cd client
npm ci
npm start

Common Commands

# Logs
docker compose logs -f dhis2-cert-api
docker compose logs dhis2-cert-migrations

# Rebuild after Dockerfile changes
docker compose up --build -d

# Stop
docker compose down

# Stop and wipe volumes (full reset)
docker compose down -v

# Skip migrations on restart
SKIP_MIGRATIONS=true docker compose up -d

# Re-run seeds only
docker compose run --rm dhis2-cert-migrations sh -c "npm run seed"

Tests

# API unit tests
cd api && npm test

# Client unit tests
cd client && npm test

# E2E (requires dev stack running)
cd client && npm run test:e2e

Project Structure

api/             NestJS backend (TypeORM, JWT auth, W3C VCs)
client/          React frontend (DHIS2 UI, Vite)
docker/          Init scripts, Vault config, nginx config
compose.yaml     Base config (production-oriented)
compose.override.yaml  Dev overrides (auto-merged)
compose.prod.yaml      Production security hardening

About

App for managing certifications (server, metadata etc)

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors