Guía de referencia rápida para agentes AI. Describe tecnologías, estructura, componentes reutilizables y consumos de API del sistema de gestión de inventario Nurax.
Sistema de gestión de inventario, ventas y proveedores para pequeños y medianos negocios.
Frontend SPA en Vue 3 + TypeScript + Vite. Backend en Django REST Framework.
⚙️ Stack Tecnológico
Capa
Tecnología
Framework
Vue 3 (Composition API, <script setup>)
Lenguaje
TypeScript
Build
Vite
Estilos
CSS Scoped + TailwindCSS v4 (tokens en style.css)
Estado
Pinia
Routing
Vue Router 4
HTTP
Fetch nativo vía ApiClient ()
Related Skills
services/api.ts
Auth
JWT (HttpOnly + Secure Cookies recomendado) — ⚠️ Actualmente en localStorage (vulnerable)
Imágenes
Cloudinary (URLs almacenadas en backend)
Animaciones
AOS (solo en Login y LandingPage)
Icons
Heroicons (@heroicons/vue/24/outline)
Excel
SheetJS (xlsx)
🎨 Diseño & Paleta
NO usar colores ad-hoc. Siempre usar los tokens del tema:
src/
│
├── App.vue # Raíz: RouterView + LoadingScreen + SnackbarContainer
├── main.ts # Bootstrap Vue + Pinia + Router
├── style.css # Design tokens globales (paleta, fuente, scrollbar)
│
├── views/ # Una vista por ruta del router
│ ├── LandingPage.vue # Página pública de promoción del producto (ruta: /)
│ ├── Login.vue # Autenticación con AOS (ruta: /auth/login)
│ ├── Inventory.vue # Panel de inventario principal (ruta: /dashboard/inventory)
│ ├── SalesHistory.vue # Historial de ventas + gráfica (ruta: /dashboard/sales)
│ ├── Suppliers.vue # CRUD de proveedores (ruta: /dashboard/suppliers)
│ ├── AdminClients.vue # Gestión de usuarios — solo admin (ruta: /dashboard/clients)
│ └── Settings.vue # Config de tienda — solo cliente (ruta: /dashboard/settings)
│
├── components/
│ ├── common/ # Componentes globales (usados en App.vue)
│ │ ├── LoadingScreen.vue # Pantalla de carga post-login
│ │ ├── Snackbar.vue # Toast individual
│ │ └── SnackbarContainer.vue # Cola de toasts
│ │
│ ├── layout/ # Shell del dashboard
│ │ ├── DashboardLayout.vue # Layout principal: sidebar + topbar + modales globales
│ │ └── Sidebar.vue # Menú lateral con navegación por roles
│ │
│ ├── dashboard/ # Componentes de panel de datos
│ │ ├── ProductTable.vue # Tabla de productos con filtros, paginación y acciones
│ │ └── StatsCard.vue # Tarjeta de estadística (ícono + valor + tendencia)
│ │
│ ├── ui/ # Design system base — SIEMPRE usar estos en lugar de HTML nativo
│ │ ├── AppButton.vue # Botón: variantes fill / outline, loading state
│ │ ├── AppInput.vue # Input: label, ícono, toggle password, error/hint
│ │ └── ConfirmationModal.vue # Modal genérico de confirmación (¿Eliminar?)
│ │
│ └── (raíz de components/) # Modales de negocio específicos
│ ├── AddProductModal.vue # Formulario alta de producto
│ ├── EditProductModal.vue # Formulario edición de producto
│ ├── AddSupplierModal.vue # Formulario alta de proveedor
│ ├── DeleteConfirmModal.vue # Confirmación de borrado
│ ├── SalesModal.vue # POS: venta rápida
│ ├── SaleSuccessModal.vue # Recibo de venta exitosa
│ ├── BarcodeScanner.vue # Escáner de código de barras (cámara)
│ ├── InventoryReceiptModal.vue # Recibo de recepción de inventario
│ ├── NotificationPanel.vue # Panel flotante de alertas de stock
│ └── ProductDetail.vue # Detalle de producto
│
├── composables/ # Lógica reactiva compartida (Vue hooks)
│ ├── useAuth.ts # ⭐ Auth principal: login, logout, initSession, currentUser
│ ├── useSnackbar.ts # Cola global de notificaciones → enqueueSnackbar()
│ ├── useLoadingScreen.ts # Control de LoadingScreen post-login
│ ├── useStoreSettings.ts # Configuración de tienda desde API (singleton)
│ └── useSuppliers.ts # CRUD de proveedores desde API
│
├── services/ # Capa HTTP — solo llaman a la API, no tienen estado
│ ├── api.ts # ⭐ ApiClient: fetch + JWT inject + refresh token interceptor
│ └── auth.service.ts # login(), fetchUser(), updateAvatar(), logout()
│
├── stores/ # Estado global Pinia
│ ├── product.store.ts # ⭐ Productos: fetch, add, update, delete, stock, computed
│ └── sales.store.ts # ⭐ Ventas: fetch, add, cancelSale, weeklyData, modal state
│
├── router/
│ └── index.ts # Rutas + guard de autenticación y roles
│
├── utils/
│ └── (formatters, helpers) # Funciones puras sin estado
│
└── assets/ # Recursos estáticos procesados por Vite
🛣️ Rutas y Roles
Ruta
Vista
Acceso
/
LandingPage.vue
Público
/auth/login
Login.vue
Público
/dashboard/inventory
Inventory.vue
Rol: cliente
/dashboard/sales
SalesHistory.vue
Rol: cliente
/dashboard/suppliers
Suppliers.vue
Rol: cliente
/dashboard/clients
AdminClients.vue
Rol: admin
/dashboard/settings
Settings.vue
Rol: cliente
El guard hace await initSession() (singleton) antes de evaluar la sesión.
Admin → redirige a /dashboard/clients. Cliente → redirige a /dashboard/inventory.
🌐 Endpoints de API
Base URL:http://localhost:8000 API Prefix:/api/v1/ (actualizado 30-Mar-2026)
⚠️ CRÍTICO: Todos los endpoints usan /api/v1/{domain}/ desde 30 de Marzo 2026. Ver BACKEND_TROUBLESHOOTING.md para detalles.
Todas las vistas del dashboard se renderizan dentro de este layout vía <slot />.
Incluye: sidebar, topbar (búsqueda, perfil, notificaciones), modales de perfil y Excel.
No importar manualmente — el router lo resuelve.
<ConfirmationModal
v-if="showConfirm"
title="¿Eliminar producto?"
message="Esta acción no se puede deshacer."
@confirm="handleDelete"
@cancel="showConfirm = false"
/>
🚫 Reglas Importantes para Agentes
No crear nuevos stores sin revisar si product.store.ts o sales.store.ts ya cubren la necesidad.
No duplicar lógica de auth — toda la autenticación pasa por useAuth.ts.
No hacer fetch directo — siempre usar apiClient de services/api.ts.
No usar colores hardcodeados — siempre usar variables CSS del tema.
No crear botones o inputs con HTML nativo — usar AppButton y AppInput.
No crear archivos en layouts/ — esa carpeta fue eliminada. Los layouts viven en components/layout/.
No crear vistas tipo "placeholder" — si una vista no tiene contenido real, no existe.
El rol admin solo ve /dashboard/clients — no tiene acceso a inventario, ventas ni proveedores.
El rol cliente no ve /dashboard/clients — el router lo bloquea y redirige.
Imágenes de productos → se suben como FormData con campo image_file → backend maneja Cloudinary.
🧭 Wizard de Inicio (v2)
Objetivo: recolectar datos en 4 pasos sin escribir en BD hasta el final.
Pasos UI:
Identidad de tienda: nombre, identificador_fiscal (opcional)
Nicho de negocio: ELECTRONICA | ABARROTES | FARMACIA | FERRETERIA
Proveedor principal: nombre, telefono (opcional, puede saltarse)