The platform is a monolithic Spring Boot application serving REST APIs to three frontend clients. All data flows through a single API gateway on port 8091.
Figure 1: System Architecture — Three-tier monolithic application with external notification services
2. Data Flow Diagrams
2.1 Student Enrollment Flow
Figure 2: Student Enrollment & Approval Data Flow
2.2 Assignment Lifecycle
Figure 3: Assignment Lifecycle Data Flow
2.3 Exam Lifecycle
Figure 4: Exam Lifecycle Data Flow with Grading Formula
2.4 Certificate Generation
Figure 5: Certificate Generation & Public Verification Flow
3. Database Schema Diagram
Figure 6: Database Entity Relationship Diagram — All 35+ tables including Flyway V1–V16 additions
All environment-specific values are centralized in a .env file at the project root. Docker Compose uses ${VAR:-default} syntax to reference these values. Spring Boot uses profile-specific application-{profile}.properties files.
Security: The .env file is in .gitignore and must NEVER be committed. Use .env.example as a template. Production credentials go in .env.production on the server only.
# Clone/deploy web-admin to /opt/web-admin
cd /opt/web-admin
npm install
npm run build
# Start with PM2 (persistent across reboots)
pm2 start npm --name "salt-web" -- start -- --port 8081
pm2 save
pm2 startup # Generates startup script for OS
# Verify
curl -s http://localhost:8081 | head
7.6 Nginx Reverse Proxy
The nginx configuration file is maintained in the repository at nginx/sites-available/stagging.saltcollegeandresourcecentre.com.conf. Copy it to the server:
# Copy config to server
sudo cp nginx/sites-available/stagging.saltcollegeandresourcecentre.com.conf \
/etc/nginx/sites-available/
# Create symlink
sudo ln -sf /etc/nginx/sites-available/stagging.saltcollegeandresourcecentre.com.conf \
/etc/nginx/sites-enabled/
# Remove default site
sudo rm -f /etc/nginx/sites-enabled/default
# Increase upload size in nginx.conf (already set)
# client_max_body_size 500M;
# Test and reload
sudo nginx -t
sudo systemctl restart nginx
Upstream Routing Summary:
Upstream
Internal Port
Nginx Path
Service
frontend_backend
127.0.0.1:8081
/
Next.js Web Admin (PM2)
backend
127.0.0.1:8091
/SaltELearnAppApi/
Spring Boot API (systemd)
jenkins_backend
127.0.0.1:8090
/jenkins/
Jenkins CI/CD
(direct)
127.0.0.1:9001
/minio/
MinIO Console
Key nginx features:
HTTPS on port 443 with Let's Encrypt auto-renewal
HTTP on port 80 redirects to HTTPS
WebSocket support for /SaltELearnAppApi/ws/ (chat)
Bug 7 fixes: soft-delete columns (original_email, original_username), data recovery for students 2018333/2024053
V7
V7__data_integrity_constraints.sql
Partial UNIQUE indexes, admission status change trigger, BOM cleanup trigger, data integrity log table
V8
V8__add_language_columns.sql
Language-based subject filtering: language on tbl_subjects, preferred_language on tbl_student, auto-detect from subject_code
Migration rules: Never modify existing migrations. Always create new V{N}__ files. Use IF NOT EXISTS / IF NOT EXISTS for safety. Test against salvation.sql before applying to production.
The platform uses Firebase Cloud Messaging (FCM) to deliver real-time push notifications to both the mobile app and the executive dashboard. The backend publishes notifications to FCM topics, and each client subscribes to the topics relevant to its role.
13.1 FCM Topic Model
Rather than maintaining individual device tokens for broadcast-style notifications, The platform uses FCM topics. Each client subscribes to a topic on startup, and the backend publishes messages to the appropriate topic.
FCM Topic
Subscriber
Purpose
salt_exec_events
Executive Dashboard (Flutter)
Broadcasts key platform events to leadership: assignment submissions, assignment markings, and student approvals.
salt_notifications
Mobile App (Flutter)
General notifications for students, tutors, and ETOs: exam codes, approval status changes, announcements, and other role-specific alerts.
Topic subscriptions are managed client-side using the firebase_messaging Flutter package:
// Executive Dashboard - subscribes on app startup
FirebaseMessaging.instance.subscribeToTopic('salt_exec_events');
// Mobile App - subscribes on login
FirebaseMessaging.instance.subscribeToTopic('salt_notifications');
13.2 Backend Trigger Points
The backend sends notifications to the salt_exec_events topic from the NotificationService.notifyExecutive() method. This method is called from three locations in the codebase:
Event
Calling Service / Method
Trigger Condition
Notification Payload
Assignment Submitted
AssignnementService — called after student successfully submits assignment via /file_handler/submit_assignment
Student uploads assignment file and record is saved in tbl_assignment_marking
AdminController / UsersService — called when Admin gives final enrollment approval
Student admission_status changes to “D” (Done/Approved)
Student name, admission number, territory, approver role (“Admin”), timestamp
Student Approved (ETO)
AdminController / UsersService — called when ETO approves student enrollment via /v2/bridge/students/{id}/approve
Student passes ETO approval stage
Student name, admission number, territory, approver role (“ETO”), timestamp
The NotificationService is an @Async service that runs notification dispatch on a separate thread pool to avoid blocking the main request thread. The FCM server key is stored in tbl_sys_settings (ID=1) and read on application startup.
Note: The notifyExecutive() method is fire-and-forget. If FCM delivery fails (e.g., network timeout), the failure is logged but does not roll back the triggering transaction (assignment submission, marking, or approval).
13.3 Executive Dashboard Firebase Setup
The Executive Dashboard Flutter app uses three Firebase/notification packages:
Package
Version
Purpose
firebase_core
Latest stable
Firebase SDK initialization. Must be called in main() before any other Firebase usage.
firebase_messaging
Latest stable
FCM topic subscription, foreground/background message handling, and token management.
flutter_local_notifications
Latest stable
Displays local notification banners when the app is in the foreground (since FCM foreground messages do not show system notifications by default).
Initialization Flow
// main.dart
await Firebase.initializeApp();
await FirebaseMessaging.instance.subscribeToTopic('salt_exec_events');
// Request notification permission (iOS and web)
await FirebaseMessaging.instance.requestPermission(
alert: true,
badge: true,
sound: true,
);
// Foreground message handler
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
// Show local notification via flutter_local_notifications
// Update badge count in NotificationProvider
});
Firebase Project & App Identifiers
Property
Value
Firebase Project ID
salt-college-dashboard
Firebase Project Number
1030054625511
Storage Bucket
salt-college-dashboard.firebasestorage.app
Platform-Specific App IDs
Platform
App ID
API Key
Bundle / Package
Android
1:1030054625511:android:794eb0bc62d9616c12e242
AIzaSyCnoUFKFaISe5x7sY0j7SWSzsEVUeDBedk
nm.sumba.salf.executive_dashboard
iOS
1:1030054625511:ios:40c54fb945f58e0412e242
AIzaSyBt2arrfaU7HnzcOTK7Y_LQKwCuynojZVo
ke.co.sumba.salt.dashboard
Web
1:1030054625511:web:32ecfb013c9ad1a412e242
AIzaSyDv17i58vpEwz18uI540LZUpdjBvqcZB3I
N/A
Web also includes: measurementId: G-2XE8S83MC7, authDomain: salt-college-dashboard.firebaseapp.com
Mobile App Firebase Identifiers
Platform
App ID
API Key
Bundle / Package
Android
1:986786589181:android:ed4ec0db21dec6b76e9194
AIzaSyCAFyZSwlg5ejex9udsUuqFCKU71ZLoCFM
elearning.sumba.co.ke
iOS
1:1030054625511:ios:2f5ee0145354cf9a12e242
AIzaSyBt2arrfaU7HnzcOTK7Y_LQKwCuynojZVo
ke.co.sumba.salt.mobile
Note: The mobile Android app uses a separate Firebase project (salt-college-e-learning, project number 986786589181). The mobile iOS app is registered under the dashboard project (salt-college-dashboard).
Platform Configuration Files
Platform
File
Dashboard Location
Mobile Location
Android
google-services.json
executive_dashboard/android/app/
mobile/android/app/
iOS
GoogleService-Info.plist
executive_dashboard/ios/Runner/
mobile/ios/Runner/
Web
index.html + firebase-messaging-sw.js
executive_dashboard/web/
N/A
Dart
firebase_options.dart
executive_dashboard/lib/
mobile/lib/
iOS AppDelegate Configuration
Both apps require Firebase initialization in ios/Runner/AppDelegate.swift:
Important: The Firebase project must have Cloud Messaging API (V1) enabled in the Google Cloud Console. The legacy FCM API is deprecated. Ensure the backend uses the V1 HTTP API endpoint (https://fcm.googleapis.com/v1/projects/{project-id}/messages:send) for sending topic messages.
Appendix A — Web Admin Route Reference
This appendix lists all web admin routes used by the platform, organised by user role. These routes are internal navigation paths used by the Next.js Web Admin application.
Admin Routes (Access Level 5)
#
Menu Item
Route
1
Dashboard
/dashboard/admin
2
Users
/dashboard/admin/users
3
Students
/dashboard/admin/students
4
Grading
/dashboard/admin/grading
5
Billing
/dashboard/admin/billing
6
Certificates
/dashboard/admin/certificates
7
Suspensions
/dashboard/admin/suspension
8
Intake Config
/dashboard/admin/intake
9
Sessions
/dashboard/admin/sessions
10
Achievements
/dashboard/admin/achievements
11
Subjects
/dashboard/admin/subjects
12
Exam Dates
/dashboard/admin/exams/dates
13
Exam Approvals
/dashboard/admin/exams/approvals
14
Student Exams
/dashboard/admin/exams/student-approvals
15
Reports
/dashboard/admin/reports
16
Announcements
/dashboard/admin/announcements
17
Countries
/dashboard/admin/countries
18
Territories
/dashboard/admin/territories
19
System Logs
/dashboard/admin/logs
20
SMS Log
/dashboard/admin/sms-log
21
Chat
/dashboard/admin/chat
22
Schema
/dashboard/admin/schema
23
Settings
/dashboard/admin/settings
Tutor Routes (Access Level 8)
Menu Item
Route
Dashboard
/dashboard/tutor/
Assignments
/dashboard/tutor/assignments
Exams
/dashboard/tutor/exams
Students
/dashboard/tutor/students
Materials
/dashboard/tutor/materials
Chat
/dashboard/tutor/chat
ETO Routes (Access Level 9)
Menu Item
Route
Dashboard
/dashboard/eto/
Approvals
/dashboard/eto/approvals
Students
/dashboard/eto/students
Enrollment
/dashboard/eto/enrollment
Reports
/dashboard/eto/reports
Chat
/dashboard/eto/chat
Student Routes (Access Level 12)
Menu Item
Route
Dashboard
/dashboard/student/
Subjects
/dashboard/student/subjects
Assignments
/dashboard/student/assignments
Exams
/dashboard/student/exams
Materials
/dashboard/student/materials
Performance
/dashboard/student/performance
Chat
/dashboard/student/chat
Profile
/dashboard/student/profile
Appendix B — Internal Status Codes
The platform uses single-character status codes internally. These codes appear in the database and API responses.
Admission Status (tbl_student.admission_status)
Code
Meaning
Description
U
Uploaded
Student record created via bulk CSV import
N
New
Student has self-registered, awaiting ETO review
EP
ETO Pending
ETO has approved, awaiting Admin final approval
P
Pending Admin
Awaiting administrator approval
D
Done / Approved
Fully approved and active
Assignment Status (tbl_assignment_marking)
Code
Meaning
Description
N
New
Assignment submitted by student, not yet reviewed
R
Returned
Returned to student for revision
T
Tutor Marked
Tutor has graded the assignment
P
Approved
Admin has approved the final mark
Subject Selection Status (tbl_student_subjects_selection)
Code
Meaning
Description
A
Active
Student is actively enrolled in the subject
P
Pending
Awaiting approval
E
Exam Ready
Student is eligible to sit the exam
N
New
Newly registered
R
Retake
Student is retaking the subject
D
Done
Subject completed
Password Change Flag (tbl_sys_users.mcp)
Value
Meaning
Y / yes
Must change password on next login
N / no
Password not yet created, or already changed
Appendix C — Access Level Hierarchy
The platform uses numeric access levels for role-based access control (RBAC). A lower number indicates higher authority.
Role
Access Level
Table: tbl_user_level
Permissions
Admin
5 (highest)
level = ‘Admin’
Full platform management, final approvals, system settings
College E-Learning — Technical Documentation v1.0 — 20th February 2026
College E-Learning — Developed by Sumba Group Limited for Salvation Army SALT College of Africa