The Shamiri Digital Hub is a comprehensive digital platform designed to manage youth mental health intervention programs at scale. Built by the Shamiri Institute, this platform streamlines the delivery of evidence-based mental health interventions across schools and communities in Kenya, with the goal of reaching 100,000+ students.
- Session Management - Schedule, track, and manage intervention sessions across multiple schools and student groups
- Attendance Tracking - Monitor student participation with detailed attendance records
- Clinical Case Management - Handle clinical screenings, referrals, and case tracking with proper escalation workflows
- Fellow Supervision - Support supervisors in managing and guiding intervention facilitators (fellows)
- Fidelity Monitoring - AI-powered session recording analysis to ensure intervention quality
- Document Management - Centralized storage for progress notes, treatment plans, and case reports
- Payouts & Expenses - Track fellow compensation and program expenses
- Multi-Hub Operations - Coordinate operations across multiple geographic hubs and schools
- Role-Based Access Control - Secure, role-appropriate access for supervisors, hub coordinators, fellows, clinical teams, and operations staff
- Framework: Next.js 16.x (App Router)
- Language: TypeScript (Strict Mode)
- Database: PostgreSQL with Prisma ORM
- Authentication: NextAuth.js with Google OAuth
- UI Components: Radix UI + TailwindCSS
- Data Visualization: Recharts
- File Storage: AWS S3
- Hosting: Vercel
This project is developed in alignment with Open Science Framework (OSF) principles, promoting transparency, reproducibility, and accessibility in youth mental health research and intervention delivery.
- Transparency: Open source codebase enabling full inspection of intervention delivery mechanisms and data collection processes
- Reproducibility: Documented setup, deployment processes, and data schemas for replication studies across different contexts
- Accessibility: MIT License enabling adaptation by researchers, NGOs, educational institutions, and governments globally
- Collaboration: Open to contributions from the research and development community
- Data Integrity: Structured data collection with audit trails supporting research validity
This platform can support your research by providing:
- Standardized intervention delivery tracking
- Structured data collection for outcome studies
- Scalable infrastructure for large-cohort studies
- Built-in fidelity monitoring for intervention quality assurance
Citation: If you use this software in your research, please cite:
Shamiri Institute. (2026). Shamiri Digital Hub [Computer software].
https://github.com/Shamiri-Institute/digitalhub-frontend
This project is licensed under the MIT License - see the LICENSE file for details.
The MIT License allows you to:
- Use the software for commercial purposes
- Modify the source code
- Distribute the software
- Use the software privately
Get the platform running locally in under 5 minutes:
- Node.js v22.x or later
- Docker Compose (for local PostgreSQL)
- npm (comes with Node.js)
# Clone the repository
git clone https://github.com/Shamiri-Institute/digitalhub-frontend.git
cd digitalhub-frontend
# Install dependencies
npm install
# Copy environment file (see Environment Setup section for details)
cp .env.example .env.development
# Start database and run migrations
npm run db:dev:up &
sleep 5 # Wait for database to start
npm run db:dev:migrate
npm run db:dev:seed
# Start development server
npm run dev- Open http://localhost:3000 in your browser
- Log in with test credentials:
- Email:
martin.odegaard@test.com - Password:
TestPassword123!
- Email:
| Requirement | Version | Notes |
|---|---|---|
| Node.js | >=22.x | Required for Next.js 16 |
| npm | >=10.x | Comes with Node.js |
| Docker | >=20.x | For local PostgreSQL |
| PostgreSQL | >=14.x | If not using Docker |
Create a .env.development file in the root directory:
# ====================================
# DATABASE
# ====================================
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/shamiri_db_dev"
# ====================================
# AUTHENTICATION
# ====================================
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="your-nextauth-secret" # Generate with: openssl rand -base64 32
# Google OAuth (OPTIONAL for local development)
# Not required when NEXT_PUBLIC_ENV=development (uses email/password instead)
GOOGLE_ID="your-google-client-id"
GOOGLE_SECRET="your-google-client-secret"
# ====================================
# GOOGLE DRIVE API (Document Storage)
# ====================================
GOOGLE_CLIENT_ID="your-google-client-id"
GOOGLE_CLIENT_EMAIL="your-google-service-account-email"
GOOGLE_PROJECT_ID="your-google-project-id"
GOOGLE_PRIVATE_KEY="your-google-private-key"
PROGRESSNOTE_FILEID="google-drive-folder-id-for-progress-notes"
TREATMENTPLAN_FILEID="google-drive-folder-id-for-treatment-plans"
CASEREPORTS_FILEID="google-drive-folder-id-for-case-reports"
# ====================================
# AWS S3 (File Uploads)
# ====================================
AWS_REGION="your-aws-region"
AWS_ACCESS_KEY_ID="your-aws-access-key-id"
AWS_SECRET_ACCESS_KEY="your-aws-secret-access-key"
S3_UPLOAD_KEY="your-s3-upload-key"
S3_UPLOAD_SECRET="your-s3-upload-secret"
S3_UPLOAD_BUCKET="your-s3-bucket-name"
S3_UPLOAD_REGION="your-aws-region"
# S3 Recordings Bucket (Session Recordings)
S3_RECORDINGS_BUCKET="your-recordings-bucket"
S3_RECORDINGS_REGION="your-aws-region"
# ====================================
# METABASE (Analytics)
# ====================================
METABASE_SECRET_KEY="your-metabase-secret-key"
METABASE_MONITORING_DASHBOARD_ID="your-metabase-dashboard-id" # Dashboard ID for Monitoring and Evaluation embed
# ====================================
# APPLICATION SETTINGS
# ====================================
NEXT_PUBLIC_APP_URL="http://localhost:3000"
NEXT_PUBLIC_ENV="development"
APP_ENV="development"
SEND_EMAILS="0" # Set to 1 to enable email sending
DEBUG="0" # Set to 1 to enable debug mode
# ====================================
# RECORDINGS API (Fidelity Service)
# ====================================
RECORDINGS_API_KEY="your-recordings-api-key"For quick local development without file upload or email features:
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/shamiri_db_dev"
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="any-random-string-for-dev"
NEXT_PUBLIC_ENV="development"Note: File uploads and email sending require AWS credentials. If you need these features, add the AWS S3 variables from the full configuration above.
# Start PostgreSQL container
npm run db:dev:up
# In a separate terminal, run migrations
npm run db:dev:migrate
# Seed with test data
npm run db:dev:seed- Create a database named
shamiri_db_dev - Update
DATABASE_URLin.env.development - Run migrations and seed:
npm run db:dev:migrate
npm run db:dev:seedOption 1: Email/Password (Recommended for Development)
When NEXT_PUBLIC_ENV=development, use test credentials from seed data:
- Email:
martin.odegaard@test.com - Password:
TestPassword123!
Option 2: Google OAuth
- Create OAuth credentials in Google Cloud Console
- Configure authorized origins:
http://localhost:3000 - Configure redirect URI:
http://localhost:3000/api/auth/callback/google - Add credentials to
.env.development
┌─────────────────────────────────────────────────────────────────┐
│ CLIENTS │
│ (Web Browser - Hub Coordinators, Supervisors, Fellows, etc.) │
└─────────────────────────────┬───────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ NEXT.JS APPLICATION │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
│ │ App │ │ Server │ │ API Routes │ │
│ │ Router │ │ Actions │ │ /api/auth, /api/rec... │ │
│ └─────────────┘ └─────────────┘ └─────────────────────────┘ │
└─────────────────────────────┬───────────────────────────────────┘
│
┌───────────────────┼───────────────────┐
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ PostgreSQL │ │ AWS S3 │ │ Google Drive │
│ (Prisma ORM) │ │ (File Storage) │ │ (Documents) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
The platform implements role-specific dashboards and data access:
| Role | Route | Description |
|---|---|---|
| Hub Coordinator | /hc/* |
Oversees operations across multiple schools in a hub |
| Supervisor | /sc/* |
Manages fellows and student groups within assigned schools |
| Fellow | /fel/* |
Conducts intervention sessions with student groups |
| Clinical Lead | /cl/* |
Handles clinical cases and high-risk screenings |
| Clinical Team | /ct/* |
Supports clinical operations and case management |
| Operations | /ops/* |
Administrative oversight and system management |
| Admin | /admin/* |
System administration and configuration |
Hub
└── Schools (many)
└── Student Groups (many)
└── Students (many)
└── Sessions (many)
└── Attendances (many)
└── Recordings (many)
Supervisor
└── Fellows (many)
└── Student Groups (many)
Clinical Case
└── Student
└── Progress Notes (many)
└── Treatment Plans (many)
The platform uses prefixed Object IDs rather than sequential integers or plain UUIDs. This approach improves security by preventing enumeration attacks and enhances debugging by making entity types identifiable in logs.
| Command | Description |
|---|---|
npm run dev |
Start development server |
npm run build |
Build for production |
npm run start |
Start production server |
| Command | Description |
|---|---|
npm run db:dev:up |
Start local PostgreSQL (Docker) |
npm run db:dev:migrate |
Run Prisma migrations |
npm run db:dev:migrate:reset |
Reset and reapply all migrations |
npm run db:dev:seed |
Seed with test data |
npm run db:dev:types |
Generate Prisma client types |
npm run db:studio |
Open Prisma Studio GUI |
| Command | Description |
|---|---|
npm run lint |
Run ESLint |
npm run typecheck |
Run TypeScript type checking |
npm run format |
Format code with Biome |
npm run stylecheck |
Check code formatting |
| Command | Description |
|---|---|
npm run test:unit |
Run Vitest unit tests |
npm run test:dev |
Run Playwright E2E tests |
npm run test:dev:ui |
Run Playwright with UI |
npm run test:ci |
Run tests in CI mode |
All code changes must pass these checks before merging:
npm run typecheck # TypeScript type checking
npm run lint # ESLint code quality
npm run stylecheck # Biome formatting
npm run test:unit # Unit testsThis project uses Conventional Commits:
feat(auth): add Google OAuth integration
fix(database): resolve migration rollback issue
chore(deps): update Next.js to v16.0.10
refactor(components): extract reusable form validation
docs(readme): update installation instructions
test(e2e): add hub coordinator flow tests
# On dev branch
git checkout dev
npm run release
git push --follow-tags
# Fast-forward merge to main
git checkout main
git merge --ff-only v<version>
git pushThis project is optimized for Vercel deployment.
Configure these in your Vercel project settings:
| Variable | Required | Description |
|---|---|---|
DATABASE_URL |
Yes | PostgreSQL connection string |
NEXTAUTH_URL |
Yes | Production URL |
NEXTAUTH_SECRET |
Yes | Authentication secret |
GOOGLE_ID |
Yes | Google OAuth Client ID |
GOOGLE_SECRET |
Yes | Google OAuth Client Secret |
AWS_ACCESS_KEY_ID |
Yes | AWS credentials for S3 |
AWS_SECRET_ACCESS_KEY |
Yes | AWS credentials for S3 |
S3_UPLOAD_BUCKET |
Yes | S3 bucket for uploads |
METABASE_SECRET_KEY |
For analytics | Metabase JWT signing key |
METABASE_MONITORING_DASHBOARD_ID |
For analytics | Metabase Monitoring and Evaluation dashboard ID (numeric) |
| Environment | Branch | Database |
|---|---|---|
| Production | main |
Production DB |
| Preview | dev / PRs |
Preview DB |
| Development | local | Local DB |
The build process automatically runs migrations:
prisma generate && prisma migrate deploy && next buildMigrations are automatically applied during Vercel builds. For manual operations:
# Preview database management
npm run db:preview:reset # Recreate from productionThe platform includes API endpoints for processing session recordings with external AI fidelity services.
All API requests require the x-api-key header matching the RECORDINGS_API_KEY environment variable.
Returns recordings awaiting processing.
curl -H "x-api-key: your-api-key" \
"https://your-domain/api/recordings/pending?limit=50"Response:
{
"recordings": [
{
"id": "<recording-id>",
"s3Key": "recordings/2025/01/school/fellow/group/session.mp3",
"fileName": "session.mp3",
"fellowName": "John Doe",
"schoolName": "Example School",
"sessionDate": "2025-01-08T00:00:00.000Z"
}
],
"count": 1
}Update recording status after processing.
curl -X PATCH \
-H "x-api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{"status": "COMPLETED", "overallScore": "85"}' \
"https://your-domain/api/recordings/<recording-id>/status"Status Values: PENDING, PROCESSING, COMPLETED, FAILED
See S3 Recordings Bucket Setup for detailed AWS configuration.
This platform can be adapted for similar intervention programs:
- Branding: Update
tailwind.config.tsfor your color scheme - Roles: Modify role definitions in
prisma/schema.prisma - Workflows: Adapt server actions in
lib/actions/ - Data Models: Extend Prisma schema for your data requirements
| Feature | Configuration | Description |
|---|---|---|
| Email Sending | SEND_EMAILS=1 |
Enable transactional emails |
| Debug Mode | DEBUG=1 |
Enable verbose logging |
| OAuth | GOOGLE_ID/SECRET |
Google authentication |
| File Storage | S3_* variables |
AWS S3 configuration |
| Analytics | METABASE_SECRET_KEY, METABASE_MONITORING_DASHBOARD_ID |
Embedded Metabase dashboards |
- Database: Use connection pooling (PgBouncer) for high traffic
- File Storage: Configure S3 lifecycle rules for cost optimization
- Caching: Implement Redis for session/query caching at scale
- CDN: Use Vercel's Edge Network for global distribution
We welcome contributions from the community!
- Fork the repository
- Create a feature branch:
git checkout -b feat/your-feature - Make your changes following our code style
- Run quality gates:
npm run typecheck && npm run lint && npm run stylecheck - Commit using conventional commits
- Open a Pull Request
- Use TypeScript strict mode
- Follow TailwindCSS-only styling
- Reuse existing components from
components/ui/ - Write tests for new functionality
- Document API changes
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Website: shamiri.institute
- Email: Contact through the website
- Installing
aws-crtis required to work around a Next.js App Router import issue
-
Create bucket in AWS Console:
- Bucket name: Choose a descriptive name for your environment (e.g.,
myorg-recordings-dev) - Region: Choose based on your target users' location
- Block Public Access: Enable ALL
- Default encryption: SSE-S3 (AES-256)
- Bucket name: Choose a descriptive name for your environment (e.g.,
-
Create IAM Policy named
ShamiriRecordingsBucketPolicy:{ "Version": "2012-10-17", "Statement": [ { "Sid": "RecordingsBucketAccess", "Effect": "Allow", "Action": ["s3:PutObject", "s3:GetObject", "s3:DeleteObject", "s3:ListBucket"], "Resource": [ "arn:aws:s3:::your-recordings-bucket-dev", "arn:aws:s3:::your-recordings-bucket-dev/*", "arn:aws:s3:::your-recordings-bucket-prod", "arn:aws:s3:::your-recordings-bucket-prod/*" ] } ] } -
Configure CORS (Permissions > CORS):
[ { "AllowedHeaders": ["*"], "AllowedMethods": ["PUT", "POST", "GET"], "AllowedOrigins": ["http://localhost:3000", "https://your-production-domain.com", "https://*.vercel.app"], "ExposeHeaders": ["ETag"], "MaxAgeSeconds": 3600 } ] -
Set Lifecycle Rules (optional):
- Archive recordings to S3 Glacier after 90 days
- Abort incomplete multipart uploads after 7 days
recordings/{year}/{month}/{school_name}/{fellow_name}/{group_name}/{session_type}_{recording_id}.{ext}
Example: recordings/2025/01/example_school/facilitator_name/group_a/session_1.mp3
MIT License - Copyright (c) 2026 Shamiri Institute
See LICENSE for the full license text.