Skip to main content

Prerequisites

Before you begin, ensure you have the following installed:
  • Node.js (v14 or higher)
  • npm or yarn
  • PostgreSQL database
  • Supabase account (for authentication)

Installation

1

Clone the Repository

Clone the source code to your local machine:
git clone <repository-url>
cd api_centro_medico
2

Install Dependencies

Install the required Node.js packages:
npm install
This will install:
  • Express.js (v5.2.1)
  • Prisma Client (v5.22.0)
  • Supabase JS (v2.87.1)
  • JSON Web Token (v9.0.3)
  • And other dependencies
3

Configure Environment Variables

Create a .env file in the project root with the following variables:
.env
# Database Configuration
# For migrations (direct connection)
DATABASE_URL="postgresql://user:password@host:5432/database"

# For production (connection pooling via PgBouncer)
# DATABASE_URL="postgresql://user:password@host:6543/postgres?pgbouncer=true"

# Supabase Configuration
SUPABASE_URL="https://your-project.supabase.co"
SUPABASE_ANON_KEY="your-anon-key"
SUPABASE_SERVICE_ROLE_KEY="your-service-role-key"
Get your Supabase credentials from your Supabase project dashboard under Settings > API
4

Run Database Migrations

Generate the Prisma Client and run migrations:
npx prisma generate
npx prisma migrate deploy
This will create the following tables:
  • personas - Internal staff
  • usuarios - Authenticated users
  • clientes_publicos - Public patients
  • especialidades - Medical specialties
  • medicos - Doctors
  • citas - Appointments
  • historial - Medical history
  • contacto - Contact messages
5

Start the Server

Start the development server:
npm run dev
Or for production:
npm start
The API will be available at http://localhost:3000

Your First API Request

Now that your server is running, let’s make your first API request!

List All Specialties (Public Endpoint)

This endpoint doesn’t require authentication and returns all available medical specialties:
curl http://localhost:3000/api/especialidades
Example Response:
[
  {
    "id": 1,
    "nombre": "Cardiología",
    "descripcion": "Especialidad médica que se ocupa del corazón",
    "created_at": "2024-03-05T10:30:00.000Z"
  },
  {
    "id": 2,
    "nombre": "Pediatría",
    "descripcion": "Atención médica de niños y adolescentes",
    "created_at": "2024-03-05T10:31:00.000Z"
  }
]

Create an Appointment (Public Endpoint)

Patients can request appointments without authentication:
curl -X POST http://localhost:3000/api/citas \
  -H "Content-Type: application/json" \
  -d '{
    "nombres": "Juan",
    "apellidos": "Pérez",
    "telefono": "555-1234",
    "email": "[email protected]",
    "fecha_solicitada": "2024-03-10",
    "hora_solicitada": "14:30",
    "sintomas": "Dolor de pecho"
  }'
Example Response:
{
  "message": "Cita registrada",
  "cita": {
    "id": 1,
    "cliente_id": 1,
    "fecha_solicitada": "2024-03-10T00:00:00.000Z",
    "hora_solicitada": "1970-01-01T14:30:00.000Z",
    "sintomas": "Dolor de pecho",
    "estado": "pendiente",
    "created_at": "2024-03-05T15:45:00.000Z"
  }
}
The appointment is created with estado: "pendiente" status. An admin or assistant must confirm it and assign a doctor.

List Public Doctors

View all active doctors available for appointments:
curl http://localhost:3000/api/medicos/public
Example Response:
[
  {
    "id": 1,
    "persona_id": 3,
    "especialidad_id": 1,
    "email": "[email protected]",
    "colegiatura": "12345",
    "activo": true,
    "persona": {
      "nombres": "María",
      "apellidos": "García",
      "telefono": "555-5678"
    },
    "especialidad": {
      "nombre": "Cardiología"
    }
  }
]

Database Schema

Here’s a quick overview of the Prisma schema:
enum rol_usuario {
  admin
  asistente
}

enum estado_cita {
  pendiente
  confirmada
  cancelada
  atendida
}

model Personas {
  id         Int      @id @default(autoincrement())
  nombres    String
  apellidos  String
  telefono   String?
  dni        String?  @unique
  created_at DateTime @default(now())
}

model Usuarios {
  id         String   @id  // UUID from Supabase
  persona_id Int      @unique
  role       rol_usuario
  created_at DateTime @default(now())
}

model Clientes_publicos {
  id         Int      @id @default(autoincrement())
  nombres    String
  apellidos  String?
  telefono   String?
  email      String?
  created_at DateTime @default(now())
}

model Citas {
  id                  Int         @id @default(autoincrement())
  cliente_id          Int
  fecha_solicitada    DateTime    @db.Date
  hora_solicitada     DateTime    @db.Time
  fecha_confirmada    DateTime?   @db.Date
  hora_confirmada     DateTime?   @db.Time
  medico_id           Int?
  sintomas            String?
  estado              estado_cita @default(pendiente)
  created_at          DateTime    @default(now())
}

Next Steps

Authentication

Learn how to authenticate admin and assistant users

API Reference

Explore all available endpoints
Remember to keep your SUPABASE_SERVICE_ROLE_KEY secret and never commit it to version control!

Build docs developers (and LLMs) love