attributes->get('api_actor'); $validated = $request->validate([ 'type' => ['required', Rule::in(['bug', 'suggestion', 'other'])], 'title' => ['required', 'string', 'max:120'], 'message' => ['required', 'string', 'max:5000'], 'context' => ['sometimes', 'array'], 'context.page' => ['sometimes', 'string', 'max:500'], 'context.url' => ['sometimes', 'string', 'max:1000'], 'context.user_agent' => ['sometimes', 'string', 'max:500'], 'context.reporter' => ['sometimes', 'string', 'max:100'], 'context.reporter_name' => ['sometimes', 'string', 'max:200'], 'context.reported_at' => ['sometimes', 'string'], ]); $ctx = $validated['context'] ?? []; $feedback = Feedback::create([ 'type' => $validated['type'], 'title' => $validated['title'], 'message' => $validated['message'], 'status' => 'open', 'reporter' => $ctx['reporter'] ?? ($actor?->identifier ?? null), 'reporter_name' => $ctx['reporter_name'] ?? null, 'page' => $ctx['page'] ?? null, 'url' => $ctx['url'] ?? null, 'user_agent' => $ctx['user_agent'] ?? null, 'reported_at' => isset($ctx['reported_at']) ? now()->parse($ctx['reported_at']) : now(), ]); return $this->ok([ 'id' => $feedback->id, 'status' => $feedback->status, ], [], 201); } public function index(Request $request): JsonResponse { /** @var ApiActor $actor */ $actor = $request->attributes->get('api_actor'); if (!$actor?->is_admin) { return $this->fail('Forbidden', 'forbidden', 403); } $query = Feedback::query()->orderByDesc('created_at'); if ($request->filled('type')) { $query->where('type', $request->query('type')); } if ($request->filled('status')) { $query->where('status', $request->query('status')); } $items = $query->paginate(20); return $this->ok($items); } public function update(Request $request, int $id): JsonResponse { /** @var ApiActor $actor */ $actor = $request->attributes->get('api_actor'); if (!$actor?->is_admin) { return $this->fail('Forbidden', 'forbidden', 403); } $feedback = Feedback::findOrFail($id); $validated = $request->validate([ 'status' => ['sometimes', Rule::in(['open', 'in_progress', 'resolved', 'closed'])], 'admin_note' => ['sometimes', 'nullable', 'string', 'max:2000'], ]); $feedback->update($validated); return $this->ok($feedback->only(['id', 'status', 'admin_note'])); } }