feat: add City10 platform with Laravel 13, AI agents, 3D viewer, and LGPD compliance
Initial commit of the complete City10 virtual city simulation platform. Backend (Laravel 13): - REST API with Sanctum tokens and session-based web authentication - Role-based access control (admin/user) with middleware protection - AI agent CRUD with OpenRouter.ai integration restricted to free models - Store management with 3D coordinates and AI shopkeeper assignment - Versioned legal documents (Terms, Privacy, Cookies) with LGPD audit trail - Math CAPTCHA on public forms and multi-language support (pt_BR, en, es) Frontend: - Responsive Blade templates with Tailwind CSS v4 - Three.js 3D city viewer with SSE chat streaming to AI agents - Admin panel for store and user administration Infrastructure: - MariaDB/MySQL database with comprehensive migrations - Database seeders for demo content and test accounts - PHPUnit test suite and Laravel Pint code styling - Vite build configuration with hot reload
This commit is contained in:
+112
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\AiAgentRequest;
|
||||
use App\Models\AiAgent;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* AI agent management endpoints (admin only).
|
||||
*
|
||||
* Agents power the NPCs and managers of the virtual city through the
|
||||
* OpenRouter.ai API, restricted to the allow-listed free models.
|
||||
*/
|
||||
class AiAgentController extends Controller
|
||||
{
|
||||
/**
|
||||
* Return the list of models allowed for agent configuration.
|
||||
*/
|
||||
public function models(): JsonResponse
|
||||
{
|
||||
return response()->json([
|
||||
'models' => config('ai.allowed_models', []),
|
||||
'default' => config('ai.default_model'),
|
||||
'api_key_configured' => filled(config('ai.openrouter.api_key')),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paginated listing of registered AI agents.
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$query = AiAgent::query()->orderBy('name');
|
||||
|
||||
if ($type = $request->query('type')) {
|
||||
$query->where('type', $type);
|
||||
}
|
||||
|
||||
if ($status = $request->query('status')) {
|
||||
$query->where('status', $status);
|
||||
}
|
||||
|
||||
return response()->json($query->paginate((int) $request->query('per_page', 15)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a compact snapshot of active agents for the 3D renderer.
|
||||
*/
|
||||
public function world(): JsonResponse
|
||||
{
|
||||
$agents = AiAgent::query()
|
||||
->where('status', '!=', 'paused')
|
||||
->get(['id', 'name', 'type', 'status', 'pos_x', 'pos_y', 'pos_z', 'rotation_y', 'current_goal'])
|
||||
->map(fn (AiAgent $agent): array => [
|
||||
'id' => $agent->id,
|
||||
'name' => $agent->name,
|
||||
'type' => $agent->type,
|
||||
'status' => $agent->status,
|
||||
'position' => [(float) $agent->pos_x, (float) $agent->pos_y, (float) $agent->pos_z],
|
||||
'rotation_y' => (float) $agent->rotation_y,
|
||||
'goal' => $agent->current_goal,
|
||||
]);
|
||||
|
||||
return response()->json(['agents' => $agents]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Persist a new AI agent.
|
||||
*/
|
||||
public function store(AiAgentRequest $request): JsonResponse
|
||||
{
|
||||
$data = $request->validated();
|
||||
|
||||
$data['model'] = $data['model'] ?? config('ai.default_model');
|
||||
$data['status'] = $data['status'] ?? 'active';
|
||||
|
||||
$agent = AiAgent::create($data);
|
||||
|
||||
return response()->json($agent, 201);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a single AI agent.
|
||||
*/
|
||||
public function show(AiAgent $aiAgent): JsonResponse
|
||||
{
|
||||
return response()->json($aiAgent->load('stores:id,name,agent_id,is_open'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an AI agent.
|
||||
*/
|
||||
public function update(AiAgentRequest $request, AiAgent $aiAgent): JsonResponse
|
||||
{
|
||||
$aiAgent->update($request->validated());
|
||||
|
||||
return response()->json($aiAgent->fresh());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an AI agent.
|
||||
*/
|
||||
public function destroy(AiAgent $aiAgent): JsonResponse
|
||||
{
|
||||
$aiAgent->delete();
|
||||
|
||||
return response()->json(['message' => __('agents.deleted')]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user