Commit 2f4c631c authored by Mahmoud Aglan's avatar Mahmoud Aglan

Enforce single-academy-per-instance architecture in seeders

DatabaseSeeder now uses Academy::first() — never creates duplicates. If
the wizard already created an academy, the seeder respects it and just
ensures the env-var admin user is super_admin on that academy.

FinancialAccountsSeeder no longer has a hardcoded 'el-captain' fallback;
it skips gracefully if no academy exists yet.
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent c22fdd7b
...@@ -2,38 +2,38 @@ ...@@ -2,38 +2,38 @@
namespace Database\Seeders; namespace Database\Seeders;
use App\Domain\Identity\Models\Branch;
use App\Domain\Identity\Models\Role; use App\Domain\Identity\Models\Role;
use App\Domain\Shared\Models\Academy; use App\Domain\Shared\Models\Academy;
use App\Models\User; use App\Models\User;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
class DatabaseSeeder extends Seeder class DatabaseSeeder extends Seeder
{ {
public function run(): void public function run(): void
{ {
$academyNameEn = env('ACADEMY_NAME_EN', 'El Captain Academy'); $adminEmail = env('ADMIN_EMAIL', 'admin@elcaptain.com');
$academyNameAr = env('ACADEMY_NAME_AR', 'أكاديمية الكابتن');
$adminEmail = env('ADMIN_EMAIL', 'admin@oc-sport.com');
$adminPassword = env('ADMIN_PASSWORD', 'Alarcade123#'); $adminPassword = env('ADMIN_PASSWORD', 'Alarcade123#');
$adminName = env('ADMIN_NAME', $academyNameAr); $adminName = env('ADMIN_NAME', env('ACADEMY_NAME_AR', 'أكاديمية الكابتن'));
$slug = \Illuminate\Support\Str::slug($academyNameEn); // Single academy per instance — use whatever exists, only create if empty
$academy = Academy::first();
$academy = Academy::firstOrCreate( if (!$academy) {
['slug' => $slug], $academy = Academy::create([
[ 'name' => env('ACADEMY_NAME_EN', 'El Captain Academy'),
'name' => $academyNameEn, 'name_ar' => env('ACADEMY_NAME_AR', 'أكاديمية الكابتن'),
'name_ar' => $academyNameAr, 'slug' => Str::slug(env('ACADEMY_NAME_EN', 'El Captain Academy')),
'slug' => $slug,
'email' => $adminEmail, 'email' => $adminEmail,
'currency' => 'EGP', 'currency' => 'EGP',
'timezone' => 'Africa/Cairo', 'timezone' => 'Africa/Cairo',
'locale' => 'ar', 'locale' => 'ar',
'status' => 'active', 'status' => 'active',
] ]);
); }
// Admin user — always on THE academy
$admin = User::firstOrCreate( $admin = User::firstOrCreate(
['email' => $adminEmail], ['email' => $adminEmail],
[ [
...@@ -46,30 +46,31 @@ public function run(): void ...@@ -46,30 +46,31 @@ public function run(): void
] ]
); );
// Ensure admin is on the correct academy
if ($admin->academy_id !== $academy->id) {
$admin->update(['academy_id' => $academy->id]);
}
$this->call(FinancialAccountsSeeder::class); $this->call(FinancialAccountsSeeder::class);
$this->call(RolesAndPermissionsSeeder::class); // Creates roles (needed before PermissionSeeder) $this->call(RolesAndPermissionsSeeder::class);
$this->call(PermissionSeeder::class); // Authoritative permission+scope assignments $this->call(PermissionSeeder::class);
$this->call(PaymentNotificationTemplateSeeder::class); $this->call(PaymentNotificationTemplateSeeder::class);
// Assign academy_owner role to the admin user (check user's own academy first) // Assign academy_owner role + super_admin
$ownerRole = Role::where('academy_id', $admin->academy_id) $ownerRole = Role::where('academy_id', $academy->id)
->where('slug', 'academy_owner') ->where('slug', 'academy_owner')
->first() ->first();
?? Role::where('academy_id', $academy->id)
->where('slug', 'academy_owner') $branch = Branch::where('academy_id', $academy->id)->first();
->first();
// Ensure admin has branch assigned $admin->update([
$branch = \App\Domain\Identity\Models\Branch::where('academy_id', $admin->academy_id)->first(); 'role_id' => $ownerRole?->id ?? $admin->role_id,
$branchId = $branch?->id ?? $admin->branch_id; 'is_super_admin' => true,
'branch_id' => $branch?->id ?? $admin->branch_id,
]);
if ($ownerRole) { if ($ownerRole && !$admin->roles()->where('role_id', $ownerRole->id)->exists()) {
$admin->update(['role_id' => $ownerRole->id, 'is_super_admin' => true, 'branch_id' => $branchId]); $admin->roles()->attach($ownerRole->id);
if (!$admin->roles()->where('role_id', $ownerRole->id)->exists()) {
$admin->roles()->attach($ownerRole->id);
}
} else {
$admin->update(['is_super_admin' => true, 'branch_id' => $branchId]);
} }
} }
} }
...@@ -12,17 +12,9 @@ public function run(): void ...@@ -12,17 +12,9 @@ public function run(): void
{ {
$academy = Academy::first(); $academy = Academy::first();
if (! $academy) { if (!$academy) {
$academy = Academy::create([ $this->command->warn('No academy exists yet — skipping financial accounts seeder.');
'name' => 'El Captain Academy', return;
'name_ar' => 'أكاديمية الكابتن',
'slug' => 'el-captain',
'email' => 'info@elcaptain.com',
'currency' => 'EGP',
'timezone' => 'Africa/Cairo',
'locale' => 'ar',
'status' => 'active',
]);
} }
$accounts = [ $accounts = [
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment