EN
bikefy — banner
← Volver a proyectos

bikefy

· 6 min de lectura

Plataforma para la administración de talleres de bicicletas que controla inventario, reparaciones y finanzas en un solo lugar, reemplazando las planillas y reduciendo errores manuales.

Next.js JavaScript TailwindCSS Express PostgreSQL

Acerca del proyecto

Los talleres de bicicletas manejan múltiples frentes a la vez: repuestos, reparaciones, finanzas y proveedores. bikefy centraliza toda esa operación en una sola plataforma, eliminando planillas y papeles.

El sistema registra cada movimiento del taller (desde la compra de un repuesto al proveedor hasta la venta al cliente) manteniendo trazabilidad completa y actualizando el stock automáticamente.

Objetivos:

  • Control de inventario con trazabilidad de stock
  • Registro de compras y ventas con actualización automática del stock
  • Gestión de servicios de reparación y mantenimiento
  • Administración financiera con balances, ingresos y egresos
  • Panel Kanban para tareas del equipo
  • Gestión de usuarios con roles (admin y empleado)

Características principales

MóduloFuncionalidades
InventarioCRUD de artículos, stock automático, categorías, precios de compra/venta, exportación Excel/PDF
Compras y VentasRegistro de transacciones vinculadas a proveedores, ajuste automático de stock, trazabilidad completa
FinanzasBalance general, gráficos de ingresos/egresos, historial de transacciones
ServiciosRegistro de reparaciones, precios, métodos de pago, estado del servicio
ProveedoresCRUD con datos de contacto, historial de compras asociadas
TareasTablero Kanban con columnas y tarjetas arrastrables
UsuariosRoles admin/empleado, autenticación JWT, recuperación de contraseña vía email

Stack tecnológico

CapaTecnologíaPropósito
FrontendNext.js 15 (Pages Router)Framework React con SSR
Tailwind CSS + CSS VariablesEstilos utilitarios con tema claro/oscuro
Shadcn/ui (New York) + Radix UI + MUIComponentes de interfaz accesibles
Formik + YupManejo de formularios y validación
Chart.js + react-chartjs-2Gráficos de finanzas
AxiosCliente HTTP para consumo de API
BackendExpress.js 4API REST
express-validator + JoiValidación de datos de entrada
jsonwebtokenAutenticación con JWT Bearer
bcryptHashing de contraseñas
CloudinaryAlmacenamiento de imágenes de perfil
NodemailerEnvío de correos (recuperación de contraseña)
Base de datosPostgreSQL 16Base relacional
pg (Client)Driver de conexión
DeployVercel (backend) + PM2 (frontend)Producción

Flujo de una compra

Usuario ──▶ Formulario (Frontend)


           POST /api/inventory/purchase


           inventory.controller → inventory.service

                ├──▶ 1. Crea transacción (INSERT transaction)
                ├──▶ 2. Por cada ítem:
                │       ├──▶ ¿Existe el artículo?
                │       │     ├── Sí → updateStock(id, cantidad, 'add')
                │       │     └── No  → createItem(nuevo artículo)
                │       ├──▶ Crea detalle (INSERT transaction_item)
                │       └──▶ Asocia proveedor (INSERT/UPDATE item_supplier)


           Stock actualizado + transacción registrada

Flujo de una venta

Usuario ──▶ Selecciona artículos del inventario


           validateStock(): ¿Hay stock suficiente?

                ├── No  → Error: "Stock insuficiente"

                └── Sí  → Crea transacción tipo 'venta'

                           └──▶ Por cada ítem:
                                   ├── updateStock(id, cantidad, 'subtract')
                                   └── Crea detalle (INSERT transaction_item)

Eliminación con rollback

Al eliminar una compra o venta, el sistema revierte automáticamente el stock:

  • Eliminar venta → devuelve el stock al inventario (add)
  • Eliminar compra → descuenta el stock comprado (subtract), y si el proveedor queda sin transacciones activas con ese artículo, se desvincula

Mi rol y contribución

Dentro del equipo de 4 integrantes, fui responsable del diseño e implementación completa de los siguientes módulos, cubriendo tanto backend como frontend:

Inventario

CRUD completo de artículos con nombre, descripción, categoría, stock y precio de venta. Cada artículo puede estar vinculado a uno o más proveedores con su respectivo precio de compra y fecha.

Componentes del frontend:

  • InventoryTable: tabla con búsqueda, filtros por categoría y proveedor, ordenamiento
  • AddItemDialog / EditItemDialog: formularios con validación Yup
  • ItemDetailsDialog: vista detallada con proveedores asociados
  • ExportButtons: exportación a Excel (XLSX) y PDF (jsPDF)

Compras y Ventas

El módulo más grande del sistema. Registra compras a proveedores y ventas a clientes, ajustando el stock automáticamente.

Compra:

  • Selección de artículos existentes o creación en el momento
  • Asignación de proveedor, cantidad, precio unitario y método de pago
  • Incremento automático del stock
  • Registro de la relación artículo-proveedor con precio de compra

Venta:

  • Selección de artículos del inventario con stock disponible
  • Validación de stock suficiente antes de confirmar
  • Decremento automático del stock
  • Registro de transacción con método de pago

Edición y eliminación:

  • Modificación de cantidades con ajuste diferencial del stock
  • Eliminación con rollback completo del inventario

Módulos en detalle

