teamMemberService = $teamMemberService; } /** * List all team members * * Get a list of all team members with optional filtering by active status. * * @authenticated * @queryParam active boolean Filter by active status. Example: true * * @response 200 [ * { * "id": "550e8400-e29b-41d4-a716-446655440000", * "name": "John Doe", * "role_id": 1, * "role": { * "id": 1, * "name": "Backend Developer" * }, * "hourly_rate": "150.00", * "active": true, * "created_at": "2024-01-15T10:00:00.000000Z", * "updated_at": "2024-01-15T10:00:00.000000Z" * } * ] */ public function index(Request $request): JsonResponse { $active = $request->has('active') ? filter_var($request->query('active'), FILTER_VALIDATE_BOOLEAN) : null; $teamMembers = $this->teamMemberService->getAll($active); return response()->json($teamMembers); } /** * Create a new team member * * Create a new team member with name, role, and hourly rate. * * @authenticated * @bodyParam name string required Team member name. Example: John Doe * @bodyParam role_id integer required Role ID. Example: 1 * @bodyParam hourly_rate numeric required Hourly rate (must be > 0). Example: 150.00 * @bodyParam active boolean Active status (defaults to true). Example: true * * @response 201 { * "id": "550e8400-e29b-41d4-a716-446655440000", * "name": "John Doe", * "role_id": 1, * "role": { * "id": 1, * "name": "Backend Developer" * }, * "hourly_rate": "150.00", * "active": true, * "created_at": "2024-01-15T10:00:00.000000Z", * "updated_at": "2024-01-15T10:00:00.000000Z" * } * @response 422 {"message":"Validation failed","errors":{"name":["The name field is required."],"hourly_rate":["Hourly rate must be greater than 0"]}} */ public function store(Request $request): JsonResponse { try { $teamMember = $this->teamMemberService->create($request->all()); return response()->json($teamMember, 201); } catch (ValidationException $e) { return response()->json([ 'message' => 'Validation failed', 'errors' => $e->validator->errors(), ], 422); } } /** * Get a single team member * * Get details of a specific team member by ID. * * @authenticated * @urlParam id string required Team member UUID. Example: 550e8400-e29b-41d4-a716-446655440000 * * @response 200 { * "id": "550e8400-e29b-41d4-a716-446655440000", * "name": "John Doe", * "role_id": 1, * "role": { * "id": 1, * "name": "Backend Developer" * }, * "hourly_rate": "150.00", * "active": true, * "created_at": "2024-01-15T10:00:00.000000Z", * "updated_at": "2024-01-15T10:00:00.000000Z" * } * @response 404 {"message":"Team member not found"} */ public function show(string $id): JsonResponse { $teamMember = $this->teamMemberService->findById($id); if (! $teamMember) { return response()->json([ 'message' => 'Team member not found', ], 404); } return response()->json($teamMember); } /** * Update a team member * * Update details of an existing team member. * * @authenticated * @urlParam id string required Team member UUID. Example: 550e8400-e29b-41d4-a716-446655440000 * @bodyParam name string Team member name. Example: John Doe * @bodyParam role_id integer Role ID. Example: 1 * @bodyParam hourly_rate numeric Hourly rate (must be > 0). Example: 175.00 * @bodyParam active boolean Active status. Example: false * * @response 200 { * "id": "550e8400-e29b-41d4-a716-446655440000", * "name": "John Doe", * "role_id": 1, * "role": { * "id": 1, * "name": "Backend Developer" * }, * "hourly_rate": "175.00", * "active": false, * "created_at": "2024-01-15T10:00:00.000000Z", * "updated_at": "2024-01-15T11:00:00.000000Z" * } * @response 404 {"message":"Team member not found"} * @response 422 {"message":"Validation failed","errors":{"hourly_rate":["Hourly rate must be greater than 0"]}} */ public function update(Request $request, string $id): JsonResponse { $teamMember = TeamMember::find($id); if (! $teamMember) { return response()->json([ 'message' => 'Team member not found', ], 404); } try { $teamMember = $this->teamMemberService->update($teamMember, $request->only([ 'name', 'role_id', 'hourly_rate', 'active' ])); return response()->json($teamMember); } catch (ValidationException $e) { return response()->json([ 'message' => 'Validation failed', 'errors' => $e->validator->errors(), ], 422); } } /** * Delete a team member * * Delete a team member. Cannot delete if member has allocations or actuals. * * @authenticated * @urlParam id string required Team member UUID. Example: 550e8400-e29b-41d4-a716-446655440000 * * @response 200 {"message":"Team member deleted successfully"} * @response 404 {"message":"Team member not found"} * @response 422 {"message":"Cannot delete team member with active allocations","suggestion":"Consider deactivating the team member instead"} * @response 422 {"message":"Cannot delete team member with historical data","suggestion":"Consider deactivating the team member instead"} */ public function destroy(string $id): JsonResponse { $teamMember = TeamMember::find($id); if (! $teamMember) { return response()->json([ 'message' => 'Team member not found', ], 404); } try { $this->teamMemberService->delete($teamMember); return response()->json([ 'message' => 'Team member deleted successfully', ]); } catch (\RuntimeException $e) { return response()->json([ 'message' => $e->getMessage(), 'suggestion' => 'Consider deactivating the team member instead', ], 422); } } }