Files
obc-terrassement/app/api/formations/[moduleId]/route.ts
Claude 41e686c560 feat: complete HookLab MVP - TikTok Shop coaching platform
Full-stack Next.js 15 application with:
- Landing page with marketing components (Hero, Testimonials, Pricing, FAQ)
- Multi-step candidature form with API route
- Stripe Checkout integration (subscription + webhooks)
- Supabase Auth (login/register) with middleware protection
- Dashboard with progress tracking and module system
- Formations pages with completion tracking
- Profile management with password change
- Database schema with RLS policies
- Resend email integration for transactional emails

Stack: Next.js 15, TypeScript, Tailwind CSS v4, Supabase, Stripe, Resend

https://claude.ai/code/session_01H2aRGDaKgarPvhay2HxN6Y
2026-02-08 12:39:18 +00:00

71 lines
1.8 KiB
TypeScript

import { NextResponse } from "next/server";
import { createClient } from "@/lib/supabase/server";
import type { Module, UserProgress } from "@/types/database.types";
// GET /api/formations/[moduleId] - Récupérer un module
export async function GET(
_request: Request,
{ params }: { params: Promise<{ moduleId: string }> }
) {
try {
const { moduleId } = await params;
const supabase = await createClient();
// Vérifier l'authentification
const {
data: { user },
} = await supabase.auth.getUser();
if (!user) {
return NextResponse.json(
{ error: "Non authentifie." },
{ status: 401 }
);
}
// Vérifier l'abonnement actif
const { data: profile } = await supabase
.from("profiles")
.select("subscription_status")
.eq("id", user.id)
.single() as { data: { subscription_status: string } | null };
if (!profile || profile.subscription_status !== "active") {
return NextResponse.json(
{ error: "Abonnement inactif." },
{ status: 403 }
);
}
// Récupérer le module
const { data: module, error } = await supabase
.from("modules")
.select("*")
.eq("id", moduleId)
.eq("is_published", true)
.single() as { data: Module | null; error: unknown };
if (error || !module) {
return NextResponse.json(
{ error: "Module non trouve." },
{ status: 404 }
);
}
// Récupérer la progression
const { data: progress } = await supabase
.from("user_progress")
.select("*")
.eq("user_id", user.id)
.eq("module_id", moduleId)
.single() as { data: UserProgress | null };
return NextResponse.json({ module, progress });
} catch {
return NextResponse.json(
{ error: "Erreur serveur." },
{ status: 500 }
);
}
}