From 3188a61431f7497f2d024ba8aa8586f0839facc5 Mon Sep 17 00:00:00 2001 From: Guillermo Arrieta Medina Date: Mon, 23 Feb 2026 13:58:02 -0600 Subject: [PATCH 1/5] =?UTF-8?q?Se=20renderiza=20el=20contenido=20tem=C3=A1?= =?UTF-8?q?tico=20en=20datos=20generales=20a=20partir=20de=20su=20columna?= =?UTF-8?q?=20en=20la=20BDD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../detalle/AsignaturaDetailPage.tsx | 142 ++++++++++++++---- 1 file changed, 112 insertions(+), 30 deletions(-) diff --git a/src/components/asignaturas/detalle/AsignaturaDetailPage.tsx b/src/components/asignaturas/detalle/AsignaturaDetailPage.tsx index d7f46ac..733f7d5 100644 --- a/src/components/asignaturas/detalle/AsignaturaDetailPage.tsx +++ b/src/components/asignaturas/detalle/AsignaturaDetailPage.tsx @@ -62,6 +62,56 @@ export interface AsignaturaResponse { datos: AsignaturaDatos } +function isRecord(value: unknown): value is Record { + return typeof value === 'object' && value !== null && !Array.isArray(value) +} + +function parseContenidoTematicoToPlainText(value: unknown): string { + if (!Array.isArray(value)) return '' + + const blocks: Array = [] + + for (const item of value) { + if (!isRecord(item)) continue + + const unidad = + typeof item.unidad === 'number' && Number.isFinite(item.unidad) + ? item.unidad + : undefined + const titulo = typeof item.titulo === 'string' ? item.titulo : '' + + const header = `${unidad ?? ''}${unidad ? '.' : ''} ${titulo}`.trim() + if (!header) continue + + const lines: Array = [header] + + const temas = Array.isArray(item.temas) ? item.temas : [] + temas.forEach((tema, idx) => { + const temaNombre = + typeof tema === 'string' + ? tema + : isRecord(tema) && typeof tema.nombre === 'string' + ? tema.nombre + : '' + if (!temaNombre) return + + if (unidad != null) { + lines.push(`${unidad}.${idx + 1} ${temaNombre}`.trim()) + } else { + lines.push(`${idx + 1}. ${temaNombre}`) + } + }) + + blocks.push(lines.join('\n')) + } + + return blocks.join('\n\n').trimEnd() +} + +const columnParsers: Partial string>> = { + contenido_tematico: parseContenidoTematicoToPlainText, +} + function EditableHeaderField({ value, onSave, @@ -122,8 +172,8 @@ export default function AsignaturaDetailPage() { useSubject(asignaturaId) // 1. Asegúrate de tener estos estados en tu componente principal const [messages, setMessages] = useState>([]) - const [asignatura, setAsignatura] = useState({}) - const [campos, setCampos] = useState>([]) + const [asignatura, setAsignatura] = useState(null) + const [campos] = useState>([]) const [activeTab, setActiveTab] = useState('datos') const updateAsignatura = useUpdateAsignatura() @@ -172,15 +222,12 @@ export default function AsignaturaDetailPage() { } const handlePersistDatoGeneral = (clave: string, value: string) => { - const baseDatos = - (asignatura as any)?.datos ?? (asignaturaApi as any)?.datos ?? {} + const baseDatos = asignatura?.datos ?? (asignaturaApi as any)?.datos ?? {} const mergedDatos = { ...baseDatos, [clave]: value } // Mantener estado local coherente para merges posteriores. - setAsignatura((prev: any) => ({ - ...(prev && Object.keys(prev).length - ? prev - : ((asignaturaApi as any) ?? {})), + setAsignatura((prev) => ({ + ...((prev ?? asignaturaApi ?? {}) as any), datos: mergedDatos, })) @@ -193,9 +240,7 @@ export default function AsignaturaDetailPage() { } /* ---------- sincronizar API ---------- */ useEffect(() => { - if (asignaturaApi?.datos) { - setAsignatura(asignaturaApi) - } + if (asignaturaApi) setAsignatura(asignaturaApi) }, [asignaturaApi]) // 2. Funciones de manejo para la IA @@ -213,7 +258,7 @@ export default function AsignaturaDetailPage() { // toast.info("Enviando consulta a la IA..."); } - const handleAcceptSuggestion = (sugerencia: IASugerencia) => { + const handleAcceptSuggestion = (_sugerencia: IASugerencia) => { // Lógica para actualizar el valor del campo en tu estado de asignatura // toast.success(`Sugerencia aplicada a ${sugerencia.campoNombre}`); } @@ -252,7 +297,7 @@ export default function AsignaturaDetailPage() { return (
{/* ================= HEADER ACTUALIZADO ================= */} -
+
- {asignaturaApi?.planes_estudio?.datos?.nombre || ''} + {(() => { + const datosPlan = asignaturaApi?.planes_estudio?.datos + return isRecord(datosPlan) + ? String((datosPlan as any).nombre ?? '') + : '' + })()} @@ -357,7 +407,7 @@ export default function AsignaturaDetailPage() { {/* ================= TAB: DATOS GENERALES ================= */} + (_id) => console.log( 'Rechazada', ) /* toast.error("Sugerencia rechazada")*/ @@ -421,7 +471,7 @@ export default function AsignaturaDetailPage() { /* ================= TAB CONTENT ================= */ interface DatosGeneralesProps { asignaturaId: string - data: AsignaturaDetail + data: AsignaturaDetail | null isLoading: boolean onPersistDato: (clave: string, value: string) => void } @@ -431,15 +481,22 @@ function DatosGenerales({ asignaturaId, onPersistDato, }: DatosGeneralesProps) { - const formatTitle = (key: string): string => - key.replace(/_/g, ' ').replace(/\b\w/g, (l: string) => l.toUpperCase()) - // 1. Extraemos la definición de la estructura (los metadatos) - const structureProps = - data.estructuras_asignatura?.definicion?.properties || {} + const definicionRaw = data?.estructuras_asignatura?.definicion + const definicion = isRecord(definicionRaw) + ? (definicionRaw as Record) + : null + + const propertiesRaw = definicion ? (definicion as any).properties : undefined + const structureProps = isRecord(propertiesRaw) + ? (propertiesRaw as Record) + : {} // 2. Extraemos los valores reales (el contenido redactado) - const valoresActuales = data.datos || {} + const datosRaw = data?.datos + const valoresActuales = isRecord(datosRaw) + ? (datosRaw as Record) + : {} return (
@@ -468,6 +525,11 @@ function DatosGenerales({ const cardTitle = config.title || key const description = config.description || '' + const xColumn = + typeof config?.['x-column'] === 'string' + ? config['x-column'] + : undefined + // Obtenemos el placeholder del arreglo 'examples' de la estructura const placeholder = config.examples && config.examples.length > 0 @@ -476,11 +538,15 @@ function DatosGenerales({ const valActual = valoresActuales[key] - const isContentEmpty = - !valActual?.description || - valActual.description === config.description + let currentContent = valActual ?? '' - const currentContent = valActual ?? '' + if (xColumn) { + const rawValue = (data as any)?.[xColumn] + const parser = columnParsers[xColumn] + currentContent = parser + ? parser(rawValue) + : String(rawValue ?? '') + } return ( console.log(contenido)} @@ -545,6 +612,7 @@ interface InfoCardProps { initialContent: any placeholder?: string description?: string + xColumn?: string required?: boolean // Nueva prop para el asterisco type?: 'text' | 'requirements' | 'evaluation' onEnhanceAI?: (content: any) => void @@ -558,6 +626,7 @@ function InfoCard({ initialContent, placeholder, description, + xColumn, required, type = 'text', onPersist, @@ -649,7 +718,20 @@ function InfoCard({ variant="ghost" size="icon" className="h-8 w-8 text-slate-400" - onClick={() => setIsEditing(true)} + onClick={() => { + // Si esta InfoCard proviene de una columna externa (ej: contenido_tematico), + // redirigimos a la pestaña de Contenido en vez de editar inline. + if (xColumn === 'contenido_tematico') { + navigate({ + to: '/planes/$planId/asignaturas/$asignaturaId', + params: { planId, asignaturaId: asignaturaId! }, + state: { activeTab: 'contenido' } as any, + }) + return + } + + setIsEditing(true) + }} > @@ -669,7 +751,7 @@ function InfoCard({ value={tempText} placeholder={placeholder} onChange={(e) => setTempText(e.target.value)} - className="min-h-[120px] text-sm leading-relaxed" + className="min-h-30 text-sm leading-relaxed" />

- TanStack Logo + La Salle Logo

diff --git a/src/types/supabase.ts b/src/types/supabase.ts index 771bbc7..3e1d507 100644 --- a/src/types/supabase.ts +++ b/src/types/supabase.ts @@ -1,10 +1,10 @@ -export type Json = +export type Json = | string | number | boolean | null | { [key: string]: Json | undefined } - | Array + | Json[] export type Database = { graphql_public: { @@ -73,11 +73,11 @@ export type Database = { } Relationships: [ { - foreignKeyName: 'archivos_subido_por_fkey' - columns: ['subido_por'] + foreignKeyName: "archivos_subido_por_fkey" + columns: ["subido_por"] isOneToOne: false - referencedRelation: 'usuarios_app' - referencedColumns: ['id'] + referencedRelation: "usuarios_app" + referencedColumns: ["id"] }, ] } @@ -92,7 +92,7 @@ export type Database = { creado_por: string | null creditos: number datos: Json - estado: Database['public']['Enums']['estado_asignatura'] + estado: Database["public"]["Enums"]["estado_asignatura"] estructura_id: string | null horas_academicas: number | null horas_independientes: number | null @@ -103,8 +103,8 @@ export type Database = { numero_ciclo: number | null orden_celda: number | null plan_estudio_id: string - tipo: Database['public']['Enums']['tipo_asignatura'] - tipo_origen: Database['public']['Enums']['tipo_origen'] | null + tipo: Database["public"]["Enums"]["tipo_asignatura"] + tipo_origen: Database["public"]["Enums"]["tipo_origen"] | null } Insert: { actualizado_en?: string @@ -116,7 +116,7 @@ export type Database = { creado_por?: string | null creditos: number datos?: Json - estado?: Database['public']['Enums']['estado_asignatura'] + estado?: Database["public"]["Enums"]["estado_asignatura"] estructura_id?: string | null horas_academicas?: number | null horas_independientes?: number | null @@ -127,8 +127,8 @@ export type Database = { numero_ciclo?: number | null orden_celda?: number | null plan_estudio_id: string - tipo?: Database['public']['Enums']['tipo_asignatura'] - tipo_origen?: Database['public']['Enums']['tipo_origen'] | null + tipo?: Database["public"]["Enums"]["tipo_asignatura"] + tipo_origen?: Database["public"]["Enums"]["tipo_origen"] | null } Update: { actualizado_en?: string @@ -140,7 +140,7 @@ export type Database = { creado_por?: string | null creditos?: number datos?: Json - estado?: Database['public']['Enums']['estado_asignatura'] + estado?: Database["public"]["Enums"]["estado_asignatura"] estructura_id?: string | null horas_academicas?: number | null horas_independientes?: number | null @@ -151,51 +151,51 @@ export type Database = { numero_ciclo?: number | null orden_celda?: number | null plan_estudio_id?: string - tipo?: Database['public']['Enums']['tipo_asignatura'] - tipo_origen?: Database['public']['Enums']['tipo_origen'] | null + tipo?: Database["public"]["Enums"]["tipo_asignatura"] + tipo_origen?: Database["public"]["Enums"]["tipo_origen"] | null } Relationships: [ { - foreignKeyName: 'asignaturas_actualizado_por_fkey' - columns: ['actualizado_por'] + foreignKeyName: "asignaturas_actualizado_por_fkey" + columns: ["actualizado_por"] isOneToOne: false - referencedRelation: 'usuarios_app' - referencedColumns: ['id'] + referencedRelation: "usuarios_app" + referencedColumns: ["id"] }, { - foreignKeyName: 'asignaturas_creado_por_fkey' - columns: ['creado_por'] + foreignKeyName: "asignaturas_creado_por_fkey" + columns: ["creado_por"] isOneToOne: false - referencedRelation: 'usuarios_app' - referencedColumns: ['id'] + referencedRelation: "usuarios_app" + referencedColumns: ["id"] }, { - foreignKeyName: 'asignaturas_estructura_id_fkey' - columns: ['estructura_id'] + foreignKeyName: "asignaturas_estructura_id_fkey" + columns: ["estructura_id"] isOneToOne: false - referencedRelation: 'estructuras_asignatura' - referencedColumns: ['id'] + referencedRelation: "estructuras_asignatura" + referencedColumns: ["id"] }, { - foreignKeyName: 'asignaturas_linea_plan_fk_compuesta' - columns: ['linea_plan_id', 'plan_estudio_id'] + foreignKeyName: "asignaturas_linea_plan_fk_compuesta" + columns: ["linea_plan_id", "plan_estudio_id"] isOneToOne: false - referencedRelation: 'lineas_plan' - referencedColumns: ['id', 'plan_estudio_id'] + referencedRelation: "lineas_plan" + referencedColumns: ["id", "plan_estudio_id"] }, { - foreignKeyName: 'asignaturas_plan_estudio_id_fkey' - columns: ['plan_estudio_id'] + foreignKeyName: "asignaturas_plan_estudio_id_fkey" + columns: ["plan_estudio_id"] isOneToOne: false - referencedRelation: 'planes_estudio' - referencedColumns: ['id'] + referencedRelation: "planes_estudio" + referencedColumns: ["id"] }, { - foreignKeyName: 'asignaturas_plan_estudio_id_fkey' - columns: ['plan_estudio_id'] + foreignKeyName: "asignaturas_plan_estudio_id_fkey" + columns: ["plan_estudio_id"] isOneToOne: false - referencedRelation: 'plantilla_plan' - referencedColumns: ['plan_estudio_id'] + referencedRelation: "plantilla_plan" + referencedColumns: ["plan_estudio_id"] }, ] } @@ -208,8 +208,8 @@ export type Database = { creado_en: string creado_por: string | null id: string - tipo: Database['public']['Enums']['tipo_bibliografia'] - tipo_fuente: Database['public']['Enums']['tipo_fuente_bibliografia'] + tipo: Database["public"]["Enums"]["tipo_bibliografia"] + tipo_fuente: Database["public"]["Enums"]["tipo_fuente_bibliografia"] } Insert: { actualizado_en?: string @@ -219,8 +219,8 @@ export type Database = { creado_en?: string creado_por?: string | null id?: string - tipo: Database['public']['Enums']['tipo_bibliografia'] - tipo_fuente?: Database['public']['Enums']['tipo_fuente_bibliografia'] + tipo: Database["public"]["Enums"]["tipo_bibliografia"] + tipo_fuente?: Database["public"]["Enums"]["tipo_fuente_bibliografia"] } Update: { actualizado_en?: string @@ -230,23 +230,23 @@ export type Database = { creado_en?: string creado_por?: string | null id?: string - tipo?: Database['public']['Enums']['tipo_bibliografia'] - tipo_fuente?: Database['public']['Enums']['tipo_fuente_bibliografia'] + tipo?: Database["public"]["Enums"]["tipo_bibliografia"] + tipo_fuente?: Database["public"]["Enums"]["tipo_fuente_bibliografia"] } Relationships: [ { - foreignKeyName: 'bibliografia_asignatura_asignatura_id_fkey' - columns: ['asignatura_id'] + foreignKeyName: "bibliografia_asignatura_asignatura_id_fkey" + columns: ["asignatura_id"] isOneToOne: false - referencedRelation: 'asignaturas' - referencedColumns: ['id'] + referencedRelation: "asignaturas" + referencedColumns: ["id"] }, { - foreignKeyName: 'bibliografia_asignatura_creado_por_fkey' - columns: ['creado_por'] + foreignKeyName: "bibliografia_asignatura_creado_por_fkey" + columns: ["creado_por"] isOneToOne: false - referencedRelation: 'usuarios_app' - referencedColumns: ['id'] + referencedRelation: "usuarios_app" + referencedColumns: ["id"] }, ] } @@ -256,10 +256,10 @@ export type Database = { cambiado_en: string cambiado_por: string | null campo: string | null - fuente: Database['public']['Enums']['fuente_cambio'] | null + fuente: Database["public"]["Enums"]["fuente_cambio"] | null id: string interaccion_ia_id: string | null - tipo: Database['public']['Enums']['tipo_cambio'] + tipo: Database["public"]["Enums"]["tipo_cambio"] valor_anterior: Json | null valor_nuevo: Json | null } @@ -268,10 +268,10 @@ export type Database = { cambiado_en?: string cambiado_por?: string | null campo?: string | null - fuente?: Database['public']['Enums']['fuente_cambio'] | null + fuente?: Database["public"]["Enums"]["fuente_cambio"] | null id?: string interaccion_ia_id?: string | null - tipo: Database['public']['Enums']['tipo_cambio'] + tipo: Database["public"]["Enums"]["tipo_cambio"] valor_anterior?: Json | null valor_nuevo?: Json | null } @@ -280,27 +280,27 @@ export type Database = { cambiado_en?: string cambiado_por?: string | null campo?: string | null - fuente?: Database['public']['Enums']['fuente_cambio'] | null + fuente?: Database["public"]["Enums"]["fuente_cambio"] | null id?: string interaccion_ia_id?: string | null - tipo?: Database['public']['Enums']['tipo_cambio'] + tipo?: Database["public"]["Enums"]["tipo_cambio"] valor_anterior?: Json | null valor_nuevo?: Json | null } Relationships: [ { - foreignKeyName: 'cambios_asignatura_asignatura_id_fkey' - columns: ['asignatura_id'] + foreignKeyName: "cambios_asignatura_asignatura_id_fkey" + columns: ["asignatura_id"] isOneToOne: false - referencedRelation: 'asignaturas' - referencedColumns: ['id'] + referencedRelation: "asignaturas" + referencedColumns: ["id"] }, { - foreignKeyName: 'cambios_asignatura_cambiado_por_fkey' - columns: ['cambiado_por'] + foreignKeyName: "cambios_asignatura_cambiado_por_fkey" + columns: ["cambiado_por"] isOneToOne: false - referencedRelation: 'usuarios_app' - referencedColumns: ['id'] + referencedRelation: "usuarios_app" + referencedColumns: ["id"] }, ] } @@ -312,7 +312,7 @@ export type Database = { id: string plan_estudio_id: string response_id: string | null - tipo: Database['public']['Enums']['tipo_cambio'] + tipo: Database["public"]["Enums"]["tipo_cambio"] valor_anterior: Json | null valor_nuevo: Json | null } @@ -323,7 +323,7 @@ export type Database = { id?: string plan_estudio_id: string response_id?: string | null - tipo: Database['public']['Enums']['tipo_cambio'] + tipo: Database["public"]["Enums"]["tipo_cambio"] valor_anterior?: Json | null valor_nuevo?: Json | null } @@ -334,17 +334,17 @@ export type Database = { id?: string plan_estudio_id?: string response_id?: string | null - tipo?: Database['public']['Enums']['tipo_cambio'] + tipo?: Database["public"]["Enums"]["tipo_cambio"] valor_anterior?: Json | null valor_nuevo?: Json | null } Relationships: [ { - foreignKeyName: 'cambios_plan_cambiado_por_fkey' - columns: ['cambiado_por'] + foreignKeyName: "cambios_plan_cambiado_por_fkey" + columns: ["cambiado_por"] isOneToOne: false - referencedRelation: 'usuarios_app' - referencedColumns: ['id'] + referencedRelation: "usuarios_app" + referencedColumns: ["id"] }, ] } @@ -381,11 +381,11 @@ export type Database = { } Relationships: [ { - foreignKeyName: 'carreras_facultad_id_fkey' - columns: ['facultad_id'] + foreignKeyName: "carreras_facultad_id_fkey" + columns: ["facultad_id"] isOneToOne: false - referencedRelation: 'facultades' - referencedColumns: ['id'] + referencedRelation: "facultades" + referencedColumns: ["id"] }, ] } @@ -397,7 +397,7 @@ export type Database = { conversacion_json: Json creado_en: string creado_por: string | null - estado: Database['public']['Enums']['estado_conversacion'] + estado: Database["public"]["Enums"]["estado_conversacion"] id: string intento_archivado: number openai_conversation_id: string @@ -409,7 +409,7 @@ export type Database = { conversacion_json?: Json creado_en?: string creado_por?: string | null - estado?: Database['public']['Enums']['estado_conversacion'] + estado?: Database["public"]["Enums"]["estado_conversacion"] id?: string intento_archivado?: number openai_conversation_id: string @@ -421,32 +421,32 @@ export type Database = { conversacion_json?: Json creado_en?: string creado_por?: string | null - estado?: Database['public']['Enums']['estado_conversacion'] + estado?: Database["public"]["Enums"]["estado_conversacion"] id?: string intento_archivado?: number openai_conversation_id?: string } Relationships: [ { - foreignKeyName: 'conversaciones_asignatura_archivado_por_fkey' - columns: ['archivado_por'] + foreignKeyName: "conversaciones_asignatura_archivado_por_fkey" + columns: ["archivado_por"] isOneToOne: false - referencedRelation: 'usuarios_app' - referencedColumns: ['id'] + referencedRelation: "usuarios_app" + referencedColumns: ["id"] }, { - foreignKeyName: 'conversaciones_asignatura_asignatura_id_fkey' - columns: ['asignatura_id'] + foreignKeyName: "conversaciones_asignatura_asignatura_id_fkey" + columns: ["asignatura_id"] isOneToOne: false - referencedRelation: 'asignaturas' - referencedColumns: ['id'] + referencedRelation: "asignaturas" + referencedColumns: ["id"] }, { - foreignKeyName: 'conversaciones_asignatura_creado_por_fkey' - columns: ['creado_por'] + foreignKeyName: "conversaciones_asignatura_creado_por_fkey" + columns: ["creado_por"] isOneToOne: false - referencedRelation: 'usuarios_app' - referencedColumns: ['id'] + referencedRelation: "usuarios_app" + referencedColumns: ["id"] }, ] } @@ -457,9 +457,10 @@ export type Database = { conversacion_json: Json creado_en: string creado_por: string | null - estado: Database['public']['Enums']['estado_conversacion'] + estado: Database["public"]["Enums"]["estado_conversacion"] id: string intento_archivado: number + nombre: string | null openai_conversation_id: string plan_estudio_id: string } @@ -469,9 +470,10 @@ export type Database = { conversacion_json?: Json creado_en?: string creado_por?: string | null - estado?: Database['public']['Enums']['estado_conversacion'] + estado?: Database["public"]["Enums"]["estado_conversacion"] id?: string intento_archivado?: number + nombre?: string | null openai_conversation_id: string plan_estudio_id: string } @@ -481,40 +483,41 @@ export type Database = { conversacion_json?: Json creado_en?: string creado_por?: string | null - estado?: Database['public']['Enums']['estado_conversacion'] + estado?: Database["public"]["Enums"]["estado_conversacion"] id?: string intento_archivado?: number + nombre?: string | null openai_conversation_id?: string plan_estudio_id?: string } Relationships: [ { - foreignKeyName: 'conversaciones_plan_archivado_por_fkey' - columns: ['archivado_por'] + foreignKeyName: "conversaciones_plan_archivado_por_fkey" + columns: ["archivado_por"] isOneToOne: false - referencedRelation: 'usuarios_app' - referencedColumns: ['id'] + referencedRelation: "usuarios_app" + referencedColumns: ["id"] }, { - foreignKeyName: 'conversaciones_plan_creado_por_fkey' - columns: ['creado_por'] + foreignKeyName: "conversaciones_plan_creado_por_fkey" + columns: ["creado_por"] isOneToOne: false - referencedRelation: 'usuarios_app' - referencedColumns: ['id'] + referencedRelation: "usuarios_app" + referencedColumns: ["id"] }, { - foreignKeyName: 'conversaciones_plan_plan_estudio_id_fkey' - columns: ['plan_estudio_id'] + foreignKeyName: "conversaciones_plan_plan_estudio_id_fkey" + columns: ["plan_estudio_id"] isOneToOne: false - referencedRelation: 'planes_estudio' - referencedColumns: ['id'] + referencedRelation: "planes_estudio" + referencedColumns: ["id"] }, { - foreignKeyName: 'conversaciones_plan_plan_estudio_id_fkey' - columns: ['plan_estudio_id'] + foreignKeyName: "conversaciones_plan_plan_estudio_id_fkey" + columns: ["plan_estudio_id"] isOneToOne: false - referencedRelation: 'plantilla_plan' - referencedColumns: ['plan_estudio_id'] + referencedRelation: "plantilla_plan" + referencedColumns: ["plan_estudio_id"] }, ] } @@ -577,7 +580,7 @@ export type Database = { id: string nombre: string template_id: string | null - tipo: Database['public']['Enums']['tipo_estructura_plan'] + tipo: Database["public"]["Enums"]["tipo_estructura_plan"] } Insert: { actualizado_en?: string @@ -586,7 +589,7 @@ export type Database = { id?: string nombre: string template_id?: string | null - tipo: Database['public']['Enums']['tipo_estructura_plan'] + tipo: Database["public"]["Enums"]["tipo_estructura_plan"] } Update: { actualizado_en?: string @@ -595,7 +598,7 @@ export type Database = { id?: string nombre?: string template_id?: string | null - tipo?: Database['public']['Enums']['tipo_estructura_plan'] + tipo?: Database["public"]["Enums"]["tipo_estructura_plan"] } Relationships: [] } @@ -644,7 +647,7 @@ export type Database = { respuesta: Json rutas_storage: Json temperatura: number | null - tipo: Database['public']['Enums']['tipo_interaccion_ia'] + tipo: Database["public"]["Enums"]["tipo_interaccion_ia"] usuario_id: string | null } Insert: { @@ -661,7 +664,7 @@ export type Database = { respuesta?: Json rutas_storage?: Json temperatura?: number | null - tipo: Database['public']['Enums']['tipo_interaccion_ia'] + tipo: Database["public"]["Enums"]["tipo_interaccion_ia"] usuario_id?: string | null } Update: { @@ -678,37 +681,37 @@ export type Database = { respuesta?: Json rutas_storage?: Json temperatura?: number | null - tipo?: Database['public']['Enums']['tipo_interaccion_ia'] + tipo?: Database["public"]["Enums"]["tipo_interaccion_ia"] usuario_id?: string | null } Relationships: [ { - foreignKeyName: 'interacciones_ia_asignatura_id_fkey' - columns: ['asignatura_id'] + foreignKeyName: "interacciones_ia_asignatura_id_fkey" + columns: ["asignatura_id"] isOneToOne: false - referencedRelation: 'asignaturas' - referencedColumns: ['id'] + referencedRelation: "asignaturas" + referencedColumns: ["id"] }, { - foreignKeyName: 'interacciones_ia_plan_estudio_id_fkey' - columns: ['plan_estudio_id'] + foreignKeyName: "interacciones_ia_plan_estudio_id_fkey" + columns: ["plan_estudio_id"] isOneToOne: false - referencedRelation: 'planes_estudio' - referencedColumns: ['id'] + referencedRelation: "planes_estudio" + referencedColumns: ["id"] }, { - foreignKeyName: 'interacciones_ia_plan_estudio_id_fkey' - columns: ['plan_estudio_id'] + foreignKeyName: "interacciones_ia_plan_estudio_id_fkey" + columns: ["plan_estudio_id"] isOneToOne: false - referencedRelation: 'plantilla_plan' - referencedColumns: ['plan_estudio_id'] + referencedRelation: "plantilla_plan" + referencedColumns: ["plan_estudio_id"] }, { - foreignKeyName: 'interacciones_ia_usuario_id_fkey' - columns: ['usuario_id'] + foreignKeyName: "interacciones_ia_usuario_id_fkey" + columns: ["usuario_id"] isOneToOne: false - referencedRelation: 'usuarios_app' - referencedColumns: ['id'] + referencedRelation: "usuarios_app" + referencedColumns: ["id"] }, ] } @@ -742,18 +745,18 @@ export type Database = { } Relationships: [ { - foreignKeyName: 'lineas_plan_plan_estudio_id_fkey' - columns: ['plan_estudio_id'] + foreignKeyName: "lineas_plan_plan_estudio_id_fkey" + columns: ["plan_estudio_id"] isOneToOne: false - referencedRelation: 'planes_estudio' - referencedColumns: ['id'] + referencedRelation: "planes_estudio" + referencedColumns: ["id"] }, { - foreignKeyName: 'lineas_plan_plan_estudio_id_fkey' - columns: ['plan_estudio_id'] + foreignKeyName: "lineas_plan_plan_estudio_id_fkey" + columns: ["plan_estudio_id"] isOneToOne: false - referencedRelation: 'plantilla_plan' - referencedColumns: ['plan_estudio_id'] + referencedRelation: "plantilla_plan" + referencedColumns: ["plan_estudio_id"] }, ] } @@ -764,7 +767,7 @@ export type Database = { leida: boolean leida_en: string | null payload: Json - tipo: Database['public']['Enums']['tipo_notificacion'] + tipo: Database["public"]["Enums"]["tipo_notificacion"] usuario_id: string } Insert: { @@ -773,7 +776,7 @@ export type Database = { leida?: boolean leida_en?: string | null payload?: Json - tipo: Database['public']['Enums']['tipo_notificacion'] + tipo: Database["public"]["Enums"]["tipo_notificacion"] usuario_id: string } Update: { @@ -782,16 +785,16 @@ export type Database = { leida?: boolean leida_en?: string | null payload?: Json - tipo?: Database['public']['Enums']['tipo_notificacion'] + tipo?: Database["public"]["Enums"]["tipo_notificacion"] usuario_id?: string } Relationships: [ { - foreignKeyName: 'notificaciones_usuario_id_fkey' - columns: ['usuario_id'] + foreignKeyName: "notificaciones_usuario_id_fkey" + columns: ["usuario_id"] isOneToOne: false - referencedRelation: 'usuarios_app' - referencedColumns: ['id'] + referencedRelation: "usuarios_app" + referencedColumns: ["id"] }, ] } @@ -808,13 +811,13 @@ export type Database = { estructura_id: string id: string meta_origen: Json - nivel: Database['public']['Enums']['nivel_plan_estudio'] + nivel: Database["public"]["Enums"]["nivel_plan_estudio"] nombre: string nombre_search: string | null numero_ciclos: number plan_hash: string | null - tipo_ciclo: Database['public']['Enums']['tipo_ciclo'] - tipo_origen: Database['public']['Enums']['tipo_origen'] | null + tipo_ciclo: Database["public"]["Enums"]["tipo_ciclo"] + tipo_origen: Database["public"]["Enums"]["tipo_origen"] | null } Insert: { activo?: boolean @@ -828,13 +831,13 @@ export type Database = { estructura_id: string id?: string meta_origen?: Json - nivel: Database['public']['Enums']['nivel_plan_estudio'] + nivel: Database["public"]["Enums"]["nivel_plan_estudio"] nombre: string nombre_search?: string | null numero_ciclos: number plan_hash?: string | null - tipo_ciclo: Database['public']['Enums']['tipo_ciclo'] - tipo_origen?: Database['public']['Enums']['tipo_origen'] | null + tipo_ciclo: Database["public"]["Enums"]["tipo_ciclo"] + tipo_origen?: Database["public"]["Enums"]["tipo_origen"] | null } Update: { activo?: boolean @@ -848,56 +851,56 @@ export type Database = { estructura_id?: string id?: string meta_origen?: Json - nivel?: Database['public']['Enums']['nivel_plan_estudio'] + nivel?: Database["public"]["Enums"]["nivel_plan_estudio"] nombre?: string nombre_search?: string | null numero_ciclos?: number plan_hash?: string | null - tipo_ciclo?: Database['public']['Enums']['tipo_ciclo'] - tipo_origen?: Database['public']['Enums']['tipo_origen'] | null + tipo_ciclo?: Database["public"]["Enums"]["tipo_ciclo"] + tipo_origen?: Database["public"]["Enums"]["tipo_origen"] | null } Relationships: [ { - foreignKeyName: 'planes_estudio_actualizado_por_fkey' - columns: ['actualizado_por'] + foreignKeyName: "planes_estudio_actualizado_por_fkey" + columns: ["actualizado_por"] isOneToOne: false - referencedRelation: 'usuarios_app' - referencedColumns: ['id'] + referencedRelation: "usuarios_app" + referencedColumns: ["id"] }, { - foreignKeyName: 'planes_estudio_carrera_id_fkey' - columns: ['carrera_id'] + foreignKeyName: "planes_estudio_carrera_id_fkey" + columns: ["carrera_id"] isOneToOne: false - referencedRelation: 'carreras' - referencedColumns: ['id'] + referencedRelation: "carreras" + referencedColumns: ["id"] }, { - foreignKeyName: 'planes_estudio_creado_por_fkey' - columns: ['creado_por'] + foreignKeyName: "planes_estudio_creado_por_fkey" + columns: ["creado_por"] isOneToOne: false - referencedRelation: 'usuarios_app' - referencedColumns: ['id'] + referencedRelation: "usuarios_app" + referencedColumns: ["id"] }, { - foreignKeyName: 'planes_estudio_estado_actual_id_fkey' - columns: ['estado_actual_id'] + foreignKeyName: "planes_estudio_estado_actual_id_fkey" + columns: ["estado_actual_id"] isOneToOne: false - referencedRelation: 'estados_plan' - referencedColumns: ['id'] + referencedRelation: "estados_plan" + referencedColumns: ["id"] }, { - foreignKeyName: 'planes_estudio_estructura_id_fkey' - columns: ['estructura_id'] + foreignKeyName: "planes_estudio_estructura_id_fkey" + columns: ["estructura_id"] isOneToOne: false - referencedRelation: 'estructuras_plan' - referencedColumns: ['id'] + referencedRelation: "estructuras_plan" + referencedColumns: ["id"] }, { - foreignKeyName: 'planes_estudio_estructura_id_fkey' - columns: ['estructura_id'] + foreignKeyName: "planes_estudio_estructura_id_fkey" + columns: ["estructura_id"] isOneToOne: false - referencedRelation: 'plantilla_plan' - referencedColumns: ['estructura_id'] + referencedRelation: "plantilla_plan" + referencedColumns: ["estructura_id"] }, ] } @@ -906,37 +909,37 @@ export type Database = { asignatura_id: string creado_en: string id: string - rol: Database['public']['Enums']['rol_responsable_asignatura'] + rol: Database["public"]["Enums"]["rol_responsable_asignatura"] usuario_id: string } Insert: { asignatura_id: string creado_en?: string id?: string - rol?: Database['public']['Enums']['rol_responsable_asignatura'] + rol?: Database["public"]["Enums"]["rol_responsable_asignatura"] usuario_id: string } Update: { asignatura_id?: string creado_en?: string id?: string - rol?: Database['public']['Enums']['rol_responsable_asignatura'] + rol?: Database["public"]["Enums"]["rol_responsable_asignatura"] usuario_id?: string } Relationships: [ { - foreignKeyName: 'responsables_asignatura_asignatura_id_fkey' - columns: ['asignatura_id'] + foreignKeyName: "responsables_asignatura_asignatura_id_fkey" + columns: ["asignatura_id"] isOneToOne: false - referencedRelation: 'asignaturas' - referencedColumns: ['id'] + referencedRelation: "asignaturas" + referencedColumns: ["id"] }, { - foreignKeyName: 'responsables_asignatura_usuario_id_fkey' - columns: ['usuario_id'] + foreignKeyName: "responsables_asignatura_usuario_id_fkey" + columns: ["usuario_id"] isOneToOne: false - referencedRelation: 'usuarios_app' - referencedColumns: ['id'] + referencedRelation: "usuarios_app" + referencedColumns: ["id"] }, ] } @@ -967,7 +970,7 @@ export type Database = { completado_en: string | null creado_en: string estado_id: string | null - estatus: Database['public']['Enums']['estado_tarea_revision'] + estatus: Database["public"]["Enums"]["estado_tarea_revision"] fecha_limite: string | null id: string plan_estudio_id: string @@ -978,7 +981,7 @@ export type Database = { completado_en?: string | null creado_en?: string estado_id?: string | null - estatus?: Database['public']['Enums']['estado_tarea_revision'] + estatus?: Database["public"]["Enums"]["estado_tarea_revision"] fecha_limite?: string | null id?: string plan_estudio_id: string @@ -989,7 +992,7 @@ export type Database = { completado_en?: string | null creado_en?: string estado_id?: string | null - estatus?: Database['public']['Enums']['estado_tarea_revision'] + estatus?: Database["public"]["Enums"]["estado_tarea_revision"] fecha_limite?: string | null id?: string plan_estudio_id?: string @@ -997,39 +1000,39 @@ export type Database = { } Relationships: [ { - foreignKeyName: 'tareas_revision_asignado_a_fkey' - columns: ['asignado_a'] + foreignKeyName: "tareas_revision_asignado_a_fkey" + columns: ["asignado_a"] isOneToOne: false - referencedRelation: 'usuarios_app' - referencedColumns: ['id'] + referencedRelation: "usuarios_app" + referencedColumns: ["id"] }, { - foreignKeyName: 'tareas_revision_estado_id_fkey' - columns: ['estado_id'] + foreignKeyName: "tareas_revision_estado_id_fkey" + columns: ["estado_id"] isOneToOne: false - referencedRelation: 'estados_plan' - referencedColumns: ['id'] + referencedRelation: "estados_plan" + referencedColumns: ["id"] }, { - foreignKeyName: 'tareas_revision_plan_estudio_id_fkey' - columns: ['plan_estudio_id'] + foreignKeyName: "tareas_revision_plan_estudio_id_fkey" + columns: ["plan_estudio_id"] isOneToOne: false - referencedRelation: 'planes_estudio' - referencedColumns: ['id'] + referencedRelation: "planes_estudio" + referencedColumns: ["id"] }, { - foreignKeyName: 'tareas_revision_plan_estudio_id_fkey' - columns: ['plan_estudio_id'] + foreignKeyName: "tareas_revision_plan_estudio_id_fkey" + columns: ["plan_estudio_id"] isOneToOne: false - referencedRelation: 'plantilla_plan' - referencedColumns: ['plan_estudio_id'] + referencedRelation: "plantilla_plan" + referencedColumns: ["plan_estudio_id"] }, { - foreignKeyName: 'tareas_revision_rol_id_fkey' - columns: ['rol_id'] + foreignKeyName: "tareas_revision_rol_id_fkey" + columns: ["rol_id"] isOneToOne: false - referencedRelation: 'roles' - referencedColumns: ['id'] + referencedRelation: "roles" + referencedColumns: ["id"] }, ] } @@ -1057,25 +1060,25 @@ export type Database = { } Relationships: [ { - foreignKeyName: 'transiciones_estado_plan_desde_estado_id_fkey' - columns: ['desde_estado_id'] + foreignKeyName: "transiciones_estado_plan_desde_estado_id_fkey" + columns: ["desde_estado_id"] isOneToOne: false - referencedRelation: 'estados_plan' - referencedColumns: ['id'] + referencedRelation: "estados_plan" + referencedColumns: ["id"] }, { - foreignKeyName: 'transiciones_estado_plan_hacia_estado_id_fkey' - columns: ['hacia_estado_id'] + foreignKeyName: "transiciones_estado_plan_hacia_estado_id_fkey" + columns: ["hacia_estado_id"] isOneToOne: false - referencedRelation: 'estados_plan' - referencedColumns: ['id'] + referencedRelation: "estados_plan" + referencedColumns: ["id"] }, { - foreignKeyName: 'transiciones_estado_plan_rol_permitido_id_fkey' - columns: ['rol_permitido_id'] + foreignKeyName: "transiciones_estado_plan_rol_permitido_id_fkey" + columns: ["rol_permitido_id"] isOneToOne: false - referencedRelation: 'roles' - referencedColumns: ['id'] + referencedRelation: "roles" + referencedColumns: ["id"] }, ] } @@ -1133,32 +1136,32 @@ export type Database = { } Relationships: [ { - foreignKeyName: 'usuarios_roles_carrera_id_fkey' - columns: ['carrera_id'] + foreignKeyName: "usuarios_roles_carrera_id_fkey" + columns: ["carrera_id"] isOneToOne: false - referencedRelation: 'carreras' - referencedColumns: ['id'] + referencedRelation: "carreras" + referencedColumns: ["id"] }, { - foreignKeyName: 'usuarios_roles_facultad_id_fkey' - columns: ['facultad_id'] + foreignKeyName: "usuarios_roles_facultad_id_fkey" + columns: ["facultad_id"] isOneToOne: false - referencedRelation: 'facultades' - referencedColumns: ['id'] + referencedRelation: "facultades" + referencedColumns: ["id"] }, { - foreignKeyName: 'usuarios_roles_rol_id_fkey' - columns: ['rol_id'] + foreignKeyName: "usuarios_roles_rol_id_fkey" + columns: ["rol_id"] isOneToOne: false - referencedRelation: 'roles' - referencedColumns: ['id'] + referencedRelation: "roles" + referencedColumns: ["id"] }, { - foreignKeyName: 'usuarios_roles_usuario_id_fkey' - columns: ['usuario_id'] + foreignKeyName: "usuarios_roles_usuario_id_fkey" + columns: ["usuario_id"] isOneToOne: false - referencedRelation: 'usuarios_app' - referencedColumns: ['id'] + referencedRelation: "usuarios_app" + referencedColumns: ["id"] }, ] } @@ -1186,11 +1189,11 @@ export type Database = { } Relationships: [ { - foreignKeyName: 'vector_stores_creado_por_fkey' - columns: ['creado_por'] + foreignKeyName: "vector_stores_creado_por_fkey" + columns: ["creado_por"] isOneToOne: false - referencedRelation: 'usuarios_app' - referencedColumns: ['id'] + referencedRelation: "usuarios_app" + referencedColumns: ["id"] }, ] } @@ -1206,54 +1209,54 @@ export type Database = { } } Functions: { - unaccent: { Args: { '': string }; Returns: string } - unaccent_immutable: { Args: { '': string }; Returns: string } + unaccent: { Args: { "": string }; Returns: string } + unaccent_immutable: { Args: { "": string }; Returns: string } } Enums: { - estado_asignatura: 'borrador' | 'revisada' | 'aprobada' | 'generando' - estado_conversacion: 'ACTIVA' | 'ARCHIVANDO' | 'ARCHIVADA' | 'ERROR' - estado_tarea_revision: 'PENDIENTE' | 'COMPLETADA' | 'OMITIDA' - fuente_cambio: 'HUMANO' | 'IA' + estado_asignatura: "borrador" | "revisada" | "aprobada" | "generando" + estado_conversacion: "ACTIVA" | "ARCHIVANDO" | "ARCHIVADA" | "ERROR" + estado_tarea_revision: "PENDIENTE" | "COMPLETADA" | "OMITIDA" + fuente_cambio: "HUMANO" | "IA" nivel_plan_estudio: - | 'Licenciatura' - | 'Maestría' - | 'Doctorado' - | 'Especialidad' - | 'Diplomado' - | 'Otro' + | "Licenciatura" + | "Maestría" + | "Doctorado" + | "Especialidad" + | "Diplomado" + | "Otro" puesto_tipo: - | 'vicerrector' - | 'director_facultad' - | 'secretario_academico' - | 'jefe_carrera' - | 'profesor' - | 'lci' - rol_responsable_asignatura: 'PROFESOR_RESPONSABLE' | 'COAUTOR' | 'REVISOR' - tipo_asignatura: 'OBLIGATORIA' | 'OPTATIVA' | 'TRONCAL' | 'OTRA' - tipo_bibliografia: 'BASICA' | 'COMPLEMENTARIA' + | "vicerrector" + | "director_facultad" + | "secretario_academico" + | "jefe_carrera" + | "profesor" + | "lci" + rol_responsable_asignatura: "PROFESOR_RESPONSABLE" | "COAUTOR" | "REVISOR" + tipo_asignatura: "OBLIGATORIA" | "OPTATIVA" | "TRONCAL" | "OTRA" + tipo_bibliografia: "BASICA" | "COMPLEMENTARIA" tipo_cambio: - | 'ACTUALIZACION_CAMPO' - | 'ACTUALIZACION_MAPA' - | 'TRANSICION_ESTADO' - | 'OTRO' - | 'CREACION' - | 'ACTUALIZACION' - tipo_ciclo: 'Semestre' | 'Cuatrimestre' | 'Trimestre' | 'Otro' - tipo_estructura_plan: 'CURRICULAR' | 'NO_CURRICULAR' - tipo_fuente_bibliografia: 'MANUAL' | 'BIBLIOTECA' - tipo_interaccion_ia: 'GENERAR' | 'MEJORAR_SECCION' | 'CHAT' | 'OTRA' + | "ACTUALIZACION_CAMPO" + | "ACTUALIZACION_MAPA" + | "TRANSICION_ESTADO" + | "OTRO" + | "CREACION" + | "ACTUALIZACION" + tipo_ciclo: "Semestre" | "Cuatrimestre" | "Trimestre" | "Otro" + tipo_estructura_plan: "CURRICULAR" | "NO_CURRICULAR" + tipo_fuente_bibliografia: "MANUAL" | "BIBLIOTECA" + tipo_interaccion_ia: "GENERAR" | "MEJORAR_SECCION" | "CHAT" | "OTRA" tipo_notificacion: - | 'PLAN_ASIGNADO' - | 'ESTADO_CAMBIADO' - | 'TAREA_ASIGNADA' - | 'COMENTARIO' - | 'OTRA' + | "PLAN_ASIGNADO" + | "ESTADO_CAMBIADO" + | "TAREA_ASIGNADA" + | "COMENTARIO" + | "OTRA" tipo_origen: - | 'MANUAL' - | 'IA' - | 'CLONADO_INTERNO' - | 'CLONADO_TRADICIONAL' - | 'OTRO' + | "MANUAL" + | "IA" + | "CLONADO_INTERNO" + | "CLONADO_TRADICIONAL" + | "OTRO" } CompositeTypes: { [_ in never]: never @@ -1261,33 +1264,33 @@ export type Database = { } } -type DatabaseWithoutInternals = Omit +type DatabaseWithoutInternals = Omit -type DefaultSchema = DatabaseWithoutInternals[Extract] +type DefaultSchema = DatabaseWithoutInternals[Extract] export type Tables< DefaultSchemaTableNameOrOptions extends - | keyof (DefaultSchema['Tables'] & DefaultSchema['Views']) + | keyof (DefaultSchema["Tables"] & DefaultSchema["Views"]) | { schema: keyof DatabaseWithoutInternals }, TableName extends DefaultSchemaTableNameOrOptions extends { schema: keyof DatabaseWithoutInternals } - ? keyof (DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions['schema']]['Tables'] & - DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions['schema']]['Views']) + ? keyof (DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] & + DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Views"]) : never = never, > = DefaultSchemaTableNameOrOptions extends { schema: keyof DatabaseWithoutInternals } - ? (DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions['schema']]['Tables'] & - DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions['schema']]['Views'])[TableName] extends { + ? (DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] & + DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Views"])[TableName] extends { Row: infer R } ? R : never - : DefaultSchemaTableNameOrOptions extends keyof (DefaultSchema['Tables'] & - DefaultSchema['Views']) - ? (DefaultSchema['Tables'] & - DefaultSchema['Views'])[DefaultSchemaTableNameOrOptions] extends { + : DefaultSchemaTableNameOrOptions extends keyof (DefaultSchema["Tables"] & + DefaultSchema["Views"]) + ? (DefaultSchema["Tables"] & + DefaultSchema["Views"])[DefaultSchemaTableNameOrOptions] extends { Row: infer R } ? R @@ -1296,23 +1299,23 @@ export type Tables< export type TablesInsert< DefaultSchemaTableNameOrOptions extends - | keyof DefaultSchema['Tables'] + | keyof DefaultSchema["Tables"] | { schema: keyof DatabaseWithoutInternals }, TableName extends DefaultSchemaTableNameOrOptions extends { schema: keyof DatabaseWithoutInternals } - ? keyof DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions['schema']]['Tables'] + ? keyof DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] : never = never, > = DefaultSchemaTableNameOrOptions extends { schema: keyof DatabaseWithoutInternals } - ? DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions['schema']]['Tables'][TableName] extends { + ? DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"][TableName] extends { Insert: infer I } ? I : never - : DefaultSchemaTableNameOrOptions extends keyof DefaultSchema['Tables'] - ? DefaultSchema['Tables'][DefaultSchemaTableNameOrOptions] extends { + : DefaultSchemaTableNameOrOptions extends keyof DefaultSchema["Tables"] + ? DefaultSchema["Tables"][DefaultSchemaTableNameOrOptions] extends { Insert: infer I } ? I @@ -1321,23 +1324,23 @@ export type TablesInsert< export type TablesUpdate< DefaultSchemaTableNameOrOptions extends - | keyof DefaultSchema['Tables'] + | keyof DefaultSchema["Tables"] | { schema: keyof DatabaseWithoutInternals }, TableName extends DefaultSchemaTableNameOrOptions extends { schema: keyof DatabaseWithoutInternals } - ? keyof DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions['schema']]['Tables'] + ? keyof DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] : never = never, > = DefaultSchemaTableNameOrOptions extends { schema: keyof DatabaseWithoutInternals } - ? DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions['schema']]['Tables'][TableName] extends { + ? DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"][TableName] extends { Update: infer U } ? U : never - : DefaultSchemaTableNameOrOptions extends keyof DefaultSchema['Tables'] - ? DefaultSchema['Tables'][DefaultSchemaTableNameOrOptions] extends { + : DefaultSchemaTableNameOrOptions extends keyof DefaultSchema["Tables"] + ? DefaultSchema["Tables"][DefaultSchemaTableNameOrOptions] extends { Update: infer U } ? U @@ -1346,36 +1349,36 @@ export type TablesUpdate< export type Enums< DefaultSchemaEnumNameOrOptions extends - | keyof DefaultSchema['Enums'] + | keyof DefaultSchema["Enums"] | { schema: keyof DatabaseWithoutInternals }, EnumName extends DefaultSchemaEnumNameOrOptions extends { schema: keyof DatabaseWithoutInternals } - ? keyof DatabaseWithoutInternals[DefaultSchemaEnumNameOrOptions['schema']]['Enums'] + ? keyof DatabaseWithoutInternals[DefaultSchemaEnumNameOrOptions["schema"]]["Enums"] : never = never, > = DefaultSchemaEnumNameOrOptions extends { schema: keyof DatabaseWithoutInternals } - ? DatabaseWithoutInternals[DefaultSchemaEnumNameOrOptions['schema']]['Enums'][EnumName] - : DefaultSchemaEnumNameOrOptions extends keyof DefaultSchema['Enums'] - ? DefaultSchema['Enums'][DefaultSchemaEnumNameOrOptions] + ? DatabaseWithoutInternals[DefaultSchemaEnumNameOrOptions["schema"]]["Enums"][EnumName] + : DefaultSchemaEnumNameOrOptions extends keyof DefaultSchema["Enums"] + ? DefaultSchema["Enums"][DefaultSchemaEnumNameOrOptions] : never export type CompositeTypes< PublicCompositeTypeNameOrOptions extends - | keyof DefaultSchema['CompositeTypes'] + | keyof DefaultSchema["CompositeTypes"] | { schema: keyof DatabaseWithoutInternals }, CompositeTypeName extends PublicCompositeTypeNameOrOptions extends { schema: keyof DatabaseWithoutInternals } - ? keyof DatabaseWithoutInternals[PublicCompositeTypeNameOrOptions['schema']]['CompositeTypes'] + ? keyof DatabaseWithoutInternals[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"] : never = never, > = PublicCompositeTypeNameOrOptions extends { schema: keyof DatabaseWithoutInternals } - ? DatabaseWithoutInternals[PublicCompositeTypeNameOrOptions['schema']]['CompositeTypes'][CompositeTypeName] - : PublicCompositeTypeNameOrOptions extends keyof DefaultSchema['CompositeTypes'] - ? DefaultSchema['CompositeTypes'][PublicCompositeTypeNameOrOptions] + ? DatabaseWithoutInternals[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"][CompositeTypeName] + : PublicCompositeTypeNameOrOptions extends keyof DefaultSchema["CompositeTypes"] + ? DefaultSchema["CompositeTypes"][PublicCompositeTypeNameOrOptions] : never export const Constants = { @@ -1384,59 +1387,60 @@ export const Constants = { }, public: { Enums: { - estado_asignatura: ['borrador', 'revisada', 'aprobada', 'generando'], - estado_conversacion: ['ACTIVA', 'ARCHIVANDO', 'ARCHIVADA', 'ERROR'], - estado_tarea_revision: ['PENDIENTE', 'COMPLETADA', 'OMITIDA'], - fuente_cambio: ['HUMANO', 'IA'], + estado_asignatura: ["borrador", "revisada", "aprobada", "generando"], + estado_conversacion: ["ACTIVA", "ARCHIVANDO", "ARCHIVADA", "ERROR"], + estado_tarea_revision: ["PENDIENTE", "COMPLETADA", "OMITIDA"], + fuente_cambio: ["HUMANO", "IA"], nivel_plan_estudio: [ - 'Licenciatura', - 'Maestría', - 'Doctorado', - 'Especialidad', - 'Diplomado', - 'Otro', + "Licenciatura", + "Maestría", + "Doctorado", + "Especialidad", + "Diplomado", + "Otro", ], puesto_tipo: [ - 'vicerrector', - 'director_facultad', - 'secretario_academico', - 'jefe_carrera', - 'profesor', - 'lci', + "vicerrector", + "director_facultad", + "secretario_academico", + "jefe_carrera", + "profesor", + "lci", ], rol_responsable_asignatura: [ - 'PROFESOR_RESPONSABLE', - 'COAUTOR', - 'REVISOR', + "PROFESOR_RESPONSABLE", + "COAUTOR", + "REVISOR", ], - tipo_asignatura: ['OBLIGATORIA', 'OPTATIVA', 'TRONCAL', 'OTRA'], - tipo_bibliografia: ['BASICA', 'COMPLEMENTARIA'], + tipo_asignatura: ["OBLIGATORIA", "OPTATIVA", "TRONCAL", "OTRA"], + tipo_bibliografia: ["BASICA", "COMPLEMENTARIA"], tipo_cambio: [ - 'ACTUALIZACION_CAMPO', - 'ACTUALIZACION_MAPA', - 'TRANSICION_ESTADO', - 'OTRO', - 'CREACION', - 'ACTUALIZACION', + "ACTUALIZACION_CAMPO", + "ACTUALIZACION_MAPA", + "TRANSICION_ESTADO", + "OTRO", + "CREACION", + "ACTUALIZACION", ], - tipo_ciclo: ['Semestre', 'Cuatrimestre', 'Trimestre', 'Otro'], - tipo_estructura_plan: ['CURRICULAR', 'NO_CURRICULAR'], - tipo_fuente_bibliografia: ['MANUAL', 'BIBLIOTECA'], - tipo_interaccion_ia: ['GENERAR', 'MEJORAR_SECCION', 'CHAT', 'OTRA'], + tipo_ciclo: ["Semestre", "Cuatrimestre", "Trimestre", "Otro"], + tipo_estructura_plan: ["CURRICULAR", "NO_CURRICULAR"], + tipo_fuente_bibliografia: ["MANUAL", "BIBLIOTECA"], + tipo_interaccion_ia: ["GENERAR", "MEJORAR_SECCION", "CHAT", "OTRA"], tipo_notificacion: [ - 'PLAN_ASIGNADO', - 'ESTADO_CAMBIADO', - 'TAREA_ASIGNADA', - 'COMENTARIO', - 'OTRA', + "PLAN_ASIGNADO", + "ESTADO_CAMBIADO", + "TAREA_ASIGNADA", + "COMENTARIO", + "OTRA", ], tipo_origen: [ - 'MANUAL', - 'IA', - 'CLONADO_INTERNO', - 'CLONADO_TRADICIONAL', - 'OTRO', + "MANUAL", + "IA", + "CLONADO_INTERNO", + "CLONADO_TRADICIONAL", + "OTRO", ], }, }, } as const + -- 2.49.1 From 3dc01c3fbaf68db7b2e2c5bad5e05583fc4c6f44 Mon Sep 17 00:00:00 2001 From: Guillermo Arrieta Medina Date: Tue, 24 Feb 2026 13:10:59 -0600 Subject: [PATCH 4/5] =?UTF-8?q?finalizaci=C3=B3n=20del=20merge=20de=20main?= =?UTF-8?q?=20a=20la=20rama=20issue/129...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../detalle/AsignaturaDetailPage.tsx | 225 +++--------------- 1 file changed, 39 insertions(+), 186 deletions(-) diff --git a/src/components/asignaturas/detalle/AsignaturaDetailPage.tsx b/src/components/asignaturas/detalle/AsignaturaDetailPage.tsx index f95cbf6..9828078 100644 --- a/src/components/asignaturas/detalle/AsignaturaDetailPage.tsx +++ b/src/components/asignaturas/detalle/AsignaturaDetailPage.tsx @@ -1,18 +1,8 @@ -import { - createFileRoute, - useNavigate, - useParams, - useRouterState, -} from '@tanstack/react-router' +import { createFileRoute, useNavigate, useParams } from '@tanstack/react-router' import { Pencil, Sparkles } from 'lucide-react' -import { useCallback, useState, useEffect } from 'react' +import { useState, useEffect } from 'react' import type { AsignaturaDetail } from '@/data' -import type { - CampoEstructura, - IAMessage, - IASugerencia, -} from '@/types/asignatura' import { Button } from '@/components/ui/button' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' @@ -97,47 +87,6 @@ const columnParsers: Partial string>> = { contenido_tematico: parseContenidoTematicoToPlainText, } -function EditableHeaderField({ - value, - onSave, - className, -}: { - value: string | number - onSave: (val: string) => void - className?: string -}) { - const textValue = String(value) - - // Manejador para cuando el usuario termina de editar (pierde el foco) - const handleBlur = (e: React.FocusEvent) => { - const newValue = e.currentTarget.innerText - if (newValue !== textValue) { - onSave(newValue) - } - } - - const handleKeyDown = (e: React.KeyboardEvent) => { - if (e.key === 'Enter') { - e.preventDefault() - e.currentTarget.blur() // Forzamos el guardado al presionar Enter - } - } - - return ( - // eslint-disable-next-line jsx-a11y/no-static-element-interactions - - {textValue} - - ) -} - export const Route = createFileRoute( '/planes/$planId/asignaturas/$asignaturaId', )({ @@ -145,67 +94,14 @@ export const Route = createFileRoute( }) export default function AsignaturaDetailPage() { - const routerState = useRouterState() - const state = routerState.location.state as any const { asignaturaId } = useParams({ from: '/planes/$planId/asignaturas/$asignaturaId', }) - const { planId } = useParams({ - from: '/planes/$planId/asignaturas/$asignaturaId', - }) - const { data: asignaturaApi, isLoading: loadingAsig } = - useSubject(asignaturaId) - // 1. Asegúrate de tener estos estados en tu componente principal - const [messages, setMessages] = useState>([]) + const { data: asignaturaApi } = useSubject(asignaturaId) + const [asignatura, setAsignatura] = useState(null) - const [campos] = useState>([]) - const [activeTab, setActiveTab] = useState('datos') const updateAsignatura = useUpdateAsignatura() - // Dentro de AsignaturaDetailPage - const [headerData, setHeaderData] = useState({ - codigo: '', - nombre: '', - creditos: 0, - ciclo: 0, - }) - - useEffect(() => { - // Si en el state de la ruta viene una pestaña específica, cámbiate a ella - if (state?.activeTab) { - setActiveTab(state.activeTab) - } - }, [state]) - - // Sincronizar cuando llegue la API - useEffect(() => { - if (asignaturaApi) { - setHeaderData({ - codigo: asignaturaApi.codigo ?? '', - nombre: asignaturaApi.nombre, - creditos: asignaturaApi.creditos, - ciclo: asignaturaApi.numero_ciclo ?? 0, - }) - } - }, [asignaturaApi]) - - const handleUpdateHeader = (key: string, value: string | number) => { - const newData = { ...headerData, [key]: value } - setHeaderData(newData) - - const patch: Record = - key === 'ciclo' - ? { numero_ciclo: value } - : { - [key]: value, - } - - updateAsignatura.mutate({ - asignaturaId, - patch, - }) - } - const handlePersistDatoGeneral = (clave: string, value: string) => { const baseDatos = asignatura?.datos ?? (asignaturaApi as any)?.datos ?? {} const mergedDatos = { ...baseDatos, [clave]: value } @@ -228,76 +124,9 @@ export default function AsignaturaDetailPage() { if (asignaturaApi) setAsignatura(asignaturaApi) }, [asignaturaApi]) - // 2. Funciones de manejo para la IA - const handleSendMessage = (text: string, campoId?: string) => { - const newMessage: IAMessage = { - id: Date.now().toString(), - role: 'user', - content: text, - timestamp: new Date(), - campoAfectado: campoId, - } - setMessages([...messages, newMessage]) - - // Aquí llamarías a tu API de OpenAI/Claude - // toast.info("Enviando consulta a la IA..."); - } - - const handleAcceptSuggestion = (_sugerencia: IASugerencia) => { - // Lógica para actualizar el valor del campo en tu estado de asignatura - // toast.success(`Sugerencia aplicada a ${sugerencia.campoNombre}`); - } - - // Dentro de tu componente principal (donde están los Tabs) - const [bibliografia, setBibliografia] = useState>([ - { - id: '1', - tipo: 'BASICA', - cita: 'Russell, S., & Norvig, P. (2020). Artificial Intelligence: A Modern Approach. Pearson.', - }, - ]) - const [isSaving, setIsSaving] = useState(false) - - const handleSaveBibliografia = (data: Array) => { - setIsSaving(true) - // Aquí iría tu llamada a la API - setBibliografia(data) - - // Simulamos un guardado - setTimeout(() => { - setIsSaving(false) - // toast.success("Cambios guardados"); - }, 1000) - } - - const [isRegenerating, setIsRegenerating] = useState(false) - - const handleRegenerateDocument = useCallback(() => { - setIsRegenerating(true) - setTimeout(() => { - setIsRegenerating(false) - }, 2000) - }, []) - return } -interface EstructuraDefinicion { - properties?: Record< - string, - { - title?: string - description?: string - examples?: Array - } - > -} -interface DatosGeneralesProps { - asignaturaId: string - data: AsignaturaDetail | null - isLoading: boolean - onPersistDato: (clave: string, value: string) => void -} function DatosGenerales({ onPersistDato, }: { @@ -309,10 +138,22 @@ function DatosGenerales({ const { data: data, isLoading: isLoading } = useSubject(asignaturaId) - const structureProps = - (data?.estructuras_asignatura?.definicion as EstructuraDefinicion) - .properties || {} - const valoresActuales = data?.datos || {} + // 1. Extraemos la definición de la estructura (los metadatos) + const definicionRaw = data?.estructuras_asignatura?.definicion + const definicion = isRecord(definicionRaw) + ? (definicionRaw as Record) + : null + + const propertiesRaw = definicion ? (definicion as any).properties : undefined + const structureProps = isRecord(propertiesRaw) + ? (propertiesRaw as Record) + : {} + + // 2. Extraemos los valores reales (el contenido redactado) + const datosRaw = data?.datos + const valoresActuales = isRecord(datosRaw) + ? (datosRaw as Record) + : {} if (isLoading) return

Cargando información...

return ( @@ -338,13 +179,28 @@ function DatosGenerales({ const cardTitle = config.title || key const description = config.description || '' + const xColumn = + typeof config?.['x-column'] === 'string' + ? config['x-column'] + : undefined + + // Obtenemos el placeholder del arreglo 'examples' de la estructura const placeholder = config.examples && config.examples.length > 0 ? config.examples[0] : '' - const valActual = (valoresActuales as Record)[key] - const currentContent = valActual ?? '' + const valActual = valoresActuales[key] + + let currentContent = valActual ?? '' + + if (xColumn) { + const rawValue = (data as any)?.[xColumn] + const parser = columnParsers[xColumn] + currentContent = parser + ? parser(rawValue) + : String(rawValue ?? '') + } return ( onPersistDato(clave, value)} @@ -524,12 +381,8 @@ function InfoCard({ // Agregamos un timestamp para forzar la actualización // de la location.state aunque la ruta sea la misma. navigate({ - to: '/planes/$planId/asignaturas/$asignaturaId', + to: '/planes/$planId/asignaturas/$asignaturaId/contenido', params: { planId, asignaturaId: asignaturaId! }, - state: { - activeTab: 'contenido', - _ts: Date.now(), - } as any, }) return } -- 2.49.1 From 3c63fdef6905fa3bb35969a4172c4996d350e13b Mon Sep 17 00:00:00 2001 From: Guillermo Arrieta Medina Date: Tue, 24 Feb 2026 13:45:39 -0600 Subject: [PATCH 5/5] =?UTF-8?q?Feat:=20Al=20picarle=20al=20bot=C3=B3n=20de?= =?UTF-8?q?=20listo,=20ya=20no=20se=20ocultan=20los=20temas=20de=20la=20un?= =?UTF-8?q?idad?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../asignaturas/detalle/ContenidoTematico.tsx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/components/asignaturas/detalle/ContenidoTematico.tsx b/src/components/asignaturas/detalle/ContenidoTematico.tsx index e324a73..9297b1e 100644 --- a/src/components/asignaturas/detalle/ContenidoTematico.tsx +++ b/src/components/asignaturas/detalle/ContenidoTematico.tsx @@ -205,13 +205,15 @@ export function ContenidoTematico() { })) setUnidades(transformed) - - // Expandir la primera unidad automáticamente - if (transformed.length > 0) { - setExpandedUnits(new Set([transformed[0].id])) - } else { - setExpandedUnits(new Set()) - } + // Mantener las unidades ya expandidas si existen; si no, expandir la primera. + setExpandedUnits((prev) => { + const validIds = new Set(transformed.map((u) => u.id)) + const filtered = new Set( + Array.from(prev).filter((id) => validIds.has(id)), + ) + if (filtered.size > 0) return filtered + return transformed.length > 0 ? new Set([transformed[0].id]) : new Set() + }) }, [data]) if (isLoading) -- 2.49.1