A microservice-based learning management system built for Paragon International University's English Preparatory Program, giving lecturers full control over content delivery and students flexible progression.

How It Works
Bulk-uploads students and lecturers via CSV, triggering automatic invite emails
Structures lessons and assessments, choosing self-paced or scheduled delivery
Works through lessons behind an assessment-wall that unlocks material on mastery
Director and lecturer dashboards track individual and class-wide progress live
Capabilities
Code Sample
// RBAC middleware enforced via Open Policy Agent
func RequireRole() gin.HandlerFunc {
return func(c *gin.Context) {
claims, ok := c.Get("jwt_claims")
if !ok {
c.AbortWithStatusJSON(401, gin.H{"error": "unauthenticated"})
return
}
user := claims.(*auth.Claims)
allowed := opa.Evaluate(user.Role, c.FullPath(), c.Request.Method)
if !allowed {
c.AbortWithStatusJSON(403, gin.H{"error": "forbidden"})
return
}
c.Next()
}
}Technical Deep Dive
Problem
Google Classroom couldn't support an assessment-wall or mixed self-paced and lecturer-controlled progression
Solution
Designed a configurable progression engine so lecturers toggle between self-paced and scheduled delivery per class
Problem
Coordinating 10 engineers across frontend, backend, API, UI/UX, and DevOps under a fixed 2-month, budget-capped timeline
Solution
Ran 2-week Agile Scrum sprints with clear service ownership and a single source of truth maintained with the tech lead
Problem
Keeping independent Go microservices and their own databases in sync without tight coupling
Solution
Adopted an event-driven architecture with RabbitMQ and Redis caching, so services react to events instead of polling each other
Architecture
Role-specific panels for director, lecturer, and student, built with Next.js and Tailwind CSS, calling the API through Kong.
Validates JWTs, enforces coarse RBAC, and rate-limits traffic before routing REST requests to backend services.
Independent user, course, assessment, and grading services communicating over gRPC, each backed by its own PostgreSQL database.
OpenTelemetry collects logs, metrics, and traces into Loki, Prometheus, and OpenSearch for live troubleshooting.