Skip to main content

Introduction

My School Education OS is an enterprise-grade, AI-first cloud ERP platform engineered for modern K-12 schools and multi-campus educational trusts. It consolidates academics, admissions, finance, LMS, staff management, hostel, transport, and parent engagement into a single multi-tenant microservices architecture.

Key Architectural Pillars:Asynchronous Kafka Outbox messaging · Keycloak OIDC security · Strict tenant schema isolation · React Native Expo mobile apps · Python FastAPI microservices · Next.js 14 App Router frontend.

What's Included

  • 15 domain service modules — Academics, Admissions, Attendance, Finance, Examinations, LMS, Library, Transport, Hostel, HRMS, Inventory, CRM, Communication, Security, Analytics
  • 7 role-based portals — Super Admin, School Owner, Principal, Teacher, Student, Parent, Accountant
  • Native mobile apps — React Native Expo for Android and iOS
  • REST + GraphQL APIs — Full programmatic access for integrations
  • Multi-tenant isolation — Strict per-school data separation

System Requirements

ComponentMinimumRecommended (Production)
CPU4 vCPU16 vCPU (AWS c5.4xlarge)
RAM8 GB32 GB
PostgreSQLv15+v16 with RDS Multi-AZ
Redis / CacheRedis 7.0AWS ElastiCache
Message BrokerKafka 3.6Amazon MSK
Container RuntimeDocker Engine 24.0+AWS ECS Fargate
Node.jsv20.0.0 LTSv20.10.0 LTS
Python3.113.12
Storage100 GB SSD1 TB S3 + EBS gp3

Installation

Prerequisites

  • Git 2.39+
  • Node.js v20.10.0 LTS (use nvm use 20)
  • Python 3.12
  • Docker Engine 24.0+ and Docker Compose v2.20+
  • PostgreSQL 15+ (or Docker image)

Clone and Setup

# 1. Clone the monorepo
git clone https://github.com/Asadxio/my-school-education-os.git
cd my-school-education-os

# 2. Install all Node.js dependencies (monorepo workspaces)
npm install

# 3. Copy environment configuration
cp .env.example .env
# Edit .env with your DB credentials, Keycloak settings, and API keys

# 4. Start infrastructure services (PostgreSQL, Kafka, Keycloak)
docker compose -f docker-compose.dev.yml up -d postgres kafka keycloak

# 5. Run database migrations
cd services/academic-service
alembic upgrade head

# 6. Start all services
npm run dev:web         # Next.js frontend on :3000
npm run dev:mobile      # Expo mobile on :19000

Environment Variables

VariableDescriptionExample
DATABASE_URLPostgreSQL connection stringpostgresql://user:pass@localhost:5432/myschool
KEYCLOAK_URLKeycloak server base URLhttp://localhost:8080
KEYCLOAK_REALMKeycloak realm namemyschool
KAFKA_BOOTSTRAP_SERVERSKafka broker addresseslocalhost:9092
NEXT_PUBLIC_API_BASE_URLFastAPI backend URLhttp://localhost:8000
RAZORPAY_KEY_IDRazorpay API keyrzp_test_...
TWILIO_ACCOUNT_SIDTwilio WhatsApp SIDAC...

Quickstart Guide

Tip: Use the make bootstrap command after cloning to run the full setup automatically including Docker services, migrations, and seed data.
# One-command bootstrap (requires Docker)
make bootstrap

# This runs:
# - docker compose up -d
# - alembic upgrade head on all services
# - npm run seed (loads demo school data)
# - npm run dev:web

Default Login Credentials (Development)

RoleUsernamePassword
Super Adminsuperadmin@demo.myschoolDemo@1234!
School Ownerowner@demo.myschoolDemo@1234!
Principalprincipal@demo.myschoolDemo@1234!
Teacherteacher@demo.myschoolDemo@1234!
Studentstudent@demo.myschoolDemo@1234!
Parentparent@demo.myschoolDemo@1234!

Microservices Architecture

The platform is composed of independently deployable Python FastAPI microservices, each owning its domain data. Services communicate asynchronously via Kafka events and synchronously via the API Gateway for read-heavy requests.

Core Services

ServicePortResponsibilityDatabase Schema
academic-service8001Courses, timetables, grading, GPAacademics
admissions-service8002Applications, enrollment pipelineadmissions
finance-service8003Fees, invoices, payment gatewayfinance
attendance-service8004Attendance records, alert triggersattendance
lms-service8005Courses, assignments, submissionslms
hrms-service8006Staff, payroll, leavehrms
transport-service8007Routes, vehicles, GPS trackingtransport
notification-service8008SMS, WhatsApp, email, pushnotifications
api-gateway8000Routing, auth, tenant context

