PromptVault/app/Http/Controllers/PromptController.php

151 lines
4.5 KiB
PHP
Raw Permalink Normal View History

2026-10-26 20:12:16 +00:00
<?php
namespace App\Http\Controllers;
use App\Actions\Prompts\ListPrompts;
use App\Exceptions\PromptRenderException;
use App\Http\Requests\StorePromptRequest;
use App\Http\Requests\UpdatePromptRequest;
use App\Models\Prompt;
use App\Services\PromptCatalog;
use App\Services\PromptRenderer;
use App\Services\PromptService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;
/**
* Thin controller: validate → DTO → service/catalog → respond.
*/
class PromptController extends Controller
{
public function __construct(
private readonly PromptService $service,
private readonly PromptCatalog $catalog,
private readonly PromptRenderer $renderer,
) {}
public function index(Request $request): Response
{
$query = new ListPrompts(
search: $request->query('search'),
tag: $request->query('tag'),
favoritesOnly: $request->query('favorites') === '1',
sort: (string) $request->query('sort', 'created_at'),
direction: (string) $request->query('direction', ''),
);
return Inertia::render('Prompts/Index', [
'prompts' => $this->catalog->list($query),
'tags' => $this->catalog->tags()->pluck('name')->values(),
'filters' => [
'search' => $query->search,
'tag' => $query->tag,
'favorites' => $query->favoritesOnly,
],
'sort' => $query->normalizedSort(),
'direction' => $query->normalizedDirection(),
]);
}
public function create(): Response
{
return Inertia::render('Prompts/Create', [
'initial' => [
'name' => old('name'),
'description' => old('description'),
'body' => old('body'),
'tags' => old('tags', []),
],
'suggestedTags' => $this->catalog->tags()->pluck('name')->values(),
]);
}
public function store(StorePromptRequest $request): RedirectResponse
{
$prompt = $this->service->store($request->toStorePrompt());
return redirect()->route('prompts.show', $prompt);
}
public function show(Prompt $prompt): Response
{
$prompt->loadMissing('tags');
return Inertia::render('Prompts/Show', [
'prompt' => $prompt,
'variables' => $this->renderer->extractVariables($prompt->body),
]);
}
public function edit(Prompt $prompt): Response
{
$prompt->loadMissing('tags');
return Inertia::render('Prompts/Edit', [
'promptId' => $prompt->id,
'initial' => [
'name' => $prompt->name,
'description' => $prompt->description,
'body' => $prompt->body,
'tags' => $prompt->tags->pluck('name')->values()->all(),
],
'suggestedTags' => $this->catalog->tags()->pluck('name')->values(),
]);
}
public function update(UpdatePromptRequest $request, Prompt $prompt): RedirectResponse
{
$this->service->update($request->toUpdatePrompt(), $prompt);
return redirect()->route('prompts.show', $prompt);
}
public function destroy(Prompt $prompt): RedirectResponse
{
$this->service->delete($prompt);
return redirect()->route('prompts.index');
}
public function duplicate(Prompt $prompt): RedirectResponse
{
$copy = $this->service->duplicate($prompt);
return redirect()->route('prompts.show', $copy);
}
public function toggleFavorite(Prompt $prompt): RedirectResponse
{
$this->service->toggleFavorite($prompt);
return back();
}
/**
* Render the prompt with the given values and record the usage.
*/
public function use(Request $request, Prompt $prompt): JsonResponse
{
$validated = $request->validate([
'values' => ['required', 'array'],
'values.*' => ['string'],
]);
try {
$rendered = $this->renderer->render($prompt->body, $validated['values']);
} catch (PromptRenderException $exception) {
return response()->json([
'message' => $exception->getMessage(),
'missing' => $exception->missingVariables,
], 422);
}
$this->service->recordUsage($prompt);
return response()->json(['rendered' => $rendered]);
}
}