bikefy
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.
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ódulo | Funcionalidades |
|---|---|
| Inventario | CRUD de artículos, stock automático, categorías, precios de compra/venta, exportación Excel/PDF |
| Compras y Ventas | Registro de transacciones vinculadas a proveedores, ajuste automático de stock, trazabilidad completa |
| Finanzas | Balance general, gráficos de ingresos/egresos, historial de transacciones |
| Servicios | Registro de reparaciones, precios, métodos de pago, estado del servicio |
| Proveedores | CRUD con datos de contacto, historial de compras asociadas |
| Tareas | Tablero Kanban con columnas y tarjetas arrastrables |
| Usuarios | Roles admin/empleado, autenticación JWT, recuperación de contraseña vía email |
Stack tecnológico
| Capa | Tecnología | Propósito |
|---|---|---|
| Frontend | Next.js 15 (Pages Router) | Framework React con SSR |
| Tailwind CSS + CSS Variables | Estilos utilitarios con tema claro/oscuro | |
| Shadcn/ui (New York) + Radix UI + MUI | Componentes de interfaz accesibles | |
| Formik + Yup | Manejo de formularios y validación | |
| Chart.js + react-chartjs-2 | Gráficos de finanzas | |
| Axios | Cliente HTTP para consumo de API | |
| Backend | Express.js 4 | API REST |
| express-validator + Joi | Validación de datos de entrada | |
| jsonwebtoken | Autenticación con JWT Bearer | |
| bcrypt | Hashing de contraseñas | |
| Cloudinary | Almacenamiento de imágenes de perfil | |
| Nodemailer | Envío de correos (recuperación de contraseña) | |
| Base de datos | PostgreSQL 16 | Base relacional |
| pg (Client) | Driver de conexión | |
| Deploy | Vercel (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, ordenamientoAddItemDialog/EditItemDialog: formularios con validación YupItemDetailsDialog: vista detallada con proveedores asociadosExportButtons: 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 conARRAY_AGG, y operaciónupdateStockcon modoadd/subtractpara 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 detalleupdateSupplier: upsert de la relación artículo-proveedor con precio de compravalidateStock: verificación de stock antes de vendergetPurchases/getSales: queries con JOINs aitem,supplierytransaction_itemsoftDeleteTransaction: 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 ygetSummarypara 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 stockcreateSale: valida stock, crea transacción, descuenta inventarioupdatePurchase/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étodo | Ruta | Descripción |
|---|---|---|
GET | /api/items | Listar artículos |
POST | /api/items | Crear artículo |
GET | /api/items/:id | Obtener artículo por ID |
PUT | /api/items/:id | Actualizar artículo |
DELETE | /api/items/:id | Eliminar artículo (soft delete) |
GET | /api/inventory/purchases | Listar compras |
POST | /api/inventory/purchase | Registrar compra |
PUT | /api/inventory/purchase/:id_transaction | Actualizar compra |
DELETE | /api/inventory/purchase/:id | Eliminar compra |
GET | /api/inventory/sales | Listar ventas |
POST | /api/inventory/sale | Registrar venta |
PUT | /api/inventory/sale/:id_transaction | Actualizar venta |
DELETE | /api/inventory/sale/:id | Eliminar 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 usandoxlsxyjspdf-autotable. -
API layer (
src/api/inventory.js): Funciones axios para consumir cada endpoint del backend. -
Validaciones frontend (
src/validations/): Schemas Yup paranewItem,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.