-
Notifications
You must be signed in to change notification settings - Fork 2
🏆 Transform Projects to Zenith Hall with Enhanced Branding #228
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,49 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { NextRequest, NextResponse } from 'next/server'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { createClient } from '@/lib/supabase/server'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export async function GET( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| request: NextRequest, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { params }: { params: Promise<{ username: string }> } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { username } = await params; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!username) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return NextResponse.json( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { error: 'Username is required' }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { status: 400 } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+11
to
+16
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add basic username validation (length/charset) to harden the endpoint. Guard early to avoid noisy queries and enforce your username contract. Example patch: if (!username) {
return NextResponse.json(
{ error: 'Username is required' },
{ status: 400 }
);
}
+ // Basic validation: 3–30 chars, alnum/underscore/dot
+ if (!/^[a-zA-Z0-9._]{3,30}$/.test(username)) {
+ return NextResponse.json(
+ { error: 'Invalid username format' },
+ { status: 400 }
+ );
+ }📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Use server-side Supabase client directly | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const supabase = await createClient(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { data: profile, error } = await supabase | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .from('profiles') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .select('*') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .eq('username', username) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .eq('is_public', true) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .single(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (error.code === 'PGRST116') { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return NextResponse.json( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { error: 'Profile not found or not public' }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { status: 404 } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.error('Error fetching public profile:', error); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return NextResponse.json( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { error: 'Failed to fetch profile' }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { status: 500 } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return NextResponse.json({ profile }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+20
to
+41
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid PII leakage: don’t select '*' on a public endpoint; whitelist safe public fields. This route is publicly accessible yet returns the whole row (including email/phone if present). That leaks PII regardless of the UI’s selective rendering. Only return a curated set of public fields. Apply: - const { data: profile, error } = await supabase
- .from('profiles')
- .select('*')
- .eq('username', username)
- .eq('is_public', true)
- .single();
+ const { data: profile, error } = await supabase
+ .from('profiles')
+ .select(`
+ id,
+ username,
+ first_name,
+ last_name,
+ bio,
+ location,
+ current_position,
+ company,
+ github_url,
+ linkedin_url,
+ twitter_url,
+ skills,
+ is_public
+ `)
+ .eq('username', username)
+ .eq('is_public', true)
+ .maybeSingle();And simplify not-found handling: - if (error) {
- if (error.code === 'PGRST116') {
- return NextResponse.json(
- { error: 'Profile not found or not public' },
- { status: 404 }
- );
- }
- console.error('Error fetching public profile:', error);
- return NextResponse.json(
- { error: 'Failed to fetch profile' },
- { status: 500 }
- );
- }
+ if (error) {
+ console.error('Error fetching public profile:', error);
+ return NextResponse.json({ error: 'Failed to fetch profile' }, { status: 500 });
+ }
+ if (!profile) {
+ return NextResponse.json({ error: 'Profile not found or not public' }, { status: 404 });
+ }📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.error('Error fetching public profile:', error); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return NextResponse.json( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { error: 'Failed to fetch profile' }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { status: 500 } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,123 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||
| import { NextRequest, NextResponse } from 'next/server' | ||||||||||||||||||||||||||||||||||||||||||||||||
| import { createClient as createServiceClient } from '@supabase/supabase-js' | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| export async function POST(request: NextRequest) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||
| const { testId, userId, userEmail, userMetadata } = await request.json() | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| if (!testId || !userId) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| return NextResponse.json( | ||||||||||||||||||||||||||||||||||||||||||||||||
| { error: 'Test ID and User ID are required' }, | ||||||||||||||||||||||||||||||||||||||||||||||||
| { status: 400 } | ||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+4
to
+13
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Validate input with a schema and return precise status codes. Add a Zod (or similar) schema to validate +import { z } from 'zod'
+
export async function POST(request: NextRequest) {
try {
- const { testId, userId, userEmail, userMetadata } = await request.json()
+ const body = await request.json()
+ const { testId, userId, userEmail, userMetadata } = z.object({
+ testId: z.string().min(1),
+ userId: z.string().min(1),
+ userEmail: z.string().email().optional(),
+ userMetadata: z.record(z.any()).optional(),
+ }).parse(body)
- if (!testId || !userId) {
- return NextResponse.json(
- { error: 'Test ID and User ID are required' },
- { status: 400 }
- )
- }
+ // continue...📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| // Use service role client to bypass RLS | ||||||||||||||||||||||||||||||||||||||||||||||||
| const serviceSupabase = createServiceClient( | ||||||||||||||||||||||||||||||||||||||||||||||||
| process.env.NEXT_PUBLIC_SUPABASE_URL!, | ||||||||||||||||||||||||||||||||||||||||||||||||
| process.env.SUPABASE_SERVICE_ROLE_KEY! | ||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+15
to
+20
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Guard env vars early; fail fast if misconfigured. Non-null assertions won’t protect at runtime. - const serviceSupabase = createServiceClient(
- process.env.NEXT_PUBLIC_SUPABASE_URL!,
- process.env.SUPABASE_SERVICE_ROLE_KEY!
- )
+ const SUPABASE_URL = process.env.NEXT_PUBLIC_SUPABASE_URL
+ const SERVICE_KEY = process.env.SUPABASE_SERVICE_ROLE_KEY
+ if (!SUPABASE_URL || !SERVICE_KEY) {
+ console.error('Supabase env vars missing')
+ return NextResponse.json({ error: 'Server misconfiguration' }, { status: 500 })
+ }
+ const serviceSupabase = createServiceClient(SUPABASE_URL, SERVICE_KEY)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||
| // Check if already registered | ||||||||||||||||||||||||||||||||||||||||||||||||
| const { data: existingRegistration } = await serviceSupabase | ||||||||||||||||||||||||||||||||||||||||||||||||
| .from('test_registrations') | ||||||||||||||||||||||||||||||||||||||||||||||||
| .select('id') | ||||||||||||||||||||||||||||||||||||||||||||||||
| .eq('test_id', testId) | ||||||||||||||||||||||||||||||||||||||||||||||||
| .eq('user_id', userId) | ||||||||||||||||||||||||||||||||||||||||||||||||
| .single() | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| if (existingRegistration) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| return NextResponse.json( | ||||||||||||||||||||||||||||||||||||||||||||||||
| { error: 'User is already registered for this test' }, | ||||||||||||||||||||||||||||||||||||||||||||||||
| { status: 400 } | ||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| // Ensure profile exists to prevent trigger failure | ||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||
| const { error: profileError } = await serviceSupabase | ||||||||||||||||||||||||||||||||||||||||||||||||
| .from('profiles') | ||||||||||||||||||||||||||||||||||||||||||||||||
| .select('id, first_name, last_name, email') | ||||||||||||||||||||||||||||||||||||||||||||||||
| .eq('id', userId) | ||||||||||||||||||||||||||||||||||||||||||||||||
| .single() | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| if (profileError && profileError.code === 'PGRST116') { | ||||||||||||||||||||||||||||||||||||||||||||||||
| // Profile doesn't exist, create a minimal one | ||||||||||||||||||||||||||||||||||||||||||||||||
| const { error: createError } = await serviceSupabase | ||||||||||||||||||||||||||||||||||||||||||||||||
| .from('profiles') | ||||||||||||||||||||||||||||||||||||||||||||||||
| .insert({ | ||||||||||||||||||||||||||||||||||||||||||||||||
| id: userId, | ||||||||||||||||||||||||||||||||||||||||||||||||
| email: userEmail, | ||||||||||||||||||||||||||||||||||||||||||||||||
| first_name: userMetadata?.first_name || userMetadata?.given_name || '', | ||||||||||||||||||||||||||||||||||||||||||||||||
| last_name: userMetadata?.last_name || userMetadata?.family_name || '', | ||||||||||||||||||||||||||||||||||||||||||||||||
| is_public: true, | ||||||||||||||||||||||||||||||||||||||||||||||||
| email_notifications: true, | ||||||||||||||||||||||||||||||||||||||||||||||||
| profile_completion_percentage: 0, | ||||||||||||||||||||||||||||||||||||||||||||||||
| is_admin: false, | ||||||||||||||||||||||||||||||||||||||||||||||||
| username_editable: true, | ||||||||||||||||||||||||||||||||||||||||||||||||
| username_set: false, | ||||||||||||||||||||||||||||||||||||||||||||||||
| profile_complete: false | ||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| if (createError) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| console.error('Error creating profile:', createError) | ||||||||||||||||||||||||||||||||||||||||||||||||
| // Continue anyway, the trigger might still work | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (profileException) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| console.error('Exception during profile check/creation:', profileException) | ||||||||||||||||||||||||||||||||||||||||||||||||
| // Continue with registration | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| // Prepare registration data with proper fallbacks for the trigger | ||||||||||||||||||||||||||||||||||||||||||||||||
| const fullName = userMetadata?.full_name || | ||||||||||||||||||||||||||||||||||||||||||||||||
| userMetadata?.name || | ||||||||||||||||||||||||||||||||||||||||||||||||
| (userMetadata?.first_name && userMetadata?.last_name ? | ||||||||||||||||||||||||||||||||||||||||||||||||
| `${userMetadata.first_name} ${userMetadata.last_name}` : | ||||||||||||||||||||||||||||||||||||||||||||||||
| null); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| // Register for the test | ||||||||||||||||||||||||||||||||||||||||||||||||
| const { data, error } = await serviceSupabase | ||||||||||||||||||||||||||||||||||||||||||||||||
| .from('test_registrations') | ||||||||||||||||||||||||||||||||||||||||||||||||
| .insert([{ | ||||||||||||||||||||||||||||||||||||||||||||||||
| test_id: testId, | ||||||||||||||||||||||||||||||||||||||||||||||||
| user_id: userId, | ||||||||||||||||||||||||||||||||||||||||||||||||
| status: 'registered', | ||||||||||||||||||||||||||||||||||||||||||||||||
| attempt_count: 0, | ||||||||||||||||||||||||||||||||||||||||||||||||
| registration_date: new Date().toISOString(), | ||||||||||||||||||||||||||||||||||||||||||||||||
| full_name: fullName, | ||||||||||||||||||||||||||||||||||||||||||||||||
| email: userEmail || null, | ||||||||||||||||||||||||||||||||||||||||||||||||
| phone: null, | ||||||||||||||||||||||||||||||||||||||||||||||||
| institution: null, | ||||||||||||||||||||||||||||||||||||||||||||||||
| department: null, | ||||||||||||||||||||||||||||||||||||||||||||||||
| year_of_study: null, | ||||||||||||||||||||||||||||||||||||||||||||||||
| experience_level: null, | ||||||||||||||||||||||||||||||||||||||||||||||||
| registration_data: { | ||||||||||||||||||||||||||||||||||||||||||||||||
| registered_via: 'api_tests_register', | ||||||||||||||||||||||||||||||||||||||||||||||||
| registration_timestamp: new Date().toISOString(), | ||||||||||||||||||||||||||||||||||||||||||||||||
| user_metadata: userMetadata | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| }]) | ||||||||||||||||||||||||||||||||||||||||||||||||
| .select() | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| if (error) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| console.error('Registration error:', error) | ||||||||||||||||||||||||||||||||||||||||||||||||
| return NextResponse.json( | ||||||||||||||||||||||||||||||||||||||||||||||||
| { error: 'Failed to register for test', details: error.message }, | ||||||||||||||||||||||||||||||||||||||||||||||||
| { status: 500 } | ||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| return NextResponse.json({ | ||||||||||||||||||||||||||||||||||||||||||||||||
| success: true, | ||||||||||||||||||||||||||||||||||||||||||||||||
| data: data[0] | ||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (error) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| console.error('Error in test registration API:', error) | ||||||||||||||||||||||||||||||||||||||||||||||||
| return NextResponse.json( | ||||||||||||||||||||||||||||||||||||||||||||||||
| { error: 'Internal server error' }, | ||||||||||||||||||||||||||||||||||||||||||||||||
| { status: 500 } | ||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Fix Next.js route handler params typing (remove Promise/await).
paramsis not a Promise in App Router route handlers. Typing it as a Promise and awaiting it is incorrect and unnecessary.Apply:
📝 Committable suggestion
🤖 Prompt for AI Agents