Kafka Transactional Outbox Pattern

To guarantee zero data loss between microservices, My School OS implements the Transactional Outbox Pattern. Instead of publishing events directly to Kafka (which can fail after a DB commit), domain events are written atomically to an outbox_events table in the same transaction as the business data.

Flow

  1. Service writes business record + outbox event in a single DB transaction.
  2. A background Relay worker polls outbox_events for unpublished rows.
  3. Relay publishes each event to the appropriate Kafka topic.
  4. Consumer services process events (e.g., Notification Service sends WhatsApp alert).
  5. On successful publish, outbox_events.published_at is stamped.
-- outbox_events table structure
CREATE TABLE outbox_events (
  id           UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id    UUID NOT NULL,
  aggregate    VARCHAR(64) NOT NULL,  -- e.g. 'student_attendance'
  event_type   VARCHAR(64) NOT NULL,  -- e.g. 'ATTENDANCE_MARKED'
  payload      JSONB NOT NULL,
  created_at   TIMESTAMPTZ DEFAULT NOW(),
  published_at TIMESTAMPTZ
);

Multi-Tenancy Isolation

Every API request must carry an X-Tenant-ID header (UUID format). The API Gateway validates this against the authenticated user's Keycloak token claims, then injects it into the RequestContext passed to every downstream service.

Security Enforcement: Every database query in every service automatically appends WHERE tenant_id = :tenant_id. No cross-tenant data access is possible at the query layer.

Tenant Context Flow

# FastAPI dependency injection pattern
from app.core.context import TenantContext

async def get_tenant_context(request: Request) -> TenantContext:
    tenant_id = request.headers.get("X-Tenant-ID")
    if not tenant_id:
        raise HTTPException(status_code=400, detail="X-Tenant-ID header required")
    return TenantContext(tenant_id=UUID(tenant_id))

Authentication (Keycloak OIDC)

Authentication is handled by Keycloak 24 using the OpenID Connect (OIDC) protocol. The Next.js frontend redirects unauthenticated users to the Keycloak login page. After successful authentication, Keycloak issues a JWT access token that is stored in the browser and included in every API request.

Token Flow

  1. User accesses /dashboard — Next.js AppShell detects no token in localStorage.
  2. Redirect to /login page.
  3. User enters credentials — POST to Keycloak Token Endpoint.
  4. Keycloak returns access_token (JWT, 15 min expiry) + refresh_token (7 days).
  5. Frontend stores tokens — API client includes Authorization: Bearer <token>.
  6. Token refresh happens silently every 13 minutes.

JWT Payload (Example)

{
  "sub": "a3f...uuid",
  "preferred_username": "teacher@demo.myschool",
  "realm_access": { "roles": ["teacher"] },
  "tenant_id": "b7e...uuid",
  "exp": 1723000000
}

Role-Based Access Control (RBAC)

Platform access is enforced at the API Gateway using Keycloak realm roles. Each role maps to a set of allowed endpoints and UI portal paths.

Role Definitions

RolePortal PathKey Permissions
super_admin/app/superadminFull platform access, tenant management, billing
school_owner/app/schoolownerSchool config, staff hiring, financial reports
principal/app/principalAcademic management, timetables, staff oversight
teacher/app/teacherAttendance entry, grade submission, LMS content
student/app/studentView attendance, grades, fees, LMS courses
parent/app/parentChild's attendance, fee payment, notifications
accountant/app/financeFull finance module, fee collection, payroll

PostgreSQL Schema

All services share a single PostgreSQL cluster but use isolated schemas per domain. Every table includes tenant_id UUID NOT NULL as a row-level isolation key.

Primary Tables

TableSchemaPurpose
tenantspublicSchool/institution registry
studentsacademicsStudent enrollment records
coursesacademicsSubject and course catalogue
attendance_recordsattendanceDaily attendance per student
fee_invoicesfinanceFee invoices and payment status
staffhrmsEmployee master records
lms_courseslmsOnline course content
outbox_eventspublicKafka outbox relay queue

Alembic Migrations

# Apply all pending migrations
alembic upgrade head

# Roll back one migration
alembic downgrade -1

# Roll back to specific revision
alembic downgrade abc123def456

# Generate a new migration from model changes
alembic revision --autogenerate -m "add_student_gpa_column"

# Check current revision
alembic current

# View migration history
alembic history --verbose
Production Rule: Never run alembic downgrade on a live database without a full backup. Always test migrations on a staging environment first.

Backup & Restore

Automated Backups

Production databases use AWS RDS with automatic daily backups retained for 30 days. Point-in-time recovery (PITR) is enabled.

Manual Backup

