Full sweep: fix broken features, redesign NodePreview, wire AI service

FIXES (from comprehensive audit):
- NodePreview: complete rewrite — 380px left panel with document
  summaries, commitment list, phase track visualization, scrollable.
  Fixed children count bug (was showing [object Object]).
  Slides in from left (not right) to not overlap branch handles.
- CommitmentForm: added required validation on eigenaar_id field
- MetroMap: wired custom metro node creation with form + POST /metro-nodes
- MetroMap: removed dead handleCliCommand console.log
- MetroMap: added metro node creation modal (naam + beschrijving)

NEW — AI Service integration:
- ai-service/main.py: real Anthropic API integration via httpx
  - Reads ANTHROPIC_API_KEY from env, uses claude-haiku-4-5-20251001
  - /api/chat fetches project context from PostgreSQL (docs, commitments)
  - /api/summarize sends content to Claude for summarization
  - /api/search does basic text search on documents + kennis_artikelen
- AiController.php: Laravel proxy for /api/ai/chat → ai-service
- CliBar.vue: complete rewrite with async API calls, processing state,
  error handling, conversation history, auto-scroll
  - Receives projectId prop for context-scoped AI queries
  - Shows "denken..." animation while waiting for response
- docker-compose.yml: passes ANTHROPIC_API_KEY to ai-service container
- config/services.php: ai service URL configuration

To activate AI: set ANTHROPIC_API_KEY in .env and rebuild ai-service.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
znetsixe
2026-04-08 15:07:51 +02:00
parent 9f033835cd
commit f4ec49254a
10 changed files with 619 additions and 84 deletions

View File

@@ -7,6 +7,7 @@ use App\Http\Controllers\MetroLineController;
use App\Http\Controllers\MetroNodeController;
use App\Http\Controllers\ProjectController;
use App\Http\Controllers\ThemaController;
use App\Http\Controllers\AiController;
use Illuminate\Support\Facades\Route;
// Redirect root to map
@@ -59,6 +60,9 @@ Route::middleware(['auth', 'verified'])->group(function () {
Route::put('/metro-nodes/{metroNode}', [MetroNodeController::class, 'update'])->name('metro-nodes.update');
Route::delete('/metro-nodes/{metroNode}', [MetroNodeController::class, 'destroy'])->name('metro-nodes.destroy');
// AI Chat
Route::post('/api/ai/chat', [AiController::class, 'chat'])->name('ai.chat');
// Dashboard (redirects to map)
Route::get('/dashboard', fn () => redirect('/map'))->name('dashboard');
});