SchoolPro

System Architecture Document

Project
Multi-School Management ERP
Version
1.0.0
Date
September 2026
Stack
Laravel 11 + MariaDB + Blade
Phase 1 Audit Complete — Ready for Implementation

Table of Contents

  1. System Architecture Tech stack, principles, directory structure, design decisions
  2. Database Design Complete ER design, 25+ tables with SQL DDL, relationships, indexes
  3. Module Map Module dependency graph, status, integration pipelines
  4. Permission Matrix 9 roles × ~120 permissions across 10 modules
  5. Accounting Architecture Double-entry engine, CoA hierarchy, voucher types, transaction flows
  6. Development Roadmap Phase breakdown, task lists, technical debt, risk assessment
Section 01

System Architecture

Technology stack, architectural principles, module structure, directory layout, and key design decisions.

Technology Stack

LayerTechnologyVersion
BackendLaravel11.55.1
PHPPHP8.2.4
DatabaseMariaDB10.4.28 (port 3305)
ServerApache (XAMPP)2.4.56
Frontend BuildVitevia laravel-vite-plugin 1.2.0
CSS FrameworkTailwind CSS3.x
JS FrameworkAlpine.js3.x
IconsLucide Icons(to be integrated)
FontsInter(via Google Fonts)
Node.jsNode.js24.16.0
Package ManagerComposer / npm2.8.2 / 11.13.0

Architectural Principles

Multi-School Tenancy

School-scoped data isolation via school_id foreign keys on all domain tables. Super Admin accesses all schools; others scoped to assigned schools via user_schools pivot with is_default flag.

Role-Based Access Control

Custom RBAC (not Spatie) with roles, permissions, role_permissions, user_roles tables. Roles are global; permissions organized by module. System roles cannot be deleted.

Double-Entry Accounting

Complete double-entry bookkeeping with Chart of Accounts. Voucher types: Receipt, Payment, Journal, Contra. Every entry must satisfy DEBIT = CREDIT. Posted records are immutable.

Service Layer Pattern

Business logic in Service classes under app/Services/. Controllers handle HTTP only. Database transactions for multi-step operations. Reusable across controllers, commands, jobs.

Form Request Validation

Dedicated Form Request classes for each endpoint. Validation rules centralized in request classes, not controllers. Auto-fails with 422 responses.

Soft Deletes

All domain entities use soft deletes for data preservation. Queries use withTrashed() only when explicitly needed. Never hard-delete domain data.

High-Level Module Structure

SchoolPro ├── Core │ ├── Multi-School Management │ ├── User Management & Authentication │ ├── Role-Based Access Control │ └── Dashboard & Analytics ├── Academic │ ├── Academic Years │ ├── Classes & Sections │ ├── Subjects & Class-Subject Mapping │ └── Grading System ├── Student Management │ ├── Student Registration & Profiles │ ├── Student Enrollments │ ├── Guardian Management │ └── Student Promotion/Transfer ├── Examination │ ├── Exam Types & Configuration │ ├── Exam Scheduling │ ├── Result Entry & Processing │ ├── Final Result Calculation │ └── Report Cards & Merit Lists ├── Employee & HR │ ├── Employee Management │ ├── Departments & Designations │ ├── Teacher-Class/Subject Assignments │ ├── Attendance Tracking │ └── Biometric Integration ├── Fee Management │ ├── Fee Categories │ ├── Fee Structures │ ├── Invoice Generation │ ├── Payment Processing │ └── Payment Allocation ├── Accounting (Double-Entry) │ ├── Chart of Accounts │ ├── Account Head Mappings │ ├── Voucher Management │ ├── Journal Entries │ └── Financial Reports ├── Payroll │ ├── Salary Structures │ ├── Salary Components │ └── Payroll Processing ├── Timetable │ ├── Time Slots │ ├── Timetable Records │ └── Custom Schedule Items ├── Notifications │ ├── In-App Notifications │ ├── SMS Integration │ └── Email Notifications ├── Documents │ ├── Document Management │ ├── Report Generation │ └── PDF Export └── System ├── Audit Logs ├── Settings └── Backup & Maintenance

Directory Structure

app/ ├── Console/ # Artisan commands ├── Enums/ # PHP 8.1+ Enums ├── Exceptions/ # Custom exceptions ├── Http/ │ ├── Controllers/ # Resource controllers │ │ ├── Auth/ # Authentication controllers │ │ └── Ajax/ # AJAX/API controllers │ ├── Middleware/ # HTTP middleware │ └── Requests/ # Form Request validation ├── Models/ # Eloquent models ├── Policies/ # Authorization policies ├── Providers/ # Service providers ├── Services/ # Business logic services │ ├── Accounting/ # Accounting-specific services │ ├── Academic/ # Academic services │ ├── Fee/ # Fee management services │ ├── HR/ # HR & payroll services │ └── Student/ # Student management services └── Traits/ # Reusable traits resources/ ├── css/ # Custom CSS (Tailwind) ├── js/ # JavaScript (Alpine.js) └── views/ ├── components/ # Reusable Blade components ├── layouts/ # Layout templates └── [module]/ # Module-specific views database/ ├── migrations/ # Database migrations ├── seeders/ # Database seeders └── factories/ # Model factories routes/ ├── web.php # Web routes ├── auth.php # Authentication routes └── console.php # Console routes

Key Design Decisions

Why NOT Vue/React

Why NOT Spatie Permissions

Why Service Layer

Database Strategy

Section 02

Database Design

Complete entity-relationship design with SQL DDL for 25+ tables, relationships, and indexes.

Table Classification

Global Tables (no school_id)

TablePurpose
usersApplication users
password_reset_tokensPassword reset
sessionsUser sessions
cacheApplication cache
cache_locksCache locks
jobsQueue jobs
job_batchesQueue batches
failed_jobsFailed jobs
account_typesChart of accounts types (Asset/Liability/Equity/Income/Expense)
voucher_typesVoucher type definitions (Receipt/Payment/Journal/Contra)
rolesUser roles (global)
permissionsGranular permissions (global)
role_permissionsRole-permission pivot
user_rolesUser-role pivot

