Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

STUMNG

Production-oriented multi-tenant Student Management SaaS implemented with Flask + SQLite, designed for portability to PostgreSQL.

Stack

  • Backend: Python, Flask, SQLAlchemy, Flask-Migrate (Alembic)
  • Frontend: Server-rendered HTML, CSS, Vanilla JavaScript
  • Database: SQLite (current), PostgreSQL-ready architecture
  • Auth: Internal session-based auth (separate platform and tenant identities)

High-level Architecture

app/
  blueprints/
    auth/         # platform/tenant login + logout
    platform/     # control plane (tenants/plans/features/limits/staff/audits)
    tenant/       # tenant app (users, students, teachers, classes, attendance, exams, calendar, audits, student portal)
  models/         # ORM domain models (all tenant domain entities carry tenant_id)
  repositories/   # data access layer (tenant-scoped repositories enforce tenant filters)
  services/       # business logic, capability resolution, usage enforcement, audit logging
  security/       # request pipeline hooks, csrf, auth decorators, permission constants
  templates/      # server-rendered pages
  static/         # CSS + JS
  cli.py          # bootstrap and maintenance CLI commands
migrations/       # Alembic migration environment and versioned migrations
run.py            # app entrypoint

Multi-tenant Request Pipeline

Implemented centrally in request hooks + decorators:

  1. Resolve tenant context (tenant_slug in path)
  2. Verify tenant is active
  3. Resolve tenant capabilities (plan + feature entitlements + overrides + limits)
  4. Verify required feature enabled (decorator)
  5. Verify user permission (decorator)
  6. Verify limits before writes (service-level enforcement)
  7. Execute business logic (service layer)
  8. Write audit log entry

Tenant Isolation Guarantees

  • Every tenant domain model has explicit tenant_id.
  • Tenant repositories require tenant_id at construction and always query with tenant filter.
  • Route decorators enforce session tenant = resolved tenant context.
  • No platform routes access tenant academic domain data.

Capability Model

Data-driven tables:

  • plans
  • features
  • plan_feature_entitlements
  • tenant_feature_overrides
  • plan_limits
  • tenant_limit_overrides

CapabilityService resolves effective profile as:

  • default feature config
  • merged with plan feature config
  • merged with tenant feature override config
  • with enabled-state precedence: tenant override > plan entitlement > disabled

Business modules consume only resolved capabilities.

RBAC Model

Separate systems:

  • Platform RBAC: platform_users, platform_roles, platform_permissions, mapping tables
  • Tenant RBAC: tenant_users, tenant_roles, tenant_permissions, mapping tables

Permission checks are string-based and route-level enforced with decorators.

Audit Logging

Unified audit_logs table stores:

  • tenant
  • actor user + actor type
  • action
  • entity type + id
  • request id
  • metadata JSON
  • timestamp

Both platform and tenant business operations produce audit logs.

Observability Foundations

  • Structured logs with request_id, tenant_id, user_id
  • Request ID generation + X-Request-ID response propagation
  • Exception logging includes contextual IDs via logging filter

Setup

  1. Create environment file:
    • Copy .env.example to .env
    • Set a secure SECRET_KEY
  2. Install dependencies:
    • pip install -r requirements.txt
  3. Set Flask app:
    • PowerShell: $env:FLASK_APP='run.py'
  4. Run migrations:
    • python -m flask db upgrade
  5. Verify active database target:
    • python -m flask doctor-db

Important:

  • If DATABASE_URL is not set, STUMNG automatically uses project-root stumng.db with an absolute path.
  • Avoid relative DATABASE_URL=sqlite:///stumng.db in environments that may change working directory.

Secure Bootstrap Flow

1) Create first platform administrator

python -m flask bootstrap-platform-admin --email admin@example.com --full-name "Platform Admin"

This command:

  • creates first platform user
  • creates initial platform_owner role
  • seeds and assigns baseline platform permissions

2) Start application

python run.py

