$ cat ~/projects/erudia/README.md

Erudia

★ Featured

K-12 school management SaaS

One backend, thousands of schools. End-to-end multi-tenant school SaaS.

Status
In development
Role
Architect & Full-Stack Lead
Period
2024 — 2025
Client
Santa Rita School (Chosica) — anchor client
1
instance for N schools
4
domain modules
<5min
onboarding per school

# Overview

Erudia is a multi-tenant SaaS platform that digitizes the entire operation of a K-12 school. Each school lives on its own subdomain (school.erudia.app) with logically isolated data over a single PostgreSQL database, allowing hundreds of institutions to run from one instance at minimal marginal cost. The backend is a NestJS modular monolith with Clean Architecture, and the frontend an Angular 20 panel with PrimeNG. It covers QR/photo attendance, grade books, treasury with Peruvian SUNAT e-invoicing and a virtual classroom.

! The problem

Mid-size schools in Peru manage attendance, grades and collections with notebooks, Excel and WhatsApp. There is no traceability, enrollments get lost and collections are manual. Existing solutions are expensive, monolithic and require one server per school.

The solution

A multi-tenant SaaS where onboarding a school = one record + one subdomain, with no new infrastructure to deploy. Per-tenant isolation on every query, a JWT carrying the tenant, and decoupled modules toggled by plan. Onboarding a school takes minutes, not weeks.

# Features

QR + photo attendance

Student QR check-in with optional photo verification; real-time guardian notification.

Grade book

Configurable periods, competencies and averages per level; export to official PDF.

Treasury + e-invoicing

Per-student statements, payments and electronic invoicing integrated with SUNAT.

Virtual classroom

Assignments, materials and teacher-guardian communication in one place.

Subdomain multi-tenancy

Host-based tenant resolution, data isolation and per-school branding.

BullMQ queues

Notifications, PDF generation and SUNAT submissions processed asynchronously and resiliently.

# Architecture

NestJS modular monolith with Clean Architecture: each domain module (Enrollment, Attendance, Grades, Treasury) exposes use cases and hides its persistence. A cross-cutting layer carries the tenant across every request and guarantees that each query is scoped to its school, without each use case having to remember it. Heavy work (PDFs, notifications, invoicing) is processed asynchronously through queues.

Components
01 Angular 20 + PrimeNG Admin & teacher panel SPA
02 NestJS API Modular monolith, REST + multi-tenant JWT
03 PostgreSQL 16 + pgvector Relational data and semantic search
04 Redis + BullMQ Queues: notifications, PDFs, SUNAT
05 Docker + Traefik Subdomain routing and automatic TLS

# Tech stack

Frontend
Angular 20PrimeNG 18RxJSSignals
Backend
NestJSTypeScriptClean ArchitectureJWT
Datos
PostgreSQL 16pgvectorRedisBullMQ
Infra
DockerTraefikWatchtowerCI/CD
TypeScript 78%
SQL 14%
Otros 8%

# Learnings

  • Tenant isolation must live in a cross-cutting layer (interceptor/middleware), never in each use case: a single controlled point of failure.
  • A well-bounded modular monolith gives 90% of the microservices benefits with 10% of the operational complexity.
  • Queues are not a luxury: SUNAT invoicing and notifications outside the request are the difference between a smooth UI and timeouts.

# Roadmap

Mobile app for guardians (attendance & grades)
AI reports on per-classroom performance
Marketplace of assessment templates

Useful for your business?

This solution can be adapted to your organization. Share the project or reach out to discuss it.

Let's talk →