School-Scoped Tables (have school_id)

TablePurpose
schoolsSchool institutions
academic_yearsAcademic years per school
classesClasses per school/year
sectionsSections per class
subjectsSubjects per school
class_subjectsSubject-to-class mapping
exam_typesExam type templates
gradesGrading scale
studentsStudent records
guardiansGuardian/parent records
student_guardiansStudent-guardian pivot
student_enrollmentsStudent class enrollment
student_attendancesStudent daily attendance
employee_attendancesEmployee daily attendance
employeesEmployee records
departmentsOrganizational departments
designationsJob designations
employee_class_assignmentsTeacher-class assignments
employee_subject_assignmentsTeacher-subject assignments
employee_salary_structuresEmployee salary config
salary_componentsSalary component definitions
employee_salary_componentsEmployee salary component values
biometric_devicesBiometric attendance devices
biometric_logsBiometric punch logs
fee_categoriesFee category definitions
fee_structuresFee amounts per class/category
student_fee_invoicesGenerated invoices
student_fee_invoice_itemsInvoice line items
payment_methodsPayment method definitions
student_fee_paymentsPayment receipts
student_fee_payment_allocationsPayment-to-invoice allocation
accountsChart of accounts per school
account_head_mappingsModule-to-account mappings
journal_entriesJournal entry headers
journal_entry_linesJournal entry lines
vouchersVoucher headers
voucher_linesVoucher lines
examsExam instances
exam_subjectsExam subject configuration
result_entriesStudent exam results
result_marksPer-subject marks
final_subject_resultsWeighted final results
user_schoolsUser-school assignment pivot
timetablesTimetable instances
timetable_time_slotsTime slot definitions
timetable_recordsSchedule entries
notificationsIn-app notifications
documentsDocument attachments
audit_logsSystem audit trail

Core Table Definitions

1. Schools

CREATE TABLE schools (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    school_code VARCHAR(30) UNIQUE NOT NULL,
    name VARCHAR(200) NOT NULL,
    short_name VARCHAR(50) NULL,
    eiin VARCHAR(20) UNIQUE NULL,          -- Bangladesh EIIN number
    address TEXT NULL,
    phone VARCHAR(30) NULL,
    email VARCHAR(100) NULL,
    website VARCHAR(150) NULL,
    logo VARCHAR(255) NULL,
    established_date DATE NULL,
    status ENUM('active','inactive') DEFAULT 'active',
    created_at TIMESTAMP NULL,
    updated_at TIMESTAMP NULL,
    deleted_at TIMESTAMP NULL
);

2. Academic Years

CREATE TABLE academic_years (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    school_id BIGINT UNSIGNED NOT NULL,
    name VARCHAR(50) NOT NULL,
    start_date DATE NOT NULL,
    end_date DATE NOT NULL,
    is_current BOOLEAN DEFAULT false,
    status ENUM('active','inactive') DEFAULT 'active',
    created_at TIMESTAMP NULL,
    updated_at TIMESTAMP NULL,
    deleted_at TIMESTAMP NULL,
    FOREIGN KEY (school_id) REFERENCES schools(id) ON DELETE CASCADE,
    UNIQUE KEY (school_id, name),
    INDEX idx_school_status (school_id, status),
    INDEX idx_school_current (school_id, is_current)
);

3. Classes

CREATE TABLE classes (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    school_id BIGINT UNSIGNED NOT NULL,
    academic_year_id BIGINT UNSIGNED NOT NULL,
    name VARCHAR(100) NOT NULL,
    short_name VARCHAR(30) NULL,
    numeric_order UNSIGNED INT DEFAULT 0,
    status ENUM('active','inactive') DEFAULT 'active',
    created_at TIMESTAMP NULL,
    updated_at TIMESTAMP NULL,
    deleted_at TIMESTAMP NULL,
    FOREIGN KEY (school_id) REFERENCES schools(id) ON DELETE CASCADE,
    FOREIGN KEY (academic_year_id) REFERENCES academic_years(id) ON DELETE CASCADE,
    UNIQUE KEY (school_id, academic_year_id, name)
);

4. Students

CREATE TABLE students (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    school_id BIGINT UNSIGNED NOT NULL,
    student_code VARCHAR(50) NOT NULL,
    admission_no VARCHAR(50) NOT NULL,
    first_name VARCHAR(100) NOT NULL,
    last_name VARCHAR(100) NULL,
    gender ENUM('male','female','other') NULL,
    date_of_birth DATE NULL,
    blood_group VARCHAR(10) NULL,
    religion VARCHAR(50) NULL,
    nationality VARCHAR(50) DEFAULT 'Bangladeshi',
    phone VARCHAR(30) NULL,
    email VARCHAR(100) NULL,
    address TEXT NULL,
    photo VARCHAR(255) NULL,
    status ENUM('active','inactive','transferred','graduated','left') DEFAULT 'active',
    created_at TIMESTAMP NULL,
    updated_at TIMESTAMP NULL,
    deleted_at TIMESTAMP NULL,
    FOREIGN KEY (school_id) REFERENCES schools(id) ON DELETE CASCADE,
    UNIQUE KEY (school_id, student_code),
    UNIQUE KEY (school_id, admission_no)
);

5. Employees

CREATE TABLE employees (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    school_id BIGINT UNSIGNED NOT NULL,
    employee_code VARCHAR(50) NOT NULL,
    first_name VARCHAR(100) NOT NULL,
    last_name VARCHAR(100) NULL,
    gender ENUM('male','female','other') NULL,
    department_id BIGINT UNSIGNED NULL,
    designation_id BIGINT UNSIGNED NULL,
    employee_type ENUM('teacher','staff','accountant','admin','support','other') DEFAULT 'staff',
    joining_date DATE NULL,
    status ENUM('active','inactive','resigned','terminated') DEFAULT 'active',
    created_at TIMESTAMP NULL,
    updated_at TIMESTAMP NULL,
    deleted_at TIMESTAMP NULL,
    FOREIGN KEY (school_id) REFERENCES schools(id) ON DELETE CASCADE,
    FOREIGN KEY (department_id) REFERENCES departments(id) ON DELETE SET NULL,
    FOREIGN KEY (designation_id) REFERENCES designations(id) ON DELETE SET NULL,
    UNIQUE KEY (school_id, employee_code)
);

