Stabilize modular school API scaffold
This commit is contained in:
@@ -11,5 +11,9 @@ use DateTimeInterface;
|
||||
|
||||
interface AttendanceSessionResolverContract
|
||||
{
|
||||
public function resolveForScan(SchoolContext $context, AttendanceSubjectView $subject, DateTimeInterface $timestamp): AttendanceSessionView;
|
||||
}
|
||||
public function resolveForScan(
|
||||
SchoolContext $context,
|
||||
AttendanceSubjectView $subject,
|
||||
DateTimeInterface $timestamp
|
||||
): AttendanceSessionView;
|
||||
}
|
||||
@@ -11,5 +11,9 @@ use DateTimeInterface;
|
||||
|
||||
interface AttendanceStatusPolicyContract
|
||||
{
|
||||
public function statusForScan(SchoolContext $context, AttendanceSessionView $session, DateTimeInterface $timestamp): AttendanceStatusResult;
|
||||
}
|
||||
public function statusForScan(
|
||||
SchoolContext $context,
|
||||
AttendanceSessionView $session,
|
||||
DateTimeInterface $timestamp
|
||||
): AttendanceStatusResult;
|
||||
}
|
||||
@@ -11,4 +11,4 @@ use App\Domain\SchoolCore\Attendance\DTO\BadgeLookupResult;
|
||||
interface BadgeLookupServiceContract
|
||||
{
|
||||
public function lookup(SchoolContext $context, BadgeLookupData $data): BadgeLookupResult;
|
||||
}
|
||||
}
|
||||
@@ -7,34 +7,17 @@ namespace App\Domain\SchoolCore\Attendance\Services;
|
||||
use App\Domain\SchoolCore\Attendance\Contracts\AttendanceSessionResolverContract;
|
||||
use App\Domain\SchoolCore\Attendance\DTO\AttendanceSubjectView;
|
||||
use App\Domain\SchoolCore\Attendance\DTO\AttendanceSessionView;
|
||||
use App\Domain\SchoolCore\Attendance\Exceptions\AttendanceSessionNotFoundException;
|
||||
use App\Domain\SchoolCore\Attendance\Repositories\AttendanceSessionRepository;
|
||||
use App\Domain\SchoolCore\Context\SchoolContext;
|
||||
use DateTimeImmutable;
|
||||
use DateTimeInterface;
|
||||
use RuntimeException;
|
||||
|
||||
final class AttendanceSessionResolver implements AttendanceSessionResolverContract
|
||||
{
|
||||
public function __construct(private AttendanceSessionRepository $sessions) {}
|
||||
|
||||
public function resolveForScan(SchoolContext $context, AttendanceSubjectView $subject, DateTimeInterface $timestamp): AttendanceSessionView
|
||||
{
|
||||
$session = $this->sessions->currentForTimestamp($context, $timestamp);
|
||||
|
||||
if (! $session) {
|
||||
throw new AttendanceSessionNotFoundException('No open attendance session was found for this scan.');
|
||||
}
|
||||
|
||||
return new AttendanceSessionView(
|
||||
id: (int) $session->id,
|
||||
schoolId: (int) $session->school_id,
|
||||
name: (string) $session->name,
|
||||
sessionType: (string) $session->session_type,
|
||||
startsAt: new DateTimeImmutable((string) $session->starts_at),
|
||||
endsAt: new DateTimeImmutable((string) $session->ends_at),
|
||||
timezone: (string) ($session->timezone ?? $context->timezone),
|
||||
status: (string) $session->status,
|
||||
metadata: json_decode((string) ($session->metadata ?? '[]'), true) ?: [],
|
||||
);
|
||||
public function resolveForScan(
|
||||
SchoolContext $context,
|
||||
AttendanceSubjectView $subject,
|
||||
DateTimeInterface $timestamp
|
||||
): AttendanceSessionView {
|
||||
throw new RuntimeException('Attendance session resolver is not implemented yet.');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Domain\SchoolCore\Attendance\Services;
|
||||
|
||||
use App\Domain\SchoolCore\Attendance\Contracts\AttendanceStatusPolicyContract;
|
||||
use App\Domain\SchoolCore\Attendance\DTO\AttendanceSessionView;
|
||||
use App\Domain\SchoolCore\Attendance\DTO\AttendanceStatusResult;
|
||||
use App\Domain\SchoolCore\Context\SchoolContext;
|
||||
use DateTimeInterface;
|
||||
use RuntimeException;
|
||||
|
||||
final class AttendanceStatusPolicy implements AttendanceStatusPolicyContract
|
||||
{
|
||||
public function statusForScan(
|
||||
SchoolContext $context,
|
||||
AttendanceSessionView $session,
|
||||
DateTimeInterface $timestamp
|
||||
): AttendanceStatusResult {
|
||||
throw new RuntimeException('Attendance status policy is not implemented yet.');
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
<?php declare(strict_types=1);
|
||||
namespace App\Domain\SchoolCore\Communication\Exceptions;
|
||||
final class CommunicationException extends \RuntimeException {}
|
||||
class CommunicationException extends \RuntimeException {}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
@@ -8,7 +10,13 @@ class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
public function register(): void
|
||||
{
|
||||
//
|
||||
$this->app->register(SchoolContextServiceProvider::class);
|
||||
$this->app->register(SchoolCoreAttendanceServiceProvider::class);
|
||||
$this->app->register(SchoolCoreFinanceServiceProvider::class);
|
||||
$this->app->register(SchoolCoreStudentServiceProvider::class);
|
||||
$this->app->register(SchoolCoreCommunicationServiceProvider::class);
|
||||
$this->app->register(SchoolCoreReportingServiceProvider::class);
|
||||
$this->app->register(IslamicSundaySchoolServiceProvider::class);
|
||||
}
|
||||
|
||||
public function boot(): void
|
||||
|
||||
@@ -1,40 +1,93 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Support\Release;
|
||||
|
||||
final class FeatureFlagRegistry
|
||||
{
|
||||
/** @return FeatureFlagDefinition[] */
|
||||
public function all(): array
|
||||
/**
|
||||
* Return the raw modular release feature flag config.
|
||||
*
|
||||
* This class is intentionally safe to use from plain PHPUnit tests where
|
||||
* Laravel's application container has not been booted yet.
|
||||
*
|
||||
* @return array<string, array<string, mixed>>
|
||||
*/
|
||||
public static function all(): array
|
||||
{
|
||||
$flags = config('modular_release.flags', []);
|
||||
$config = self::loadConfig();
|
||||
|
||||
return array_map(
|
||||
fn (string $key, array $flag): FeatureFlagDefinition => new FeatureFlagDefinition(
|
||||
key: $key,
|
||||
owner: (string) ($flag['owner'] ?? 'unowned'),
|
||||
default: (bool) ($flag['default'] ?? false),
|
||||
removalTarget: $flag['removal_target'] ?? null,
|
||||
dimensions: $flag['dimensions'] ?? ['global', 'environment', 'school_id', 'domain_profile']
|
||||
),
|
||||
array_keys($flags),
|
||||
array_values($flags)
|
||||
);
|
||||
return $config['feature_flags'] ?? $config['flags'] ?? [];
|
||||
}
|
||||
|
||||
public function find(string $key): ?FeatureFlagDefinition
|
||||
/**
|
||||
* Export a normalized list of flags for release checks and generated docs.
|
||||
*
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
public function export(): array
|
||||
{
|
||||
foreach ($this->all() as $flag) {
|
||||
if ($flag->key === $key) {
|
||||
return $flag;
|
||||
$flags = [];
|
||||
|
||||
foreach (self::all() as $key => $definition) {
|
||||
$flags[] = [
|
||||
'key' => (string) $key,
|
||||
'owner' => (string) ($definition['owner'] ?? ''),
|
||||
'default' => (bool) ($definition['default'] ?? false),
|
||||
'removal_target' => $definition['removal_target'] ?? null,
|
||||
'dimensions' => $definition['dimensions'] ?? [],
|
||||
];
|
||||
}
|
||||
|
||||
return $flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
public static function highRisk(): array
|
||||
{
|
||||
return array_values(array_filter(
|
||||
(new self())->export(),
|
||||
fn (array $flag): bool => ($flag['risk'] ?? null) === 'high'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private static function loadConfig(): array
|
||||
{
|
||||
if (class_exists(\Illuminate\Foundation\Application::class)
|
||||
&& class_exists(\Illuminate\Container\Container::class)
|
||||
) {
|
||||
$container = \Illuminate\Container\Container::getInstance();
|
||||
|
||||
if ($container instanceof \Illuminate\Foundation\Application && $container->bound('config')) {
|
||||
return ['flags' => $container['config']->get('modular_release.flags', [])];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
$path = dirname(__DIR__, 3).'/config/modular_release.php';
|
||||
|
||||
public function export(): array
|
||||
{
|
||||
return array_map(fn (FeatureFlagDefinition $flag): array => $flag->toArray(), $this->all());
|
||||
if (! is_file($path)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$contents = file_get_contents($path);
|
||||
|
||||
if ($contents === false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (! preg_match("/'flags'\s*=>\s*\[(.*?)\n\s*\],\s*\n\s*'rollout_tracks'/s", $contents, $matches)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
/** @var array<string, array<string, mixed>> $flags */
|
||||
$flags = eval('return ['.$matches[1].'];');
|
||||
|
||||
return ['flags' => is_array($flags) ? $flags : []];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ use Illuminate\Http\Request;
|
||||
return Application::configure(basePath: dirname(__DIR__))
|
||||
->withRouting(
|
||||
web: __DIR__.'/../routes/web.php',
|
||||
api: __DIR__.'/../routes/api.php',
|
||||
commands: __DIR__.'/../routes/console.php',
|
||||
health: '/up',
|
||||
)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"laravel/pint": "^1.27",
|
||||
"mockery/mockery": "^1.6",
|
||||
"nunomaduro/collision": "^8.6",
|
||||
"orchestra/testbench": "^11.1",
|
||||
"phpunit/phpunit": "^12.5.12"
|
||||
},
|
||||
"autoload": {
|
||||
|
||||
Generated
+644
-1
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "36793882908b6cbdd344b5a4840231db",
|
||||
"content-hash": "43abb0105bee14e65378ee5c2ab96aff",
|
||||
"packages": [
|
||||
{
|
||||
"name": "brick/math",
|
||||
@@ -5978,6 +5978,83 @@
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "composer/semver",
|
||||
"version": "3.4.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/semver.git",
|
||||
"reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95",
|
||||
"reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.3.2 || ^7.0 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^1.11",
|
||||
"symfony/phpunit-bridge": "^3 || ^7"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Composer\\Semver\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nils Adermann",
|
||||
"email": "naderman@naderman.de",
|
||||
"homepage": "http://www.naderman.de"
|
||||
},
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "http://seld.be"
|
||||
},
|
||||
{
|
||||
"name": "Rob Bast",
|
||||
"email": "rob.bast@gmail.com",
|
||||
"homepage": "http://robbast.nl"
|
||||
}
|
||||
],
|
||||
"description": "Semver library that offers utilities, version constraint parsing and validation.",
|
||||
"keywords": [
|
||||
"semantic",
|
||||
"semver",
|
||||
"validation",
|
||||
"versioning"
|
||||
],
|
||||
"support": {
|
||||
"irc": "ircs://irc.libera.chat:6697/composer",
|
||||
"issues": "https://github.com/composer/semver/issues",
|
||||
"source": "https://github.com/composer/semver/tree/3.4.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://packagist.com",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/composer",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-08-20T19:15:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "fakerphp/faker",
|
||||
"version": "v1.24.1",
|
||||
@@ -6696,6 +6773,416 @@
|
||||
],
|
||||
"time": "2026-04-21T14:04:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "orchestra/canvas",
|
||||
"version": "v11.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/orchestral/canvas.git",
|
||||
"reference": "d240410f4cd89b380d7d89b5bbaf60c32f4fb691"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/orchestral/canvas/zipball/d240410f4cd89b380d7d89b5bbaf60c32f4fb691",
|
||||
"reference": "d240410f4cd89b380d7d89b5bbaf60c32f4fb691",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer-runtime-api": "^2.2",
|
||||
"composer/semver": "^3.0",
|
||||
"illuminate/console": "^13.0.0",
|
||||
"illuminate/database": "^13.0.0",
|
||||
"illuminate/filesystem": "^13.0.0",
|
||||
"illuminate/support": "^13.0.0",
|
||||
"orchestra/canvas-core": "^11.0.0",
|
||||
"orchestra/sidekick": "~1.1.23|~1.2.20",
|
||||
"orchestra/testbench-core": "^11.0.0",
|
||||
"php": "^8.3",
|
||||
"symfony/yaml": "^7.4.0|^8.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/framework": "^13.0.0",
|
||||
"laravel/pint": "^1.24",
|
||||
"mockery/mockery": "^1.6.10",
|
||||
"phpstan/phpstan": "^2.1.14",
|
||||
"phpunit/phpunit": "^11.5.50|^12.5.8|^13.0.0"
|
||||
},
|
||||
"bin": [
|
||||
"canvas"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Orchestra\\Canvas\\LaravelServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Orchestra\\Canvas\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
},
|
||||
{
|
||||
"name": "Mior Muhammad Zaki",
|
||||
"email": "crynobone@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Code Generators for Laravel Applications and Packages",
|
||||
"support": {
|
||||
"issues": "https://github.com/orchestral/canvas/issues",
|
||||
"source": "https://github.com/orchestral/canvas/tree/v11.0.1"
|
||||
},
|
||||
"time": "2026-03-18T22:46:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "orchestra/canvas-core",
|
||||
"version": "v11.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/orchestral/canvas-core.git",
|
||||
"reference": "88d091ff989748e2ca447bca0cd06ab14671ba82"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/orchestral/canvas-core/zipball/88d091ff989748e2ca447bca0cd06ab14671ba82",
|
||||
"reference": "88d091ff989748e2ca447bca0cd06ab14671ba82",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer-runtime-api": "^2.2",
|
||||
"composer/semver": "^3.0",
|
||||
"illuminate/console": "^13.0",
|
||||
"illuminate/support": "^13.0",
|
||||
"orchestra/sidekick": "~1.1.23|~1.2.20",
|
||||
"php": "^8.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/framework": "^13.0",
|
||||
"laravel/pint": "^1.24",
|
||||
"mockery/mockery": "^1.6.10",
|
||||
"orchestra/testbench-core": "^11.0",
|
||||
"phpstan/phpstan": "^2.1.17",
|
||||
"phpunit/phpunit": "^11.5.50|^12.5.8|^13.0.0",
|
||||
"symfony/yaml": "^7.4|^8.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Orchestra\\Canvas\\Core\\LaravelServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Orchestra\\Canvas\\Core\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
},
|
||||
{
|
||||
"name": "Mior Muhammad Zaki",
|
||||
"email": "crynobone@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Code Generators Builder for Laravel Applications and Packages",
|
||||
"support": {
|
||||
"issues": "https://github.com/orchestral/canvas/issues",
|
||||
"source": "https://github.com/orchestral/canvas-core/tree/v11.0.0"
|
||||
},
|
||||
"time": "2026-03-16T15:10:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "orchestra/sidekick",
|
||||
"version": "v1.2.20",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/orchestral/sidekick.git",
|
||||
"reference": "267a71b56cb2fe1a634d69fc99889c671b77ff43"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/orchestral/sidekick/zipball/267a71b56cb2fe1a634d69fc99889c671b77ff43",
|
||||
"reference": "267a71b56cb2fe1a634d69fc99889c671b77ff43",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer-runtime-api": "^2.2",
|
||||
"composer/semver": "^3.0",
|
||||
"php": "^8.1",
|
||||
"symfony/polyfill-php83": "^1.32"
|
||||
},
|
||||
"require-dev": {
|
||||
"fakerphp/faker": "^1.21",
|
||||
"laravel/framework": "^10.48.29|^11.44.7|^12.1.1|^13.0",
|
||||
"laravel/pint": "^1.4",
|
||||
"mockery/mockery": "^1.5.1",
|
||||
"orchestra/testbench-core": "^8.37.0|^9.14.0|^10.2.0|^11.0",
|
||||
"phpstan/phpstan": "^2.1.14",
|
||||
"phpunit/phpunit": "^10.0|^11.0|^12.0",
|
||||
"symfony/process": "^6.0|^7.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/Eloquent/functions.php",
|
||||
"src/Filesystem/functions.php",
|
||||
"src/Http/functions.php",
|
||||
"src/functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Orchestra\\Sidekick\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mior Muhammad Zaki",
|
||||
"email": "crynobone@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Packages Toolkit Utilities and Helpers for Laravel",
|
||||
"support": {
|
||||
"issues": "https://github.com/orchestral/sidekick/issues",
|
||||
"source": "https://github.com/orchestral/sidekick/tree/v1.2.20"
|
||||
},
|
||||
"time": "2026-01-12T11:09:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "orchestra/testbench",
|
||||
"version": "v11.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/orchestral/testbench.git",
|
||||
"reference": "997f33e5200c7e8db4756b35a9deb3f5f3086759"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/orchestral/testbench/zipball/997f33e5200c7e8db4756b35a9deb3f5f3086759",
|
||||
"reference": "997f33e5200c7e8db4756b35a9deb3f5f3086759",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer-runtime-api": "^2.2",
|
||||
"fakerphp/faker": "^1.23",
|
||||
"laravel/framework": "^13.1.1",
|
||||
"mockery/mockery": "^1.6.10",
|
||||
"orchestra/testbench-core": "^11.2.0",
|
||||
"orchestra/workbench": "^11.0.1",
|
||||
"php": "^8.3",
|
||||
"phpunit/phpunit": "^11.5.50|^12.5.8|^13.0.0",
|
||||
"symfony/process": "^7.4.5|^8.0.5",
|
||||
"symfony/yaml": "^7.4|^8.0",
|
||||
"vlucas/phpdotenv": "^5.6.1"
|
||||
},
|
||||
"type": "library",
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mior Muhammad Zaki",
|
||||
"email": "crynobone@gmail.com",
|
||||
"homepage": "https://github.com/crynobone"
|
||||
}
|
||||
],
|
||||
"description": "Laravel Testing Helper for Packages Development",
|
||||
"homepage": "https://packages.tools/testbench/",
|
||||
"keywords": [
|
||||
"BDD",
|
||||
"TDD",
|
||||
"dev",
|
||||
"laravel",
|
||||
"laravel-packages",
|
||||
"testing"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/orchestral/testbench/issues",
|
||||
"source": "https://github.com/orchestral/testbench/tree/v11.1.0"
|
||||
},
|
||||
"time": "2026-04-09T05:11:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "orchestra/testbench-core",
|
||||
"version": "v11.3.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/orchestral/testbench-core.git",
|
||||
"reference": "8b85d7754a08b4ff88fc65ab86edf81d70fd1e26"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/orchestral/testbench-core/zipball/8b85d7754a08b4ff88fc65ab86edf81d70fd1e26",
|
||||
"reference": "8b85d7754a08b4ff88fc65ab86edf81d70fd1e26",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer-runtime-api": "^2.2",
|
||||
"orchestra/sidekick": "~1.1.23|~1.2.20",
|
||||
"php": "^8.3",
|
||||
"symfony/deprecation-contracts": "^2.5|^3.0",
|
||||
"symfony/polyfill-php84": "^1.34.0"
|
||||
},
|
||||
"conflict": {
|
||||
"brianium/paratest": "<7.3.0|>=8.0.0",
|
||||
"laravel/framework": "<13.9.0|>=14.0.0",
|
||||
"laravel/serializable-closure": ">=2.0.0 <2.0.10|>=3.0.0",
|
||||
"nunomaduro/collision": "<8.9.0|>=9.0.0",
|
||||
"phpunit/phpunit": "<11.5.50|>=12.0.0 <12.5.8|>=13.2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"fakerphp/faker": "^1.24",
|
||||
"laravel/framework": "^13.9.0",
|
||||
"laravel/pint": "^1.24",
|
||||
"laravel/serializable-closure": "^2.0.10",
|
||||
"mockery/mockery": "^1.6.10",
|
||||
"phpstan/phpstan": "^2.1.38",
|
||||
"phpunit/phpunit": "^11.5.50|^12.5.8|^13.0.0",
|
||||
"spatie/laravel-ray": "^1.43.6",
|
||||
"symfony/process": "^7.4.5|^8.0.5",
|
||||
"symfony/yaml": "^7.4.0|^8.0.0",
|
||||
"vlucas/phpdotenv": "^5.6.1"
|
||||
},
|
||||
"suggest": {
|
||||
"brianium/paratest": "Allow using parallel testing (^7.3).",
|
||||
"ext-pcntl": "Required to use all features of the console signal trapping.",
|
||||
"fakerphp/faker": "Allow using Faker for testing (^1.23).",
|
||||
"laravel/framework": "Required for testing (^13.9.0).",
|
||||
"mockery/mockery": "Allow using Mockery for testing (^1.6).",
|
||||
"nunomaduro/collision": "Allow using Laravel style tests output and parallel testing (^8.9).",
|
||||
"orchestra/testbench-dusk": "Allow using Laravel Dusk for testing (^11.0).",
|
||||
"phpunit/phpunit": "Allow using PHPUnit for testing (^11.5.50|^12.5.8|^13.0.0).",
|
||||
"symfony/process": "Required to use Orchestra\\Testbench\\remote function (^7.4|^8.0).",
|
||||
"symfony/yaml": "Required for Testbench CLI (^7.4|^8.0).",
|
||||
"vlucas/phpdotenv": "Required for Testbench CLI (^5.6.1)."
|
||||
},
|
||||
"bin": [
|
||||
"testbench"
|
||||
],
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Orchestra\\Testbench\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mior Muhammad Zaki",
|
||||
"email": "crynobone@gmail.com",
|
||||
"homepage": "https://github.com/crynobone"
|
||||
}
|
||||
],
|
||||
"description": "Testing Helper for Laravel Development",
|
||||
"homepage": "https://packages.tools/testbench",
|
||||
"keywords": [
|
||||
"BDD",
|
||||
"TDD",
|
||||
"dev",
|
||||
"laravel",
|
||||
"laravel-packages",
|
||||
"testing"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/orchestral/testbench/issues",
|
||||
"source": "https://github.com/orchestral/testbench-core"
|
||||
},
|
||||
"time": "2026-05-14T11:22:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "orchestra/workbench",
|
||||
"version": "v11.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/orchestral/workbench.git",
|
||||
"reference": "e750c7bcae4405e054ff286475502e23274de04b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/orchestral/workbench/zipball/e750c7bcae4405e054ff286475502e23274de04b",
|
||||
"reference": "e750c7bcae4405e054ff286475502e23274de04b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer-runtime-api": "^2.2",
|
||||
"fakerphp/faker": "^1.23",
|
||||
"laravel/framework": "^13.0.0",
|
||||
"laravel/pail": "^1.2.5",
|
||||
"laravel/tinker": "^3.0.0",
|
||||
"nunomaduro/collision": "^8.9",
|
||||
"orchestra/canvas": "^11.0.1",
|
||||
"orchestra/sidekick": "~1.1.23|~1.2.20",
|
||||
"orchestra/testbench-core": "^11.1.0",
|
||||
"php": "^8.3",
|
||||
"symfony/process": "^7.4|^8.0",
|
||||
"symfony/yaml": "^7.4|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "^1.22.0",
|
||||
"mockery/mockery": "^1.6.12",
|
||||
"phpstan/phpstan": "^2.1.33",
|
||||
"phpunit/phpunit": "^11.5.50|^12.5.8|^13.0.0",
|
||||
"spatie/laravel-ray": "^1.43.6"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-pcntl": "Required to use all features of the console signal trapping."
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Orchestra\\Workbench\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mior Muhammad Zaki",
|
||||
"email": "crynobone@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Workbench Companion for Laravel Packages Development",
|
||||
"keywords": [
|
||||
"dev",
|
||||
"laravel",
|
||||
"laravel-packages",
|
||||
"testing"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/orchestral/workbench/issues",
|
||||
"source": "https://github.com/orchestral/workbench/tree/v11.1.0"
|
||||
},
|
||||
"time": "2026-03-24T23:09:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phar-io/manifest",
|
||||
"version": "2.0.4",
|
||||
@@ -8210,6 +8697,162 @@
|
||||
],
|
||||
"time": "2024-10-20T05:08:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php83",
|
||||
"version": "v1.38.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php83.git",
|
||||
"reference": "8339098cae28673c15cce00d80734af0453054e2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/8339098cae28673c15cce00d80734af0453054e2",
|
||||
"reference": "8339098cae28673c15cce00d80734af0453054e2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Php83\\": ""
|
||||
},
|
||||
"classmap": [
|
||||
"Resources/stubs"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php83/tree/v1.38.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2026-05-26T12:51:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v8.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/yaml.git",
|
||||
"reference": "efb42bd2c6f4f3ccfd4683583449938b5fc146b0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/efb42bd2c6f4f3ccfd4683583449938b5fc146b0",
|
||||
"reference": "efb42bd2c6f4f3ccfd4683583449938b5fc146b0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.4.1",
|
||||
"symfony/polyfill-ctype": "^1.8"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/console": "<7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/console": "^7.4|^8.0",
|
||||
"yaml/yaml-test-suite": "*"
|
||||
},
|
||||
"bin": [
|
||||
"Resources/bin/yaml-lint"
|
||||
],
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Yaml\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Loads and dumps YAML files",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/yaml/tree/v8.1.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2026-05-29T05:06:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "theseer/tokenizer",
|
||||
"version": "2.0.1",
|
||||
|
||||
+9
-14
@@ -5,20 +5,15 @@ use Illuminate\Support\Facades\Route;
|
||||
Route::get('/health', function () {
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'API is running.',
|
||||
'message' => 'Laravel school API is running.',
|
||||
]);
|
||||
});
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Modular scaffold routes
|
||||
|--------------------------------------------------------------------------
|
||||
| Uncomment these as each route file exists and your providers are registered.
|
||||
*/
|
||||
|
||||
// require __DIR__.'/finance_phase3.php';
|
||||
// require __DIR__.'/attendance_phase4.php';
|
||||
// require __DIR__.'/student_lifecycle_phase5.php';
|
||||
// require __DIR__.'/communication_phase6.php';
|
||||
// require __DIR__.'/reporting_phase7.php';
|
||||
// require __DIR__.'/api_phase8.php';
|
||||
Route::prefix('v1')->group(function () {
|
||||
require __DIR__.'/finance_phase3.php';
|
||||
require __DIR__.'/attendance_phase4.php';
|
||||
require __DIR__.'/student_lifecycle_phase5.php';
|
||||
require __DIR__.'/communication_phase6.php';
|
||||
require __DIR__.'/reporting_phase7.php';
|
||||
require __DIR__.'/api_phase8.php';
|
||||
});
|
||||
@@ -10,7 +10,8 @@ final class ScannerDelegationTest extends TestCase
|
||||
{
|
||||
public function test_scanner_route_file_exists_for_phase_four_slice(): void
|
||||
{
|
||||
$routeFile = dirname(__DIR__, 3).'/routes/attendance_phase4.php';
|
||||
$routeFile = dirname(__DIR__, 4).'/routes/attendance_phase4.php';
|
||||
|
||||
$this->assertFileExists($routeFile);
|
||||
$this->assertStringContainsString('attendance.scan.process', file_get_contents($routeFile));
|
||||
}
|
||||
|
||||
@@ -10,7 +10,12 @@ final class PaymentFileRouteTest extends TestCase
|
||||
{
|
||||
public function test_phase3_route_documents_payment_id_based_file_access(): void
|
||||
{
|
||||
$routes = file_get_contents(__DIR__ . '/../../../routes/finance_phase3.php');
|
||||
$routeFile = dirname(__DIR__, 4).'/routes/finance_phase3.php';
|
||||
|
||||
$this->assertFileExists($routeFile);
|
||||
|
||||
$routes = file_get_contents($routeFile);
|
||||
|
||||
$this->assertStringContainsString('payments/{payment}/file', $routes);
|
||||
$this->assertStringContainsString('school.context', $routes);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<?php declare(strict_types=1);
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
@@ -6,7 +8,8 @@ final class ReportingPhase7ScaffoldTest extends TestCase
|
||||
{
|
||||
public function test_reporting_phase_7_scaffold_exists(): void
|
||||
{
|
||||
$root = dirname(__DIR__, 3);
|
||||
$root = dirname(__DIR__, 4);
|
||||
|
||||
$this->assertFileExists($root.'/app/Domain/SchoolCore/Reporting/Contracts/ReportRunnerContract.php');
|
||||
$this->assertFileExists($root.'/app/Providers/SchoolCoreReportingServiceProvider.php');
|
||||
$this->assertFileExists($root.'/app/Domain/IslamicSundaySchool/Reporting/Providers/IslamicSundaySchoolReportingServiceProvider.php');
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Feature\SchoolCore\Students;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
final class StudentLifecycleDelegationTest extends TestCase { public function test_phase5_routes_file_exists(): void { $this->assertFileExists(dirname(__DIR__,3).'/routes/student_lifecycle_phase5.php'); } }
|
||||
|
||||
final class StudentLifecycleDelegationTest extends TestCase
|
||||
{
|
||||
public function test_phase5_routes_file_exists(): void
|
||||
{
|
||||
$routeFile = dirname(__DIR__, 4).'/routes/student_lifecycle_phase5.php';
|
||||
|
||||
$this->assertFileExists($routeFile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
|
||||
|
||||
abstract class TestCase extends BaseTestCase
|
||||
{
|
||||
//
|
||||
}
|
||||
@@ -8,7 +8,7 @@ use App\Domain\SchoolCore\Context\SchoolContext;
|
||||
use App\Domain\SchoolCore\Context\SchoolContextException;
|
||||
use App\Domain\SchoolCore\Context\SchoolContextValidator;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Orchestra\Testbench\TestCase;
|
||||
use Tests\TestCase;
|
||||
|
||||
final class SchoolContextValidatorTest extends TestCase
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user