Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/JFKoryy/autopart-pro/llms.txt

Use this file to discover all available pages before exploring further.

AutoPart Pro is built as two completely independent processes that communicate over HTTP: a Node.js/Express REST API on the backend and a React single-page application on the frontend. The backend owns all business logic, data persistence, and security enforcement; the frontend is a pure UI consumer that calls the API and renders role-appropriate views. There is no server-side rendering — the SPA is served as static assets by Vite during development (and can be served by any static host in production), while the API server handles every authenticated and unauthenticated data request.

Stack at a Glance

Backend

Node.js 18+ runtime with Express 5 for routing and middleware. Data is persisted in MySQL 8 and accessed through a mysql2 promise-based connection pool. Passwords are hashed with bcryptjs (salt rounds: 10) and sessions are stateless — every authenticated request carries a JWT signed via jsonwebtoken.

Frontend

React 19 component tree bundled by Vite 6. Styling is handled by Tailwind CSS 4 utility classes. Client-side navigation is managed by React Router v7, and all icons come from lucide-react. Global state lives in two React contexts: AuthContext and CartContext.

Backend: MVC Pattern

The backend follows a strict Model-View-Controller separation where “view” is replaced by JSON responses. Every inbound HTTP request passes through the global middleware stack first, then protect and authorize are applied selectively per route.
HTTP Request


CORS (origin whitelist)           ← global, app.js


express.json() (body parsing)     ← global, app.js


Router (route matching)

    ├── Public routes (no auth)
    │     e.g. POST /api/auth/login, GET /api/products

    └── Protected routes


        protect (JWT verification)  ──► 401 if token missing/invalid


        authorize (role check)      ──► 403 if role not permitted


        Controller (business logic)


        Model (SQL queries via mysql2)


        MySQL 8 Database

Route Groups

All API routes are mounted under the /api prefix. The four route groups are:
PrefixDescription
POST /api/auth/registerPublic — register a new client account
POST /api/auth/loginPublic — exchange credentials for a JWT
GET /api/auth/meProtected — re-validate a stored token
GET /api/auth/profileProtected — fetch the authenticated user’s profile
/api/productsProduct inventory — read is public, writes require admin
/api/salesSales records — requires authentication
/api/usersUser management — requires admin role

Health Check

A lightweight endpoint lets load balancers and monitoring tools verify the server is running without touching the database:
GET /api/health
{
  "status": "ON",
  "message": "Servidor de AutoPart Pro funcionando correctamente",
  "timestamp": "2025-01-15T10:30:00.000Z"
}

Low-Stock Event Emitter

When a product’s stock falls to or below its min_stock threshold after a sale, the backend emits a low-stock event on a Node.js EventEmitter instance (stockEmitter). The listener in app.js logs a console alert:
// backend/src/app.js
stockEmitter.on('low-stock', (product) => {
    console.log(`⚠️ Alerta de stock bajo: "${product.name}" (SKU: ${product.sku}) tiene stock de ${product.stock}.`);
});
The low-stock emitter is a backend-only, in-process notification. It logs to stdout and does not send push notifications, emails, or websocket messages in the current implementation.

CORS Configuration

The backend explicitly allows cross-origin requests from two origins — the local development server and a LAN IP used during development:
// backend/src/app.js
app.use(cors({
    origin: [
        'http://localhost:5173',
        'http://192.168.1.165:5173'
    ],
    methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
    allowedHeaders: ['Content-Type', 'Authorization']
}));

Database Connection Pool

The mysql2 pool is initialised once at startup with a connection limit of 10. All queries go through promisePool so controllers can use async/await directly:
// backend/src/config/db.js
const pool = mysql.createPool({
    host: process.env.DB_HOST,
    user: process.env.DB_USER,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_NAME,
    port: process.env.DB_PORT || 3306,
    waitForConnections: true,
    connectionLimit: 10,
    queueLimit: 0
});

const promisePool = pool.promise();
module.exports = promisePool;

Frontend: React SPA

The frontend is a client-side rendered SPA. After the initial HTML+JS bundle is loaded, all navigation is handled in-browser by React Router — no full page reloads occur.

Context Providers

Two React contexts wrap the entire application in App.jsx:
  • AuthContext — holds the authenticated user object (decoded from the JWT), exposes signIn, signUp, signOut helpers, and a can permission map derived from user.role.
  • CartContext — manages the shopping cart state (items, addItem, updateQty, removeItem, clearCart). Cart contents are persisted to localStorage between page refreshes.

Route Structure

React Router v7 defines two layout groups plus public routes:
PathLayoutAccess
/login, /registroNone (public)Anyone
/catalogo, /producto/:id, /carrito, /checkoutShopLayoutAnyone
/admin, /admin/inventario, /admin/ventasAdminLayoutadmin or employee
/admin/producto/nuevo, /admin/producto/:idAdminLayoutadmin only
/admin/usuariosAdminLayoutadmin only

API Service Layer

All backend communication is centralised in frontend/src/services/api.js. Authenticated requests include a Bearer token via getAuthHeader():
// frontend/src/services/api.js
function getAuthHeader() {
  const token = localStorage.getItem('token')
  return {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${token}`
  }
}

Directory Structure

autopart-pro/
├── backend/
│   ├── database.sql                  # Schema and migration statements
│   ├── package.json
│   └── src/
│       ├── app.js                    # Express entry point, CORS, route mounting
│       ├── config/
│       │   └── db.js                 # mysql2 connection pool
│       ├── controllers/
│       │   ├── authController.js
│       │   ├── productController.js
│       │   ├── saleController.js
│       │   └── userController.js
│       ├── events/
│       │   └── stockEmitter.js       # Node.js EventEmitter for low-stock alerts
│       ├── middleware/
│       │   ├── authMiddleware.js     # JWT verification (protect)
│       │   ├── productMiddleware.js  # Input validation + SKU normalisation
│       │   └── roleMiddleware.js     # Role-based access control (authorize)
│       ├── models/
│       │   ├── productModel.js
│       │   ├── saleModel.js
│       │   └── userModel.js
│       └── routes/
│           ├── authRoutes.js
│           ├── productRoutes.js
│           ├── saleRoutes.js
│           └── userRoutes.js

└── frontend/
    ├── index.html
    ├── package.json
    └── src/
        ├── App.jsx                   # Router tree, context providers
        ├── main.jsx
        ├── components/
        │   ├── AdminLayout.jsx
        │   ├── Modal.jsx
        │   ├── Navbar.jsx
        │   ├── ProductCard.jsx
        │   ├── ProtectedRoute.jsx
        │   └── ShopLayout.jsx
        ├── context/
        │   ├── AuthContext.jsx       # Auth state, token management
        │   └── CartContext.jsx       # Shopping cart state
        ├── pages/
        │   ├── Catalog.jsx
        │   ├── Cart.jsx
        │   ├── Checkout.jsx
        │   ├── Dashboard.jsx
        │   ├── Inventory.jsx
        │   ├── Login.jsx
        │   ├── ProductDetail.jsx
        │   ├── ProductForm.jsx
        │   ├── Register.jsx
        │   ├── SalesHistory.jsx
        │   └── Users.jsx
        ├── services/
        │   ├── api.js                # All fetch calls to the backend
        │   └── mockData.js           # Static mock data for development
        └── utils/
            └── formatters.js         # Shared formatting helpers

Build docs developers (and LLMs) love