Technology stack, architectural principles, module structure, directory layout, and key design decisions.
| Layer | Technology | Version |
|---|---|---|
| Backend | Laravel | 11.55.1 |
| PHP | PHP | 8.2.4 |
| Database | MariaDB | 10.4.28 (port 3305) |
| Server | Apache (XAMPP) | 2.4.56 |
| Frontend Build | Vite | via laravel-vite-plugin 1.2.0 |
| CSS Framework | Tailwind CSS | 3.x |
| JS Framework | Alpine.js | 3.x |
| Icons | Lucide Icons | (to be integrated) |
| Fonts | Inter | (via Google Fonts) |
| Node.js | Node.js | 24.16.0 |
| Package Manager | Composer / npm | 2.8.2 / 11.13.0 |
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.
Custom RBAC (not Spatie) with roles, permissions, role_permissions, user_roles tables. Roles are global; permissions organized by module. System roles cannot be deleted.
Complete double-entry bookkeeping with Chart of Accounts. Voucher types: Receipt, Payment, Journal, Contra. Every entry must satisfy DEBIT = CREDIT. Posted records are immutable.
Business logic in Service classes under app/Services/. Controllers handle HTTP only. Database transactions for multi-step operations. Reusable across controllers, commands, jobs.
Dedicated Form Request classes for each endpoint. Validation rules centralized in request classes, not controllers. Auto-fails with 422 responses.
All domain entities use soft deletes for data preservation. Queries use withTrashed() only when explicitly needed. Never hard-delete domain data.
Complete entity-relationship design with SQL DDL for 25+ tables, relationships, and indexes.
| Table | Purpose |
|---|---|
users | Application users |
password_reset_tokens | Password reset |
sessions | User sessions |
cache | Application cache |
cache_locks | Cache locks |
jobs | Queue jobs |
job_batches | Queue batches |
failed_jobs | Failed jobs |
account_types | Chart of accounts types (Asset/Liability/Equity/Income/Expense) |
voucher_types | Voucher type definitions (Receipt/Payment/Journal/Contra) |
roles | User roles (global) |
permissions | Granular permissions (global) |
role_permissions | Role-permission pivot |
user_roles | User-role pivot |
| Table | Purpose |
|---|---|
schools | School institutions |
academic_years | Academic years per school |
classes | Classes per school/year |
sections | Sections per class |
subjects | Subjects per school |
class_subjects | Subject-to-class mapping |
exam_types | Exam type templates |
grades | Grading scale |
students | Student records |
guardians | Guardian/parent records |
student_guardians | Student-guardian pivot |
student_enrollments | Student class enrollment |
student_attendances | Student daily attendance |
employee_attendances | Employee daily attendance |
employees | Employee records |
departments | Organizational departments |
designations | Job designations |
employee_class_assignments | Teacher-class assignments |
employee_subject_assignments | Teacher-subject assignments |
employee_salary_structures | Employee salary config |
salary_components | Salary component definitions |
employee_salary_components | Employee salary component values |
biometric_devices | Biometric attendance devices |
biometric_logs | Biometric punch logs |
fee_categories | Fee category definitions |
fee_structures | Fee amounts per class/category |
student_fee_invoices | Generated invoices |
student_fee_invoice_items | Invoice line items |
payment_methods | Payment method definitions |
student_fee_payments | Payment receipts |
student_fee_payment_allocations | Payment-to-invoice allocation |
accounts | Chart of accounts per school |
account_head_mappings | Module-to-account mappings |
journal_entries | Journal entry headers |
journal_entry_lines | Journal entry lines |
vouchers | Voucher headers |
voucher_lines | Voucher lines |
exams | Exam instances |
exam_subjects | Exam subject configuration |
result_entries | Student exam results |
result_marks | Per-subject marks |
final_subject_results | Weighted final results |
user_schools | User-school assignment pivot |
timetables | Timetable instances |
timetable_time_slots | Time slot definitions |
timetable_records | Schedule entries |
notifications | In-app notifications |
documents | Document attachments |
audit_logs | System audit trail |
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
);
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)
);
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)
);
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)
);
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)
);
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)
);
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)
);
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)
);
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
);
| From | Relationship | To | Type |
|---|---|---|---|
| School | hasMany | AcademicYear, Student, Employee, Account | 1:N |
| School | belongsToMany | User (via user_schools) | M:M |
| AcademicYear | hasMany | Class, Exam | 1:N |
| Class | hasMany | Section | 1:N |
| Class | belongsToMany | Subject (via class_subjects) | M:M |
| Student | hasMany | Enrollment, FeeInvoice, ResultEntry | 1:N |
| Student | belongsToMany | Guardian (via student_guardians) | M:M |
| Employee | belongsTo | Department, Designation | N:1 |
| Account | self-referencing | Account (parent) | 1:N |
| JournalEntry | hasMany | JournalEntryLine | 1:N |
| Voucher | hasMany | VoucherLine | 1:N |
| User | belongsToMany | Role, School | M:M |
| Role | belongsToMany | Permission | M:M |
Module dependency graph, current status, and key integration pipelines.
| Module | Status | Notes |
|---|---|---|
| Schools | Complete | CRUD working |
| Users & Auth | Complete | Breeze auth, user CRUD |
| Roles & Permissions | Complete | Custom RBAC working |
| Dashboard | Complete | Basic stats implemented |
| Academic Years | Complete | With is_current flag |
| Classes | Complete | Scoped to school+year |
| Sections | Complete | Scoped to school+year+class |
| Subjects | Complete | Subject types, marks config |
| Class-Subjects | Complete | AJAX-driven mapping |
| Exam Types | Complete | With result_weight |
| Grades | Complete | With overlap detection |
| Students | Complete | Full CRUD with enrollment |
| Exams | Complete | Full CRUD with subjects |
| Result Entry | Complete | Entry + processing |
| Result Processing | Complete | GPA, grade calculation |
| Module | Status | Notes |
|---|---|---|
| Fee Categories | Model only | Needs Controller + Views |
| Fee Structures | Model only | Needs Controller + Views |
| Fee Invoices | Model only | Needs Controller + Views |
| Fee Payments | Model only | Needs Controller + Views |
| Payment Methods | Model only | Needs Seeder + Controller |
| Chart of Accounts | Model only | Needs Controller + Views |
| Account Types | Model only | Needs Seeder |
| Account Mappings | Model only | Needs Controller |
| Journal Entries | Model only | Has relationships only |
| Vouchers | Model only | Has relationships only |
| Voucher Posting | Partial | VoucherPostingService (61 lines) |
| Module | Status | Notes |
|---|---|---|
| Employees | Model only | Needs Controller + Views |
| Departments | Model only | Needs Controller + Views |
| Designations | Model only | Needs Controller + Views |
| Class Assignments | Model only | Needs Controller |
| Subject Assignments | Model only | Needs Controller |
| Salary Structures | Model only | Needs Controller |
| Salary Components | Model only | Needs Controller |
| Employee Attendance | Model only | Needs Controller + Views |
| Biometric Devices | Model only | Needs Controller |
| Module | Status | Notes |
|---|---|---|
| Timetable | Not started | Needs full implementation |
| Leave Management | Not started | Needs migration + implementation |
| Notifications | Not started | Needs migration + implementation |
| Documents | Not started | Needs migration + implementation |
| Audit Logs | Not started | Needs migration + implementation |
| Student Promotion | Not started | Sidebar link exists but commented out |
| Transfer Certificate | Not started | Sidebar link exists but commented out |
| ID Card Generation | Not started | Needs full implementation |
| Report Cards | Not started | Needs full implementation |
| SMS Integration | Not started | External API integration |
| Email Notifications | Not started | Laravel Mail setup |
| Settings | Not started | Needs full implementation |
9 roles with ~120 permissions across 10 modules. Custom RBAC implementation.
| Role | Slug | Scope | Description |
|---|---|---|---|
| Super Admin | super-admin | Global (all schools) | System-wide access, can manage all schools |
| School Admin | school-admin | Assigned schools | Full access to assigned schools |
| Principal | principal | Assigned schools | Academic oversight, reports |
| Teacher | teacher | Assigned school + classes | Teaching tasks, marks, attendance |
| Accountant | accountant | Assigned school | Fee collection, accounting, reports |
| HR/Admin | hr-admin | Assigned school | Employee management, payroll |
| Staff | staff | Assigned school | Limited operational tasks |
| Student | student | Own data only | View own profile, fees, results |
| Guardian | guardian | Ward data only | View child's profile, fees, results |
| Permission | Super Admin | School Admin | Principal | Teacher | Accountant | HR/Admin | Staff | Student | Guardian |
|---|---|---|---|---|---|---|---|---|---|
schools.view | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
schools.create | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
schools.update | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
schools.delete | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Permission | Super Admin | School Admin | Principal | Teacher | Accountant | HR/Admin | Staff | Student | Guardian |
|---|---|---|---|---|---|---|---|---|---|
academic-years.view | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
academic-years.create | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
classes.view | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ |
classes.create | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
sections.view | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ |
subjects.view | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ |
exam-types.view | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
grades.view | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ |
| Permission | Super Admin | School Admin | Principal | Teacher | Accountant | HR/Admin | Staff | Student | Guardian |
|---|---|---|---|---|---|---|---|---|---|
students.view | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ |
students.create | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ |
students.update | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
students.promote | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
enrollments.view | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ |
guardians.view | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ |
guardians.create | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ |
| Permission | Super Admin | School Admin | Principal | Teacher | Accountant | HR/Admin | Staff | Student | Guardian |
|---|---|---|---|---|---|---|---|---|---|
employees.view | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
employees.create | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
departments.view | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
designations.view | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
teacher-assignments.view | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
teacher-assignments.create | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
| Permission | Super Admin | School Admin | Principal | Teacher | Accountant | HR/Admin | Staff | Student | Guardian |
|---|---|---|---|---|---|---|---|---|---|
student-attendance.view | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ |
student-attendance.mark | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ |
student-attendance.report | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
employee-attendance.view | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
employee-attendance.mark | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
| Permission | Super Admin | School Admin | Principal | Teacher | Accountant | HR/Admin | Staff | Student | Guardian |
|---|---|---|---|---|---|---|---|---|---|
exams.view | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ |
exams.create | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
results.view | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ |
results.enter | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
results.process | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
results.publish | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
results.report-card | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ |
results.merit-list | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Permission | Super Admin | School Admin | Principal | Teacher | Accountant | HR/Admin | Staff | Student | Guardian |
|---|---|---|---|---|---|---|---|---|---|
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 | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
| Permission | Super Admin | School Admin | Principal | Teacher | Accountant | HR/Admin | Staff | Student | Guardian |
|---|---|---|---|---|---|---|---|---|---|
accounts.view | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
accounts.create | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
accounts.chart | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
vouchers.view | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
vouchers.create | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
vouchers.post | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
journals.view | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
journals.create | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
financial-reports | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
| Permission | Super Admin | School Admin | Principal | Teacher | Accountant | HR/Admin | Staff | Student | Guardian |
|---|---|---|---|---|---|---|---|---|---|
payroll.view | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ |
payroll.process | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ |
payroll.salary-structures.view | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ |
payroll.salary-components.view | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ |
| Permission | Super Admin | School Admin | Principal | Teacher | Accountant | HR/Admin | Staff | Student | Guardian |
|---|---|---|---|---|---|---|---|---|---|
users.view | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
users.create | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
roles.view | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
roles.create | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
audit-logs.view | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
settings.view | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
settings.update | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Permission | Super Admin | School Admin | Principal | Teacher | Accountant | HR/Admin | Staff | Student | Guardian |
|---|---|---|---|---|---|---|---|---|---|
profile.view | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
profile.update | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
profile.change-password | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
student.profile.view | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
student.fees.view | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
student.results.view | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
guardian.children.view | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ |
// 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.');
}
}
// 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');
}
}
Double-entry bookkeeping engine, Chart of Accounts hierarchy, voucher types, transaction flows, and financial reports.
| Code | Name | Normal Balance | Description |
|---|---|---|---|
100 | Asset | Debit | Resources owned (Cash, Bank, Receivables) |
200 | Liability | Credit | Obligations (Payables, Loans) |
300 | Equity | Credit | Owner's equity, retained earnings |
400 | Income | Credit | Revenue (Fee income, other income) |
500 | Expense | Debit | Costs (Salary, utilities, supplies) |
| Code | Name | Description | Typical Use |
|---|---|---|---|
RCP | Receipt | Money received | Fee collection, donations, grants |
PMT | Payment | Money paid | Salary, bills, purchases |
JNL | Journal | General journal entry | Adjustments, accruals, depreciation |
CON | Contra | Cash/bank transfer | Transfer between bank accounts |
-- 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
-- Journal Entry for salary payment:
DEBIT Teacher Salary (511) ৳50,000
DEBIT Staff Salary (512) ৳30,000
CREDIT Cash at Bank (121) ৳80,000
DEBIT Savings Account (122) ৳100,000
CREDIT Primary Bank Account (121) ৳100,000
-- Depreciation entry:
DEBIT Depreciation (563) ৳10,000
CREDIT Computer Equipment (153) ৳10,000
Every journal entry MUST satisfy: SUM(all debits) = SUM(all credits). Enforced at voucher line validation, journal entry creation, and application level.
Once a journal entry status is posted: cannot be edited, cannot be deleted, cannot be cancelled without creating a reversal.
To correct a posted entry: create a REVERSAL entry (swap debits/credits), reference the original, then create the CORRECT entry.
Financial modules (Fees, Payroll) map to accounts via account_head_mappings. Each fee category maps to an income account.
Sequential per school per type. Format: {TYPE}-{YYYY}-{SEQUENCE} (e.g., RCP-2026-001).
Each academic year serves as a fiscal period. Vouchers dated within the academic year. Year-end closing creates closing entry.
// 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
});
}
| Account Code | Account Name | Debit | Credit |
|---|---|---|---|
| 111 | Cash in Hand | ৳50,000 | |
| 121 | Cash at Bank | ৳200,000 | |
| 410 | Tuition Fee Income | ৳250,000 | |
| 511 | Teacher Salary | ৳150,000 | |
| TOTAL | ৳400,000 | ৳400,000 | |
| Item | Amount |
|---|---|
| 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 |
| Item | Amount |
|---|---|
| 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 |
| Date | Voucher No | Description | Debit | Credit | Balance |
|---|---|---|---|---|---|
| 2026-01-01 | RCP-2026-001 | Fee collection | ৳5,000 | ৳5,000 | |
| 2026-01-05 | RCP-2026-002 | Fee collection | ৳3,000 | ৳8,000 | |
| 2026-01-10 | PMT-2026-001 | Office supplies | ৳2,000 | ৳6,000 |
Financial amounts: DECIMAL(15,2) (up to 999,999,999,999.99). Currency: Bangladeshi Taka (৳). All calculations use bccomp(), bcmul(), bcdiv().
Every financial transaction creates an audit log entry. Journal entries record who posted, when, what changed. Original values preserved in JSON.
Bank reconciliation matches system transactions with bank statements. Unreconciled items flagged for review. Period-end reconciliation reports.
Phase breakdown, task priorities, technical debt, and risk assessment for implementation.
| Task | Status | Notes |
|---|---|---|
| Laravel 11 project setup | Done | SchoolPro---Manual AI |
| Laravel Breeze auth | Done | Login, register, password reset |
| Multi-school model | Done | schools table with soft deletes |
| User model with roles | Done | Custom RBAC, not Spatie |
| Admin layout with sidebar | Done | 2109-line admin layout |
| Dashboard with stats | Done | Basic stats, attendance, payments |
| Task | Status | Notes |
|---|---|---|
| Academic Years CRUD | Done | With is_current flag |
| Classes CRUD | Done | Scoped to school+year |
| Sections CRUD | Done | Scoped to school+year+class |
| Subjects CRUD | Done | Subject types, marks config |
| Class-Subjects CRUD | Done | AJAX-driven mapping |
| Exam Types CRUD | Done | With result_weight |
| Grades CRUD | Done | With overlap detection |
| Task | Status | Notes |
|---|---|---|
| Students CRUD | Done | With enrollment, photo upload |
| Student code generation | Done | Year+sequence pattern |
| Enrollment management | Done | Auto roll number |
| Exams CRUD | Done | With subjects, auto code |
| Result Entry | Done | Per student, per exam |
| Result Processing | Done | GPA, grade, percentage |
| Final Subject Results | Done | Weighted across exams |
| Task | Priority | Complexity | Depends On |
|---|---|---|---|
| Fee Categories CRUD | High | Low | Phase 1 |
| Fee Structures CRUD | High | Medium | Fee Categories, Academic Years, Classes |
| Fee Invoices generation | High | High | Fee Structures, Student Enrollments |
| Payment Methods CRUD | High | Low | - |
| Fee Payments processing | High | High | Fee Invoices, Payment Methods |
| Payment Allocation logic | High | High | Fee Payments, Fee Invoices |
| Fee reports | Medium | Medium | All fee tables |
| Bulk invoice generation | Medium | High | Fee Structures |
| Task | Priority | Complexity | Depends On |
|---|---|---|---|
| Account Types seeder | High | Low | - |
| Accounts CRUD | High | Medium | Account Types |
| Account Head Mappings CRUD | High | Medium | Accounts |
| Default CoA seeder (per school) | High | Medium | Account Types |
| Voucher Types seeder | High | Low | - |
| Vouchers CRUD with posting | High | High | Voucher Types, Accounts |
| Journal Entry management | High | High | Accounts |
| Reversal entry creation | High | High | Journal Entries |
| Task | Priority | Complexity | Depends On |
|---|---|---|---|
| Fee collection → Journal entry | High | High | All Phase 2 modules |
| Payment receipt voucher creation | High | High | Vouchers, Fee Payments |
| Account head mapping config | High | Medium | Account Mappings |
| Fee category → Income account mapping | High | Medium | Account Mappings |
| Task | Priority | Complexity | Depends On |
|---|---|---|---|
| Departments CRUD | High | Low | Phase 1 |
| Designations CRUD | High | Low | Departments |
| Employees CRUD | High | High | Departments, Designations |
| Teacher-Class/Subject assignments | High | Medium | Employees, Classes |
| Employee attendance CRUD | High | Medium | Employees |
| Student attendance CRUD | High | High | Student Enrollments |
| Salary components CRUD | High | Medium | - |
| Salary structure CRUD | High | Medium | Salary Components, Employees |
| Payroll processing | High | High | Salary Structures |
| Payroll → Accounting integration | High | High | Payroll, Accounts |
| Leave management | Medium | High | Leave Types, Employees |
| Task | Priority | Complexity | Depends On |
|---|---|---|---|
| Timetable management | Medium | High | Time Slots, Classes, Subjects |
| In-app notification system | Medium | High | Notifications table |
| Email notification setup | Medium | Medium | Laravel Mail |
| SMS integration | Low | High | External API |
| Document upload system | Medium | Medium | Laravel Storage |
| Student promotion | Medium | High | Students, Enrollments |
| Transfer certificate | Medium | Medium | Students, Enrollments |
| Report cards | Medium | High | Results, Grades |
| ID card generation | Low | Medium | Students, School |
| Audit log system | High | Medium | - |
| Settings management | Medium | Medium | - |
| Task | Priority | Complexity | Depends On |
|---|---|---|---|
| Student enrollment reports | Medium | Medium | Students, Enrollments |
| Attendance reports | Medium | Medium | Attendance |
| Fee collection reports | High | High | Fee Payments |
| Outstanding fee reports | High | Medium | Fee Invoices |
| Financial reports (P&L, Balance Sheet) | High | High | Journal Entries |
| Trial balance report | High | Medium | Journal Entry Lines |
| General ledger report | High | High | Journal Entry Lines |
| Dashboard charts | Medium | Medium | All modules |
| Export to Excel/PDF | Medium | Medium | All reports |
| Risk | Impact | Likelihood | Mitigation |
|---|---|---|---|
| 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.