Fundamentos de Programación para Ingenieros que Vibecodean
Para ingenieros que usan IA para programar y les funciona, pero quieren entender QUÉ están haciendo, no solo que funcione.
1. Tipos de Datos — Los Materiales de Construcción
En ingeniería no mezclas acero con hormigón sin saber qué hace cada uno. En código es igual: cada dato tiene un tipo, y mezclarlos mal causa el 50% de los bugs.
Los básicos
// JavaScript
let nombre = "Adrián"; // String — texto, siempre entre comillas
let edad = 32; // Number — número (entero o decimal)
let esPadre = true; // Boolean — verdadero o falso, sin más
let nulo = null; // Null — "esto existe pero está vacío"
let sinDefinir = undefined; // Undefined — "esto ni se ha definido"
# Python — casi igual pero con matices
nombre = "Adrián" # str
edad = 32 # int (entero)
precio_kg = 1.43 # float (decimal)
es_padre = True # bool (ojo: True/False con mayúscula)
nulo = None # None (equivale a null)
Colecciones — donde se complica (y donde importa)
Arrays / Listas — una lista ordenada de cosas:
// JS: Array
let materiales = ["PGC", "PGU", "Triangle"];
materiales[0]; // "PGC" — los índices empiezan en 0, no en 1
materiales.length; // 3
materiales.push("Viroc"); // añade al final
# Python: Lista
materiales = ["PGC", "PGU", "Triangle"]
materiales[0] # "PGC"
len(materiales) # 3
materiales.append("Viroc") # añade al final
Objetos / Diccionarios — el tipo de dato más importante que vas a usar:
// JS: Objeto
let panel = {
tipo: "PGC",
espesor: 1.2, // mm
acero: "Z275",
peso_m2: 10, // kg/m²
certificado: true
};
panel.tipo; // "PGC"
panel.espesor; // 1.2
panel["acero"]; // "Z275" — otra forma de acceder
# Python: Diccionario
panel = {
"tipo": "PGC",
"espesor": 1.2,
"acero": "Z275",
"peso_m2": 10,
"certificado": True
}
panel["tipo"] # "PGC"
panel.get("acero") # "Z275" — más seguro, no explota si no existe
¿Por qué importa? Porque las APIs, bases de datos, configs... TODO devuelve objetos/diccionarios. Cuando ves esto:
{
"status": "running",
"balance": 1250.50,
"positions": [
{"symbol": "BTC", "size": 0.01, "pnl": 15.20}
]
}
Eso es un objeto con un array de objetos dentro. Si sabes leer esto, sabes leer el 90% del código que tocas.
Trampas comunes
// El clásico bug de tipos
"5" + 3 // "53" — ¡concatena como texto! No suma.
"5" - 3 // 2 — aquí sí resta. JavaScript es raro.
5 + 3 // 8 — esto sí es lo esperado
// Comparación
"5" == 5 // true — JS convierte tipos (peligroso)
"5" === 5 // false — comparación estricta (usa SIEMPRE esta)
2. Variables y Scope — Dónde Vive Cada Cosa
Declaración (JS)
const PI = 3.14159; // Constante — no cambia nunca. Usa esto por defecto.
let contador = 0; // Variable — puede cambiar. Usa cuando necesites reasignar.
var antiguo = "no uses"; // Antiguo — tiene bugs de scope. No lo uses.
Regla: usa const siempre. Solo usa let si necesitas reasignar. var nunca.
Scope — el muro entre habitaciones
const edificio = "Hotel Los Patios"; // Scope global — visible desde cualquier sitio
function calcularPeso() {
const peso_panel = 10; // Scope local — solo existe dentro de esta función
console.log(edificio); // ✅ Puede ver el global
console.log(peso_panel); // ✅ Puede ver lo suyo
}
console.log(peso_panel); // ❌ ERROR — no existe fuera de la función
Piénsalo como plantas de un edificio: desde la planta 3 ves la planta baja (global), pero desde la planta baja no ves lo que hay en la 3.
3. Funciones — Las Máquinas de la Obra
Una función es una máquina: le metes material (parámetros), hace algo, y saca un resultado (return).
// Definir la máquina
function calcularPesoPanel(ancho, alto, peso_m2) {
const area = ancho * alto;
const peso = area * peso_m2;
return peso; // Lo que sale de la máquina
}
// Usar la máquina
const peso = calcularPesoPanel(2.24, 3.0, 10);
console.log(peso); // 67.2 kg
# Python — igual pero sin llaves
def calcular_peso_panel(ancho, alto, peso_m2):
area = ancho * alto
peso = area * peso_m2
return peso
peso = calcular_peso_panel(2.24, 3.0, 10)
print(peso) # 67.2
Arrow functions (JS moderno)
// Forma clásica
function sumar(a, b) { return a + b; }
// Arrow function — lo mismo, más corto
const sumar = (a, b) => a + b;
// Las verás MUCHO en React (MMA Manager) y en callbacks
materiales.filter(m => m.espesor > 1.5);
materiales.map(m => m.tipo.toUpperCase());
Callbacks — funciones que llaman a otras funciones
// "Cuando termines de cargar los datos, ejecuta esta función"
fetch("/api/status")
.then(response => response.json()) // callback 1: convierte a JSON
.then(data => console.log(data)) // callback 2: usa los datos
.catch(error => console.error(error)); // callback 3: si falla
Esto es como decirle al operario de grúa: "Cuando subas el panel, avísame (callback). Si se cae, para la obra (catch)."
4. Flujo de Datos — De Dónde Viene, Por Dónde Pasa, Dónde Acaba
Este es el concepto MÁS IMPORTANTE. Cuando algo falla, la pregunta siempre es: ¿dónde se rompió el flujo?
Ejemplo real: AlphaHunter
1. Hyperliquid API → envía datos de mercado (precio BTC, funding rates) 2. AlphaHunter (Python/Railway) → recibe, analiza con 5 familias de señales 3. Si 3+ señales GREEN → genera orden de trading 4. Orden → se envía a Hyperliquid API 5. Resultado → se guarda en base de datos 6. Dashboard (frontend) → pide datos al backend → los muestra
Si el dashboard no muestra posiciones, ¿dónde está el fallo? Puede ser en CUALQUIER paso. Saber trazar este flujo es debugging.
Ejemplo real: mideBC3
1. Usuario escribe mediciones en el frontend (HTML/JS) 2. Frontend valida los datos (¿son números? ¿faltan campos?) 3. Frontend envía datos a Supabase (backend/base de datos) 4. Supabase guarda en PostgreSQL 5. Cuando otro usuario abre el proyecto → Supabase devuelve los datos 6. Frontend los renderiza en la tabla
5. Async/Await — Esperar Sin Parar la Obra
En una obra, no paras TODO porque estás esperando un pedido de Triangle. Sigues con otra tarea y cuando llega el material, continúas. En programación es exactamente igual.
El problema
// ❌ Código síncrono (bloqueante) — imaginario
const datos = pedirDatosAlServidor(); // Tarda 2 segundos
console.log(datos); // Muestra los datos
// Mientras espera esos 2 segundos, TODA la página se congela.
// No puedes hacer scroll, no puedes hacer clic. Inaceptable.
La solución: Promesas + Async/Await
Una Promesa es exactamente lo que suena: "te prometo que te daré un resultado... eventualmente."
// Una promesa tiene 3 estados:
// 🔄 Pending — esperando (el pedido está en camino)
// ✅ Resolved — éxito (el material llegó)
// ❌ Rejected — error (el pedido se canceló)
Async/Await es la forma limpia de trabajar con promesas:
// ✅ Con async/await — léelo como español
async function obtenerBalance() {
try {
const respuesta = await fetch("https://api.hyperliquid.xyz/info");
const datos = await respuesta.json();
console.log(datos.balance);
} catch (error) {
console.error("Error:", error);
}
}
# Python con async — AlphaHunter usa esto
import aiohttp
async def obtener_balance():
try:
async with aiohttp.ClientSession() as session:
async with session.get("https://api.hyperliquid.xyz/info") as resp:
datos = await resp.json()
print(datos["balance"])
except Exception as e:
print(f"Error: {e}")
Analogía de obra:
fetch()= hacer el pedido a Triangleawait= "espero a que llegue, pero mientras el resto de la obra sigue"try/catch= "si el pedido falla, no para la obra entera, solo gestionamos el problema"- Sin
await= enviar 50 pedidos a la vez y procesar cada uno cuando llegue
Error clásico
// ❌ Olvidar el await
async function mal() {
const datos = fetch("/api/status"); // Sin await
console.log(datos); // Imprime "Promise {<pending>}" — no los datos
}
// ✅ Con await
async function bien() {
const datos = await fetch("/api/status");
const json = await datos.json();
console.log(json); // Ahora sí, los datos reales
}
6. APIs y Endpoints — El Tema que Flaqueabas
¿Qué es una API?
API = Application Programming Interface. Es la puerta de entrada a un servicio.
Analogía: un restaurante. Tú (cliente/frontend) no entras en la cocina (servidor/backend). Le dices al camarero (API) lo que quieres, y él te trae el plato.
¿Qué es un Endpoint?
Un endpoint es una dirección específica dentro de una API. Cada endpoint hace una cosa concreta.
https://api.alphahunter.com/api/status ← endpoint de estado
https://api.alphahunter.com/api/positions ← endpoint de posiciones
https://api.alphahunter.com/api/signals ← endpoint de señales
Es como las extensiones de teléfono de una empresa: Extensión 100 → Recepción (status), Extensión 200 → Contabilidad (positions), Extensión 300 → Producción (signals).
Métodos HTTP — Qué Quieres Hacer
GET → LEER datos → "Dame el estado actual" POST → CREAR datos → "Guarda esta nueva medición" PUT → ACTUALIZAR datos → "Cambia el precio de este material" DELETE → BORRAR datos → "Elimina esta partida"
Ejemplo real con mideBC3 y Supabase:
// GET — Obtener todas las mediciones de un proyecto
const resp = await fetch(
"https://tuproyecto.supabase.co/rest/v1/mediciones?proyecto_id=eq.5",
{ headers: { "apikey": "tu-clave-supabase" } }
);
const mediciones = await resp.json();
// POST — Crear una nueva medición
const resp = await fetch(
"https://tuproyecto.supabase.co/rest/v1/mediciones",
{
method: "POST",
headers: {
"apikey": "tu-clave-supabase",
"Content-Type": "application/json"
},
body: JSON.stringify({
proyecto_id: 5,
partida: "01.01",
descripcion: "Panel LSF e=1.2mm",
cantidad: 45.5,
precio: 1.43
})
}
);
Request y Response
Cada llamada a una API tiene dos partes:
Request (lo que envías):
→ URL: https://api.alphahunter.com/api/status
→ Método: GET
→ Headers: { "Authorization": "Bearer tu-token" }
→ Body: (vacío en GET, con datos en POST)
Response (lo que recibes):
← Status Code: 200
← Headers: { "Content-Type": "application/json" }
← Body: { "status": "running", "balance": 1250.50 }
Status Codes — El Semáforo
2xx → ✅ Todo bien 200 OK — éxito 201 Created — se creó algo nuevo 204 No Content — éxito pero sin datos que devolver 3xx → ↪️ Redirección 301 Moved — la URL cambió permanentemente 304 Not Modified — no ha cambiado desde la última vez 4xx → ❌ Error TUYO (del cliente) 400 Bad Request — enviaste datos mal formados 401 Unauthorized — no tienes permiso (falta token/API key) 403 Forbidden — tienes token pero no permisos suficientes 404 Not Found — ese endpoint no existe 429 Too Many Requests — estás pidiendo demasiado rápido (rate limit) 5xx → 💥 Error DEL SERVIDOR 500 Internal Server Error — el servidor petó 502 Bad Gateway — Railway/proxy no puede conectar con tu app 503 Service Unavailable — el servicio está caído
Cuando AlphaHunter devuelve 502, no es tu código — es Railway. Cuando devuelve 500, SÍ es tu código.
7. JSON — El Idioma Universal
JSON = JavaScript Object Notation. Es el formato en que se comunican TODAS las APIs, bases de datos, y configuraciones modernas.
Ya lo lees sin saberlo. Cada vez que ves esto, es JSON:
{
"proyecto": "Hotel Los Patios",
"cliente": "Estruconsa",
"modulos": [
{
"id": 1,
"tipo": "habitacion",
"dimensiones": { "ancho": 2.24, "largo": 3.80, "alto": 3.0 },
"peso_kg": 1200,
"estado": "fabricacion"
},
{
"id": 2,
"tipo": "baño",
"dimensiones": { "ancho": 2.24, "largo": 2.40, "alto": 3.0 },
"peso_kg": 800,
"estado": "diseño"
}
],
"presupuesto_total": 125000.00,
"iva_incluido": false
}
Reglas de JSON:
- Las claves SIEMPRE van entre comillas dobles
"clave" - Strings entre comillas dobles
"texto" - Números sin comillas
42,3.14 - Booleanos:
true/false(minúsculas) - Null:
null - NO permite comentarios (a diferencia de JS)
- NO permite coma final
{"a": 1,}← esto falla
Convertir entre JSON y código:
// Objeto JS → JSON (para enviar)
const panel = { tipo: "PGC", espesor: 1.2 };
const json = JSON.stringify(panel);
// '{"tipo":"PGC","espesor":1.2}'
// JSON → Objeto JS (para usar)
const texto = '{"tipo":"PGC","espesor":1.2}';
const objeto = JSON.parse(texto);
objeto.tipo; // "PGC"
import json
# Dict → JSON
panel = {"tipo": "PGC", "espesor": 1.2}
texto = json.dumps(panel)
# JSON → Dict
texto = '{"tipo": "PGC", "espesor": 1.2}'
panel = json.loads(texto)
panel["tipo"] # "PGC"
8. Arquitectura — Frontend, Backend, Base de Datos
La analogía del edificio
🏗️ ARQUITECTURA DE SOFTWARE = ARQUITECTURA DE UN EDIFICIO
┌─────────────────────────────────────┐
│ FRONTEND (Fachada) │ ← Lo que ve el usuario
│ HTML = Estructura (hormigón) │ Navegador web
│ CSS = Acabados (pintura, azulejos) │ React, HTML, Three.js
│ JS = Instalaciones (electricidad) │ Interactividad
└──────────────┬──────────────────────┘
│ APIs (tuberías/conductos)
│ HTTP requests
┌──────────────▼──────────────────────┐
│ BACKEND (Estructura) │ ← La lógica, lo que no se ve
│ Servidor que procesa peticiones │ Python (AlphaHunter)
│ Reglas de negocio │ Node.js (Express)
│ Autenticación │ Railway, VPS
└──────────────┬──────────────────────┘
│ Queries SQL
│
┌──────────────▼──────────────────────┐
│ BASE DE DATOS (Cimientos) │ ← Donde viven los datos
│ PostgreSQL, SQLite, Supabase │ Permanente
│ Tablas, filas, columnas │ El almacén
└─────────────────────────────────────┘
Ejemplos de arquitecturas reales
| Tipo de proyecto | Frontend | Backend | Base de datos |
|---|---|---|---|
| Bot de trading | Dashboard (HTML/JS estático) | Python en Railway | SQLite/archivos |
| App de mediciones | HTML5 + JS | Supabase (serverless) | PostgreSQL (Supabase) |
| Configurador 3D | Three.js + Vite | No tiene (todo en frontend) | LocalStorage |
| Juego web | React + TS | No tiene (GitHub Pages) | Zustand (memoria) |
| Panel de gestión | Frontend web | SQLite + API | SQLite |
Nota: No todos los proyectos necesitan backend separado. Supabase actúa como backend+BD a la vez (Backend as a Service). Un juego web puede tener todo en el navegador.
Cliente-Servidor
TU NAVEGADOR (Cliente) RAILWAY/VPS (Servidor) ┌─────────────┐ request ┌─────────────┐ │ Chrome │ ───────────► │ Tu app │ │ Firefox │ │ Python/Node │ │ Safari │ ◄─────────── │ │ └─────────────┘ response └─────────────┘ El cliente PIDE. El servidor RESPONDE. Siempre. El cliente nunca accede a la BD directamente.
9. MVC — Separar Responsabilidades
¿Qué significa MVC y por qué te importa?
MVC = Model - View - Controller
MODEL (Modelo) → Los datos y la lógica de negocio
Dimensiones del módulo, materiales, cálculos de peso
VIEW (Vista) → Lo que se ve en pantalla
El render 3D en Three.js, los formularios, los botones
CONTROLLER → El intermediario
"El usuario pulsó 'añadir módulo' → dile al modelo que
cree uno → dile a la vista que lo pinte"
Sin MVC (monolito):
// ❌ Todo mezclado en un archivo de 2000 líneas
botonAñadir.onclick = function() {
modulos.push({ancho: 2.24, largo: 3.80}); // Datos
scene.add(new THREE.Mesh(...)); // 3D
document.getElementById("lista").innerHTML += "..."; // HTML
calcularPrecio(); // Lógica
actualizarResumen(); // Más HTML
}
Con MVC:
// ✅ model.js — solo datos
class ModuloModel {
constructor(ancho, largo, alto) {
this.ancho = ancho;
this.largo = largo;
this.alto = alto;
}
getPeso() { return this.ancho * this.largo * 10; }
getPrecio() { return this.getPeso() * 1.43; }
}
// ✅ view.js — solo render
class ModuloView {
render3D(modulo, scene) { /* Three.js */ }
renderLista(modulos) { /* HTML */ }
renderResumen(total) { /* HTML */ }
}
// ✅ controller.js — coordina
class ModuloController {
añadirModulo(ancho, largo, alto) {
const modulo = new ModuloModel(ancho, largo, alto);
this.modulos.push(modulo);
this.view.render3D(modulo, this.scene);
this.view.renderLista(this.modulos);
this.view.renderResumen(this.calcularTotal());
}
}
Ventaja: Si quieres cambiar cómo se ve el 3D, tocas SOLO la vista. Si cambian los precios, tocas SOLO el modelo. Nada se rompe en cascada.
10. Git — Control de Versiones
Probablemente ya lo usas. Entender qué hace internamente ayuda.
Conceptos
WORKING DIRECTORY → Los archivos en tu carpeta, tal cual STAGING AREA → "Esto es lo que quiero guardar" (git add) REPOSITORY → El historial completo de cambios (git commit) REMOTE → La copia en GitHub (git push)
# Flujo normal
git status # ¿Qué ha cambiado?
git add . # Marca TODO para guardar
git add archivo.js # Marca solo ese archivo
git commit -m "fix: corregido cálculo peso panel" # Guarda snapshot
git push # Sube a GitHub
# Ver historial
git log --oneline # Lista de commits
git diff # Ver qué ha cambiado antes de commit
# Branches — líneas paralelas de trabajo
git branch nueva-feature # Crear rama
git checkout nueva-feature # Cambiar a esa rama
git checkout -b fix/bug-123 # Crear y cambiar en un paso
# Merge — unir ramas
git checkout main # Volver a la principal
git merge nueva-feature # Traer los cambios
Analogía: Git es como tener fotos de la obra cada día. Si algo sale mal, puedes volver a la foto del martes y ver qué cambió. Las branches son como tener dos cuadrillas trabajando en zonas distintas — cuando terminan, juntas el trabajo (merge).
Convención de commits
feat: nueva funcionalidad → "feat: añadido cálculo de izaje" fix: corrección de bug → "fix: corregido NaN en precio unitario" refactor: mejorar sin cambiar → "refactor: migrar cálculos a módulo separado" docs: documentación → "docs: actualizar README con instrucciones deploy" style: formato/estilo → "style: formatear con prettier" chore: mantenimiento → "chore: actualizar dependencias"
11. Debugging — Encontrar Dónde Se Rompe
console.log — Tu mejor amigo
async function cargarPosiciones() {
console.log("1. Iniciando carga...");
const resp = await fetch("/api/positions");
console.log("2. Response status:", resp.status);
const datos = await resp.json();
console.log("3. Datos recibidos:", datos);
console.log("3b. Tipo:", typeof datos);
console.log("3c. Nº posiciones:", datos.length);
datos.forEach(pos => {
console.log("4. Posición:", pos.symbol, pos.pnl);
});
}
Si ves el "1" pero no el "2", el problema es el fetch. Si ves el "2" con status 500, el problema es el servidor. Así acorralas el bug.
Leer errores
TypeError: Cannot read properties of undefined (reading 'balance') │ │ │ │ │ │ │ └─ La propiedad que buscas │ │ └─ El objeto es undefined │ └─ No puede leer propiedades └─ Tipo de error: estás tratando algo como objeto que no lo es
Traducción: Algo que esperabas que fuera un objeto con .balance es undefined. Probablemente el fetch falló o no esperaste con await.
Errores comunes y qué significan
ReferenceError: x is not defined → Variable no existe (typo o scope) TypeError: x is not a function → Estás llamando algo que no es función SyntaxError: Unexpected token → Error de escritura (falta }, coma, etc.) CORS error → El servidor no permite peticiones desde tu dominio 404 Not Found → La URL/endpoint no existe ECONNREFUSED → El servidor no está corriendo
12. Entorno de Desarrollo — Por Qué Necesitas Cada Cosa
Node.js
No es un framework ni una librería. Es un runtime — permite ejecutar JavaScript fuera del navegador. Como Python tiene el intérprete python, JavaScript tiene node.
node archivo.js # Ejecuta JS fuera del navegador
node -v # Ver versión instalada
npm (Node Package Manager)
El almacén de piezas. Como pedir materiales a un proveedor:
npm install three # Instala Three.js (3D para Modular Designer)
npm install zustand # Instala Zustand (estado para MMA Manager)
npm install # Instala TODO lo que dice package.json
package.json = la lista de materiales del proyecto. node_modules/ = el almacén donde se guardan. (Por eso node_modules pesa tanto — es literalmente TODAS las dependencias.)
Vite
Servidor de desarrollo que hace que tu código se actualice en el navegador al instante cuando guardas un archivo. Sin Vite, tendrías que recargar manualmente cada vez.
npm run dev # Arranca Vite → abre localhost:5173
npm run build # Empaqueta todo para producción → carpeta dist/
npm run dev = la obra en construcción (andamios, cambios en directo)
npm run build = la obra terminada (limpia, optimizada, lista para entregar)
13. Deploy — De Tu PC al Mundo
GitHub Pages (frontends estáticos)
Tu código → git push → GitHub → GitHub Pages sirve los archivos Solo HTML/CSS/JS. No ejecuta Python ni Node en el servidor. Gratis. Ideal para: MMA Manager, opifex.es
Railway (backends)
Tu código → git push → Railway detecta el lenguaje → Crea contenedor Docker → Instala dependencias → Ejecuta tu app → Le da una URL pública Pago por uso. Ideal para: AlphaHunter (Python que necesita correr 24/7)
Hostinger (webs estáticas + FTP)
Archivos → FTP upload → Hostinger sirve desde su servidor Como GitHub Pages pero con dominio propio y más control.
La diferencia clave
ESTÁTICO (GitHub Pages, Hostinger): → Solo sirve archivos. No ejecuta código del servidor. → Tu JS se ejecuta en el NAVEGADOR del usuario. DINÁMICO (Railway, VPS): → Ejecuta código en el servidor (Python, Node). → Puede acceder a bases de datos, APIs externas, cron jobs. → AlphaHunter NECESITA esto porque ejecuta lógica 24/7.
14. React y Estado — Para MMA Manager
Si usas React con TypeScript, estos son los conceptos clave:
Componentes
Un componente = un bloque reutilizable de UI. Como un panel LSF prefabricado.
// Un componente simple
function FighterCard({ nombre, peso, record }) {
return (
<div className="card">
<h3>{nombre}</h3>
<p>{peso} kg</p>
<p>{record}</p>
</div>
);
}
// Usarlo
<FighterCard nombre="Jon Jones" peso={93} record="27-1" />
<FighterCard nombre="Islam Makhachev" peso={70} record="26-1" />
Estado (State) y Zustand
El estado es la memoria de tu aplicación en un momento dado. Zustand lo gestiona:
// store.js — la "base de datos" en memoria
import { create } from 'zustand';
const useGameStore = create((set) => ({
dinero: 100000,
fighters: [],
contratarFighter: (fighter) => set((state) => ({
fighters: [...state.fighters, fighter],
dinero: state.dinero - fighter.coste
}))
}));
// En un componente
function Dashboard() {
const dinero = useGameStore(state => state.dinero);
const contratar = useGameStore(state => state.contratarFighter);
return <p>Dinero: ${dinero}</p>;
}
Cuando dinero cambia, React automáticamente re-renderiza los componentes que lo usan. No tienes que actualizar el HTML manualmente.
Glosario Rápido
| Término | Qué es | Analogía |
|---|---|---|
| API | Interfaz para comunicar sistemas | Camarero entre cocina y cliente |
| Endpoint | URL específica de una API | Extensión telefónica |
| JSON | Formato de datos universal | El idioma que hablan todas las APIs |
| Async/Await | Esperar sin bloquear | Pedir material y seguir trabajando |
| Promise | Valor futuro | Albarán de pedido en camino |
| Callback | Función que se ejecuta después | "Cuando llegue el material, avísame" |
| Frontend | Lo que ve el usuario | Fachada del edificio |
| Backend | Lógica del servidor | Estructura y cimentación |
| Base de datos | Almacén de datos permanente | Archivo de planos de la obra |
| HTTP | Protocolo de comunicación web | El idioma de las peticiones |
| GET/POST | Leer/Crear datos | Pedir un informe / Enviar un pedido |
| Status code | Resultado de la petición | Semáforo (200=verde, 404=rojo) |
| npm | Gestor de paquetes JS | Proveedor de materiales |
| node_modules | Dependencias instaladas | Almacén de la obra |
| Vite | Servidor de desarrollo | Andamio con vista en directo |
| Build | Empaquetar para producción | Retirar andamios, limpiar obra |
| Deploy | Subir a producción | Entrega de llaves |
| Git | Control de versiones | Foto diaria de la obra |
| Branch | Línea paralela de trabajo | Dos cuadrillas en zonas distintas |
| Merge | Unir ramas | Juntar el trabajo de las cuadrillas |
| Commit | Guardar snapshot | Foto del estado actual |
| Component | Bloque de UI reutilizable | Panel LSF prefabricado |
| State | Datos en memoria de la app | Estado actual de la obra |
| Scope | Visibilidad de variables | Cada planta ve la baja, no al revés |
| Runtime | Motor que ejecuta código | La grúa que mueve las piezas |
| CORS | Restricción de seguridad web | Permiso de acceso entre dominios |
| Middleware | Código entre request y response | Control de acceso en la puerta |
| Token/API Key | Credencial de acceso | Tarjeta de acceso a la obra |
| Rate limit | Límite de peticiones | "Solo 100 camiones al día" |
| Docker | Contenedor aislado | Caseta de obra portátil |
| Environment variable | Config secreta (.env) | Código de la caja fuerte |
| TypeScript | JS con tipos obligatorios | JS con planos detallados |
Siguiente Paso
No intentes memorizar esto. Tenlo como referencia. Cuando estés trabajando en un proyecto y algo no te cuadre, busca la sección relevante. Con el tiempo, estos conceptos se van quedando solos.
Febrero 2026 — OPIFEX