6. Fee Management Tables

CREATE TABLE fee_categories (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    school_id BIGINT UNSIGNED NOT NULL,
    name VARCHAR(100) NOT NULL,
    code VARCHAR(50) NOT NULL,
    is_recurring BOOLEAN DEFAULT true,
    status ENUM('active','inactive') DEFAULT 'active',
    FOREIGN KEY (school_id) REFERENCES schools(id) ON DELETE CASCADE,
    UNIQUE KEY (school_id, code)
);

CREATE TABLE fee_structures (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    school_id BIGINT UNSIGNED NOT NULL,
    academic_year_id BIGINT UNSIGNED NOT NULL,
    class_id BIGINT UNSIGNED NOT NULL,
    fee_category_id BIGINT UNSIGNED NOT NULL,
    amount DECIMAL(12,2) NOT NULL,
    frequency ENUM('one_time','monthly','quarterly','half_yearly','yearly') DEFAULT 'monthly',
    FOREIGN KEY (school_id) REFERENCES schools(id) ON DELETE CASCADE,
    FOREIGN KEY (academic_year_id) REFERENCES academic_years(id) ON DELETE CASCADE,
    FOREIGN KEY (class_id) REFERENCES classes(id) ON DELETE CASCADE,
    FOREIGN KEY (fee_category_id) REFERENCES fee_categories(id) ON DELETE CASCADE,
    UNIQUE KEY (school_id, academic_year_id, class_id, fee_category_id, frequency)
);

CREATE TABLE student_fee_invoices (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    school_id BIGINT UNSIGNED NOT NULL,
    student_id BIGINT UNSIGNED NOT NULL,
    enrollment_id BIGINT UNSIGNED NOT NULL,
    invoice_no VARCHAR(50) NOT NULL,
    invoice_date DATE NOT NULL,
    due_date DATE NULL,
    subtotal DECIMAL(12,2) DEFAULT 0,
    discount DECIMAL(12,2) DEFAULT 0,
    fine DECIMAL(12,2) DEFAULT 0,
    total_amount DECIMAL(12,2) DEFAULT 0,
    paid_amount DECIMAL(12,2) DEFAULT 0,
    due_amount DECIMAL(12,2) DEFAULT 0,
    status ENUM('unpaid','partial','paid','cancelled') DEFAULT 'unpaid',
    FOREIGN KEY (school_id) REFERENCES schools(id) ON DELETE CASCADE,
    FOREIGN KEY (student_id) REFERENCES students(id) ON DELETE CASCADE,
    FOREIGN KEY (enrollment_id) REFERENCES student_enrollments(id) ON DELETE CASCADE,
    UNIQUE KEY (school_id, invoice_no)
);

CREATE TABLE student_fee_payments (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    school_id BIGINT UNSIGNED NOT NULL,
    student_id BIGINT UNSIGNED NOT NULL,
    receipt_no VARCHAR(50) NOT NULL,
    payment_date DATE NOT NULL,
    payment_method_id BIGINT UNSIGNED NOT NULL,
    amount DECIMAL(12,2) NOT NULL,
    reference_no VARCHAR(100) NULL,
    status ENUM('completed','cancelled') DEFAULT 'completed',
    FOREIGN KEY (school_id) REFERENCES schools(id) ON DELETE CASCADE,
    FOREIGN KEY (student_id) REFERENCES students(id) ON DELETE CASCADE,
    FOREIGN KEY (payment_method_id) REFERENCES payment_methods(id) ON DELETE RESTRICT,
    UNIQUE KEY (school_id, receipt_no)
);

7. Accounting Tables

CREATE TABLE accounts (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    school_id BIGINT UNSIGNED NOT NULL,
    account_type_id BIGINT UNSIGNED NOT NULL,
    parent_id BIGINT UNSIGNED NULL,
    account_code VARCHAR(50) NOT NULL,
    name VARCHAR(150) NOT NULL,
    is_group BOOLEAN DEFAULT false,
    status ENUM('active','inactive') DEFAULT 'active',
    FOREIGN KEY (school_id) REFERENCES schools(id) ON DELETE CASCADE,
    FOREIGN KEY (account_type_id) REFERENCES account_types(id) ON DELETE RESTRICT,
    FOREIGN KEY (parent_id) REFERENCES accounts(id) ON DELETE SET NULL,
    UNIQUE KEY (school_id, account_code)
);

CREATE TABLE journal_entries (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    school_id BIGINT UNSIGNED NOT NULL,
    journal_no VARCHAR(50) NOT NULL,
    journal_date DATE NOT NULL,
    reference_type VARCHAR(100) NULL,
    reference_id BIGINT UNSIGNED NULL,
    description VARCHAR(500) NULL,
    status ENUM('draft','posted','cancelled') DEFAULT 'posted',
    FOREIGN KEY (school_id) REFERENCES schools(id) ON DELETE CASCADE,
    UNIQUE KEY (school_id, journal_no)
);

CREATE TABLE journal_entry_lines (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    journal_entry_id BIGINT UNSIGNED NOT NULL,
    account_id BIGINT UNSIGNED NOT NULL,
    debit DECIMAL(15,2) DEFAULT 0,
    credit DECIMAL(15,2) DEFAULT 0,
    description VARCHAR(500) NULL,
    FOREIGN KEY (journal_entry_id) REFERENCES journal_entries(id) ON DELETE CASCADE,
    FOREIGN KEY (account_id) REFERENCES accounts(id) ON DELETE RESTRICT
);

