Skip to content

Technology Stack Analysis

1. Summary

This document provides a comparative analysis of technology stacks, hosting solutions, and managed services for the SIS platform. The analysis is based on the current project status and priorities:

  • MVP Scope: Student and teacher management, roles/permissions system
  • Critical Requirement: Multitenancy architecture from day one
  • Goals: Minimize administrative overhead, reduce manual intervention, faster resolution
  • Deferred: External integrations, scalability optimization

2. Project Constraints & Requirements

2.1 Functional Requirements (MVP)

Requirement Impact on Stack
Complex relational data model (20+ entities) Needs robust ORM with migrations
RBAC with 12+ roles Framework with middleware/guard support
Document uploads Object storage integration
i18n (Italian/English) Framework-level i18n support
Audit logging Database triggers or application-level hooks

2.2 Non-Functional Requirements

Requirement Impact on Stack
Multitenancy Schema-per-tenant OR row-level isolation
GDPR compliance Data isolation, consent management, audit trails
Response time <500ms Adequate for any modern framework
WCAG 2.1 AA Frontend framework with a11y support

2.3 Team & Budget Assumptions

  • Small team (2-4 developers)
  • Preference for managed services to reduce ops overhead
  • No dedicated DevOps initially

3. Backend Framework Analysis

3.1 NestJS (Node.js + TypeScript)

Runtime: Node.js 20+
Language: TypeScript
Framework: NestJS 10+
ORM: Prisma 5+

Architecture Fit:

Aspect Assessment
RBAC Built-in Guards and decorators (@Roles(), @Permissions())
Multitenancy Prisma supports schema-per-tenant via $extends
API Generation OpenAPI/Swagger auto-generation
Validation class-validator with DTOs
Testing Jest integration out of box

Pros: - Single language frontend + backend accelerates development - Prisma provides type-safe database access with excellent migration tooling - Modular architecture aligns with domain separation (students, teachers, admissions) - Large npm ecosystem for utilities - Excellent IDE support (VS Code)

Cons: - Multitenancy requires custom implementation or third-party packages - Node.js memory management needs attention for large data exports - Prisma has some limitations with complex raw queries


3.2 Django (Python)

Runtime: Python 3.11+
Framework: Django 5+ with Django REST Framework
ORM: Django ORM
Multitenancy: django-tenants

Architecture Fit:

Aspect Assessment
RBAC django-guardian for object-level permissions
Multitenancy django-tenants is production-proven
API Generation drf-spectacular for OpenAPI
Validation Serializers + model validation
Admin UI Django Admin included

Pros: - Django Admin provides immediate back-office interface - django-tenants is the most mature multitenancy solution available - Excellent for data-heavy applications - Built-in i18n framework - Strong ORM for complex queries

Cons: - Two languages in stack (Python + JavaScript for frontend) - Django REST Framework adds boilerplate - Async support is newer and less mature - Deployment slightly more complex (WSGI/ASGI servers)


