import { createClient } from '@/lib/supabase' import type { BrandConfig, Survey } from '@/lib/types' import type { FormSchema, Question as EngineQuestion } from '@/lib/form-engine.types' import { buildFormSchema } from '@/lib/form-engine' import { WizardForm } from '@/components/wizard-form' // Preguntas de consentimiento (S1, 1.1, 1.2): las resuelve ConsentScreen, no el // motor de flujo — su texto legal (ADR-003) no vive en el hint de estas filas // todavía. Se excluyen del FormSchema para que el wizard arranque en S2. const CONSENT_CODES = new Set(['S1', '1.1', '1.2']) // Force dynamic rendering — page fetches from Supabase at request time. export const dynamic = 'force-dynamic' // In Next.js 15, searchParams is a Promise and must be awaited. interface PageProps { searchParams: Promise<{ s?: string }> } export default async function Page({ searchParams }: PageProps) { const { s: surveyId } = await searchParams const supabase = createClient() // 1. Fetch survey — by ?s=UUID if provided, otherwise first live survey const surveyQuery = supabase .from('surveys') .select('id, org_id, title, status, is_anonymous, k_threshold, consent_version_id, brand_config') const { data: surveyRow, error: surveyError } = surveyId ? await surveyQuery.eq('id', surveyId).maybeSingle() : await surveyQuery.eq('status', 'live').maybeSingle() if (surveyError) { return (

Error al cargar la encuesta

No fue posible conectarse a la base de datos. Revisá las variables de entorno.

{surveyError.message}
) } if (!surveyRow) { return (

No hay encuesta activa

Para ver el formulario, la encuesta debe estar en estado live, o pasá el UUID por parámetro: ?s=UUID.

          {`-- Activar en Supabase Cloud:\nUPDATE surveys SET status = 'live'\nWHERE id = '30000000-0000-0000-0000-000000000001';`}
        
) } // 2. Fetch questions ordered by position — incluye hint/instance_generator/instance_of (4D) const { data: questionRows, error: questionsError } = await supabase .from('questions') .select( 'id, survey_id, code, type, prompt, position, is_sensitive, required, hint, ' + 'max_select, options, conditional_rules, instance_generator, instance_of' ) .eq('survey_id', surveyRow.id) .order('position', { ascending: true }) if (questionsError || !questionRows) { return (

Error al cargar las preguntas

{questionsError?.message ?? 'Respuesta vacía del servidor.'}

) } // Cast en dos pasos: el cliente Supabase no tiene un Database genérico configurado // (lib/supabase.ts), así que el tipo de fila que infiere para .select() no solapa // directamente con EngineQuestion. Las columnas pedidas arriba sí coinciden 1:1. const engineQuestions = questionRows as unknown as EngineQuestion[] console.log(`[4D] Survey loaded: id=${surveyRow.id} | questions=${engineQuestions.length}`) const survey: Survey = { id: surveyRow.id, org_id: surveyRow.org_id, title: surveyRow.title, status: surveyRow.status, is_anonymous: surveyRow.is_anonymous, k_threshold: surveyRow.k_threshold, consent_version_id: surveyRow.consent_version_id, brand_config: (surveyRow.brand_config as BrandConfig) ?? null, questions: [], } // El consentimiento (S1, 1.1, 1.2) lo resuelve ConsentScreen, no el motor — ver nota arriba. const schema: FormSchema = buildFormSchema( engineQuestions.filter((q) => !CONSENT_CODES.has(q.code)) ) return }