- Move 12 markdown files from root to docs/ subdirectories - Organize documentation by category: • docs/troubleshooting/ (1 file) - Technical troubleshooting guides • docs/deployment/ (4 files) - Deployment and security documentation • docs/guides/ (3 files) - Feature-specific guides • docs/planning/ (4 files) - Planning and improvement proposals Root directory cleanup: - Reduced from 16 to 4 markdown files in root - Only essential project files remain: • CLAUDE.md (AI instructions) • README.md (Main project readme) • CLEANUP_PLAN.md (Current cleanup plan) • SRC_STRUCTURE_IMPROVEMENTS.md (Structure improvements) This improves: ✅ Documentation discoverability ✅ Logical organization by purpose ✅ Clean root directory ✅ Better maintainability
169 lines
4.7 KiB
PHP
169 lines
4.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Framework\Admin;
|
|
|
|
use App\Framework\Http\HttpRequest;
|
|
use App\Framework\Http\Status;
|
|
use App\Framework\Router\Result\JsonResult;
|
|
|
|
/**
|
|
* Admin API Handler
|
|
*
|
|
* Handles auto-generated API endpoints for admin resources
|
|
*/
|
|
final readonly class AdminApiHandler
|
|
{
|
|
public function handleList(
|
|
HttpRequest $request,
|
|
mixed $repository
|
|
): JsonResult {
|
|
// Extract query parameters
|
|
$page = (int) ($request->query->get('page') ?? 1);
|
|
$perPage = (int) ($request->query->get('per_page') ?? 25);
|
|
$sortBy = $request->query->get('sort_by');
|
|
$sortDir = $request->query->get('sort_dir') ?? 'asc';
|
|
$search = $request->query->get('search');
|
|
|
|
// Build filters
|
|
$filters = [];
|
|
if ($search) {
|
|
$filters['search'] = $search;
|
|
}
|
|
|
|
// Fetch data from repository
|
|
$data = $repository->findAll($filters);
|
|
|
|
// Apply sorting if requested
|
|
if ($sortBy && method_exists($repository, 'sortBy')) {
|
|
$data = $repository->sortBy($data, $sortBy, $sortDir);
|
|
}
|
|
|
|
// Apply pagination
|
|
$total = count($data);
|
|
$offset = ($page - 1) * $perPage;
|
|
$paginatedData = array_slice($data, $offset, $perPage);
|
|
|
|
// Convert to arrays
|
|
$items = array_map(
|
|
fn($item) => method_exists($item, 'toArray') ? $item->toArray() : (array) $item,
|
|
$paginatedData
|
|
);
|
|
|
|
return new JsonResult([
|
|
'success' => true,
|
|
'data' => $items,
|
|
'pagination' => [
|
|
'page' => $page,
|
|
'per_page' => $perPage,
|
|
'total' => $total,
|
|
'pages' => (int) ceil($total / $perPage),
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function handleGet(
|
|
string $id,
|
|
mixed $repository
|
|
): JsonResult {
|
|
$item = $repository->findById($id);
|
|
|
|
if ($item === null) {
|
|
return new JsonResult([
|
|
'success' => false,
|
|
'error' => 'Resource not found',
|
|
], Status::NOT_FOUND);
|
|
}
|
|
|
|
$data = method_exists($item, 'toArray') ? $item->toArray() : (array) $item;
|
|
|
|
return new JsonResult([
|
|
'success' => true,
|
|
'data' => $data,
|
|
]);
|
|
}
|
|
|
|
public function handleCreate(
|
|
HttpRequest $request,
|
|
mixed $repository
|
|
): JsonResult {
|
|
$data = $request->parsedBody->toArray();
|
|
|
|
try {
|
|
$item = $repository->create($data);
|
|
|
|
$responseData = method_exists($item, 'toArray') ? $item->toArray() : (array) $item;
|
|
|
|
return new JsonResult([
|
|
'success' => true,
|
|
'data' => $responseData,
|
|
'message' => 'Resource created successfully',
|
|
], Status::CREATED);
|
|
} catch (\Exception $e) {
|
|
return new JsonResult([
|
|
'success' => false,
|
|
'error' => $e->getMessage(),
|
|
], Status::BAD_REQUEST);
|
|
}
|
|
}
|
|
|
|
public function handleUpdate(
|
|
string $id,
|
|
HttpRequest $request,
|
|
mixed $repository
|
|
): JsonResult {
|
|
$data = $request->parsedBody->toArray();
|
|
|
|
try {
|
|
$item = $repository->update($id, $data);
|
|
|
|
if ($item === null) {
|
|
return new JsonResult([
|
|
'success' => false,
|
|
'error' => 'Resource not found',
|
|
], Status::NOT_FOUND);
|
|
}
|
|
|
|
$responseData = method_exists($item, 'toArray') ? $item->toArray() : (array) $item;
|
|
|
|
return new JsonResult([
|
|
'success' => true,
|
|
'data' => $responseData,
|
|
'message' => 'Resource updated successfully',
|
|
]);
|
|
} catch (\Exception $e) {
|
|
return new JsonResult([
|
|
'success' => false,
|
|
'error' => $e->getMessage(),
|
|
], Status::BAD_REQUEST);
|
|
}
|
|
}
|
|
|
|
public function handleDelete(
|
|
string $id,
|
|
mixed $repository
|
|
): JsonResult {
|
|
try {
|
|
$deleted = $repository->delete($id);
|
|
|
|
if (!$deleted) {
|
|
return new JsonResult([
|
|
'success' => false,
|
|
'error' => 'Resource not found',
|
|
], Status::NOT_FOUND);
|
|
}
|
|
|
|
return new JsonResult([
|
|
'success' => true,
|
|
'message' => 'Resource deleted successfully',
|
|
]);
|
|
} catch (\Exception $e) {
|
|
return new JsonResult([
|
|
'success' => false,
|
|
'error' => $e->getMessage(),
|
|
], Status::BAD_REQUEST);
|
|
}
|
|
}
|
|
}
|