Skip to content

Modules & Feature Flags

KoAkademy provides modular extensibility and runtime configurability through three distinct mechanisms:

  1. Modules (Code level): Optional domain features with dedicated models, controllers, migrations, and UI.
  2. Feature Flags (Runtime level): Class-based toggles powered by Laravel Pennant for gradual feature rollouts.
  3. Institution Settings (Configuration level): Per-school settings stored via spatie/laravel-settings.

Modules are managed via nwidart/laravel-modules and integrated with Filament through coolsam/modules:

KoAkademy includes six bundled modules under Modules/ that are active by default:

ModuleNamespacePurpose
AnnouncementModules\AnnouncementSchool-wide news and targeted broadcast banners
CashierModules\CashierIn-person student balance lookup and cashier payment processing
InventoryModules\InventoryCampus equipment tracking, suppliers, and stock ledger
LibrarySystemModules\LibrarySystemBook cataloging, borrow/return logs, and digital paper archives
NotificationCenterModules\NotificationCenterDynamic notification templates and batch broadcast jobs
StudentMedicalRecordsModules\StudentMedicalRecordsConfidential clinic visit notes and student medical profiles

Standalone modules (like the Forms Module) are published as separate Composer packages via the KoAkademy Module Registry.

Installation is performed at the Composer level:

Terminal window
# Add the registry repository
composer config repositories.koakademy composer https://yukazakiri.github.io/koakademy-modules
# Require the desired module package
composer require koakademy/module-forms:^1.0
# Run module database migrations
php artisan migrate --force

KoAkademy uses class-based feature flags located in app/Features/Toggles/. Feature flags are defined in AppServiceProvider and mapped in FeatureToggleRegistry.

To add a new feature toggle:

  1. Create a toggle class in app/Features/Toggles/:
<?php
declare(strict_types=1);
namespace App\Features\Toggles;
use App\Features\Concerns\ResolvesFeatureToggle;
use App\Features\Contracts\FeatureToggle;
final class FacultyAnalytics implements FeatureToggle
{
use ResolvesFeatureToggle;
public function key(): string
{
return 'faculty-analytics';
}
public function name(): string
{
return 'Faculty Analytics';
}
public function summary(): string
{
return 'Visual class attendance and grade distribution charts.';
}
public function audience(): string
{
return 'faculty';
}
public function badge(): string
{
return 'Analytics';
}
public function accent(): string
{
return 'text-primary';
}
public function ctaLabel(): string
{
return 'View Analytics';
}
public function ctaUrl(): string
{
return '/faculty/analytics';
}
public function steps(): array
{
return [];
}
public function category(): string
{
return 'Faculty';
}
}
  1. Register the class in App\Services\FeatureToggleRegistry:
private const array KEY_TO_CLASS = [
// ...
'faculty-analytics' => FacultyAnalytics::class,
];
  1. Define the feature in App\Providers\AppServiceProvider::definePennantFeatures():
Feature::define(FacultyAnalytics::class);
  1. Guard backend routes using the EnsureFeatureEnabled middleware in app/Http/Middleware/EnsureFeatureEnabled.php or controller policies.

Choosing the Right Extensibility Mechanism

Section titled “Choosing the Right Extensibility Mechanism”
If you are adding…Use this mechanism
A complete domain with separate database tables and migrationsA Module
A toggleable screen, sub-feature, or staged rolloutA Pennant Feature Flag
School-specific preferences (e.g. school logo, term labels, fees)A GeneralSetting property