3.3 ASP.NET Core (C#)

Runtime: .NET 8
Framework: ASP.NET Core + ABP Framework (optional)
ORM: Entity Framework Core

Architecture Fit:

Aspect Assessment
RBAC ASP.NET Identity + Policy-based authorization
Multitenancy ABP Framework or Finbuckle.MultiTenant
API Generation Swashbuckle/NSwag
Validation Data annotations + FluentValidation
Admin UI ABP includes admin module

Pros: - ABP Framework includes multitenancy, audit logging, RBAC out of box - Excellent performance characteristics - Strong enterprise tooling and debugging - Entity Framework migrations are robust

Cons: - ABP has steep learning curve - Smaller web ecosystem compared to Node/Python - Team expertise requirement - Higher memory consumption


3.4 Go

Runtime: Go 1.21+
Framework: Gin or Echo
ORM: GORM or sqlc
RBAC: Casbin

Architecture Fit:

Aspect Assessment
RBAC Casbin is powerful but requires setup
Multitenancy Manual implementation required
API Generation swaggo/swag
Validation go-playground/validator

Pros: - Single binary deployment - Lowest resource consumption - Casbin is a powerful policy engine - Excellent for future microservices

Cons: - Slowest development velocity for CRUD - Most multitenancy work is manual - Verbose for rapid prototyping - Smaller talent pool for web development


3.5 Backend Comparison Matrix

Criterion NestJS Django ASP.NET Go
Dev Speed ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐
RBAC Maturity ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐
Multitenancy ⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐
Complex Relations ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐
Type Safety ⭐⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
Ecosystem ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐
Hiring Pool ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐

4. Database Analysis

5.1 PostgreSQL

Capabilities: - Row-level security for multitenancy - Schema-per-tenant support - JSONB for flexible custom fields - Excellent with Prisma/TypeORM/Django ORM - Free and open source

Multitenancy Strategies:

Strategy Pros Cons
Schema-per-tenant Strong isolation, easy backup/restore per tenant More complex migrations, connection pooling
Row-level security Single schema, simpler ops Requires careful policy management
Separate databases Maximum isolation Highest operational overhead

5.2 Other Databases

Database Notes
MySQL Viable but weaker schema/RLS support
SQL Server Good features but licensing costs apply
MongoDB NoSQL - different paradigm from relational model
CockroachDB Distributed SQL, higher complexity

6. Managed Services & BaaS Analysis

6.1 Supabase

Includes: PostgreSQL, Auth, Storage, Edge Functions, Realtime
Aspect Assessment
Database PostgreSQL with automatic backups
Auth Built-in with RLS integration
Storage S3-compatible for documents
Multitenancy RLS-based (row-level), not schema-per-tenant

Pros: - Fast time to market - Auth + Storage + DB in one platform - Row-level security is first-class

Cons: - RLS-based multitenancy only (not schema isolation) - Vendor lock-in concerns - Edge Functions less mature than dedicated backend


6.2 Firebase / Google Cloud

Includes: Firestore/RTDB, Auth, Storage, Cloud Functions
Aspect Assessment
Database Firestore (NoSQL) or Cloud SQL (PostgreSQL)
Auth Firebase Auth is mature
Storage Google Cloud Storage
Multitenancy Manual implementation

Pros: - Firebase Auth is mature - Real-time capabilities built-in - Google Cloud SQL for PostgreSQL

Cons: - Firestore is NoSQL (different paradigm for relational data) - Cloud SQL + Firebase = multiple services to manage


6.3 AWS Amplify

Includes: Cognito, AppSync/API Gateway, DynamoDB/RDS, S3
Aspect Assessment
Database RDS PostgreSQL or DynamoDB
Auth Cognito (complex but powerful)
Storage S3
Multitenancy Manual with RDS, or DynamoDB partitioning

Pros: - Enterprise-grade infrastructure - RDS PostgreSQL is solid - S3 for document storage

Cons: - Cognito has steep learning curve - Amplify abstractions can be limiting


6.4 Neon (Serverless PostgreSQL)

Includes: PostgreSQL only (serverless)
Aspect Assessment
Database PostgreSQL with branching
Auth Not included
Storage Not included
Multitenancy Full PostgreSQL schema support

Pros: - True PostgreSQL with all features - Database branching for dev/preview environments - Schema-per-tenant works fully - Scales to zero

Cons: - Database only - need separate auth/storage - Cold starts on free tier - Newer service


6.5 PlanetScale

Includes: MySQL-compatible serverless database
Aspect Assessment
Database MySQL (Vitess)
Branching Yes, with safe migrations
Multitenancy Schema-per-tenant possible

Pros: - Excellent branching and migration workflow - Good performance

Cons: - MySQL not PostgreSQL - Foreign key constraints had limitations (now resolved)


6.6 Managed Services Comparison

Service DB Type Auth Storage Multitenancy
Supabase PostgreSQL Yes Yes RLS-based
Firebase NoSQL/SQL Yes Yes Manual
AWS Amplify PostgreSQL/DynamoDB Yes Yes Manual
Neon PostgreSQL No No Schema-per-tenant
PlanetScale MySQL No No Schema-per-tenant

7. Hosting & Deployment Analysis

7.1 Railway

Type: PaaS
Supports: Node.js, Python, Go, Docker, PostgreSQL, Redis
Aspect Assessment
Ease of Deploy Git push deployment
PostgreSQL Managed, included
Scaling Vertical + horizontal
Region US, EU

Pros: - Simple deployment experience - Managed PostgreSQL included - Preview environments per PR - Good logging and monitoring

Cons: - Smaller than major clouds - Limited regions - No built-in CDN


7.2 Render

Type: PaaS
Supports: Node.js, Python, Go, Docker, PostgreSQL
Aspect Assessment
Ease of Deploy Git push deployment
PostgreSQL Managed, free tier available
Scaling Automatic
Region US, EU, Singapore

Pros: - Free tier available for testing - PostgreSQL included - Auto-scaling available - Preview environments

Cons: - Free tier has cold starts - Less intuitive UI than Railway


7.3 Fly.io

Type: Edge PaaS
Supports: Docker, PostgreSQL (via Fly Postgres)
Aspect Assessment
Ease of Deploy Dockerfile required
PostgreSQL Fly Postgres (managed)
Scaling Global edge deployment
Region Global (30+ regions)

Pros: - Global edge deployment - Free tier available - Supports any Docker container

Cons: - Requires Docker knowledge - Fly Postgres is self-managed (not fully managed) - Steeper learning curve


7.4 Vercel

Type: Frontend PaaS + Serverless Functions
Supports: Next.js, static sites, serverless
Aspect Assessment
Ease of Deploy Git push, instant
Backend Serverless functions only
Database External only (Vercel Postgres is Neon)

Pros: - Best-in-class for Next.js - Excellent preview deployments - Edge functions available

Cons: - Not suitable for traditional backend (NestJS, Django) - Database is external - Per-seat pricing model


7.5 Traditional Cloud (AWS/GCP/Azure)

Aspect Assessment
Flexibility Maximum
Managed Services Extensive
DevOps Required Yes

Notes: Requires dedicated DevOps expertise. Suitable for scale phase with Kubernetes.


7.6 Cloudflare Workers

Type: Edge Serverless Platform
Runtime: V8 Isolates (NOT Node.js)
Aspect Assessment
Ease of Deploy Wrangler CLI, Git integration
Backend Support JavaScript/TypeScript only (no Node.js APIs)
Database D1 (SQLite), or external via HTTP
Region Global edge (300+ locations)

Critical Limitation: NestJS Incompatibility

Cloudflare Workers uses V8 isolates, not Node.js. This means:

NestJS Dependency Workers Support Issue
Express/Fastify No Requires Node.js http module
Prisma ORM No Requires Node.js runtime
File System No No fs module
Native modules No No node_modules with native bindings

Alternative Frameworks for Workers:

Framework Workers Compatible Trade-offs
Hono Yes No DI, no decorators, lighter weight
itty-router Yes Minimal, no validation built-in
ElysiaJS No (Bun only) -

Database Options on Workers:

Database Workers Support Notes
Cloudflare D1 Yes (native) SQLite-based, no schema-per-tenant
Neon (HTTP) Yes (via driver) Adds latency
PlanetScale Yes (HTTP driver) MySQL, not PostgreSQL
Prisma Accelerate Yes (proxy) Adds latency

Note: Cloudflare Workers is not compatible with NestJS and Prisma. Cloudflare services can be used for other layers (see Hybrid Architecture).


7.8 Hosting Comparison Matrix

Platform Setup Ease PostgreSQL Scaling DevOps Need
Railway ⭐⭐⭐⭐⭐ Included Good None
Render ⭐⭐⭐⭐⭐ Included Good None
Fly.io ⭐⭐⭐ Included* Excellent Low
Vercel ⭐⭐⭐⭐⭐ External Auto None
DigitalOcean ⭐⭐⭐⭐ Included Manual Low
CF Workers ⭐⭐⭐⭐ D1 only Excellent Low
AWS/GCP/Azure ⭐⭐ Yes Unlimited High

8. Hybrid Cloudflare Architecture

A hybrid architecture leverages Cloudflare's edge services while hosting the core backend elsewhere. This approach addresses Cloudflare Workers' limitations for Node.js-based backends.

8.1 Architecture Overview

┌─────────────────────────────────────────────────────────────────────────┐
│                         CLOUDFLARE EDGE                                  │
│  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐         │
│  │ Cloudflare CDN  │  │ Cloudflare WAF  │  │  DDoS Protection │         │
│  │ (Static Assets) │  │ (Security)      │  │                  │         │
│  └────────┬────────┘  └────────┬────────┘  └────────┬────────┘         │
│           │                    │                    │                   │
│  ┌────────▼────────────────────▼────────────────────▼────────┐         │
│  │                    Cloudflare DNS                          │         │
│  │              (Proxy mode enabled for API)                  │         │
│  └────────────────────────────┬──────────────────────────────┘         │
└───────────────────────────────┼─────────────────────────────────────────┘
        ┌───────────────────────┼───────────────────────┐
        │                       │                       │
        ▼                       ▼                       ▼
┌───────────────┐      ┌───────────────┐      ┌───────────────┐
│   FRONTEND    │      │    BACKEND    │      │    STORAGE    │
│               │      │               │      │               │
│ Cloudflare    │      │ PaaS Provider │      │ Cloudflare R2 │
│ Pages         │      │ (Railway,     │      │               │
│               │      │  Render, etc) │      │ (S3-compat)   │
│ React SPA     │      │               │      │               │
│ Static build  │      │ NestJS API    │      │ Documents,    │
│               │      │ + Prisma      │      │ Uploads       │
└───────────────┘      └───────┬───────┘      └───────────────┘
                      ┌───────────────┐
                      │   DATABASE    │
                      │               │
                      │ PostgreSQL    │
                      │ (Managed)     │
                      └───────────────┘

8.4 Architecture Approaches Comparison

Approach Pros Cons
Full Cloudflare (Workers + D1) Lowest latency, simplest ops Can't use NestJS/Prisma, limited DB
Hybrid Cloudflare NestJS compatible, edge benefits Multiple providers to manage
Single PaaS (Railway/Render only) Simplest architecture No edge caching, no CDN
Vercel + External API Great DX for Next.js Per-seat pricing, separate backend needed

9. Authentication Services

9.1 Clerk

Type: Authentication as a Service

Pros: - Developer-friendly experience - Pre-built React components - Organizations & RBAC built-in - Free tier available (10k MAU)

Cons: - Pricing scales with users - Less control than self-hosted


9.2 Auth0

Type: Authentication as a Service

Pros: - Enterprise-grade - Extensive customization - RBAC and organizations

Cons: - Complex pricing structure - Can be complex for simple use cases


9.3 Self-Hosted (Passport.js / Django Auth)

Pros: - Full control - No per-user costs - Data stays in your DB

Cons: - Security responsibility on team - More development time


10. Stack Combinations

10.1 NestJS + React + Hybrid Cloudflare

┌─────────────────────────────────────────────────────────────────┐
│                      CLOUDFLARE EDGE                             │
│  DNS (Proxied) + CDN + WAF + DDoS Protection                    │
└──────────────────────────┬──────────────────────────────────────┘
       ┌───────────────────┼───────────────────┐
       │                   │                   │
       ▼                   ▼                   ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│    FRONTEND     │ │     BACKEND     │ │     STORAGE     │
│                 │ │                 │ │                 │
│ Cloudflare      │ │ NestJS + Prisma │ │ Cloudflare R2   │
│ Worker          │ │                 │ │                 │
│                 │ │ Hosted on:      │ │ S3-compatible   │
│ React 18 +      │ │ Railway or      │ │                 │
│ TypeScript +    │ │ Render          │ │ Documents,      │
│ TanStack Query  │ │                 │ │ Uploads         │
│ + shadcn/ui     │ │                 │ │                 │
└─────────────────┘ └────────┬────────┘ └─────────────────┘
                    ┌─────────────────┐
                    │    DATABASE     │
                    │                 │
                    │ PostgreSQL      │
                    │ Schema-per-     │
                    │ tenant          │
                    └─────────────────┘

Components: - Frontend: Cloudflare Pages with React 18 + TypeScript + TanStack Query + shadcn/ui - Backend: NestJS + Prisma on Railway or Render - Database: PostgreSQL with schema-per-tenant multitenancy - Storage: Cloudflare R2 - Auth: Clerk (managed) or self-hosted (Passport.js + JWT) - Email: Resend or SendGrid - Edge Logic (optional): Cloudflare Workers for tenant resolution


10.2 Django Stack

Backend: Django 5 + DRF + django-tenants
Frontend: React or Vue.js
Database: PostgreSQL (schema-per-tenant via django-tenants)
Hosting: Railway or Render
Auth: Django built-in + django-guardian

Trade-off: Django Admin provides immediate back-office functionality but requires managing two languages (Python + JavaScript).


11. Migration Path

Phase 1: MVP

Architecture: NestJS monolith on Railway
Database:     Managed PostgreSQL (Railway) with service-layer tenantId filtering
Cache/Queue:  Not yet deployed (request-scoped permission memoization only)
Frontend:     2-3 MFEs on Cloudflare Workers (shell + students + teachers)
Storage:      Cloudflare R2
Auth:         Custom JWT (Passport.js)
Monitoring:   Railway built-in logs + Sentry for error tracking

Focus: Student/teacher management, RBAC with Entity-Scope model, basic attendance, substitution workflow.

Phase 2: Growth (Months 7–12)

+ Redis caching layer for hot data (tenant configs, permission sets, timetables)
+ BullMQ job queues for background processing
+ Cloudflare CDN rules for API response caching (public data)
+ PostgreSQL RLS policies as defense-in-depth safety net
+ PostgreSQL read replica for reporting queries
+ Additional MFEs: attendance, admissions, communications, timetabling
+ Email integration (Resend/SendGrid) via BullMQ workers
+ Centralized log aggregation (Pino structured logging already implemented)

Focus: Full feature set, performance optimization, operational observability.

Phase 3: Scale (Months 12–24)

+ Dockerize NestJS (already container-ready)
+ Migrate to Kubernetes (DigitalOcean K8s or AWS EKS)
+ Split hot modules into independent services (admissions, timetabling)
+ PostgreSQL connection pooling (PgBouncer)
+ Consider moving to schema-per-tenant if isolation requirements increase
+ API gateway (Kong or AWS API Gateway) in front of services
+ CI/CD pipeline (GitHub Actions → Docker → K8s)

Decision point: If a single school grows beyond ~10,000 users or if enterprise clients require stronger data isolation, evaluate schema-per-tenant migration. The tenant_id column approach makes this migration additive (add schema routing) rather than destructive.


12. Decision Points

Decision Options Considerations
Backend Framework NestJS, Django, ASP.NET, Go Team expertise, dev speed, multitenancy maturity
ORM Prisma, Django ORM, EF Core, GORM Type safety, migrations, query complexity
Frontend React, Vue.js, Next.js Ecosystem, learning curve, full-stack needs
Frontend Hosting Cloudflare Pages, Vercel, same as backend CDN needs, preview deploys, pricing model
Database PostgreSQL, MySQL Multitenancy support, RLS, schema features
Multitenancy Schema-per-tenant, RLS, separate DBs Isolation needs, operational complexity
Backend Hosting Railway, Render, Fly.io, DO, AWS/GCP DevOps capacity, region needs, scaling
Object Storage Cloudflare R2, S3, DO Spaces Egress costs, S3 compatibility
CDN/Security Cloudflare, AWS CloudFront WAF features, DDoS, caching needs
Auth Clerk, Auth0, self-hosted Control vs convenience, per-user costs

Appendix: Decision Log

Date Decision Decided By Context
2025-02 NestJS over Django/Go Team Dev speed priority, single language
2025-02 RLS over schema-per-tenant Team Simpler ops for MVP, acceptable isolation
2025-02 Custom auth over Clerk/Auth0 Team Entity-Scope model needs full control
2025-02 MFEs over monolithic SPA Team Independent deploys, team scalability
2025-02 Railway over Render/Fly.io Team Best DX, managed PostgreSQL + Redis
2025-02 BullMQ over pg-boss Team More mature, Redis dual-use for caching
2025-02 Cloudflare R2 over S3 Team Zero egress, edge integration
2026-02 No repository layer — direct Prisma Team Prisma already is a typed repository; CRUD modules too simple to justify wrapping
2026-02 No domain models yet — revisit per-module Team No business logic to encapsulate; premature abstraction for anagraphic CRUD
2026-02 Separate docs per concern Team Deduplication; each doc authoritative for its concern