feat: 휴가 관리 API 구현 (Phase 1)

- leaves, leave_balances 테이블 마이그레이션 추가
- Leave, LeaveBalance 모델 구현 (BelongsToTenant, SoftDeletes)
- LeaveService 서비스 구현 (CRUD, 승인/반려/취소, 잔여일수 관리)
- LeaveController 및 FormRequest 5개 생성
- API 엔드포인트 11개 등록 (/v1/leaves/*)
- Swagger 문서 (LeaveApi.php) 작성
- i18n 메시지 키 추가 (message.leave.*, error.leave.*)
This commit is contained in:
2025-12-17 20:13:48 +09:00
parent cac409e7dc
commit e81e5d7084
15 changed files with 1646 additions and 0 deletions

View File

@@ -23,6 +23,7 @@
use App\Http\Controllers\Api\V1\EstimateController;
use App\Http\Controllers\Api\V1\FileStorageController;
use App\Http\Controllers\Api\V1\FolderController;
use App\Http\Controllers\Api\V1\LeaveController;
use App\Http\Controllers\Api\V1\ItemMaster\CustomTabController;
use App\Http\Controllers\Api\V1\ItemMaster\EntityRelationshipController;
use App\Http\Controllers\Api\V1\ItemMaster\ItemBomItemController;
@@ -241,6 +242,21 @@
Route::post('/bulk-delete', [AttendanceController::class, 'bulkDelete'])->name('v1.attendances.bulkDelete');
});
// Leave API (휴가 관리)
Route::prefix('leaves')->group(function () {
Route::get('', [LeaveController::class, 'index'])->name('v1.leaves.index');
Route::post('', [LeaveController::class, 'store'])->name('v1.leaves.store');
Route::get('/balance', [LeaveController::class, 'balance'])->name('v1.leaves.balance');
Route::get('/balance/{userId}', [LeaveController::class, 'userBalance'])->name('v1.leaves.userBalance');
Route::put('/balance', [LeaveController::class, 'setBalance'])->name('v1.leaves.setBalance');
Route::get('/{id}', [LeaveController::class, 'show'])->name('v1.leaves.show');
Route::patch('/{id}', [LeaveController::class, 'update'])->name('v1.leaves.update');
Route::delete('/{id}', [LeaveController::class, 'destroy'])->name('v1.leaves.destroy');
Route::post('/{id}/approve', [LeaveController::class, 'approve'])->name('v1.leaves.approve');
Route::post('/{id}/reject', [LeaveController::class, 'reject'])->name('v1.leaves.reject');
Route::post('/{id}/cancel', [LeaveController::class, 'cancel'])->name('v1.leaves.cancel');
});
// Permission API
Route::prefix('permissions')->group(function () {
Route::get('departments/{dept_id}/menu-matrix', [PermissionController::class, 'deptMenuMatrix'])->name('v1.permissions.deptMenuMatrix'); // 부서별 권한 메트릭스