11import { createClient } from "@/lib/supabase/server" ;
2+ import { createAdminClient } from "@/lib/supabase/admin" ;
23import { Button } from "@/components/ui/button" ;
34import Link from "next/link" ;
45import { notFound } from "next/navigation" ;
@@ -22,7 +23,7 @@ import {
2223} from "@/components/ui/accordion" ;
2324import { Card , CardContent } from "@/components/ui/card" ;
2425import { getTranslations } from 'next-intl/server' ;
25- import { getCurrentUserId } from '@/lib/supabase/tenant'
26+ import { getCurrentUserId , getCurrentTenantId } from '@/lib/supabase/tenant'
2627
2728export const dynamic = 'force-dynamic' ;
2829
@@ -36,11 +37,14 @@ interface Lesson {
3637export default async function CourseDetailsPage ( props : { params : Promise < { id : string } > } ) {
3738 const params = await props . params ;
3839 const t = await getTranslations ( 'coursePublicDetails' ) ;
39- const supabase = await createClient ( ) ;
40+ const tenantId = await getCurrentTenantId ( ) ;
41+ // Use admin client for public reads — anon JWT has no tenant_id claim,
42+ // so RLS get_tenant_id() defaults to wrong tenant for non-default tenants.
43+ const adminClient = createAdminClient ( ) ;
4044
4145 const userId = await getCurrentUserId ( )
4246 // Fetch course with lessons and category
43- const { data : course , error } = await supabase
47+ const { data : course , error } = await adminClient
4448 . from ( "courses" )
4549 . select ( `
4650 *,
@@ -57,6 +61,7 @@ export default async function CourseDetailsPage(props: { params: Promise<{ id: s
5761 ` )
5862 . eq ( "course_id" , parseInt ( params . id ) )
5963 . eq ( "status" , "published" )
64+ . eq ( "tenant_id" , tenantId )
6065 . single ( ) ;
6166
6267 if ( error || ! course ) {
@@ -66,7 +71,7 @@ export default async function CourseDetailsPage(props: { params: Promise<{ id: s
6671 // Fetch author separately (profiles is global, no tenant_id)
6772 let author = null ;
6873 if ( course . author_id ) {
69- const { data : authorData } = await supabase
74+ const { data : authorData } = await adminClient
7075 . from ( "profiles" )
7176 . select ( "id, full_name, avatar_url, bio" )
7277 . eq ( "id" , course . author_id )
@@ -80,9 +85,10 @@ export default async function CourseDetailsPage(props: { params: Promise<{ id: s
8085 const estimatedHours = Math . floor ( totalLessons * 10 / 60 ) ;
8186 const estimatedMinutes = ( totalLessons * 10 ) % 60 ;
8287
83- // Check user's enrollment
88+ // Check user's enrollment (uses RLS client — only works for logged-in users)
8489 let hasAccess = false ;
8590 if ( userId ) {
91+ const supabase = await createClient ( ) ;
8692 const { data : enrollment } = await supabase
8793 . from ( 'enrollments' )
8894 . select ( 'enrollment_id' )
@@ -97,7 +103,7 @@ export default async function CourseDetailsPage(props: { params: Promise<{ id: s
97103 }
98104
99105 // Fetch product for pricing
100- const { data : productCourses } = await supabase
106+ const { data : productCourses } = await adminClient
101107 . from ( 'product_courses' )
102108 . select ( 'product:products(*)' )
103109 . eq ( 'course_id' , parseInt ( params . id ) )
0 commit comments