⚡ Quick Start
Get EduDesk running in under 10 minutes. No CLI required for the basic setup.
Upload & Create DB
Upload files to your web root. Create a MySQL database with full privileges in cPanel or phpMyAdmin.
Run Setup Wizard
Open your domain — you'll be redirected to setup.php. Complete the 4-step wizard.
Run Migrations
Visit /migrate_all.php once to apply all schema upgrades. Then start managing your school.
Worker (Emails, SMS, Webhooks)
# Add to cPanel cron jobs (every minute) * * * * * /usr/bin/php /home/user/public_html/worker.php # Or run directly php worker.php
Daily Cron (Reminders, Trial Warnings, Reports)
# Run once per day at 7 AM
0 7 * * * /usr/bin/php /home/user/public_html/cron/daily.php
📋 Overview
EduDesk is a production-grade, multi-tenant school management SaaS built on PHP 8.3 and MySQL 8. It ships as a single-page web application (SPA) with no JavaScript framework dependency — no React, no Vue, no Node.js runtime required.
From K–12 schools in emerging markets to international private schools requiring SAML SSO and GDPR compliance, EduDesk covers the full spectrum. Its open PHP architecture means it runs on any shared hosting, VPS, or cloud environment without a build step.
Who It's For
- Small schools (50–500 students) — Affordable, full-featured management out of the box
- Large institutions (500–5,000 students) — Enterprise SSO, SAML, audit logs, API access
- SaaS operators — White-label, multi-school superadmin console, plan-based billing
- Developers / resellers — REST API, webhooks, API keys, OpenAPI spec
📊 Honest SaaS Score Card
An honest internal assessment of where EduDesk v1 stands as an enterprise SaaS platform. Last reviewed: May 2026 — updated after latest UX & stability sprint.
Score Notes
| Category | Why not 10/10 |
|---|---|
| Security (9.5) | All technical controls are implemented (SAML, TOTP, CSRF, HMAC, SOC 2 CC6/CC7 logging). Held at 9.5 pending external SOC 2 Type II audit — a business process, not a code gap. |
| API / Dev Tools (9.5) | Audit log sort/filter, billing API, permissions API, and error handling all polished in the latest sprint. Minor gap: no GraphQL / gRPC option and no auto-generated SDK packages. |
| Performance (9) | Performance indexes, Redis caching, and APCu are in place. No Redis required for typical deployments. Full CDN integration and query-level profiling tooling not yet bundled. |
| Multi-Campus (9) | District Overview dashboard with KPIs, comparison table, and CSV export is live. Deeper cross-campus timetable merging and budget consolidation not yet available. |
| UX / UI Polish (9.5) | Dark-theme landing page, working billing toggle, gender filter, clickable dashboard names, teacher photos, 40+ emoji display fixes, and audit sort all shipped. Held at 9.5 — onboarding wizard and mobile responsive edge cases still being refined. |
Still Missing for a True 10/10
| Gap | Impact | Status |
|---|---|---|
| SOC 2 Type II certification | High | All technical controls implemented — external auditor engagement pending |
Previously Missing — Now Built ✅
| Gap | What shipped |
|---|---|
| Native mobile app (iOS / Android) | Full React Native / Expo app — parent portal (dashboard, attendance, academics, fees, notices), student portal (dashboard, timetable, exams, grades, notices), teacher portal (dashboard, attendance marking, class roster, notices); biometric auth, push notifications, offline cache, OTA updates — v1.1.0 |
| Full district / multi-campus | District Overview dashboard — KPI totals, per-campus comparison, bar chart, CSV export |
| Email/SMS template editor (WYSIWYG) | In-dashboard WYSIWYG editor with formatting toolbar, variable picker, live preview, SMS body — per-school DB overrides |
| SOC 2 technical controls | security_events table, failed-login / lockout / 2FA event logging, Security Events viewer (SOC 2 CC6 / CC7 evidence), data retention policies |
| Custom student fields (per-school) | Configurable per-school field definitions, full UI + API |
| Parent-to-teacher messaging | Bidirectional parent ↔ teacher messaging in parent portal |
| Build pipeline (minification) | Asset minification + version-stamped cache busting |
| Role permissions editor | Granular role permission editor — migration 0006; infinite-loading bug fixed with auto-table recovery + JS error boundary |
| Staff profile pages | LinkedIn-style profile with wall, social links, achievements |
| Student profile pages | Full student profile with all extended PII fields; profile photo now persists across refreshes (migration 0008) |
| Analytics dashboard | Usage analytics API + customer success dashboard in superadmin |
| Teacher profile photos | teachers.user_id now properly set on create and backfilled via migration 0008; getAll JOINs user_profiles to return avatar — photos display correctly in all teacher lists |
| Billing plan & cycle toggle | _renderPlanCards() hoisted to module scope — plan selection and Monthly/Annual toggle both functional |
| Audit log sort & filter controls | Sort asc/desc toggle button added; Clear filter button fixed with named function scope; api/audit.php accepts &sort= parameter |
| Student gender filter | Male / Female / All toggle buttons on the Students page; state preserved alongside search and class filters |
| Dashboard quick-links to profiles | Top Students and Fee Defaulters widget names are now clickable links to the student profile page |
| Emoji display corruption | 40+ emoji rendered as ?? / ??? across CA Scores, QR Attendance, Inventory, Webhooks, API Keys, Certificates, Fee Reminders — all fixed in app-advanced.js |
| Landing page design polish | Pricing and Add-Ons sections restyled from plain white to deep navy gradient matching app theme — glassmorphism cards, radial glow orbs, updated text colours |
⚙️ Requirements
| Component | Minimum | Recommended |
|---|---|---|
| PHP | 8.0 | 8.3 (tested) |
| MySQL / MariaDB | MySQL 5.7 / MariaDB 10.4 | MySQL 8.0 / MariaDB 10.11 |
| Web Server | Apache 2.4 (mod_rewrite) | Apache 2.4 or Nginx 1.20+ |
| PHP Extensions | PDO, PDO_MySQL, JSON, mbstring, openssl, curl | + APCu (caching), Redis (queue) |
| Redis (optional) | — | 7.0+ for job queue + cache |
| Disk Space | 20 MB | 500 MB+ (uploads, backups) |
| RAM | 512 MB | 1 GB+ |
🚀 Installation
Upload Files
Extract the archive and upload all files to your web root (
public_html/) via FTP or cPanel File Manager.Create a MySQL Database
In cPanel → MySQL Databases, create a database + user with All Privileges. Note the credentials.
Open the Setup Wizard
Navigate to your domain. You'll be redirected to
setup.phpautomatically. The 4-step wizard installs all tables and writesconfig/config.php.Configure School & Admin
Enter school name, academic terms, fee structure defaults, and create your first superadmin account (min. 8-character password).
Run Migrations
Visit
/migrate_all.phponce to apply all schema upgrades. This is idempotent — safe to re-run.Configure Stripe (SaaS mode)
In
config/config.phpadd yourSTRIPE_WEBHOOK_SECRET. In Settings → Billing, add your Stripe keys.Start the Worker
For email delivery, webhook dispatch, and SMS:
* * * * * php /path/to/worker.php
.htaccess is Apache-only. Block /config/ and /includes/ in your Nginx server block. See the Security section.📁 File Structure
🎓 Academic Modules
Students
Full profile, admission numbers, photo upload, soft-delete preserving history.
Teachers
Staff records with auto-login account creation, subject assignments.
Classes
Class + section management, class teacher assignment, capacity tracking.
Timetable
Drag-drop weekly schedules with conflict detection across teachers and rooms.
Attendance
Daily class attendance (present/absent/late/excused). QR-code check-in supported.
Exams
Exam management, results entry, automatic grade calculation with custom scales.
Online Exams
MCQ + open-ended exams with timer, auto-grade, manual scoring for essays.
Report Cards
Term report cards with subject scores, CA scores, remarks, printable PDF.
CA Scores
Continuous assessment with configurable components (tests, projects, homework).
Assignments
Create, distribute and collect assignments; grade submissions in-app with class roster view.
Tabulation
End-of-term tabulation sheets showing all subjects and positions.
Bulk Promotion
Promote entire classes to next grade with one click in New Year wizard.
💰 Finance & Fees
Fee Management
Per-student fee recording, discounts, fines, outstanding balance tracking.
Fee Structures
Per-class fee schedules with line items. Auto-applies to new students.
Fee Installments
Split term fees into installment plans with due-date tracking.
Fee Receipts
One-click printable receipts for every payment. Parent-facing download.
Invoices
Professional invoice generation per student, downloadable as PDF.
Bulk Fee Apply
Apply a fee to every student in a class instantly.
Fee Reminders
Scheduled SMS/email reminders on configurable days of the week.
Payroll
Staff salary grades, monthly payroll processing, payslip generation.
Online Payments
Stripe, Paystack, Flutterwave, PayPal with webhook verification.
Report Builder
Custom financial reports with XLSX/CSV export and CSV injection protection.
📱 Communication
Internal Messages
Staff-to-staff messaging with inbox, sent box, unread counter.
Notice Board
School-wide announcements with priority levels (urgent/normal/low) and read receipts.
Bulk SMS
Blast SMS to any class. Supports Twilio, Africa's Talking, Vonage, MessageBird, Infobip, Termii.
Parent Portal
Parents view child's attendance, fees, report cards. PWA installable on Android/iOS.
Student Portal
Student login: assignments, results, timetable, downloads.
SMTP Email
Configurable SMTP (Gmail, SendGrid, Mailgun, custom). Queue-based delivery.
Push Notifications
Web push (VAPID) notifications — fees due, notices, attendance alerts.
Absence Alerts
Auto-SMS parents when child marked absent. Bulk notify for whole class.
🏢 Enterprise Features
SAML 2.0 SSO
SP-initiated SSO with XML signature verification. Works with Okta, Azure AD, Google Workspace.
Google / Microsoft OAuth
OAuth2 + PKCE login with JWKS JWT verification (RS256).
Two-Factor Auth
TOTP-based 2FA (Google Authenticator compatible) for all users.
Audit Logs
Immutable audit log for all admin actions, filterable, CSV exportable.
GDPR / FERPA
Right to erasure (Art.17), data portability (Art.20), filtered audit log viewer.
System Backup
On-demand encrypted database backup with email delivery and download.
Admin Users
Create multiple admin/principal/bursar/teacher accounts with granular roles.
Biometric Integration
Register fingerprint/face scanners. HMAC-signed webhook check-in events.
☁️ SaaS & Billing
Superadmin Console
Platform MRR/ARR, school list, bulk activate/suspend, plan upgrades, CSV export, school groups.
Stripe Billing
Monthly/annual plans with prorating, plan changes, cancellation, reactivation.
Plan Gating
Feature flags per plan tier (starter/pro/enterprise). Enforced server-side.
Trial Reminders
Automated drip emails at days 1, 3, 7. Trial expiry warnings at days 10, 7, 3, 1.
Webhooks
Outbound HTTPS webhooks for 10+ event types. HMAC-SHA256 signed. Delivery logs.
API Keys
Create scoped REST API keys with prefix, last-used tracking, revocation.
School Groups
Organize schools into networks/groups in the superadmin console. Useful for resellers.
Health Endpoint
/api/health.php — uptime monitoring with secret-key authentication.
🔧 Developer Tools
REST API (v1)
| Endpoint | Methods | Description |
|---|---|---|
/api/v1/students.php | GET, POST | List, create, update, delete students |
/api/v1/teachers.php | GET, POST | Manage teacher records |
/api/v1/classes.php | GET | List class definitions |
/api/v1/attendance.php | GET, POST | Read and record attendance |
/api/v1/fees.php | GET, POST | Query and record fee payments |
/api/v1/notices.php | GET | Read school notices |
/api/v1/reports.php | GET | Aggregated data reports |
/api/v1/timetable.php | GET | Class timetables |
/api/v1/import.php | POST | Bulk CSV import (students/teachers) |
🔐 Roles & Permissions
| Role | Who | Key Permissions |
|---|---|---|
| admin | School Administrator | Full access — all modules, settings, create/delete, billing |
| principal | Head Teacher / Principal | Academic + HR view, reports, no billing/system settings |
| bursar | Finance Officer | All finance modules, student view, payroll |
| teacher | Teaching Staff | Attendance, results, assignments, timetable, messages |
| receptionist | Front Desk | Visitor log, admissions intake |
| librarian | Library Staff | Library management only |
teacher123 — instruct all new users to change their password on first login.⚙️ Settings Reference
Settings are stored as a JSON blob in the settings table, scoped per school_id. All keys below are writable via the Settings API. Arbitrary key injection is blocked server-side via a whitelist of ~70 allowed keys.
School Identity
| Key | Description |
|---|---|
schoolName | Display name used in headers and report cards |
schoolMotto | Motto / tagline |
country | ISO country code (used for phone formatting defaults) |
timezone | IANA timezone (e.g. America/New_York) |
currency / currencyCode | ISO 4217 code (e.g. USD, GBP, NGN) |
language | UI language: en, fr, es, pt, ar, sw |
primaryColor / accentColor | Hex colors for school branding |
schoolLogo | URL to school logo image |
Academic
| Key | Description |
|---|---|
t1_name / t2_name / t3_name | Term display names |
t1_fee / t2_fee / t3_fee | Default per-term fee amounts |
gradingScale | Active grading scale ID |
gradePassMark | Minimum marks to pass (default 50) |
promotionPassRate | Minimum pass % for automatic promotion |
caWeight / examWeight | CA vs exam contribution to final grade (%) |
🔑 Environment Variables
These constants are set in config/config.php (written by the setup wizard). You can also set them as actual environment variables and read them via getenv() for containerized deployments.
| Constant | Required | Description |
|---|---|---|
DB_HOST | Required | MySQL host (usually localhost) |
DB_NAME | Required | MySQL database name |
DB_USER | Required | MySQL username |
DB_PASS | Required | MySQL password |
APP_SECRET | Required | 64-char random hex — used for CSRF tokens and session signing |
APP_URL | Recommended | Full base URL (e.g. https://app.edu.com) — used in emails and webhooks |
STRIPE_WEBHOOK_SECRET | SaaS mode | Stripe webhook signing secret from your Stripe dashboard |
REDIS_URL | Optional | Redis connection URL (e.g. redis://localhost:6379). Falls back to MySQL queue. |
SUPERADMIN_EMAIL | Optional | Email address for the platform superadmin account |
HEALTH_SECRET | Optional | Secret token for /api/health.php uptime checks |
config/config.php to version control. It contains your database credentials and APP_SECRET. Add it to .gitignore.🔒 Security
Authentication
- PHP sessions with
session_regenerate_id(true)on login - Session fingerprinting (IP + User-Agent hash) to detect hijacking
- Idle timeout (configurable, default 60 min)
- CSRF double-submit tokens on all state-changing requests
- Passwords:
password_hash(PASSWORD_BCRYPT), min 8 chars - 2FA: TOTP (RFC 6238), QR-code enrollment, backup codes
Application Security
- All DB queries use PDO prepared statements — SQL injection impossible
- All output uses
htmlspecialchars()— XSS mitigated - Settings API: server-side whitelist of ~70 allowed keys
- File uploads: MIME type + extension validation, stored outside webroot
- Webhook secrets: stored as SHA-256 hash, never in job payloads
- API keys: stored as hashed prefix, raw key shown once only
Rate Limiting
- Login page: 10 attempts / 15 min per IP
- Superadmin login: 5 attempts / 15 min per IP
- Password reset: 3 requests / 30 min per email
- REST API: 300 req / min per API key
- Parent login: 5 attempts / 15 min per IP
Nginx Configuration
# Block protected directories location ~ ^/(config|includes|lang)/(.*\.php)$ { deny all; return 404; } location ~ /\. { deny all; } # Security headers add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; add_header Referrer-Policy strict-origin-when-cross-origin;
⏰ Cron & Background Worker
EduDesk has two background processes: the worker (processes jobs from the queue) and the daily cron (time-sensitive tasks like reminders and reports).
Worker (worker.php)
Processes email delivery, SMS sending, and webhook dispatch. Should run every minute.
# cPanel cron — every minute * * * * * /usr/bin/php /path/to/worker.php >/dev/null 2>&1 # With Redis (recommended): BLPOP-based, near-instant dispatch # Without Redis: polls job_queue table every 5 seconds
Daily Cron (cron/daily.php)
Run once per day — typically at 7–8 AM school time. Handles the following tasks:
| Task | Description |
|---|---|
| Trial expiry warnings | Sends warning emails at days 10, 7, 3, 1 before trial expires |
| Onboarding drip | Sends Day 1, Day 3, Day 7 onboarding emails to new school admins |
| Fee reminders | Sends SMS/email reminders per school's configured schedule |
| Attendance summary | Weekly attendance summary email to school admins (Mondays) |
| Auto-suspend expired trials | Sets billing_status = 'suspended' on expired unpaid schools |
| Worker heartbeat | Records last successful cron run for monitoring |
# cPanel cron — daily at 7 AM
0 7 * * * /usr/bin/php /path/to/cron/daily.php >/dev/null 2>&1*/5 * * * *. Email delivery will have up to a 5-minute delay.🌐 REST API v1
The v1 REST API enables third-party integrations. All requests require a Bearer API key created from the admin dashboard (Settings → API Keys).
# Authentication Authorization: Bearer edu_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Base URL https://yourdomain.com/api/v1/ # OpenAPI docs (interactive) https://yourdomain.com/api/v1/docs.php?ui
/api/v1/docs.php (JSON) or ?ui for Swagger UI — no extra installation needed.🔗 Webhooks
Configure outbound webhooks from Settings → Webhooks. EduDesk will POST to your HTTPS endpoint whenever a subscribed event fires.
Request Format
{
"event": "student.created",
"school_id": "abc123",
"timestamp": 1700000000,
"data": { ... }
}Signature Verification
# Header sent with every request: X-EduDesk-Signature: sha256=<hmac_hex> # Verify in PHP: $expected = hash_hmac('sha256', $rawBody, $secret); hash_equals($expected, $receivedSig); // true = authentic
Supported events: student.created, student.updated, student.deleted, fee.paid, attendance.marked, exam.scored, teacher.created, report.generated, ping (test).
Retry policy: 3 attempts with exponential backoff. Failed deliveries move to dead-letter queue, visible in the webhook delivery log.
🗄️ Database Schema
migrate_all.php is the canonical migration runner — idempotent, safe to re-run. It installs and upgrades all tables across 28 migration groups (A through CC).
Core Tables
| Table | Purpose | Notable Columns |
|---|---|---|
schools | Tenant registry | id, name, plan, billing_status, stripe_customer_id, trial_ends_at |
users | Login accounts | id, school_id, username, role, totp_secret, deleted_at, last_login_at |
students | Student records | id, school_id, admission_no, class_name, photo, deleted_at |
fees | Fee payments | id, school_id, student_id, amount, discount, fine, idempotency_key |
settings | Per-school config | school_id (PK), data (JSON) |
audit_logs | Immutable audit trail | id, school_id, user_id, action, details (JSON), created_at |
webhook_endpoints | Outbound webhooks | id, school_id, url, events (JSON), secret_hash |
job_queue | Async job queue | id, job, payload (JSON), status, attempts, next_run_at |
parent_accounts | Parent portal auth | id, student_id, name, phone, email, password_hash |
onboarding_emails | Drip email dedup | school_id, step, sent_at (UNIQUE school_id+step) |
random_bytes(). Soft-delete (deleted_at) is used on students and users to preserve fee/attendance history.🔧 Troubleshooting
Most issues fall into one of these categories. Check them in order before posting a support ticket.
1. "Table doesn't exist" / SQL errors on first load
/migrate_all.php while logged in as admin. It's idempotent — safe to run multiple times.2. Blank page / 500 error after upload
- Check PHP version: must be 8.0+. In cPanel → PHP Selector, confirm the active version.
- Check PHP extensions: PDO, PDO_MySQL, JSON, mbstring, openssl, curl must all be enabled.
- Check file permissions:
config/,uploads/should be writable (755 directories, 644 files). - Enable error display temporarily: add
ini_set('display_errors',1);at the top ofindex.php.
3. Login redirects back to login page
- Sessions not persisting — check that PHP session save path is writable.
- Cookie domain mismatch — if on a subdomain, ensure
session.cookie_domainis set correctly. - HTTPS/HTTP mismatch — if
APP_URLuses https but you're on http, session cookie flags won't match.
4. Emails not sending
- Worker not running — confirm
worker.phpcron is active. Check thejob_queuetable for stuck jobs. - SMTP credentials wrong — use Settings → Email → Send Test Email to verify.
- Gmail blocking — enable "Less secure apps" or use an App Password with 2FA-enabled accounts.
- Port blocked by host — try port 465 (SSL) or 587 (TLS) if 25 is blocked.
5. SMS not sending
- Check gateway selection in Settings → SMS. Confirm your API key has credit/balance.
- Phone numbers must include country code (e.g.
+233xxxxxxxxxfor Ghana). - For Africa's Talking sandbox mode, numbers must be in your sandbox whitelist.
- Check
sms_logstable for error responses from the gateway.
6. Webhooks not delivering
- Endpoint must be HTTPS with a valid SSL certificate (self-signed certs are rejected).
- Private IP addresses (192.168.x.x, 10.x.x.x) are blocked for SSRF protection.
- Your endpoint must respond with HTTP 200 within 10 seconds, or it's marked as failed.
- Check
webhook_deliveriestable for the exact response code and body.
7. PDF / Report cards not generating
- EduDesk uses PHP's built-in HTML output for print-optimized PDFs. Enable the browser's "Print to PDF" option.
- If using a third-party PDF library (Dompdf/mPDF add-on), ensure the library files are uploaded and permissions are correct.
8. "APP_SECRET is too short" warning
APP_SECRET in config/config.php to a 64-char random hex string. Generate one with: bin2hex(random_bytes(32))9. Superadmin can't log in
- Superadmin uses a separate login at
/superadmin/— not the same as the school admin login. - Credentials are set in
config/config.phpasSUPERADMIN_EMAILandSUPERADMIN_PASS. - Rate limit: 5 failed attempts locks the IP for 15 minutes.
10. Migration fails partway through
- All migration steps use
IF NOT EXISTS— re-running is safe. - If a step fails due to a missing column dependency, run the migration twice (second run fills gaps).
- For a fresh database, migrations run cleanest from an empty schema rather than upgrading from a very old version.
📝 Changelog
- Photo persistence — migration 0008 ensures
students.photoandteachers.user_idcolumns exist; back-fills user_id for existing teacher records via display_name match; photos now survive page refresh - Teacher photos in all lists —
api/teachers.php getAllLEFT JOINsuser_profilesand returns avatar asphoto;photoOrAv(t)used everywhere in the teacher UI - Billing toggle fixed —
_renderPlanCards()hoisted to module scope; Monthly/Annual toggle and plan card selection now fully functional - Audit log sort & clear — asc/desc sort toggle button added; Clear Filters button fixed via named function
_auditClear();api/audit.phpvalidates and injects&sort=parameter safely - Role permissions — no more infinite spinner —
api/permissions.phpauto-createsrole_permissionstable on first access; JS wrapped in try/catch shows error message instead of hanging - Student gender filter — Male / Female / All toggle buttons on the Students page with state preserved alongside existing search and class filters
- Dashboard profile links — Top Students and Fee Defaulters widget student names are now clickable links routing to the student profile view
- Emoji corruption fixed — 40+
??/???display bugs resolved across CA Scores, QR Attendance, Inventory, Webhooks, API Keys, Certificates, and Fee Reminders inapp-advanced.js - Landing page dark theme — Pricing and Add-Ons sections restyled with deep navy gradient background, glassmorphism cards, radial glow orbs and correct light text colours matching the EduDesk app theme
- Teacher portal — dashboard (today's classes, pending attendance counter, quick actions), attendance marking (select class → mark each student present/absent/late → submit), class roster (search, gender filter, today's attendance status), notices tab, profile
- Teacher login —
api/mobile.phpextended to authenticate againstuserstable (role=teacher/admin); issues 30-day sliding-window Bearer token; returns subjects array from timetable - Teacher API actions —
getTeacherDashboard,getClassRoster,markAttendance(with 2-day backdating guard and ON DUPLICATE KEY upsert) - Dedicated Notices screen for parent, student, and teacher portals — full paginated list, priority filter chips, full-text search, tap-to-expand modal, page navigation
- Notices tab added to all three portal tab bars (parent, student, teacher)
- AccountType widened to
'parent' | 'student' | 'teacher'across TypeScript types, API client, and DB ENUM - Login screen tab switcher now includes Teacher tab with email/username input
- Deep-link allowlist extended with all notices and teacher screens
- TanStack Query hooks added:
useTeacherDashboard,useClassRoster,useMarkAttendance
- District Overview dashboard — KPI totals (students, teachers, classes, revenue YTD) across all campuses
- Per-campus comparison table with students-per-teacher ratio and one-click CSV district report export
- Students-per-campus bar chart — visual district breakdown
- SOC 2 CC6/CC7 security events log —
security_eventstable, failed-login and lockout recording - Security Events viewer in admin — filter by severity/type, 30-day timeline, critical-24h counter, CSV export
- Data retention policy table — configurable retain_days per data type (SOC 2 CC6.5)
- WYSIWYG Email Template editor — formatting toolbar (bold, italic, headings, links, lists), variable picker
- Live email preview — renders template in new tab with real sample data
- SMS template editor — per-template SMS body with 640-char counter, default fallback preserved
- Per-school DB overrides —
email_templatestable; built-in defaults used when no override exists
- LinkedIn-style staff profile pages — wall, social links, achievements, pinned posts
- Full student profile page — all extended PII, custom fields, photo, guardian info
- In-dashboard teacher profile card with class assignments and quick actions
- Dashboard chart reordering — personalised layout per user
- Student save 500 fix — widened PII columns to support all extended fields
- Campus UI — multi-campus management views and school group foundations
- Custom student fields — per-school configurable field definitions with full UI + API
- Parent-to-teacher direct messaging — bidirectional in parent portal
- Asset build pipeline — minification + version-stamped cache busting
- Role permissions editor — granular per-role permission control (migration 0006)
- Analytics API + customer success dashboard in superadmin console
- React Native / Expo mobile app (EduDesk-Mobile) — iOS + Android, push via Expo
- Referral capture system (migration 0005)
- Notice read receipts (migration 0004)
- Photo columns for staff and students (migration 0008)
- Onboarding drip emails: Day 1/3/7 sequences with deduplication table
- Trial expiry warnings extended to days 10, 7, 3, 1
- Demo data seeder — 5 classes, 40 students, 1 week attendance (Settings → Load Sample Data)
- Bulk Create Parents — one-click parent portal accounts for all students
- Staff & teacher welcome emails on account creation
- RC workflow explainer banner for new schools with no classes
- Assignment submission roster — full class view with status/grade/export
- Multi-school groups in superadmin console
- Parent PWA: manifest shortcuts, service worker v3, assetlinks.json (TWA)
- Parent PWA install prompt with 30s defer and persistent banner
- DB reconnect: getPDO() auto-reconnects on MySQL error 2006/2013
- Webhook management UI: register, edit, delete, test, view delivery logs
- API Keys management UI: create scoped keys, revoke, last-used tracking
- Soft-delete on students and users (preserves all historical data)
- Performance indexes on fees, audit_logs, attendance
- OpenAPI 3.0.3 spec + Swagger UI at /api/v1/docs.php?ui
- Settings injection whitelist (70 keys, file-scope const)
- Superadmin rate limiting (5/15 min per IP)
- Report Builder XLSX fixed (ZipArchive OOXML) + CSV injection protection
- APP_SECRET hardened to 64-char cryptographic random hex
- Added Spanish (es) and Portuguese (pt) UI translations
- Billing frontend: plan cards, Stripe checkout, portal, invoice history
- Redis → APCu → array caching layer
- Timetable conflict detection (teacher + room)
- Fee installments
- Report Builder with XLSX/CSV export
- Admin Users UI, Parent/Student self-service portals
- Meaningful test suite (11 files)
- JWT RS256 verification (Google JWKS) + PKCE on all OAuth2 flows
- SAML 2.0 SSO (SP-initiated, XML sig verification)
- GDPR/FERPA audit UI (Art.17 erasure, Art.20 portability)
- Redis job queue with dead-letter
- Superadmin console (MRR/ARR, bulk actions)
- 50+ academic, finance, HR and communication modules
- Multi-tenant architecture with school_id isolation
- Role-based access (admin, principal, bursar, teacher, receptionist, librarian)
- Setup wizard, Stripe billing, SSO, 2FA, audit logs, backup
- PWA + service worker, 6-language i18n, dark-mode-first UI
❓ FAQ
* * * * * /usr/bin/php /path/to/EduDesk-PHP/worker.php. The worker processes one batch per minute. With Redis set (REDIS_URL), jobs dispatch immediately via BLPOP; otherwise the MySQL job_queue table is polled every 5 seconds.https://yourdomain.com/migrate_all.php while logged in as admin, or run php migrate_all.php from CLI. It is idempotent — running it multiple times is safe. It uses ADD COLUMN IF NOT EXISTS and CREATE TABLE IF NOT EXISTS everywhere.💬 Support
CodeCanyon Comments
Post on the item page. Response within 48 hours (business days).
This Documentation
This README covers all features, configuration, security and troubleshooting.
OpenAPI Docs
Interactive API reference at /api/v1/docs.php?ui on your installation.
Bug Reports
Include PHP version, MySQL version, browser console log and the exact error message.
migrate_all.php has been run after any upgrade.What's Included in Support
- ✅ Feature questions and usage guidance
- ✅ Installation help on standard hosting
- ✅ Bug fixes for issues in the delivered code
- ✅ Security issue reports (treated with priority)
- ❌ Custom development / feature additions (available as paid service via Nubrix Technologies)
- ❌ Support for heavily modified installations
© 2026 Nubrix Technologies