# Full database dump
pg_dump -h localhost -U myschool_user -d myschool_prod \
  --format=custom --compress=9 \
  -f backup_$(date +%Y%m%d_%H%M%S).dump

# Upload to S3
aws s3 cp backup_*.dump s3://myschool-backups/postgres/ \
  --sse aws:kms

Restore Procedure

# 1. Download backup from S3
aws s3 cp s3://myschool-backups/postgres/backup_20260808.dump .

# 2. Stop application services
docker compose stop app

# 3. Restore database
pg_restore -h localhost -U myschool_user -d myschool_prod \
  --clean --if-exists backup_20260808.dump

# 4. Restart services
docker compose start app

REST API Reference

Required Headers

Authorization: Bearer <access_token>
X-Tenant-ID: <tenant_uuid>
Content-Type: application/json

SDK & Code Snippets

curl -X GET "https://api.myschoolos.com/v1/academics/students" \
  -H "Authorization: Bearer <access_token>" \
  -H "X-Tenant-ID: <tenant_uuid>"

Academics Endpoints

MethodEndpointDescriptionRoles
GET/academics/studentsList studentsadmin, teacher
POST/academics/studentsEnroll studentadmin
GET/academics/coursesList coursesall
POST/academics/attendanceRecord attendanceteacher

🧪 Interactive API Request Playground

Request: GET https://api.myschoolos.com/v1/academics/students?limit=1
// Click "Run Sample" to execute live mock payload

Finance Endpoints

MethodEndpointDescription
POST/finance/invoicesCreate fee invoice
GET/finance/invoices/{id}Get invoice details
POST/finance/payments/razorpayInitiate Razorpay payment
POST/finance/payments/webhookRazorpay webhook handler

GraphQL Gateway

The GraphQL gateway aggregates data from all microservices into a unified schema. Use it for complex multi-entity queries that would require multiple REST calls.

# Example: Fetch student profile with attendance summary
query StudentDashboard($studentId: ID!) {
  student(id: $studentId) {
    id
    fullName
    rollNumber
    attendanceSummary {
      presentDays
      absentDays
      percentage
    }
    feeStatus {
      totalDue
      totalPaid
      pendingAmount
    }
    currentGPA
  }
}

Interactive GraphQL Query Playground

// Click "Execute GraphQL Query" to see live schema result

Docker Setup

Development Stack

# Start full development environment
docker compose -f docker-compose.dev.yml up -d

# Services started:
# - postgres:16       → localhost:5432
# - redis:7           → localhost:6379
# - kafka:3.6         → localhost:9092
# - zookeeper         → localhost:2181
# - keycloak:24       → localhost:8080
# - mailhog           → localhost:1025 (SMTP) / 8025 (UI)

Production Build

# Build all service images
docker compose -f docker-compose.prod.yml build

# Deploy with rolling update
docker compose -f docker-compose.prod.yml up -d --no-downtime

# Scale a specific service
docker compose up -d --scale academic-service=3

AWS Infrastructure

Architecture Components

AWS ServicePurpose
ECS FargateServerless container orchestration for all microservices
RDS PostgreSQLMulti-AZ managed database with automated backups
ElastiCache RedisSession cache and API response caching
Amazon MSKManaged Kafka for event-driven outbox messaging
ALBApplication Load Balancer for service routing
S3File storage, database backups, exported reports
CloudFrontCDN for static frontend assets
Route 53DNS management and health checks
ACMFree SSL/TLS certificate management

CI/CD Pipeline

# .github/workflows/deploy.yml (overview)
on:
  push:
    branches: [main]

jobs:
  test:
    - npm run typecheck
    - pytest services/ --cov
    - npx playwright test

  build:
    - docker build + push to ECR

  deploy:
    - aws ecs update-service (rolling deploy)
    - alembic upgrade head (migrations)
    - Netlify deploy (frontend)

Deployment Environments

EnvironmentBranchURL
Developmentmainlocalhost
Stagingstagingstaging.myschoolos.com
Productionmain (tagged)app.myschoolos.com

School Administrator Guide

Daily Operations

  • Dashboard: Navigate to /app/principal after login to view the school overview dashboard.
  • Attendance Review: Go to Attendance → Today's Summary to see real-time class-wise attendance percentages.
  • Timetable Management: Use Academics → Timetables to create and edit period schedules for each class.
  • Academic Calendar: Set term dates, exam schedules, and holidays in Academics → Calendar.

Student Management

  • Enroll new students via Admissions → New Application.
  • Transfer or withdraw students in Academics → Students → Actions.
  • Generate TC (Transfer Certificate) from the student record page.

Teacher Guide

