user(); $artwork = Artwork::findOrFail($id); $this->authorize('award', [ArtworkAward::class, $artwork]); $data = $request->validate([ 'medal' => ['required', 'string', 'in:gold,silver,bronze'], ]); $award = $this->service->award($artwork, $user, $data['medal']); return response()->json( $this->buildPayload($artwork->id, $user->id), 201 ); } /** * PUT /api/artworks/{id}/award * Change an existing award medal. */ public function update(Request $request, int $id): JsonResponse { $user = $request->user(); $artwork = Artwork::findOrFail($id); $existingAward = ArtworkAward::where('artwork_id', $artwork->id) ->where('user_id', $user->id) ->firstOrFail(); $this->authorize('change', $existingAward); $data = $request->validate([ 'medal' => ['required', 'string', 'in:gold,silver,bronze'], ]); $award = $this->service->changeAward($artwork, $user, $data['medal']); return response()->json($this->buildPayload($artwork->id, $user->id)); } /** * DELETE /api/artworks/{id}/award * Remove the user's award for this artwork. */ public function destroy(Request $request, int $id): JsonResponse { $user = $request->user(); $artwork = Artwork::findOrFail($id); $existingAward = ArtworkAward::where('artwork_id', $artwork->id) ->where('user_id', $user->id) ->firstOrFail(); $this->authorize('remove', $existingAward); $this->service->removeAward($artwork, $user); return response()->json($this->buildPayload($artwork->id, $user->id)); } /** * GET /api/artworks/{id}/awards * Return award stats + viewer's current award. */ public function show(Request $request, int $id): JsonResponse { $artwork = Artwork::findOrFail($id); return response()->json($this->buildPayload($artwork->id, $request->user()?->id)); } // ------------------------------------------------------------------------- // All authorization is delegated to ArtworkAwardPolicy via $this->authorize(). private function buildPayload(int $artworkId, ?int $userId): array { $stat = \App\Models\ArtworkAwardStat::find($artworkId); $userAward = $userId ? ArtworkAward::where('artwork_id', $artworkId) ->where('user_id', $userId) ->value('medal') : null; return [ 'awards' => [ 'gold' => $stat?->gold_count ?? 0, 'silver' => $stat?->silver_count ?? 0, 'bronze' => $stat?->bronze_count ?? 0, 'score' => $stat?->score_total ?? 0, ], 'viewer_award' => $userAward, ]; } }