Files
perfil/nuxt4/server/api/contacts/index.get.ts
josedario87 6da1552ae1
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 59s
fix: usar field IDs numéricos en query Metabase
El filtro de empleados no funcionaba porque Metabase
requiere IDs de campo numéricos (463 para empleado, 453 para id)
en lugar de nombres de campo como strings.
2025-12-05 12:01:20 -06:00

119 lines
3.2 KiB
TypeScript

/**
* API endpoint para obtener contactos desde Metabase
* Consulta la tabla Clientes del proyecto facturador en Supabase via Metabase API
*/
interface Contact {
id: number
name: string
cedula: number | null
ubicacion: string | null
grupo_estudio: string | null
empleado: boolean
avatar_url: string | null
telefono: string | null
idciat: string | null
}
interface MetabaseResponse {
data: {
cols: Array<{ name: string }>
rows: Array<Array<unknown>>
}
}
export default defineEventHandler(async (event): Promise<Contact[]> => {
const config = useRuntimeConfig()
const headers = getRequestHeaders(event)
const query = getQuery(event)
// Verificar autenticación
const uid = headers['x-authentik-uid']
if (!uid) {
throw createError({
statusCode: 401,
message: 'Usuario no autenticado'
})
}
// Obtener configuración de Metabase
const metabaseUrl = config.metabaseApiUrl as string
const metabaseApiKey = config.metabaseApiKey as string
const databaseId = config.metabaseDatabaseId as number
const tableId = config.metabaseTableId as number
if (!metabaseApiKey) {
throw createError({
statusCode: 500,
message: 'API Key de Metabase no configurada'
})
}
// Construir filtros para la query
// Nota: Metabase requiere field IDs numéricos, no nombres de campo
// IDs obtenidos de la metadata de la tabla 15 (Clientes):
// - id: 453, empleado: 463
const filters: unknown[] = []
// Filtro de empleados (por defecto true)
const empleadoFilter = query.empleado !== 'false'
if (empleadoFilter) {
filters.push(['=', ['field', 463, null], true])
}
// Filtro por ID exacto
if (query.id) {
const idNum = parseInt(query.id as string)
if (!isNaN(idNum)) {
filters.push(['=', ['field', 453, null], idNum])
}
}
// Construir la query para Metabase
const metabaseQuery = {
database: databaseId,
type: 'query',
query: {
'source-table': tableId,
'order-by': [['asc', ['field', 453, null]]],
filter: filters.length > 0
? (filters.length === 1 ? filters[0] : ['and', ...filters])
: undefined
}
}
console.log('📊 Query a Metabase:', JSON.stringify(metabaseQuery, null, 2))
try {
const response = await $fetch<MetabaseResponse>(`${metabaseUrl}/api/dataset`, {
method: 'POST',
headers: {
'X-API-Key': metabaseApiKey,
'Content-Type': 'application/json'
},
body: metabaseQuery
})
console.log('📊 Respuesta Metabase - filas:', response.data?.rows?.length || 0)
// Mapear columnas a objetos
const cols = response.data.cols.map((col) => col.name)
const contacts: Contact[] = response.data.rows.map((row) => {
const contact: Record<string, unknown> = {}
cols.forEach((colName, index) => {
contact[colName] = row[index]
})
return contact as unknown as Contact
})
return contacts
} catch (error: unknown) {
console.error('Error al obtener contactos de Metabase:', error)
const err = error as { statusCode?: number; message?: string }
throw createError({
statusCode: err.statusCode || 500,
message: err.message || 'Error al obtener los contactos'
})
}
})