| |
Proyecto MF0492_3. CREACIÓN Y ACCESO A BASE DE DATOS
Objetivos
- Crear la Base de Datos (en Supabase / PostGres) para el MVP de una Tienda Virtual que será programada utilizando Astro / NodeJS.
- Crear la primera pantalla en la cual se muestre el complemento MenuCategorias.astro.
- Crear la conexión y mostrar en el complemento, las categorías guardadas en la tabla categorias.
Requerimientos de la Base de Datos:
Tablas
-
CLIENTES (alrededor de 15 clientes)
- pk_cliente UUID REFERENCES auth.users ON DELETE CASCADE PRIMARY KEY
- email (la autentificación la haremos por la cuenta de Google)
- tipo (empresa/autónomo)
- razon_social (escribir acá persona natural en caso de ser autónomo)
- nombres_cliente
- apellido1_cliente
- apellido2_cliente
- telefono_movil
- rol (cliente/administrador)
- fecha_registro TIMESTAMP WITH TIME ZONE DEFAULT NOW()
auth.users hace referencia directa a la tabla interna del sistema de autenticación de Supabase.
La tabla auth.users de Supabase utiliza obligatoriamente identificadores del tipo UUID. Por eso el campo pk_cliente debe ser obligatoriamente UUID, de lo contrario PostgreSQL arrojará un error de incompatibilidad de tipos al intentar crear la tabla.
-
CATEGORIAS (entre 5 y 10 categorías)
- pk_categoria
- nom_categoria
- descripcion_categoria
-
PRODUCTOS (entre 5 y 10 por categoría)
Haremos una tienda virtual sencilla, con lo cual a un producto sólo se le podrá asignar una única categoría.
- pk_producto
- fk_categoria
- nombre_producto
- url_imagen TEXT,
- descripcion_producto (que se puede desglosar en varios campos)
- precio
- iva (en caso de que haya iva diferencial)
- descuento (para productos promocionales)
- stock
- punto_reposicion (ROP: Reorder Point)
- fecha_creacion TIMESTAMP WITH TIME ZONE DEFAULT NOW()
- fecha_baja TIMESTAMP WITH TIME ZONE DEFAULT NULL
-
FACTURAS
Una vez que un cliente incluya producto(s) a la cesta y la compra haya sido confirmada por Stripe, la tienda guardará el registro de compras con el número de factura asociado a la misma.
- pk_factura
- fk_cliente
- fecha_compra
- stripe_payment_intent_id TEXT NOT NULL UNIQUE,
- iva (si todos los productos de la tienda tienen el mismo iva, se registrará acá, de lo contrario se registrará en la tabla DETALLE_FACTURA)
-
DETALLE_FACTURA
- fk-factura
- fk-producto
- cantidad
- precio-unitario
- precio_total NUMERIC GENERATED ALWAYS AS (precio * cantidad) STORED
- descuento
- iva (si aplica)
La cláusula GENERATED ALWAYS AS (fórmula) STORED se utiliza para crear columnas calculadas (también conocidas como columnas autogeneradas). El valor de este tipo de columna se calcula automáticamente a partir de otras columnas de la misma fila y se guarda físicamente en el disco.
Reglas para crear columnas calculadas
- Deben llevar STORED: PostgreSQL actualmente solo soporta columnas generadas persistentes (STORED). No se calculan al vuelo en cada consulta, sino que se guardan al insertar o actualizar.
- Son de solo lectura: No puedes insertar ni actualizar datos directamente en esa columna. Postgres se encarga de todo.
- La fórmula solo puede usar columnas de la misma fila y funciones deterministas (que siempre devuelven el mismo resultado con los mismos datos). No puedes usar funciones como NOW() o incluir subconsultas a otras tablas.
Requerimientos de la Conexión:
Al conectar un backend a una base de datos, las buenas prácticas se enfocan en tres pilares: seguridad, rendimiento y mantenibilidad.
Seguridad
- Nunca guardes contraseñas en el código. Utiliza variables de entorno (
.env).
- Principio de menor privilegio: Configura el usuario de la base de datos con los permisos mínimos necesarios (por ejemplo, si un usuario solo debe leer datos, no le des permisos de escritura o eliminación).
- Prevención de Inyección SQL: Usa siempre consultas preparadas (Prepared Statements) en lugar de concatenar texto directamente en las sentencias SQL.
- Cifrado en tránsito: Fuerza conexiones seguras utilizando SSL/TLS para evitar que los datos sean interceptados entre el backend y la base de datos.
Rendimiento y Eficiencia
- Usa un Pool de Conexiones (Connection Pooling): Abrir y cerrar una conexión por cada solicitud es costoso. Mantén un grupo de conexiones reutilizables preabiertas para mejorar el tiempo de respuesta.
- Cierre de conexiones: Asegúrate de liberar o devolver la conexión al pool una vez que la consulta termine, idealmente usando bloques try-catch-finally
- Control de Tiempos de Espera (Timeouts): Configura límites de tiempo (connectTimeout y socketTimeout). Esto evita que un hilo del backend se quede bloqueado indefinidamente si la base de datos no responde.
Mantenibilidad y Arquitectura
- Manejo de errores centralizado: Captura las excepciones (errores) de la base de datos y muéstralas de forma genérica para el usuario. Nunca muestres errores internos del motor (como códigos de error SQL) en la respuesta del cliente, ya que revelan información de la infraestructura.
- Define interfaces para los resultados de tus consultas. Así mantendrás tu proyecto Astro escalable y robusto.
- Estrategia de Reintentos (Retry Logic): Implementa reintentos automáticos con un retraso exponencial (exponential backoff) únicamente para fallos temporales de red, evitando saturar el servidor.
Forma de Entrega:
Deberéis subir cuatro documentos al siguiente formulario:
- Un archivo
ejercicios.sql comentando, con la solución de los ejercicios SELECT: ★ Consultas simples, ★ Consultas multitabla y ★ Consultas agrupadas.
- Un archivo
tienda_tu_nombre.sql con las instrucciones para la creación e inserción de registros en la Base de Datos.
- El archivo del componente
MenuCategorias.astro
- Un archivo
tu_nombre.zip con el contenido de los archivos de conexión (carpeta /src/lib/ de Astro) y los archivos astro.config.mjs y package.json
|