CREATE TABLE vouchers (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    school_id BIGINT UNSIGNED NOT NULL,
    voucher_type_id BIGINT UNSIGNED NOT NULL,
    voucher_no VARCHAR(50) NOT NULL,
    voucher_date DATE NOT NULL,
    payee_payer VARCHAR(200) NULL,
    description TEXT NULL,
    status ENUM('draft','posted','cancelled') DEFAULT 'draft',
    FOREIGN KEY (school_id) REFERENCES schools(id) ON DELETE CASCADE,
    FOREIGN KEY (voucher_type_id) REFERENCES voucher_types(id) ON DELETE RESTRICT,
    UNIQUE KEY (school_id, voucher_no)
);

8. Examination & Results

CREATE TABLE exams (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    school_id BIGINT UNSIGNED NOT NULL,
    academic_year_id BIGINT UNSIGNED NOT NULL,
    exam_type_id BIGINT UNSIGNED NOT NULL,
    class_id BIGINT UNSIGNED NOT NULL,
    name VARCHAR(150) NOT NULL,
    code VARCHAR(50) NOT NULL,
    start_date DATE NULL,
    end_date DATE NULL,
    status ENUM('draft','active','completed','published','cancelled') DEFAULT 'draft',
    FOREIGN KEY (school_id) REFERENCES schools(id) ON DELETE CASCADE,
    FOREIGN KEY (academic_year_id) REFERENCES academic_years(id) ON DELETE CASCADE,
    FOREIGN KEY (exam_type_id) REFERENCES exam_types(id) ON DELETE RESTRICT,
    FOREIGN KEY (class_id) REFERENCES classes(id) ON DELETE CASCADE,
    UNIQUE KEY (school_id, academic_year_id, code)
);

CREATE TABLE result_entries (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    exam_id BIGINT UNSIGNED NOT NULL,
    student_id BIGINT UNSIGNED NOT NULL,
    total_marks DECIMAL(10,2) DEFAULT 0,
    percentage DECIMAL(5,2) DEFAULT 0,
    gpa DECIMAL(5,2) NULL,
    grade VARCHAR(20) NULL,
    merit_position UNSIGNED INT NULL,
    FOREIGN KEY (exam_id) REFERENCES exams(id) ON DELETE CASCADE,
    FOREIGN KEY (student_id) REFERENCES students(id) ON DELETE CASCADE,
    UNIQUE KEY (exam_id, student_id)
);

9. Payroll Tables

CREATE TABLE salary_components (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    school_id BIGINT UNSIGNED NOT NULL,
    name VARCHAR(100) NOT NULL,
    code VARCHAR(50) NOT NULL,
    component_type ENUM('earning','deduction') NOT NULL,
    calculation_type ENUM('fixed','percentage') DEFAULT 'fixed',
    default_amount DECIMAL(12,2) DEFAULT 0,
    FOREIGN KEY (school_id) REFERENCES schools(id) ON DELETE CASCADE,
    UNIQUE KEY (school_id, code)
);

CREATE TABLE employee_salary_structures (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    school_id BIGINT UNSIGNED NOT NULL,
    employee_id BIGINT UNSIGNED NOT NULL,
    basic_salary DECIMAL(12,2) DEFAULT 0,
    house_rent DECIMAL(12,2) DEFAULT 0,
    medical_allowance DECIMAL(12,2) DEFAULT 0,
    gross_salary DECIMAL(12,2) DEFAULT 0,
    effective_from DATE NOT NULL,
    FOREIGN KEY (school_id) REFERENCES schools(id) ON DELETE CASCADE,
    FOREIGN KEY (employee_id) REFERENCES employees(id) ON DELETE CASCADE
);

Relationship Summary

FromRelationshipToType
SchoolhasManyAcademicYear, Student, Employee, Account1:N
SchoolbelongsToManyUser (via user_schools)M:M
AcademicYearhasManyClass, Exam1:N
ClasshasManySection1:N
ClassbelongsToManySubject (via class_subjects)M:M
StudenthasManyEnrollment, FeeInvoice, ResultEntry1:N
StudentbelongsToManyGuardian (via student_guardians)M:M
EmployeebelongsToDepartment, DesignationN:1
Accountself-referencingAccount (parent)1:N
JournalEntryhasManyJournalEntryLine1:N
VoucherhasManyVoucherLine1:N
UserbelongsToManyRole, SchoolM:M
RolebelongsToManyPermissionM:M
Section 03

Module Map

Module dependency graph, current status, and key integration pipelines.

Module Dependency Graph

CORE MODULES (Foundation - must be built first) ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ Schools │ │ Users │ │ Roles & │ │Dashboard │ │ │←─┤ & Auth │←─┤Permissions│ │ │ └────┬─────┘ └──────────┘ └──────────┘ └──────────┘ │ (Every other module depends on School) ▼ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ ACADEMIC CORE │ │ STUDENT MGMT │ │ EMPLOYEE & HR │ │ │ │ │ │ │ │ Academic Years │ │ Students │ │ Employees │ │ Classes │ │ Enrollments │ │ Departments │ │ Sections │ │ Guardians │ │ Designations │ │ Subjects │ │ │ │ Class Assignments│ │ Class-Subjects │ │ │ │ Subj. Assignments│ │ Exam Types │ │ │ │ Attendance │ │ Grades │ │ │ │ Biometric │ └────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘ │ │ │ ▼ ▼ ▼ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ EXAMINATION │ │ FEE MANAGEMENT │ │ PAYROLL │ │ │ │ │ │ │ │ Exams │ │ Fee Categories │ │ Salary Components│ │ Exam Subjects │ │ Fee Structures │ │ Salary Structures│ │ Result Entry │ │ Invoices │ │ Payroll Process │ │ Result Marks │ │ Payments │ │ │ │ Result Process │ │ Payment Alloc. │ │ │ │ Final Results │ │ Payment Methods │ │ │ └────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘ │ │ │ └──────────┬─────────┘ │ ▼ │ ┌──────────────────┐ │ │ ACCOUNTING │◄──────────────────────┘ │ (Double-Entry) │ │ │ │ Chart of Accounts│ │ Account Mappings │ │ Vouchers │ │ Journal Entries │ │ Financial Rpts │ └──────────────────┘

