مراجعة البنية
Architecture Review
11
Critical
9
Medium
5
Low
6
Broken Flows
Critical Issues (11)
These issues will cause runtime crashes, data loss, or security breaches in production. They must be resolved before any deploy.
Missing Database Tables Referenced by API
Student API routes reference 4 tables that do not exist: guardians, student_documents, student_transfers, student_medical. These tables were never created in any migration.
Impact
All guardian CRUD, document upload, transfer, and medical endpoints throw "table does not exist" runtime errors. Student enrollment flow is broken.
Fix
Create migration 013 with CREATE TABLE statements for guardians, student_documents, student_transfers, and student_medical with proper FK constraints.
All Admin Pages Use Hardcoded Mock Data
Every admin dashboard page contains hardcoded arrays (const STUDENTS = [...], const INVOICES = [...]) instead of calling API hooks. No admin page fetches or persists real data.
Impact
Users see the same fake data every session. Forms submit to nowhere. Zero data persistence. The entire admin panel is a visual mockup.
Fix
Replace hardcoded arrays with useApi() / SWR hooks from lib/hooks.ts. Wire form onSubmit handlers to API POST/PATCH endpoints. Add loading and error states.
Frontend Form Schema ≠ API Schema
StudentForm sends date_of_birth (API expects dob), class_id (API expects section_id), guardian fields inline (API expects separate /guardians endpoint), medical_notes (no such field in schema). Missing required fields: admission_no, academic_year_id.
Impact
Form submission fails Zod validation on the API. Even if it passed, data would be inserted into wrong columns or ignored.
Fix
Align field names: date_of_birth → dob, class_id → section_id. Add admission_no and academic_year_id inputs. Split guardian creation into separate API call after student is created.
SQL Injection in Communications Module
Line 10 uses string interpolation: `AND (audience = 'all' OR audience = '${role === 'student' ? 'students' : ...}')` instead of parameterized queries. Even though role values are enum-restricted, this introduces a SQL injection vector.
Impact
Malicious role string could be injected. Tenant isolation can be bypassed if role value is not validated upstream.
Fix
Replace template literal with parameterized query: use CASE statement with ? placeholders for role values.
SQL Injection in BaseRepository orderBy Parameter
orderBy parameter is directly interpolated into SQL: `ORDER BY ${orderBy}` without parameterization. If orderBy comes from user input, arbitrary SQL can be injected.
Impact
ORDER BY injection could expose data, cause DoS, or lead to database enumeration attacks.
Fix
Whitelist allowed orderBy values in a constant. Map user input to whitelisted options: const ALLOWED_ORDERS = { name_asc: 'name ASC', ... }; if (!ALLOWED_ORDERS[orderBy]) throw error(...);
Rate Limiter Redis Connection Not Verified
Rate limiter calls redis.incr() every request but does not check if Redis is connected. If Redis is down, middleware throws unhandled exception.
Impact
Redis downtime → entire API is unavailable (500 on all routes). No fallback to in-memory rate limiting.
Fix
Add try-catch in rateLimit middleware. Fallback to in-memory rate limiting if Redis unavailable. Check isRedisReady() before redis calls.
No Authentication Context — Silent Auth Failures
No AuthContext provider. Token is stored in localStorage but never validated on app load. No refresh token mechanism. Components render with no token and fail silently on API calls.
Impact
After page refresh, user appears logged in but all API requests fail with 401. No state management — impossible to implement protected routes correctly.
Fix
Create AuthProvider with useAuth hook. Validate token via GET /auth/me on mount. Implement refresh token exchange. Redirect to login on 401.
Feature Gating Middleware Built But Never Applied
requireFeature() middleware exists but is NOT imported or applied in ANY route file. Plan-based access control is completely disabled.
Impact
Maktab ($19/mo) users access all features. No monetization — SaaS model collapses.
Fix
Apply requireFeature() to all protected routes in each module.
Tenant Isolation Gaps in Multiple Modules
GET /hifz/plans/:planId and similar endpoints return any resource by ID without verifying tenant ownership.
Impact
Tenant A reads Tenant B's data by guessing IDs. Critical data leak.
Fix
Add tenant_id verification to all resource lookups.
No Docker / Containerization
No Dockerfile, docker-compose.yml, .dockerignore. Cannot deploy or scale application in containers.
Impact
No standardized deployment. Cannot run on cloud platforms (AWS, DigitalOcean, Kubernetes). Manual server setup required.
Fix
Create Dockerfile for API and frontend. Create docker-compose.yml for local dev. Add .dockerignore.
No CI/CD Pipeline
No GitHub Actions, GitLab CI, or any automated testing/deployment. Every deploy is manual.
Impact
No automated tests. No linting. No build verification. High human error risk.
Fix
Create .github/workflows/test.yml and .github/workflows/deploy.yml for automated testing and deployment.
Medium Issues (9)
Features partially work but will produce incorrect results, poor UX, or security risks.
API Hooks Reference Unverified Endpoints
Frontend hooks call GET /reports/dashboard, /reports/fees/collection, /reports/attendance/by-class, /reports/hifz/progress, /reports/payroll/summary — these routes may exist but controller implementations are unverified.
Impact
Dashboard widgets and report pages will show empty states or crash if any endpoint returns 404 or malformed data.
Fix
Audit all report controller functions. Ensure every hooked endpoint returns correct response shape. Add TypeScript response interfaces.
Missing Database Indexes on High-Traffic Columns
Tables sections, subjects, timetable_slots, billing_invoices lack indexes on tenant_id. Every query does full table scans filtered by tenant.
Impact
Progressively slower queries as data grows. At 50+ tenants with 500+ students each, dashboard loads will degrade significantly.
Fix
Add migration 013+: ALTER TABLE ... ADD INDEX idx_<table>_tenant (tenant_id) for all affected tables.
Attendance Doesn't Respect Holidays
holidays table exists but attendance_sessions table has no validation against it. Attendance can be marked on holidays without warning.
Impact
Wrong attendance statistics. School holidays counted as absences for students who didn't attend (because school was closed).
Fix
Add holiday check in attendance service before marking. Return 422 with holiday info if date is a holiday. Add override flag for special cases.
No Form Validation Before Submission
All forms submit directly via onSubmit(form) with zero client-side validation. No required field checks, email format validation, date range validation, or phone format validation.
Impact
Bad data reaches API (or would, if forms were wired). Users get no feedback about invalid inputs. API rejects with cryptic Zod errors.
Fix
Add Zod schemas mirroring API schemas. Validate before calling onSubmit. Show field-level error messages.
No Error Boundaries on Admin Pages
No React error boundaries. If an API error or JS exception occurs on any admin page, the entire page crashes with a white screen — no recovery path.
Impact
One API timeout or unexpected null value crashes the entire admin dashboard. No retry or fallback UI.
Fix
Add error.tsx files in each admin route segment. Wrap data-fetching sections with Suspense boundaries and error fallbacks.
Custom Tailwind Classes Undefined
Classes badge-gold, badge-emerald, btn-gold, btn-outline, input-islamic are used but not defined in globals.css @layer components. They render as plain unstyled elements.
Impact
Buttons, badges, and form inputs appear as raw HTML elements with no styling. Visual design is broken.
Fix
Add @layer components block in globals.css defining badge-gold, badge-emerald, btn-gold, btn-outline, input-islamic with proper Tailwind utilities.
Tenant Middleware Dev Fallback Missing
In development mode, if X-Tenant-Slug header is not provided, slug is null → returns 400 for every request. No default tenant for local dev.
Impact
Developers cannot test API locally without manually adding X-Tenant-Slug header to every request. Postman/curl workflows are tedious.
Fix
Default to "demo" tenant in development: slug = req.headers['x-tenant-slug'] || 'demo'.
JWT_SECRET Not Validated on Startup
auth middleware calls jwt.verify(token, process.env.JWT_SECRET) without checking if JWT_SECRET is defined. If undefined, jwt.verify uses empty string as secret.
Impact
In production without JWT_SECRET env var, tokens signed with empty string would be validated — total auth bypass.
Fix
Add startup check: if (!process.env.JWT_SECRET) throw new Error("JWT_SECRET required"). Log warning if secret length < 32.
Missing Sidebar Nav for Teacher/Student/Accountant
Role-specific sidebar components exist but navigation items may not cover all available features for each role. Teacher sidebar missing Hifz session logging link; Student sidebar missing exam results.
Impact
Users in non-admin roles can't navigate to features relevant to them. Incomplete role-based experience.
Fix
Audit each sidebar against available API endpoints per role. Add nav items for all accessible features.
Low Issues (5)
Hardcoded Mock Data Should Never Ship
Large const arrays of fake data (12 mock students, 5 mock invoices, etc.) committed to production. Even when API is connected, dead mock data remains.
Impact
Code bloat. Confusing for new developers. Risk of accidentally rendering mock instead of real data.
Fix
Remove all mock arrays once API integration is complete. Use MSW (Mock Service Worker) for dev/test mocking instead.
No TypeScript Strict Mode
TypeScript strict mode not fully enforced. Loose types in hooks (generic objects instead of typed interfaces). Response shapes not validated.
Impact
Runtime type errors that TypeScript should catch at build time. Developer confidence in types is low.
Fix
Enable strict: true in tsconfig.json. Create interface files for all API response shapes.
No RTL Support for Arabic Content
HTML lang="en" set globally. Arabic text (scattered throughout UI) renders LTR. No dir="rtl" on Arabic content blocks.
Impact
Arabic text displays incorrectly — punctuation and flow are wrong. Bad UX for Arabic-reading users.
Fix
Add dir="rtl" attribute to Arabic-language text containers. Consider next-intl for proper i18n.
Missing .env.example Files
No .env.example at root or in api/. At least 12 environment variables are referenced in code (NEXT_PUBLIC_API_URL, DB_HOST, JWT_SECRET, REDIS_HOST, etc.) but undocumented.
Impact
New developers can't set up the project without reading source code to discover required env vars.
Fix
Create .env.example files listing all required variables with example values and comments.
Pagination Page Size Mismatch
Frontend uses PAGE_SIZE = 8. Backend paginate() defaults to limit = 10. Different page sizes cause confusing pagination UX.
Impact
Last page may show fewer items than expected. Page count calculations are wrong.
Fix
Align pagination: either both use 10 or make frontend send limit param to API.
Broken User Flows (6)
End-to-end user journeys that fail at specific steps. Each flow was traced from the UI through to the API and database.
Student Enrollment
/admin/students → Enrol StudentStep 4: Parent page has no API call wired
Form data is consumed by no handler. Even if it were submitted, field names mismatch API schema (date_of_birth→dob, class_id→section_id). Missing required admission_no, academic_year_id. Guardian data sent inline but API expects separate /guardians endpoint.
Fee Payment Processing
/admin/fees → Record PaymentStep 2: Data is fake and read-only
No API integration. No payment form. No way to change invoice status. The fees page is a static screenshot.
Hifz Session Logging
/admin/hifz → Log SessionStep 3: No form to create hifz sessions
API has POST /hifz/plans/:planId/sessions but no frontend form calls it. The entire Hifz tracking workflow is missing.
Attendance Marking
/admin/attendance → Mark AttendanceStep 4: Attendance data is never persisted
No integration with POST /attendance/sessions. Class selection is fake. Marked attendance evaporates on page refresh.
Exam Creation & Grading
/admin/exams → Create Exam → GradeStep 2: No exam creation form
API has full CRUD for exams/results but frontend has no forms or API calls. Exam grading workflow doesn't exist.
SaaS Plan Enforcement
Any feature-gated actionStep 3: Feature gate middleware not applied
requireFeature() exists but is imported by zero route files. All plan tiers get identical access.
Module Completion Matrix
| Module | DB Schema | API Routes | API Logic | Frontend UI | Integration | Notes |
|---|---|---|---|---|---|---|
| Students | Missing guardians/documents/transfers tables. UI uses mock data. | |||||
| Hifz Tracking | No session logging form. Tenant isolation gap. | |||||
| Fees & Billing | UI is read-only mock. No payment recording form. | |||||
| Attendance | UI hardcoded to one class. No holiday awareness. | |||||
| Examinations | No exam creation or grading forms. | |||||
| Communications | Route exists. Controller implementation unverified. | |||||
| Staff & Payroll | Route exists. No payroll calculations verified. | |||||
| Settings | Settings page exists but depth unknown. | |||||
| Reports / Analytics | Some report endpoints. Frontend hooks exist. | |||||
| SaaS Billing | Feature gating not enforced. Admin page uses mock data. | |||||
| Auth / Multi-tenancy | No AuthContext. No login page. No session mgmt. |
Remediation Roadmap
Phase 1 — SECURITY CRITICAL FIXES
- Fix SQL injection in comms.repository.js:10 — parameterize audience filter
- Fix SQL injection in BaseRepository.js:77 — whitelist orderBy values
- Fix rate limiter Redis fallback — add error handling and in-memory fallback
- Add missing database tables: guardians, student_documents, student_transfers, student_medical
- Verify JWT_SECRET validation on server startup (min 32 chars)
- Add tenant_id checks to ALL resource lookups in Hifz, Billing, Payroll modules
Phase 2 — INFRASTRUCTURE & DEPLOYMENT
- Create Dockerfile for API and frontend
- Create docker-compose.yml with MySQL, Redis, API, frontend services
- Setup GitHub Actions: test.yml (lint, build, test) and deploy.yml (auto-deploy on main)
- Create .env.example files documenting all required variables
- Add health check endpoints and logging to production
Phase 3 — WIRE FRONTEND TO BACKEND
- Create AuthContext/AuthProvider — token validation on mount, refresh handling
- Replace ALL hardcoded mock data with API calls (students, fees, hifz, attendance, exams)
- Fix StudentForm schema mismatch: date_of_birth→dob, class_id→section_id
- Wire form submissions to POST/PATCH endpoints
- Add loading states, error boundaries, empty states
- Define missing CSS classes: badge-gold, badge-emerald, btn-gold, btn-outline, input-islamic
Phase 4 — BILLING & SaaS ENFORCEMENT
- Apply requireFeature() middleware to protected routes (fees→fee_management, exams→examinations, etc.)
- Implement per-tenant usage limits (student count, storage, API calls)
- Test plan downgrades and upgrade paths
- Implement feature flags per plan in frontend (hide unavailable features)
Phase 5 — POLISH & LAUNCH
- Add Zod client-side validation to all forms
- Implement holiday-aware attendance checking
- Add database indexes for high-traffic columns (tenant_id, email, etc.)
- Enable TypeScript strict mode across codebase
- Add RTL support for Arabic content
- Remove all hardcoded mock data arrays (12x student, 5x invoice arrays, etc.)
- Create comprehensive README with deployment instructions