Backend

  • Modelo Item (backend/src/models/Item.js): CRUD de artículos con queries SQL parametrizadas, búsqueda por nombre (ILIKE), agregación de proveedores asociados con ARRAY_AGG, y operación updateStock con modo add/subtract para ajustes atómicos de inventario.

  • Modelo Inventory (backend/src/models/Inventory.js): Capa de acceso a datos para transacciones de compra/venta. Incluye:

    • createTransaction / createTransactionDetails: inserción de cabecera y detalle
    • updateSupplier: upsert de la relación artículo-proveedor con precio de compra
    • validateStock: verificación de stock antes de vender
    • getPurchases / getSales: queries con JOINs a item, supplier y transaction_item
    • softDeleteTransaction: borrado lógico (is_deleted = TRUE)
    • getActiveTransactionsByItemAndSupplier: para decidir si desvincular proveedor al eliminar
  • Modelo Transaction (backend/src/models/Transaction.js): CRUD de transacciones financieras y getSummary para el balance de ingresos/egresos.

  • Servicio inventory.service.js: Toda la lógica de negocio del flujo compra/venta:

    • createPurchase: crea o actualiza artículos, asigna proveedores, ajusta stock
    • createSale: valida stock, crea transacción, descuenta inventario
    • updatePurchase / updateSale: ajuste diferencial de stock (diferencia entre cantidad nueva y anterior)
    • deletePurchase / deleteSale: rollback de stock y desvinculación de proveedores
  • Controllers (inventory.controller.js, item.controller.js, transaction.controller.js): Manejo de peticiones HTTP, validación con Joi, y respuestas con códigos de estado apropiados.

  • Validaciones (item.validation.js, transaction.validation.js): Schemas Joi para crear y actualizar artículos y transacciones.

  • Rutas (inventory.routes.js, item.routes.js, transaction.routes.js): Definición de endpoints con middleware de autenticación y autorización.

Endpoints implementados:

MétodoRutaDescripción
GET/api/itemsListar artículos
POST/api/itemsCrear artículo
GET/api/items/:idObtener artículo por ID
PUT/api/items/:idActualizar artículo
DELETE/api/items/:idEliminar artículo (soft delete)
GET/api/inventory/purchasesListar compras
POST/api/inventory/purchaseRegistrar compra
PUT/api/inventory/purchase/:id_transactionActualizar compra
DELETE/api/inventory/purchase/:idEliminar compra
GET/api/inventory/salesListar ventas
POST/api/inventory/saleRegistrar venta
PUT/api/inventory/sale/:id_transactionActualizar venta
DELETE/api/inventory/sale/:idEliminar venta

Frontend

  • Página inventory.jsx: Layout de 3 pestañas (Productos / Compras / Ventas) con navegación por tabs.

  • InventoryTable.jsx: Tabla interactiva con búsqueda, filtros por categoría y proveedor, ordenamiento por columnas, menú contextual, y diálogos modales para crear, editar, detallar y eliminar.

  • PurchasesTable.jsx / SalesTable.jsx: Tablas de historial de transacciones con formato de moneda, fechas localizadas, y exportación.

  • Diálogos: AddItemDialog, EditItemDialog, ItemDetailsDialog, SellItemDialog, AddPurchaseDialog, EditPurchaseDialog, EditSaleDialog, PurchaseDetailsDialog, SaleDetailsDialog, NewPurchaseForm, ExistingPurchaseForm.

  • ExportButtons.jsx: Exportación de inventario, compras y ventas a Excel y PDF usando xlsx y jspdf-autotable.

  • API layer (src/api/inventory.js): Funciones axios para consumir cada endpoint del backend.

  • Validaciones frontend (src/validations/): Schemas Yup para newItem, modifyItem, newPurchase, modifyPurchase, newSale, modifySale.


Aprendizajes y desafíos

Sincronización de stock en tiempo real

El mayor desafío fue garantizar la consistencia del inventario ante compras, ventas, ediciones y eliminaciones. Lo resolví con ajustes atómicos de stock (stock = stock +/- cantidad) en SQL, lo que evita condiciones de carrera. Al editar una transacción, el servicio calcula la diferencia entre la cantidad nueva y la anterior y ajusta solo el delta. La eliminación revierte por completo el efecto sobre el inventario.

Asociación artículo-proveedor con precios de compra

Un mismo artículo puede comprarse a distintos proveedores a diferentes precios. Implementé una tabla intermedia item_supplier que registra cada relación con su purchase_price y purchase_date. Al eliminar una compra, el sistema verifica si el proveedor tiene otras transacciones activas con ese artículo antes de desvincularlo, evitando perder el historial.

Soft delete con integridad referencial

Todas las eliminaciones son lógicas (is_deleted = TRUE) para preservar el historial. Las queries incluyen siempre el filtro WHERE is_deleted = FALSE, y las eliminaciones en cascada lógica requieren verificación manual en el servicio antes de proceder.

Validación y formato de RUT chileno

Implementé el algoritmo de validación de RUT chileno (dígito verificador módulo 11) tanto en backend como en frontend; identifica de manera única a usuarios y proveedores.


Referencias

  • Next.js: Framework React con Pages Router y SSR.
  • Express.js: Framework minimalista para APIs REST en Node.js.
  • PostgreSQL: Sistema de gestión de bases de datos relacional.
  • Tailwind CSS: Framework de utilidades CSS con variables y tema oscuro.
  • Shadcn/ui: Componentes React reutilizables con Radix UI y Tailwind.
  • JWT: Estándar de tokens de autenticación Bearer.
  • PM2: Administrador de procesos para Node.js en producción.
  • Cloudinary: Almacenamiento y gestión de imágenes en la nube.

Proyecto desarrollado en conjunto con Rocío Rivas, Álvaro Loyola y Anaís Saldías.