Module Status

Phase 1: Foundation Complete

ModuleStatusNotes
SchoolsCompleteCRUD working
Users & AuthCompleteBreeze auth, user CRUD
Roles & PermissionsCompleteCustom RBAC working
DashboardCompleteBasic stats implemented
Academic YearsCompleteWith is_current flag
ClassesCompleteScoped to school+year
SectionsCompleteScoped to school+year+class
SubjectsCompleteSubject types, marks config
Class-SubjectsCompleteAJAX-driven mapping
Exam TypesCompleteWith result_weight
GradesCompleteWith overlap detection
StudentsCompleteFull CRUD with enrollment
ExamsCompleteFull CRUD with subjects
Result EntryCompleteEntry + processing
Result ProcessingCompleteGPA, grade calculation

Phase 2: Fee & Accounting Partially Scaffolded

ModuleStatusNotes
Fee CategoriesModel onlyNeeds Controller + Views
Fee StructuresModel onlyNeeds Controller + Views
Fee InvoicesModel onlyNeeds Controller + Views
Fee PaymentsModel onlyNeeds Controller + Views
Payment MethodsModel onlyNeeds Seeder + Controller
Chart of AccountsModel onlyNeeds Controller + Views
Account TypesModel onlyNeeds Seeder
Account MappingsModel onlyNeeds Controller
Journal EntriesModel onlyHas relationships only
VouchersModel onlyHas relationships only
Voucher PostingPartialVoucherPostingService (61 lines)

Phase 3: Employee & HR Scaffolded

ModuleStatusNotes
EmployeesModel onlyNeeds Controller + Views
DepartmentsModel onlyNeeds Controller + Views
DesignationsModel onlyNeeds Controller + Views
Class AssignmentsModel onlyNeeds Controller
Subject AssignmentsModel onlyNeeds Controller
Salary StructuresModel onlyNeeds Controller
Salary ComponentsModel onlyNeeds Controller
Employee AttendanceModel onlyNeeds Controller + Views
Biometric DevicesModel onlyNeeds Controller

Phase 4: Advanced Features Not Started

ModuleStatusNotes
TimetableNot startedNeeds full implementation
Leave ManagementNot startedNeeds migration + implementation
NotificationsNot startedNeeds migration + implementation
DocumentsNot startedNeeds migration + implementation
Audit LogsNot startedNeeds migration + implementation
Student PromotionNot startedSidebar link exists but commented out
Transfer CertificateNot startedSidebar link exists but commented out
ID Card GenerationNot startedNeeds full implementation
Report CardsNot startedNeeds full implementation
SMS IntegrationNot startedExternal API integration
Email NotificationsNot startedLaravel Mail setup
SettingsNot startedNeeds full implementation

Key Integration Pipelines

Fee → Accounting

StudentFeePayment.created Find AccountHeadMapping Create Voucher (RCP) VoucherPostingService.post() JournalEntry created

Payroll → Accounting

PayrollProcessed Map salary components Create Voucher (PMT) VoucherPostingService.post() JournalEntry created

Exam → Result → Final Result

Exam Created Exam Subjects Configured Result Entry ResultProcessingService FinalSubjectResult

Student Enrollment → Fee Invoice

Student Enrolled Fee Structures Loaded Invoices Generated Payments Received Invoice Status Updated
Section 04

Permission Matrix

9 roles with ~120 permissions across 10 modules. Custom RBAC implementation.

Role Definitions

RoleSlugScopeDescription
Super Adminsuper-adminGlobal (all schools)System-wide access, can manage all schools
School Adminschool-adminAssigned schoolsFull access to assigned schools
PrincipalprincipalAssigned schoolsAcademic oversight, reports
TeacherteacherAssigned school + classesTeaching tasks, marks, attendance
AccountantaccountantAssigned schoolFee collection, accounting, reports
HR/Adminhr-adminAssigned schoolEmployee management, payroll
StaffstaffAssigned schoolLimited operational tasks
StudentstudentOwn data onlyView own profile, fees, results
GuardianguardianWard data onlyView child's profile, fees, results

Permission Naming Convention

Pattern: {module}.{action} Actions: view, create, update, delete, export, import, print, process, publish, cancel

Module: Schools

PermissionSuper AdminSchool AdminPrincipalTeacherAccountantHR/AdminStaffStudentGuardian
schools.view
schools.create
schools.update
schools.delete

Module: Academic

PermissionSuper AdminSchool AdminPrincipalTeacherAccountantHR/AdminStaffStudentGuardian
academic-years.view
academic-years.create
classes.view
classes.create
sections.view
subjects.view
exam-types.view
grades.view

Module: Students

PermissionSuper AdminSchool AdminPrincipalTeacherAccountantHR/AdminStaffStudentGuardian
students.view
students.create
students.update
students.promote
enrollments.view
guardians.view
guardians.create

Module: Employees

PermissionSuper AdminSchool AdminPrincipalTeacherAccountantHR/AdminStaffStudentGuardian
employees.view
employees.create
departments.view
designations.view
teacher-assignments.view
teacher-assignments.create

Module: Attendance

PermissionSuper AdminSchool AdminPrincipalTeacherAccountantHR/AdminStaffStudentGuardian
student-attendance.view
student-attendance.mark
student-attendance.report
employee-attendance.view
employee-attendance.mark

Module: Examinations

PermissionSuper AdminSchool AdminPrincipalTeacherAccountantHR/AdminStaffStudentGuardian
exams.view
exams.create
results.view
results.enter
results.process
results.publish
results.report-card
results.merit-list

Module: Fees

PermissionSuper AdminSchool AdminPrincipalTeacherAccountantHR/AdminStaffStudentGuardian
fees.view
fees.categories.view
fees.categories.create
fees.structures.view
fees.invoices.view
fees.invoices.create
fees.payments.view
fees.payments.create
fees.reports