Visit http://127.0.0.1:5000/auth/platform/login and login.

3) Create first tenant from Platform Portal

In Platform Portal dashboard:

  • create plan(s)
  • create feature definitions
  • configure plan entitlements
  • create tenant and assign plan
  • configure tenant feature overrides and limits

4) Create first tenant administrator

python -m flask bootstrap-tenant-admin --tenant-slug your-tenant-slug --email owner@school.edu --full-name "Tenant Owner"

This command:

  • creates first tenant user
  • creates initial tenant_owner role
  • seeds and assigns baseline tenant permissions

Then login at http://127.0.0.1:5000/auth/tenant/login using tenant slug + credentials.

Realistic Sample Dataset (B.E. CSE 2022-2026)

Seed realistic Indian mock data for a tenant:

python -m flask seed-cse-2022-2026 --tenant-slug springfield-high --students 250 --reset

This populates:

  • 250 students (CSE220001 to CSE220250)
  • teachers
  • class/sections
  • attendance records
  • exams and marks
  • academic calendar events
  • tenant audit logs for seeded operations

Tenant Detail Management Page

Platform staff can open a dedicated tenant page:

  • /platform/tenants/<tenant_id>

From this page they can:

  • view tenant summary and usage counters
  • suspend/archive/reactivate tenant
  • assign/update tenant plan
  • configure tenant feature overrides
  • configure tenant limit overrides
  • review recent tenant audit activity

All actions are permission-gated and route-level enforced.

Feature Keys Used by Tenant Modules

Tenant module routes enforce these feature keys:

  • tenant_user_management
  • student_management
  • teacher_management
  • class_management
  • attendance
  • exams
  • academic_calendar
  • audit_logs

Create these features in Platform Portal and enable them via plan/override to unlock modules.

Permission Keys Used by Tenant Modules

Common keys:

  • tenant.dashboard.read
  • tenant.user.manage
  • student.read, student.create
  • student.self.read
  • teacher.read, teacher.create
  • class.read, class.create
  • attendance.read, attendance.write
  • attendance.self.read
  • exam.read, exam.create, exam.mark.write
  • exam.self.read
  • calendar.read, calendar.create
  • calendar.self.read
  • tenant.audit.read

Student Portal

Each tenant can provide a student self-service view at:

  • /tenant/<tenant_slug>/student-portal

Tenant admins can:

  • create a student portal account linked to a student profile
  • link an existing tenant user account to a student profile

Student users can view (permission + feature controlled):

  • profile and class assignment
  • attendance history and summary
  • exam marks
  • upcoming calendar events

Student Login Notes

  • Students use the standard tenant login page: /auth/tenant/login
  • Tenant slug is mandatory along with student email and password
  • On successful login, linked student users are redirected to /tenant/<tenant_slug>/student-portal

If student login fails because credentials are unknown, use:

python -m flask set-tenant-user-password --tenant-slug springfield-high --email student.cse220001@springfield.edu

To provision student logins in bulk for all active students in a tenant:

python -m flask provision-student-logins --tenant-slug springfield-high --email-domain springfield.edu --max-accounts 0

To backfill access for already linked student users:

python -m flask sync-student-portal-access --tenant-slug springfield-high

Migration Strategy

  • Alembic is configured under migrations/
  • Initial schema: migrations/versions/20260304_0001_initial.py
  • Additional migration: migrations/versions/20260304_0002_student_user_links.py
  • Future schema changes should be generated with python -m flask db migrate and applied using python -m flask db upgrade

Security Controls

  • CSRF tokens validated for all state-changing requests
  • Secure session defaults (env-driven)
  • Password hashing with Werkzeug
  • Auth responses are set with no-store cache headers to prevent stale login-page back navigation
  • Consistent authz failure responses without data leakage
  • Internal auth only (no third-party identity dependency)

About

Production-grade multi-tenant Student Management SaaS platform with Flask, RBAC, feature flags, and strict tenant isolation.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages