perf: 회원가입 쿼리 최적화 (268개 → 58개, 78% 감소)

- MenuObserver: Bulk insert + 지연 캐시 삭제로 메뉴당 28개 → 3개 쿼리
- RegisterService: 중복 권한 생성 로직 제거 (27개 쿼리 감소)
- 캐시 삭제: 126개 → 11개 (91% 감소)
- 확장성 유지: 관리자 메뉴 추가 시에도 최적화 적용
This commit is contained in:
2025-11-10 10:30:35 +09:00
parent c558606954
commit 657623fef5
3 changed files with 293 additions and 19 deletions

View File

@@ -3,6 +3,7 @@
namespace App\Observers;
use App\Models\Commons\Menu; // ← 실제 경로 확인
use Illuminate\Support\Facades\DB;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\PermissionRegistrar;
@@ -24,7 +25,7 @@ public function created(Menu $menu): void
$this->setTeam((int) $menu->tenant_id);
$this->ensurePermissions($menu);
$this->forgetCache();
$this->forgetCacheAfterCommit();
}
public function updated(Menu $menu): void
@@ -41,7 +42,7 @@ public function deleted(Menu $menu): void
$this->setTeam((int) $menu->tenant_id);
$this->removePermissions($menu);
$this->forgetCache();
$this->forgetCacheAfterCommit();
}
public function restored(Menu $menu): void
@@ -52,7 +53,7 @@ public function restored(Menu $menu): void
$this->setTeam((int) $menu->tenant_id);
$this->ensurePermissions($menu);
$this->forgetCache();
$this->forgetCacheAfterCommit();
}
public function forceDeleted(Menu $menu): void
@@ -63,7 +64,7 @@ public function forceDeleted(Menu $menu): void
$this->setTeam((int) $menu->tenant_id);
$this->removePermissions($menu);
$this->forgetCache();
$this->forgetCacheAfterCommit();
}
/** teams 사용 시 tenant_id 없는 공용 메뉴는 스킵하는 게 안전 */
@@ -79,13 +80,22 @@ protected function setTeam(int $tenantId): void
protected function ensurePermissions(Menu $menu): void
{
foreach ($this->actions() as $act) {
Permission::firstOrCreate([
$actions = $this->actions();
$permissionsData = [];
$now = now();
foreach ($actions as $act) {
$permissionsData[] = [
'tenant_id' => (int) $menu->tenant_id,
'guard_name' => $this->guard,
'name' => "menu:{$menu->id}.{$act}",
]);
'created_at' => $now,
'updated_at' => $now,
];
}
// Bulk insert using insertOrIgnore to avoid duplicate errors
DB::table('permissions')->insertOrIgnore($permissionsData);
}
protected function removePermissions(Menu $menu): void
@@ -103,4 +113,12 @@ protected function forgetCache(): void
{
app(PermissionRegistrar::class)->forgetCachedPermissions();
}
protected function forgetCacheAfterCommit(): void
{
// Defer cache clearing until after transaction commits
DB::afterCommit(function () {
app(PermissionRegistrar::class)->forgetCachedPermissions();
});
}
}