Module: Accounting

PermissionSuper AdminSchool AdminPrincipalTeacherAccountantHR/AdminStaffStudentGuardian
accounts.view
accounts.create
accounts.chart
vouchers.view
vouchers.create
vouchers.post
journals.view
journals.create
financial-reports

Module: Payroll

PermissionSuper AdminSchool AdminPrincipalTeacherAccountantHR/AdminStaffStudentGuardian
payroll.view
payroll.process
payroll.salary-structures.view
payroll.salary-components.view

Module: System

PermissionSuper AdminSchool AdminPrincipalTeacherAccountantHR/AdminStaffStudentGuardian
users.view
users.create
roles.view
roles.create
audit-logs.view
settings.view
settings.update

Module: Self (Own Data)

PermissionSuper AdminSchool AdminPrincipalTeacherAccountantHR/AdminStaffStudentGuardian
profile.view
profile.update
profile.change-password
student.profile.view
student.fees.view
student.results.view
guardian.children.view

Authorization Implementation

Current (Manual)

// In controllers - custom authorizeSchool() method
private function authorizeSchool(int $schoolId): void
{
    if (auth()->user()->hasRole('Super Admin')) {
        return;
    }

    $hasSchool = auth()->user()->schools()
        ->where('school_id', $schoolId)
        ->wherePivot('status', 'active')
        ->exists();

    if (!$hasSchool) {
        abort(403, 'Unauthorized access to this school.');
    }
}

Target (Policy-Based)

// app/Policies/SchoolPolicy.php
class SchoolPolicy
{
    public function viewAny(User $user): bool
    {
        return $user->hasPermission('schools.view');
    }

    public function view(User $user, School $school): bool
    {
        if ($user->hasRole('super-admin')) return true;
        return $user->schools()->where('schools.id', $school->id)
            ->wherePivot('status', 'active')->exists()
            && $user->hasPermission('schools.view');
    }
}
Section 05

Accounting Architecture

Double-entry bookkeeping engine, Chart of Accounts hierarchy, voucher types, transaction flows, and financial reports.

Core Principle Every financial transaction is recorded as balanced journal entries where TOTAL DEBIT = TOTAL CREDIT. Posted records are immutable; corrections via reversal entries.

Account Types (Global - seeded once)

CodeNameNormal BalanceDescription
100AssetDebitResources owned (Cash, Bank, Receivables)
200LiabilityCreditObligations (Payables, Loans)
300EquityCreditOwner's equity, retained earnings
400IncomeCreditRevenue (Fee income, other income)
500ExpenseDebitCosts (Salary, utilities, supplies)

Chart of Accounts Hierarchy (Per School)

ASSETS (100) ├── Current Assets (110) │ ├── Cash in Hand (111) │ ├── Cash at Bank (120) │ │ ├── Primary Bank Account (121) │ │ └── Savings Account (122) │ ├── Accounts Receivable (130) │ │ ├── Student Fee Receivable (131) │ │ └── Other Receivables (132) │ └── Prepaid Expenses (140) ├── Fixed Assets (150) │ ├── Buildings (151) │ ├── Furniture & Fixtures (152) │ ├── Computer Equipment (153) │ └── Vehicles (154) └── Other Assets (160) LIABILITIES (200) ├── Current Liabilities (210) │ ├── Accounts Payable (211) │ ├── Salary Payable (212) │ ├── Tax Payable (213) │ └── Student Advances (214) ├── Long-term Liabilities (220) │ ├── Bank Loans (221) │ └── Other Loans (222) └── Other Liabilities (230) EQUITY (300) ├── Capital Fund (310) ├── Retained Earnings (320) └── Reserve Fund (330) INCOME (400) ├── Tuition Fee Income (410) ├── Admission Fee Income (411) ├── Exam Fee Income (412) ├── Activity Fee Income (413) ├── Transport Fee Income (414) ├── Hostel Fee Income (415) ├── Library Fee Income (416) ├── Lab Fee Income (417) ├── Other Fee Income (418) ├── Donations & Grants (420) ├── Government Grants (421) ├── Investment Income (430) └── Other Income (440) EXPENSES (500) ├── Staff Expenses (510) │ ├── Teacher Salary (511) │ ├── Staff Salary (512) │ ├── Accountant Salary (513) │ ├── Bonus & Incentives (514) │ └── Employee Benefits (515) ├── Operational Expenses (520) │ ├── Electricity (521) │ ├── Water & Sewerage (522) │ ├── Internet & Phone (523) │ ├── Office Supplies (524) │ ├── Printing & Stationery (525) │ └── Maintenance & Repairs (526) ├── Academic Expenses (530) │ ├── Books & Materials (531) │ ├── Lab Equipment (532) │ ├── Sports Equipment (533) │ └── Educational Software (534) ├── Administrative Expenses (540) │ ├── Rent (541) │ ├── Insurance (542) │ ├── Legal & Professional (543) │ └── Bank Charges (544) ├── Transportation Expenses (550) │ ├── Vehicle Fuel (551) │ ├── Vehicle Maintenance (552) │ └── Driver Salaries (553) └── Other Expenses (560) ├── Donations Made (561) ├── Miscellaneous (562) └── Depreciation (563)

Voucher Types

CodeNameDescriptionTypical Use
RCPReceiptMoney receivedFee collection, donations, grants
PMTPaymentMoney paidSalary, bills, purchases
JNLJournalGeneral journal entryAdjustments, accruals, depreciation
CONContraCash/bank transferTransfer between bank accounts

Transaction Flows

1. Fee Collection (Receipt Voucher)

Create StudentFeePayment Allocate to Invoices Create Receipt Voucher Post → Journal Entry
-- Journal Entry for fee collection:
DEBIT   Cash in Hand (111)              ৳5,000
CREDIT  Tuition Fee Income (410)        ৳5,000

-- Or if deposited to bank:
DEBIT   Cash at Bank (121)              ৳5,000
CREDIT  Tuition Fee Income (410)        ৳5,000

