The patient endpoint retrieves patient information from Airtable based on a record ID, used to display the patient’s name in the application header.
Endpoint
Request parameters
The Airtable record ID of the patient to fetch
Success response (200 OK)
Always true for successful responses
Patient information object
The patient’s full name from the “Nombre Completo” field in Airtable
The Airtable record ID (echoed from request)
Example success response
{
"success": true,
"patient": {
"name": "Juan Pérez",
"recordId": "rec123abc456"
}
}
Error responses
400 Bad Request
Returned when the recordId parameter is missing.
{
"error": "recordId is required"
}
404 Not Found
Returned when the patient record exists but doesn’t have a name field.
{
"error": "Patient name not found in record"
}
405 Method Not Allowed
Returned when using a method other than GET.
{
"error": "Method not allowed"
}
500 Internal Server Error
Returned for server configuration issues or Airtable API errors.
{
"error": "Server configuration error"
}
or
{
"error": "Internal server error",
"details": "Error message"
}
Implementation
From api/patient.js:
export default async function handler(req, res) {
// Set CORS headers
res.setHeader('Access-Control-Allow-Origin', '*')
res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS')
res.setHeader('Access-Control-Allow-Headers', 'Content-Type')
// Handle preflight requests
if (req.method === 'OPTIONS') {
res.status(200).end()
return
}
if (req.method !== 'GET') {
return res.status(405).json({ error: 'Method not allowed' })
}
// Get record ID from query parameters
const { recordId } = req.query
if (!recordId) {
return res.status(400).json({ error: 'recordId is required' })
}
// Fetch patient data from Airtable
const airtableUrl = `https://api.airtable.com/v0/${process.env.AIRTABLE_BASE_ID}/Pacientes/${recordId}`
const response = await fetch(airtableUrl, {
headers: {
'Authorization': `Bearer ${process.env.AIRTABLE_API_KEY}`,
'Content-Type': 'application/json'
}
})
if (!response.ok) {
return res.status(response.status).json({
error: 'Failed to fetch patient data',
details: `Airtable API returned ${response.status}`
})
}
const patientData = await response.json()
// Extract patient name from the response
const patientName = patientData.fields['Nombre Completo']
if (!patientName) {
return res.status(404).json({ error: 'Patient name not found in record' })
}
// Return patient information
res.status(200).json({
success: true,
patient: {
name: patientName,
recordId: recordId
}
})
}
Frontend usage
The endpoint is called by patient-display.js when the page loads:
async function fetchAndDisplayPatientName() {
try {
// Get record ID from URL parameters
const urlParams = new URLSearchParams(window.location.search)
const recordId = urlParams.get('recordId') || urlParams.get('id')
if (!recordId) {
setFallbackPatientName()
return
}
// Call the API endpoint
const apiUrl = `/api/patient?recordId=${encodeURIComponent(recordId)}`
const response = await fetch(apiUrl)
const data = await response.json()
if (response.ok && data.success) {
updatePatientHeader(data.patient.name, true)
} else {
setFallbackPatientName()
}
} catch (error) {
console.error('Error fetching patient data:', error)
setFallbackPatientName()
}
}
URL parameter handling
The application accepts patient identification through URL parameters:
?recordId=rec123abc456 (preferred)
?id=rec123abc456 (alternative)
Patient name storage
Once fetched, the patient name is stored in multiple locations for application-wide access:
function updatePatientHeader(patientName, isLoaded) {
const patientNameElement = document.getElementById('patientName')
if (patientNameElement) {
patientNameElement.textContent = patientName.toUpperCase()
// Store globally for access by other scripts
window.currentPatientName = patientName.toUpperCase()
localStorage.setItem('currentPatientName', patientName.toUpperCase())
// Update page title
document.title = `Odontograma - ${patientName}`
}
}
Environment variables
Airtable API key for authentication
Airtable base ID containing the Pacientes table
CORS configuration
The endpoint allows cross-origin requests from any domain:
res.setHeader('Access-Control-Allow-Origin', '*')
res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS')
res.setHeader('Access-Control-Allow-Headers', 'Content-Type')
In production, consider restricting CORS to specific domains for better security.
Airtable table structure
The endpoint expects an Airtable table named Pacientes with at minimum:
- Nombre Completo (text field) - Patient’s full name
Error handling
The implementation includes comprehensive error handling:
Validate request method
Only GET and OPTIONS methods are allowed
Check required parameters
Validate that recordId is provided
Verify environment variables
Ensure Airtable credentials are configured
Handle Airtable API errors
Return appropriate error codes for API failures
Validate response data
Check that the patient name field exists in the record
Related pages
Airtable integration
Complete Airtable setup guide
Upload endpoint
Upload odontogram data to Airtable