Marking Attendance

  1. Log in and navigate to Attendance → Mark Today.
  2. Select your class and subject from the dropdown.
  3. Click each student's name to toggle Present/Absent.
  4. Click Submit Attendance — parents are automatically notified via WhatsApp for absent students.

Entering Grades

  1. Navigate to Examinations → Grade Entry.
  2. Select the exam, class, and subject.
  3. Enter marks for each student in the grid.
  4. Click Save Grades — GPA is calculated automatically.

LMS Course Management

  • Create assignments in LMS → My Courses → Assignments → Add.
  • Upload study materials (PDF, video link) in the Course Content section.
  • Review student submissions and enter scores.

Student Guide

Accessing Your Dashboard

Log in at educationos-app.netlify.app/login with your student credentials provided by your school. Your dashboard shows attendance summary, pending fees, upcoming exams, and recent grades.

Viewing Attendance

Go to Attendance → My Record to view your monthly attendance chart and identify any days marked absent.

Fee Payment

  1. Navigate to Finance → My Fees.
  2. Click on a pending invoice.
  3. Click Pay Now — you'll be directed to the Razorpay payment page.
  4. A PDF receipt is sent to your registered email and parent's WhatsApp automatically.

Parent Guide

Mobile App Setup

  1. Download MySchool OS Parent App from Google Play Store or Apple App Store.
  2. Enter your registered mobile number and OTP to sign in.
  3. If you have multiple children, switch between them using the profile selector.

What You Can Do

  • ✅ View daily attendance in real time
  • ✅ Receive push notifications for absences immediately
  • ✅ Pay school fees via UPI, card, or net banking
  • ✅ Download fee receipts as PDF
  • ✅ View term report cards and exam results
  • ✅ Read school announcements and circulars
  • ✅ Track child's school bus location (GPS)

School Owner Guide

Executive Dashboard

Log in at /app/schoolowner to access the School Owner Executive Dashboard with real-time KPIs:

  • Total enrolled students vs. capacity
  • Monthly fee collection vs. outstanding
  • Attendance rate school-wide
  • Staff payroll summary
  • New admissions pipeline funnel

Financial Reports

Navigate to Finance → Reports to download:

  • Monthly Collection Report (PDF)
  • Outstanding Fee Arrears Report
  • Term-wise Income Statement
  • Scholarship Disbursement Summary

Troubleshooting

Login / Auth Issues

SymptomCauseSolution
"401 Unauthorized" on all API callsAccess token expiredClear localStorage and log in again; check token refresh interval
Redirect loop on /loginMissing KEYCLOAK_URL env varVerify .env has correct Keycloak URL and realm
Role not recognizedMissing Keycloak realm roleAssign correct role in Keycloak Admin Console → Users → Role Mappings

Database Issues

SymptomSolution
Migration lock error on alembic upgradeRun SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE state = 'idle in transaction'
Connection pool exhaustedIncrease pool_size in SQLAlchemy settings; check for unclosed sessions

Build Issues

# Next.js build fails with TypeScript errors
npm run typecheck --workspace=apps/web  # Check errors
# The project has ignoreBuildErrors: true for production builds

# npm install fails in monorepo
rm -rf node_modules package-lock.json
npm install  # Fresh install

Developer FAQ

How do I add a new microservice?

Copy the services/template-service/ folder, rename it, add it to docker-compose.yml, create an Alembic migration for its schema, and register its routes in the API Gateway router.

Can I use the REST API without the frontend?

Yes. All endpoints are available at https://api.myschoolos.com/v1/ with a valid Bearer token and X-Tenant-ID header. The Swagger UI is available at /docs.

How do I reset the development database?

docker compose stop postgres
docker volume rm myschool_postgres_data
docker compose up -d postgres
alembic upgrade head
npm run seed

How do webhooks work for Razorpay payments?

Configure your Razorpay webhook to POST to /finance/payments/webhook. The service verifies the signature using your RAZORPAY_WEBHOOK_SECRET env var and marks the invoice as paid.

Release Notes

v1.0.0 — August 2026 Current

Initial Commercial Release

  • 15 fully implemented domain modules
  • 7 role-based portals with Keycloak OIDC
  • Razorpay + Stripe payment gateway integration
  • Twilio WhatsApp + SMS notification hub
  • React Native Expo mobile apps (Android + iOS)
  • Kafka Transactional Outbox pattern
  • Alembic database migrations
  • Playwright E2E test suite
  • AWS ECS + RDS production infrastructure
  • Next.js 14 App Router frontend with Tailwind CSS
Roadmap (v1.1 — Q4 2026): Biometric attendance device integration · AI-powered fee defaulter prediction · Parent-Teacher meeting scheduling module · WhatsApp chatbot for fee queries