diff --git a/controllers/Database.php b/controllers/Database.php
new file mode 100644
index 0000000..3b94aca
--- /dev/null
+++ b/controllers/Database.php
@@ -0,0 +1,38 @@
+<?php 
+
+class Database {
+    private static $instance = null;
+    private $mysqli;
+
+    private function __construct() {
+        $host = 'localhost';
+        $db = 'lania_cc';
+        $user = 'root';
+        $pass = 'P@ssw0rd';
+
+        try {
+            $this->mysqli = new mysqli($host, $user, $pass, $db);
+            
+            // Verificar conexión
+            if ($this->mysqli->connect_error) {
+                throw new Exception("Database: Conexión fallida. " . $this->mysqli->connect_error);
+            }
+            
+        } catch (Exception $e) {
+            throw new Exception("Database: Error . " . $e->getMessage());
+        }
+    }
+
+    public static function getInstance() {
+        if (self::$instance === null) {
+            self::$instance = new Database();
+        }
+        return self::$instance->mysqli;
+    }
+}
+
+
+// Uso:
+// $db = Database::getInstance();
+
+?>
\ No newline at end of file
diff --git a/controllers/login.php b/controllers/login.php
new file mode 100644
index 0000000..87d6868
--- /dev/null
+++ b/controllers/login.php
@@ -0,0 +1,26 @@
+<?php
+
+require_once __DIR__ . '/../models/Usuario.php';
+
+if ($_SERVER['REQUEST_METHOD'] === 'POST') {
+
+    // Crear una instancia del modelo usuario
+    $usuarioModel = new Usuario();
+
+    // Obtener los datos de la solicitud
+    $usuario = $_POST['numero-personal'];
+    $contrasena = $_POST['contrasena'];
+
+    try {
+        // Iniciar sesión del usuario
+        if ($usuarioModel->iniciarSesion($usuario, $contrasena)) {
+            echo json_encode(['loginExitoso' => true, 'message' => 'Inicio de sesión exitoso']);
+        } else {
+            echo json_encode(['loginExitoso' => false, 'message' => 'Usuario o contraseña incorrectos']);
+        }
+    } catch (Exception $e) {
+        echo json_encode(['loginExitoso' => false, 'message' => $e->getMessage()]);
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/js/login.js b/js/login.js
index 04e7f1d..4554a2c 100644
--- a/js/login.js
+++ b/js/login.js
@@ -13,7 +13,7 @@ formulario.addEventListener("submit", async (event) => {
   data.append("contrasena", contrasena);
   
   try {
-    const respuestaPeticion =  await fetch('controladores/login.php', {
+    const respuestaPeticion =  await fetch("controllers/login.php", {
       method: "POST",
       body: data,
     });
diff --git a/models/Candidato.php b/models/Candidato.php
new file mode 100644
index 0000000..6292641
--- /dev/null
+++ b/models/Candidato.php
@@ -0,0 +1,71 @@
+<?php
+
+require_once __DIR__ . '/../controllers/Database.php';
+
+class Candidato {
+
+    private $conn;
+
+    public function __construct() {
+        $this->conn = Database::getInstance();
+    }
+
+    /**
+     * Insertar información de candidatos en la base de datos.
+     * @param int $id_candidato ID del candidato.
+     * @param int $id_pais ID del país.
+     * @param int $id_estado ID del estado.
+     * @param int $id_municipio ID del municipio.
+     * @param int $id_colonia ID de la colonia.
+     * @param int $id_nivel ID del nivel máxímo de estudios.
+     * @param int $id_giro ID del giro de la empresa.
+     * @param string $nombre_empresa_institucion Nombre de la empresa o institución de la que proviene el candidato.
+     * @param string $motivo_examen Motivo del examen.
+     * @param int $calificacion_servicio Calificación del servicio.
+     * @param int $consentimiento_pub Consentimiento para la publicación de datos.
+     */
+    public function insertarInfoCandidatos(
+        $id_candidato,
+        $id_pais,
+        $id_estado,
+        $id_municipio,
+        $id_colonia,
+        $id_nivel,
+        $id_giro,
+        $nombre_empresa_institucion,
+        $motivo_examen,
+        $calificacion_servicio,
+        $consentimiento_pub
+    ) {
+        $sql = "INSERT INTO info_candidatos ( id_candidato, id_pais, id_estado, id_municipio, id_colonia, id_nivel, id_giro, nombre_empresa_institucion, motivo_examen, calificacion_servicio, consentimiento_pub ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+        $stmt = $this->conn->prepare($sql);
+        if ($stmt === false) {
+            throw new Exception("Error en la preparación de la consulta: " . $this->conn->error);
+        }
+    
+        $stmt->bind_param(
+            "iiiiiiissii",
+            $id_candidato,
+            $id_pais,
+            $id_estado,
+            $id_municipio,
+            $id_colonia,
+            $id_nivel,
+            $id_giro,
+            $nombre_empresa_institucion,
+            $motivo_examen,
+            $calificacion_servicio,
+            $consentimiento_pub
+        );
+    
+        if (!$stmt->execute()) {
+            throw new Exception("Error al insertar datos de información del candidato: " . $stmt->error);
+        }
+    
+        $stmt->close();
+    }
+
+}
+
+
+?>
\ No newline at end of file
diff --git a/models/Catalogos.php b/models/Catalogos.php
new file mode 100644
index 0000000..cb29367
--- /dev/null
+++ b/models/Catalogos.php
@@ -0,0 +1,98 @@
+<?php
+
+require_once __DIR__ . '/../controllers/Database.php';
+
+class Catalogos{
+    private $conn;
+
+    public function __construct() {
+        $this->conn = Database::getInstance();
+    }
+
+    public function obtenerGeneros(){
+        $sql = "SELECT id_genero, descripcion FROM genero";
+        $result = $this->conn->query($sql);
+        
+        $generos = [];
+        while($row = $result->fetch_assoc()){
+            $generos[] = $row;
+        }
+        
+        return $generos;
+    }
+
+    public function obtenerRangosEdad(){
+        $sql = "SELECT id_rango_edad, descripcion FROM rango_edad";
+        $result = $this->conn->query($sql);
+        
+        $rangos = [];
+        while($row = $result->fetch_assoc()){
+            $rangos[] = $row;
+        }
+        
+        return $rangos;
+    }
+
+    public function obtenerTiposIdentificacion(){
+        $sql = "SELECT id_tipo_id, descripcion FROM tipo_identificacion ORDER BY descripcion";
+        $result = $this->conn->query($sql);
+        
+        $tipos = [];
+        while($row = $result->fetch_assoc()){
+            $tipos[] = $row;
+        }
+        
+        return $tipos;
+    }
+
+    public function obtenerNivelesEstudio(){
+        $sql = "SELECT id_nivel, descripcion FROM nivel_estudio";
+        $result = $this->conn->query($sql);
+        
+        $niveles = [];
+        while($row = $result->fetch_assoc()){
+            $niveles[] = $row;
+        }
+        
+        return $niveles;
+    }
+
+    public function obtenerGiros(){
+        $sql = "SELECT id_giro, descripcion FROM giro ORDER BY descripcion";
+        $result = $this->conn->query($sql);
+        
+        $giros = [];
+        while($row = $result->fetch_assoc()){
+            $giros[] = $row;
+        }
+        
+        return $giros;
+    }
+
+    public function obtenerExamenes(){
+        $sql = "SELECT id_examen, nombre_examen FROM examen ORDER BY nombre_examen";
+        $result = $this->conn->query($sql);
+        
+        $examenes = [];
+        while($row = $result->fetch_assoc()){
+            $examenes[] = $row;
+        }
+        
+        return $examenes;
+    }
+
+    public function obtenerPaises(){
+        $sql = "SELECT int as id, nombre FROM paises ORDER BY nombre";
+        $result = $this->conn->query($sql);
+        
+        $paises = [];
+        while($row = $result->fetch_assoc()){
+            $paises[] = $row;
+        }
+        
+        return $paises;
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/models/Usuario.php b/models/Usuario.php
new file mode 100644
index 0000000..b4e3813
--- /dev/null
+++ b/models/Usuario.php
@@ -0,0 +1,63 @@
+<?php
+
+require_once __DIR__ . '/../controllers/Database.php';
+
+class Usuario {
+    private $conn;
+
+    public function __construct() {
+        $this->conn = Database::getInstance();
+    }
+
+    /**
+     * Registrar un nuevo usuario
+     */
+    public function registrarUsuario($usuario, $contrasena){
+        // Hashear contraseña
+        $contrasena_hash = password_hash($contrasena, PASSWORD_DEFAULT);
+
+        // Preparar la consulta mysql usando msqli
+        $stmt = $this->conn->prepare("INSERT INTO usuario (usuario, contrasena) VALUES (?, ?)");
+        $stmt->bind_param("ss", $usuario, $contrasena_hash);
+        if (!$stmt->execute()) {
+            throw new Exception("Error al registrar usuario: " . $stmt->error);
+        }
+    
+        $stmt->close();
+    }
+
+    /**
+     * Iniciar sesión de un usuario
+     * @param string $usuario Nombre de usuario
+     * @param string $contrasena Contraseña del usuario
+     * @return bool true si el inicio de sesión es exitoso, false en caso contrario
+     */
+    public function iniciarSesion($usuario, $contrasena) {
+        // Preparar la consulta mysql usando msqli
+        $stmt = $this->conn->prepare("SELECT contrasena FROM usuario WHERE usuario = ?");
+        $stmt->bind_param("s", $usuario);
+        if (!$stmt->execute()) {
+            throw new Exception("Error al iniciar sesión: " . $stmt->error);
+        }
+    
+        // Obtener el resultado
+        $stmt->store_result();
+        if ($stmt->num_rows == 0) {
+            return false; // Usuario no encontrado
+        }
+    
+        // Obtener el hash de la contraseña
+        $stmt->bind_result($contrasena_hash);
+        $stmt->fetch();
+    
+        // Verificar la contraseña
+        if (password_verify($contrasena, $contrasena_hash)) {
+            return true; // Inicio de sesión exitoso
+        } else {
+            return false; // Contraseña incorrecta
+        }
+    }
+
+}
+
+?>
\ No newline at end of file