'super_admin', 'label' => '최고관리자'], ['name' => 'finance', 'label' => '정산관리'], ['name' => 'product', 'label' => '상품관리'], ['name' => 'support', 'label' => 'CS/상담'], ]; foreach ($roles as $r) { DB::table('admin_roles')->updateOrInsert( ['name' => $r['name']], ['label' => $r['label'], 'updated_at' => now(), 'created_at' => now()] ); } // 2) 권한(permissions) - 최소 셋 $perms = [ ['name' => 'admin.access', 'label' => '관리자 접근'], ['name' => 'settlement.manage', 'label' => '정산 관리'], ['name' => 'product.manage', 'label' => '상품 관리'], ['name' => 'support.manage', 'label' => 'CS/상담 관리'], ['name' => 'member.manage', 'label' => '회원 관리'], ]; foreach ($perms as $p) { DB::table('admin_permissions')->updateOrInsert( ['name' => $p['name']], ['label' => $p['label'], 'updated_at' => now(), 'created_at' => now()] ); } // 3) super_admin 역할에 모든 권한 부여 $superRoleId = (int) DB::table('admin_roles')->where('name', 'super_admin')->value('id'); $permIds = DB::table('admin_permissions')->pluck('id')->map(fn($v) => (int)$v)->all(); foreach ($permIds as $pid) { DB::table('admin_permission_role')->updateOrInsert([ 'admin_permission_id' => $pid, 'admin_role_id' => $superRoleId, ], []); } // 4) super_admin 유저 1명 생성(없으면) $email = (string) env('ADMIN_SEED_EMAIL', 'admin@pinforyou.com'); $rawPw = (string) env('ADMIN_SEED_PASSWORD', 'ChangeMe!234'); $name = (string) env('ADMIN_SEED_NAME', 'Super Admin'); $phone = (string) env('ADMIN_SEED_PHONE', '01012345678'); $phoneE164 = $this->toE164Kr($phone); // +8210... $hashKey = (string) config('admin.phone_hash_key', env('ADMIN_PHONE_HASH_KEY', '')); if ($hashKey === '') { throw new \RuntimeException('ADMIN_PHONE_HASH_KEY (admin.phone_hash_key) is empty. Set it in .env'); } $phoneHash = hash_hmac('sha256', $phoneE164, $hashKey); $phoneEnc = Crypt::encryptString($phoneE164); $last4 = substr(preg_replace('/\D+/', '', $phoneE164), -4) ?: null; $user = DB::table('admin_users')->where('email', $email)->first(); if (!$user) { $adminUserId = DB::table('admin_users')->insertGetId([ 'email' => $email, 'password' => Hash::make($rawPw), 'name' => $name, 'nickname' => null, 'phone_enc' => $phoneEnc, 'phone_hash' => $phoneHash, 'phone_last4' => $last4, 'status' => 'active', 'must_reset_password' => 1, // totp는 “사용” 정책이니 enabled=1, secret은 등록 플로우에서 세팅 'totp_secret_enc' => null, 'totp_enabled' => 1, 'totp_verified_at' => null, 'last_login_at' => null, 'last_login_ip' => null, 'failed_login_count' => 0, 'locked_until' => null, 'remember_token' => null, 'created_at' => now(), 'updated_at' => now(), 'deleted_at' => null, ]); // super_admin 역할 부여 DB::table('admin_role_user')->insert([ 'admin_user_id' => $adminUserId, 'admin_role_id' => $superRoleId, ]); } else { // 이미 있으면 role만 보장 $adminUserId = (int) $user->id; DB::table('admin_role_user')->updateOrInsert([ 'admin_user_id' => $adminUserId, 'admin_role_id' => $superRoleId, ], []); } } private function toE164Kr(string $raw): string { $n = preg_replace('/\D+/', '', $raw) ?? ''; if ($n === '') return '+82'; // 010xxxxxxxx 형태 -> +8210xxxxxxxx if (str_starts_with($n, '0')) { $n = substr($n, 1); } return '+82'.$n; } }