2. Salary Payment (Payment Voucher)

Process Payroll Create Payment Voucher Post → Journal Entry
-- Journal Entry for salary payment:
DEBIT   Teacher Salary (511)            ৳50,000
DEBIT   Staff Salary (512)              ৳30,000
CREDIT  Cash at Bank (121)              ৳80,000

3. Bank Transfer (Contra Voucher)

DEBIT   Savings Account (122)           ৳100,000
CREDIT  Primary Bank Account (121)      ৳100,000

4. General Adjustment (Journal Voucher)

-- Depreciation entry:
DEBIT   Depreciation (563)              ৳10,000
CREDIT  Computer Equipment (153)        ৳10,000

Accounting Rules

Rule 1: Double-Entry Balance

Every journal entry MUST satisfy: SUM(all debits) = SUM(all credits). Enforced at voucher line validation, journal entry creation, and application level.

Rule 2: Immutability

Once a journal entry status is posted: cannot be edited, cannot be deleted, cannot be cancelled without creating a reversal.

Rule 3: Reversal Entries

To correct a posted entry: create a REVERSAL entry (swap debits/credits), reference the original, then create the CORRECT entry.

Rule 4: Account Head Mappings

Financial modules (Fees, Payroll) map to accounts via account_head_mappings. Each fee category maps to an income account.

Rule 5: Voucher Numbering

Sequential per school per type. Format: {TYPE}-{YYYY}-{SEQUENCE} (e.g., RCP-2026-001).

Rule 6: Fiscal Period

Each academic year serves as a fiscal period. Vouchers dated within the academic year. Year-end closing creates closing entry.

VoucherPostingService

// app/Services/Accounting/VoucherPostingService.php
public function post(Voucher $voucher): JournalEntry
{
    return DB::transaction(function () use ($voucher) {
        // 1. Validate voucher is in 'posted' status
        // 2. Validate at least 2 lines
        // 3. Validate SUM(debit) == SUM(credit)
        // 4. Create journal entry from voucher
        // 5. Copy voucher lines to journal entry lines
        // 6. Return the created journal entry
    });
}

Financial Reports

1. Trial Balance

Account CodeAccount NameDebitCredit
111Cash in Hand৳50,000
121Cash at Bank৳200,000
410Tuition Fee Income৳250,000
511Teacher Salary৳150,000
TOTAL৳400,000৳400,000

2. Profit & Loss Statement

ItemAmount
Revenue
  Tuition Fee Income৳250,000
  Other Income৳10,000
Total Revenue৳260,000
Expenses
  Teacher Salary৳150,000
  Staff Salary৳30,000
  Electricity৳5,000
  Other Expenses৳8,000
Total Expenses৳193,000
Net Income৳67,000

3. Balance Sheet

ItemAmount
Assets
  Cash in Hand৳50,000
  Cash at Bank৳200,000
  Computer Equipment৳80,000
Total Assets৳330,000
Liabilities
  Salary Payable৳20,000
Total Liabilities৳20,000
Equity
  Capital Fund৳250,000
  Retained Earnings৳60,000
Total Equity৳310,000
Total Liabilities + Equity৳330,000

4. General Ledger

DateVoucher NoDescriptionDebitCreditBalance
2026-01-01RCP-2026-001Fee collection৳5,000৳5,000
2026-01-05RCP-2026-002Fee collection৳3,000৳8,000
2026-01-10PMT-2026-001Office supplies৳2,000৳6,000

Data Integrity

Decimal Precision

Financial amounts: DECIMAL(15,2) (up to 999,999,999,999.99). Currency: Bangladeshi Taka (৳). All calculations use bccomp(), bcmul(), bcdiv().

Audit Trail

Every financial transaction creates an audit log entry. Journal entries record who posted, when, what changed. Original values preserved in JSON.

Reconciliation

Bank reconciliation matches system transactions with bank statements. Unreconciled items flagged for review. Period-end reconciliation reports.

Integration Diagram

┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ Fee Module │────▶│ Accounting │◀────│ Payroll Module │ │ │ │ Engine │ │ │ │ Fee Categories │ │ │ │ Salary Components│ │ Fee Structures │ │ Chart of │ │ Salary Structures│ │ Invoices │ │ Accounts │ │ Payroll Process │ │ Payments │ │ │ │ │ └─────────────────┘ │ Vouchers │ └─────────────────┘ │ Journal Entries │ ┌─────────────────┐ │ Account Mappings │ ┌─────────────────┐ │ Bank Module │────▶│ │◀────│ Expense Module │ │ │ │ Financial │ │ │ │ Transfers │ │ Reports │ │ Bills, Invoices │ │ Reconciliation │ │ │ │ Purchases │ └─────────────────┘ └─────────────────┘ └─────────────────┘
Section 06

Development Roadmap

Phase breakdown, task priorities, technical debt, and risk assessment for implementation.

Phase 1: Foundation Complete

Core Infrastructure

TaskStatusNotes
Laravel 11 project setupDoneSchoolPro---Manual AI
Laravel Breeze authDoneLogin, register, password reset
Multi-school modelDoneschools table with soft deletes
User model with rolesDoneCustom RBAC, not Spatie
Admin layout with sidebarDone2109-line admin layout
Dashboard with statsDoneBasic stats, attendance, payments

Academic Module

TaskStatusNotes
Academic Years CRUDDoneWith is_current flag
Classes CRUDDoneScoped to school+year
Sections CRUDDoneScoped to school+year+class
Subjects CRUDDoneSubject types, marks config
Class-Subjects CRUDDoneAJAX-driven mapping
Exam Types CRUDDoneWith result_weight
Grades CRUDDoneWith overlap detection

Student & Examination Module

TaskStatusNotes
Students CRUDDoneWith enrollment, photo upload
Student code generationDoneYear+sequence pattern
Enrollment managementDoneAuto roll number
Exams CRUDDoneWith subjects, auto code
Result EntryDonePer student, per exam
Result ProcessingDoneGPA, grade, percentage
Final Subject ResultsDoneWeighted across exams

Phase 2: Fee Management & Accounting Current Phase

Fee Management

TaskPriorityComplexityDepends On
Fee Categories CRUDHighLowPhase 1
Fee Structures CRUDHighMediumFee Categories, Academic Years, Classes
Fee Invoices generationHighHighFee Structures, Student Enrollments
Payment Methods CRUDHighLow-
Fee Payments processingHighHighFee Invoices, Payment Methods
Payment Allocation logicHighHighFee Payments, Fee Invoices
Fee reportsMediumMediumAll fee tables
Bulk invoice generationMediumHighFee Structures

Chart of Accounts & Vouchers

TaskPriorityComplexityDepends On
Account Types seederHighLow-
Accounts CRUDHighMediumAccount Types
Account Head Mappings CRUDHighMediumAccounts
Default CoA seeder (per school)HighMediumAccount Types
Voucher Types seederHighLow-
Vouchers CRUD with postingHighHighVoucher Types, Accounts
Journal Entry managementHighHighAccounts
Reversal entry creationHighHighJournal Entries

Fee-Accounting Integration

TaskPriorityComplexityDepends On
Fee collection → Journal entryHighHighAll Phase 2 modules
Payment receipt voucher creationHighHighVouchers, Fee Payments
Account head mapping configHighMediumAccount Mappings
Fee category → Income account mappingHighMediumAccount Mappings

Phase 3: Employee & HR Planned

TaskPriorityComplexityDepends On
Departments CRUDHighLowPhase 1
Designations CRUDHighLowDepartments
Employees CRUDHighHighDepartments, Designations
Teacher-Class/Subject assignmentsHighMediumEmployees, Classes
Employee attendance CRUDHighMediumEmployees
Student attendance CRUDHighHighStudent Enrollments
Salary components CRUDHighMedium-
Salary structure CRUDHighMediumSalary Components, Employees
Payroll processingHighHighSalary Structures
Payroll → Accounting integrationHighHighPayroll, Accounts
Leave managementMediumHighLeave Types, Employees

Phase 4: Advanced Features Planned

TaskPriorityComplexityDepends On
Timetable managementMediumHighTime Slots, Classes, Subjects
In-app notification systemMediumHighNotifications table
Email notification setupMediumMediumLaravel Mail
SMS integrationLowHighExternal API
Document upload systemMediumMediumLaravel Storage
Student promotionMediumHighStudents, Enrollments
Transfer certificateMediumMediumStudents, Enrollments
Report cardsMediumHighResults, Grades
ID card generationLowMediumStudents, School
Audit log systemHighMedium-
Settings managementMediumMedium-

Phase 5: Reporting & Analytics Planned

TaskPriorityComplexityDepends On
Student enrollment reportsMediumMediumStudents, Enrollments
Attendance reportsMediumMediumAttendance
Fee collection reportsHighHighFee Payments
Outstanding fee reportsHighMediumFee Invoices
Financial reports (P&L, Balance Sheet)HighHighJournal Entries
Trial balance reportHighMediumJournal Entry Lines
General ledger reportHighHighJournal Entry Lines
Dashboard chartsMediumMediumAll modules
Export to Excel/PDFMediumMediumAll reports

Development Sequence

Immediate (Next Sprint)

  1. Fee Categories CRUD (Controller + Views)
  2. Fee Structures CRUD (Controller + Views)
  3. Account Types seeder
  4. Accounts CRUD (Controller + Views)
  5. Voucher Types seeder

Short-term (2-3 Sprints)

  1. Fee Invoices generation logic
  2. Payment Methods CRUD
  3. Fee Payments processing
  4. Payment Allocation logic
  5. Account Head Mappings CRUD

Medium-term (1-2 Months)

  1. Voucher CRUD with posting
  2. Journal Entry management
  3. Reversal entry system
  4. Fee → Accounting integration
  5. Dashboard financial widgets

Long-term (2-3 Months)

  1. Employee module (full)
  2. Attendance module
  3. Payroll module
  4. Payroll → Accounting integration
  5. Financial reports

Technical Debt

High Priority

Critical issues to address before production
  1. Consolidate layout systems - admin.blade.php vs app.blade.php
  2. Add authorization to all controllers - SchoolController, SchoolClassController, PermissionController, RoleController, UserController currently have NONE
  3. Refactor authorizeSchool() to use Policies - DRY up the repeated pattern
  4. Add Form Request classes - Only 2 exist; need one per controller method
  5. Complete empty models - ~25 models have no fillable, no relationships, no casts

Medium Priority

Important improvements
  1. Add Lucide Icons - Replace inline SVGs
  2. Switch font to Inter - Currently uses Figtree
  3. Add Alpine.js to admin layout - Replace vanilla JS sidebar logic
  4. Add database seeders - Roles, permissions, account types, voucher types, default CoA
  5. Add model factories - For testing

Low Priority

Polish and optimization
  1. Add unit tests - Zero domain tests exist
  2. Add feature tests - Only Breeze default auth tests
  3. Implement API routes - For mobile app or third-party integration
  4. Add rate limiting - To AJAX endpoints
  5. Performance optimization - Query optimization, caching

Risk Assessment

RiskImpactLikelihoodMitigation
Empty models lack relationships High Certain Complete all models before building controllers
No authorization on key controllers High Certain Implement policies immediately
Financial precision issues High Medium Use bcmath, decimal(15,2), test thoroughly
Concurrent fee payment race conditions High Medium Use DB transactions + locking
Layout inconsistency (two systems) Medium Certain Consolidate to single admin layout
Missing form requests Medium Certain Create dedicated request classes
No test coverage Medium Certain Write tests alongside features
Performance with large datasets Medium Medium Implement pagination, indexes, caching
Accounting balance violations High Low Enforce at service + database level
Data corruption from direct DB edits High Low Audit logs, soft deletes, backup strategy

SchoolPro System Architecture Document — Version 1.0.0 — September 2026

Generated from source documentation. All rights reserved.