Files
acad-ia-2/src/data/api/subjects.api.ts
Alejandro Rosales d0b05256b0 refactor: rename Materia to Asignatura across the codebase
- Updated type definitions and interfaces to replace 'Materia' with 'Asignatura'.
- Refactored components and routes to reflect the new naming convention.
- Adjusted related types and constants for consistency.
- Removed the old Materia type definition and added Asignatura type definition.
- Ensured all references in UI components and logic are updated accordingly.

fix #50
2026-01-30 08:13:30 -06:00

227 lines
6.2 KiB
TypeScript

import { supabaseBrowser } from '../supabase/client'
import { invokeEdge } from '../supabase/invokeEdge'
import { throwIfError, requireData } from './_helpers'
import type {
Asignatura,
BibliografiaAsignatura,
CambioAsignatura,
TipoAsignatura,
UUID,
} from '../types/domain'
import type { DocumentoResult } from './plans.api'
const EDGE = {
subjects_create_manual: 'subjects_create_manual',
ai_generate_subject: 'ai_generate_subject',
subjects_persist_from_ai: 'subjects_persist_from_ai',
subjects_clone_from_existing: 'subjects_clone_from_existing',
subjects_import_from_file: 'subjects_import_from_file',
subjects_update_fields: 'subjects_update_fields',
subjects_update_contenido: 'subjects_update_contenido',
subjects_update_bibliografia: 'subjects_update_bibliografia',
subjects_generate_document: 'subjects_generate_document',
subjects_get_document: 'subjects_get_document',
} as const
export async function subjects_get(subjectId: UUID): Promise<Asignatura> {
const supabase = supabaseBrowser()
const { data, error } = await supabase
.from('asignaturas')
.select(
`
id,plan_estudio_id,estructura_id,facultad_propietaria_id,codigo,nombre,tipo,creditos,horas_semana,numero_ciclo,linea_plan_id,orden_celda,datos,contenido_tematico,tipo_origen,meta_origen,creado_por,actualizado_por,creado_en,actualizado_en,
planes_estudio(
id,carrera_id,estructura_id,nombre,nivel,tipo_ciclo,numero_ciclos,datos,estado_actual_id,activo,tipo_origen,meta_origen,creado_por,actualizado_por,creado_en,actualizado_en,
carreras(id,facultad_id,nombre,nombre_corto,clave_sep,activa, facultades(id,nombre,nombre_corto,color,icono))
),
estructuras_asignatura(id,nombre,version,definicion)
`,
)
.eq('id', subjectId)
.single()
throwIfError(error)
return requireData(data, 'Asignatura no encontrada.')
}
export async function subjects_history(
subjectId: UUID,
): Promise<CambioAsignatura[]> {
const supabase = supabaseBrowser()
const { data, error } = await supabase
.from('cambios_asignatura')
.select(
'id,asignatura_id,cambiado_por,cambiado_en,tipo,campo,valor_anterior,valor_nuevo,fuente,interaccion_ia_id',
)
.eq('asignatura_id', subjectId)
.order('cambiado_en', { ascending: false })
throwIfError(error)
return data ?? []
}
export async function subjects_bibliografia_list(
subjectId: UUID,
): Promise<BibliografiaAsignatura[]> {
const supabase = supabaseBrowser()
const { data, error } = await supabase
.from('bibliografia_asignatura')
.select(
'id,asignatura_id,tipo,cita,tipo_fuente,biblioteca_item_id,creado_por,creado_en,actualizado_en',
)
.eq('asignatura_id', subjectId)
.order('tipo', { ascending: true })
.order('creado_en', { ascending: true })
throwIfError(error)
return data ?? []
}
/** Wizard: crear asignatura manual (Edge Function) */
export type SubjectsCreateManualInput = {
planId: UUID
datosBasicos: {
nombre: string
clave?: string
tipo: TipoAsignatura
creditos: number
horasSemana?: number
estructuraId: UUID
}
}
export async function subjects_create_manual(
payload: SubjectsCreateManualInput,
): Promise<Asignatura> {
return invokeEdge<Asignatura>(EDGE.subjects_create_manual, payload)
}
export async function ai_generate_subject(payload: {
planId: UUID
datosBasicos: {
nombre: string
clave?: string
tipo: TipoAsignatura
creditos: number
horasSemana?: number
estructuraId: UUID
}
iaConfig: {
descripcionEnfoque: string
notasAdicionales?: string
archivosExistentesIds?: UUID[]
repositoriosIds?: UUID[]
archivosAdhocIds?: UUID[]
usarMCP?: boolean
}
}): Promise<any> {
return invokeEdge<any>(EDGE.ai_generate_subject, payload)
}
export async function subjects_persist_from_ai(payload: {
planId: UUID
jsonAsignatura: any
}): Promise<Asignatura> {
return invokeEdge<Asignatura>(EDGE.subjects_persist_from_ai, payload)
}
export async function subjects_clone_from_existing(payload: {
asignaturaOrigenId: UUID
planDestinoId: UUID
overrides?: Partial<{
nombre: string
codigo: string
tipo: TipoAsignatura
creditos: number
horas_semana: number
}>
}): Promise<Asignatura> {
return invokeEdge<Asignatura>(EDGE.subjects_clone_from_existing, payload)
}
export async function subjects_import_from_file(payload: {
planId: UUID
archivoWordAsignaturaId: UUID
archivosAdicionalesIds?: UUID[]
}): Promise<Asignatura> {
return invokeEdge<Asignatura>(EDGE.subjects_import_from_file, payload)
}
/** Guardado de tarjetas/fields (Edge: merge server-side en asignaturas.datos y columnas) */
export type SubjectsUpdateFieldsPatch = Partial<{
codigo: string | null
nombre: string
tipo: TipoAsignatura
creditos: number
horas_semana: number | null
numero_ciclo: number | null
linea_plan_id: UUID | null
datos: Record<string, any>
}>
export async function subjects_update_fields(
subjectId: UUID,
patch: SubjectsUpdateFieldsPatch,
): Promise<Asignatura> {
return invokeEdge<Asignatura>(EDGE.subjects_update_fields, {
subjectId,
patch,
})
}
export async function subjects_update_contenido(
subjectId: UUID,
unidades: any[],
): Promise<Asignatura> {
return invokeEdge<Asignatura>(EDGE.subjects_update_contenido, {
subjectId,
unidades,
})
}
export type BibliografiaUpsertInput = Array<{
id?: UUID
tipo: 'BASICA' | 'COMPLEMENTARIA'
cita: string
tipo_fuente?: 'MANUAL' | 'BIBLIOTECA'
biblioteca_item_id?: string | null
}>
export async function subjects_update_bibliografia(
subjectId: UUID,
entries: BibliografiaUpsertInput,
): Promise<{ ok: true }> {
return invokeEdge<{ ok: true }>(EDGE.subjects_update_bibliografia, {
subjectId,
entries,
})
}
/** Documento SEP asignatura */
/* export type DocumentoResult = {
archivoId: UUID;
signedUrl: string;
mimeType?: string;
nombre?: string;
}; */
export async function subjects_generate_document(
subjectId: UUID,
): Promise<DocumentoResult> {
return invokeEdge<DocumentoResult>(EDGE.subjects_generate_document, {
subjectId,
})
}
export async function subjects_get_document(
subjectId: UUID,
): Promise<DocumentoResult | null> {
return invokeEdge<DocumentoResult | null>(EDGE.subjects_get_document, {
subjectId,
})
}