prepare(" SELECT t.id, t.slug, t.title, t.description, t.duration_min, t.sort_order, COALESCE(tp.completed, false) AS completed, tp.completed_at FROM tutorials t LEFT JOIN tutorial_progress tp ON tp.tutorial_id = t.id AND tp.user_id = :uid ORDER BY t.sort_order "); $stmt->execute([':uid' => $user_id]); json_ok(['tutorials' => $stmt->fetchAll()]); } // GET /api/tutorials/{slug} if (get_method() === 'GET' && !empty($segments[1]) && ($segments[2] ?? '') !== 'complete') { $stmt = $pdo->prepare(" SELECT t.*, COALESCE(tp.completed, false) AS completed FROM tutorials t LEFT JOIN tutorial_progress tp ON tp.tutorial_id = t.id AND tp.user_id = :uid WHERE t.slug = :slug "); $stmt->execute([':slug' => $segments[1], ':uid' => $user_id]); $tutorial = $stmt->fetch(); if (!$tutorial) json_error('Tutorial nicht gefunden', 404); json_ok(['tutorial' => $tutorial]); } // POST /api/tutorials/{slug}/complete if (get_method() === 'POST' && !empty($segments[1]) && ($segments[2] ?? '') === 'complete') { $stmt = $pdo->prepare("SELECT id FROM tutorials WHERE slug = :slug"); $stmt->execute([':slug' => $segments[1]]); $tutorial = $stmt->fetch(); if (!$tutorial) json_error('Tutorial nicht gefunden', 404); $stmt = $pdo->prepare(" INSERT INTO tutorial_progress (user_id, tutorial_id, completed, completed_at) VALUES (:uid, :tid, true, NOW()) ON CONFLICT (user_id, tutorial_id) DO UPDATE SET completed = true, completed_at = NOW() "); $stmt->execute([':uid' => $user_id, ':tid' => $tutorial['id']]); json_ok(['ok' => true]); } json_error('Unbekannter Tutorials-Endpunkt', 404);