feat: [payroll] 급여관리 페이지 접근 제한 (이름 기반)

- 허용 사용자: 이경호, 전진선, 김보곤
- 웹 컨트롤러: 미허용 시 안내 뷰 반환
- API 컨트롤러: 모든 엔드포인트에 403 반환
- restricted.blade.php 안내 페이지 생성
This commit is contained in:
김보곤
2026-02-27 17:59:50 +09:00
parent 732d021b6d
commit 53c7f00340
3 changed files with 90 additions and 1 deletions

View File

@@ -12,15 +12,33 @@
class PayrollController extends Controller
{
private const ALLOWED_PAYROLL_USERS = ['이경호', '전진선', '김보곤'];
public function __construct(
private PayrollService $payrollService
) {}
private function checkPayrollAccess(): ?JsonResponse
{
if (! in_array(auth()->user()->name, self::ALLOWED_PAYROLL_USERS)) {
return response()->json([
'success' => false,
'message' => '급여관리는 관계자만 볼 수 있습니다.',
], 403);
}
return null;
}
/**
* 급여 목록 조회 (HTMX → HTML / 일반 → JSON)
*/
public function index(Request $request): JsonResponse|Response
{
if ($denied = $this->checkPayrollAccess()) {
return $denied;
}
$payrolls = $this->payrollService->getPayrolls(
$request->all(),
$request->integer('per_page', 20)
@@ -47,6 +65,10 @@ public function index(Request $request): JsonResponse|Response
*/
public function stats(Request $request): JsonResponse|Response
{
if ($denied = $this->checkPayrollAccess()) {
return $denied;
}
$stats = $this->payrollService->getMonthlyStats(
$request->integer('year') ?: null,
$request->integer('month') ?: null
@@ -67,6 +89,10 @@ public function stats(Request $request): JsonResponse|Response
*/
public function store(Request $request): JsonResponse
{
if ($denied = $this->checkPayrollAccess()) {
return $denied;
}
$validated = $request->validate([
'user_id' => 'required|integer|exists:users,id',
'pay_year' => 'required|integer|min:2020|max:2100',
@@ -124,6 +150,10 @@ public function store(Request $request): JsonResponse
*/
public function update(Request $request, int $id): JsonResponse
{
if ($denied = $this->checkPayrollAccess()) {
return $denied;
}
$validated = $request->validate([
'base_salary' => 'sometimes|required|numeric|min:0',
'overtime_pay' => 'nullable|numeric|min:0',
@@ -175,6 +205,10 @@ public function update(Request $request, int $id): JsonResponse
*/
public function destroy(Request $request, int $id): JsonResponse|Response
{
if ($denied = $this->checkPayrollAccess()) {
return $denied;
}
try {
$result = $this->payrollService->deletePayroll($id);
@@ -214,6 +248,10 @@ public function destroy(Request $request, int $id): JsonResponse|Response
*/
public function confirm(Request $request, int $id): JsonResponse
{
if ($denied = $this->checkPayrollAccess()) {
return $denied;
}
try {
$payroll = $this->payrollService->confirmPayroll($id);
@@ -245,6 +283,10 @@ public function confirm(Request $request, int $id): JsonResponse
*/
public function pay(Request $request, int $id): JsonResponse
{
if ($denied = $this->checkPayrollAccess()) {
return $denied;
}
try {
$payroll = $this->payrollService->payPayroll($id);
@@ -276,6 +318,10 @@ public function pay(Request $request, int $id): JsonResponse
*/
public function copyFromPrevious(Request $request): JsonResponse
{
if ($denied = $this->checkPayrollAccess()) {
return $denied;
}
$validated = $request->validate([
'pay_year' => 'required|integer|min:2020|max:2100',
'pay_month' => 'required|integer|min:1|max:12',
@@ -315,6 +361,10 @@ public function copyFromPrevious(Request $request): JsonResponse
*/
public function bulkGenerate(Request $request): JsonResponse
{
if ($denied = $this->checkPayrollAccess()) {
return $denied;
}
$validated = $request->validate([
'year' => 'required|integer|min:2020|max:2100',
'month' => 'required|integer|min:1|max:12',
@@ -342,8 +392,12 @@ public function bulkGenerate(Request $request): JsonResponse
/**
* 엑셀(CSV) 내보내기
*/
public function export(Request $request): StreamedResponse
public function export(Request $request): StreamedResponse|JsonResponse
{
if ($denied = $this->checkPayrollAccess()) {
return $denied;
}
$payrolls = $this->payrollService->getExportData($request->all());
$year = $request->input('year', now()->year);
$month = $request->input('month', now()->month);
@@ -392,6 +446,10 @@ public function export(Request $request): StreamedResponse
*/
public function settingsIndex(Request $request): JsonResponse|Response
{
if ($denied = $this->checkPayrollAccess()) {
return $denied;
}
$settings = $this->payrollService->getSettings();
if ($request->header('HX-Request')) {
@@ -409,6 +467,10 @@ public function settingsIndex(Request $request): JsonResponse|Response
*/
public function settingsUpdate(Request $request): JsonResponse
{
if ($denied = $this->checkPayrollAccess()) {
return $denied;
}
$validated = $request->validate([
'health_insurance_rate' => 'nullable|numeric|min:0|max:100',
'long_term_care_rate' => 'nullable|numeric|min:0|max:100',
@@ -444,6 +506,10 @@ public function settingsUpdate(Request $request): JsonResponse
*/
public function calculate(Request $request): JsonResponse
{
if ($denied = $this->checkPayrollAccess()) {
return $denied;
}
$validated = $request->validate([
'base_salary' => 'required|numeric|min:0',
'overtime_pay' => 'nullable|numeric|min:0',