Senior Architect Analysis

مراجعة البنية

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

C-001Database
database/migrations/api/src/modules/students/students.routes.js

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

C-002Frontend
app/admin/students/page.tsxapp/admin/fees/page.tsxapp/admin/hifz/page.tsxapp/admin/attendance/page.tsxapp/admin/exams/page.tsx

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

C-003Data Contract
components/dashboard/forms/StudentForm.tsxapi/src/modules/students/students.schema.js

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

C-004Security
api/src/modules/communications/comms.repository.js:10

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

C-005-SECSecurity
api/src/utils/BaseRepository.js:77

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

C-006-SECInfrastructure
api/src/middleware/rateLimit.js

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

C-007Auth / Security
lib/api.tslib/auth.tsxapp/layout.tsx

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

C-008Billing / SaaS
api/src/middleware/featureGate.jsapi/src/modules/*/routes.js

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

C-009Security
api/src/modules/hifz/hifz.service.jsapi/src/modules/billing/api/src/modules/payroll/

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

C-010DevOps
root/

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

C-011DevOps
.github/workflows/

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

M-001API Contract
lib/hooks.tsapi/src/modules/reports/

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

M-002Database
database/migrations/002_academic.sqldatabase/migrations/010_settings_audit_timetable.sql

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

M-003Business Logic
database/migrations/007_attendance.sqldatabase/migrations/010_settings_audit_timetable.sql

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

M-004Frontend
components/dashboard/forms/StudentForm.tsxcomponents/dashboard/forms/FeesForm.tsxcomponents/dashboard/forms/ExamForm.tsx

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

M-005Frontend
app/admin/

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

M-006Styling
components/dashboard/FormModal.tsxapp/admin/billing/page.tsx

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

M-007DevEx
api/src/middleware/tenant.js

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

M-008Security
api/src/middleware/auth.js

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

M-009Frontend
components/teacher/TeacherSidebar.tsxcomponents/student/StudentSidebar.tsxcomponents/accountant/AccountantSidebar.tsx

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

L-001Cleanup
app/admin/students/page.tsxapp/admin/fees/page.tsxapp/admin/billing/page.tsx

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

L-002Type Safety
tsconfig.json

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

L-003i18n
app/layout.tsx

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

L-004DevEx
root/api/

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

L-005Data Consistency
app/admin/students/page.tsxapi/src/lib/paginate.js

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 Student
1.Admin opens Students page — sees hardcoded mock data
2.Clicks "Enrol Student" — FormModal opens with StudentForm
3.Fills first_name, last_name, date_of_birth, gender, class_id, guardian fields
4.Clicks Submit — onSubmit(form) fires on parent page

Step 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 Payment
1.Admin opens Fees page — sees hardcoded INVOICES array
2.Views invoice list — data never updates
3.Clicks "Record Payment" — no input or modal appears

Step 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 Session
1.Admin/Teacher opens Hifz page — sees mock student list
2.Wants to log sabaq/sabqi/manzil session for a student
3.No "Log Session" button or form exists in UI

Step 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 Attendance
1.Admin opens Attendance page — sees hardcoded class 6A students
2.Cannot switch classes (hardcoded data)
3.Toggles checkboxes — state changes in UI only
4.Clicks "Save Attendance" — no API call

Step 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 → Grade
1.Admin opens Exams page — sees 6 hardcoded exams
2.No "Create Exam" form available
3."Add Results" button exists but with no handler

Step 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 action
1.Maktab plan tenant ($19/mo) logs into admin
2.Navigates to Fees Management (plan says: disabled)
3.Full fees module loads with no restriction

Step 3: Feature gate middleware not applied

requireFeature() exists but is imported by zero route files. All plan tiers get identical access.

Module Completion Matrix

ModuleDB SchemaAPI RoutesAPI LogicFrontend UIIntegrationNotes
StudentsMissing guardians/documents/transfers tables. UI uses mock data.
Hifz TrackingNo session logging form. Tenant isolation gap.
Fees & BillingUI is read-only mock. No payment recording form.
AttendanceUI hardcoded to one class. No holiday awareness.
ExaminationsNo exam creation or grading forms.
CommunicationsRoute exists. Controller implementation unverified.
Staff & PayrollRoute exists. No payroll calculations verified.
SettingsSettings page exists but depth unknown.
Reports / AnalyticsSome report endpoints. Frontend hooks exist.
SaaS BillingFeature gating not enforced. Admin page uses mock data.
Auth / Multi-tenancyNo AuthContext. No login page. No session mgmt.
Done Partial Missing

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