docs: add README, API reference, and architecture documentation

- README.md: project overview, features, quick start, API overview
- docs/API.md: full endpoint reference with examples
- docs/ARCHITECTURE.md: system diagram, DB schema, data pipeline, auth flow

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-18 22:30:53 +00:00
parent d269bc1ffb
commit fb6ea31100
3 changed files with 1992 additions and 468 deletions

432
README.md
View File

@@ -1,333 +1,205 @@
# Nexus Autoparts # Nexus Autoparts
Sistema completo de gestión de base de datos de vehículos y nexus-autoparts con dashboard web, herramientas de web scraping y múltiples interfaces de consulta. **Sistema de catalogo de autopartes con navegacion jerarquica, similar a 7zap.com/RockAuto.**
## Descripción Plataforma SaaS que conecta talleres con bodegas/distribuidores. Permite buscar partes OEM y aftermarket por vehiculo (marca, modelo, ano, motor), gestionar inventario de bodegas, y consultar disponibilidad y precios en tiempo real.
**Nexus Autoparts** es una solución integral para la gestión de información de vehículos que incluye: ## Tech Stack
- Base de datos SQLite normalizada con información de marcas, modelos, motores y años | Componente | Tecnologia |
- Dashboard web moderno y responsivo para consultar y explorar datos |------------|-----------|
- Herramientas de web scraping para recopilar datos de RockAuto.com | Backend | Python 3, Flask |
- Interfaces de línea de comandos (CLI) y programática | Base de datos | PostgreSQL |
- Scripts de utilidad para gestión y mantenimiento de datos | ORM / SQL | SQLAlchemy (`text()` raw SQL) |
| Autenticacion | JWT (PyJWT) + bcrypt |
| Data import | TecDoc via Apify, NHTSA VIN API |
| Frontend | HTML/CSS/JS vanilla (sin framework) |
| Dependencias extra | openpyxl (Excel), csv (CSV import) |
## Estadísticas de la Base de Datos ## Estadisticas de la Base de Datos
| Elemento | Cantidad | - **1.4M+** partes OEM
|----------|----------| - **300K+** partes aftermarket
| Marcas | 12 | - **13M+** cross-references (numeros alternos, supersesiones, intercambios)
| Modelos | 10,923 | - **12B+** vehicle-part links (fitment)
| Motores | 10,919 | - **100+** marcas, miles de modelos, anos 1956-2026
| Combinaciones modelo-año-motor | 12,075 |
## Tecnologías Utilizadas ## Features
### Backend - **Catalogo de autopartes** con navegacion jerarquica: Marca > Modelo > Ano > Motor > Categoria > Grupo > Parte
- **Python 3** - Lenguaje principal - **TecDoc integration** (via Apify) para importar datos OEM y aftermarket de Europa/Mexico
- **SQLite 3** - Base de datos - **SaaS multi-tenant** con roles: `ADMIN`, `OWNER`, `TALLER`, `BODEGA`
- **Flask 2.3.3** - Framework web - **JWT authentication** con access tokens (15 min) y refresh tokens (30 dias)
- **BeautifulSoup4** - Web scraping - **Gestion de inventario** para bodegas con mapeo flexible de columnas CSV/Excel
- **requests** - HTTP client - **Disponibilidad de partes** en multiples bodegas con precios comparativos
- **lxml** - Parser XML/HTML - **Alternativas aftermarket** con cross-references por cada parte OEM
- **Panel de administracion** con gestion de usuarios, import/export CSV, CRUD de categorias/grupos/partes/fabricantes/fitment
- **Busqueda full-text** en el catalogo de partes (PostgreSQL `tsvector`)
- **Busqueda combinada** vehiculo + parte (e.g., "Toyota Corolla 2020 frenos")
- **VIN decoder** via NHTSA API con cache en base de datos
- **Diagramas explosionados** con hotspots clickeables
- **Vehicle-to-part linking** (12B+ vehicle_parts links)
### Frontend ## Quick Start
- **HTML5** - Estructura
- **Bootstrap 5.3.0** - Framework CSS
- **JavaScript (ES6+)** - Lógica cliente
- **Font Awesome 6.0.0** - Iconos
## Estructura del Proyecto ### Requisitos previos
``` - Python 3.8+
Autopartes/ - PostgreSQL con la base `nexus_autoparts`
├── vehicle_database/ # Sistema principal de base de datos
│ ├── sql/
│ │ └── schema.sql # Esquema de la base de datos
│ ├── scripts/
│ │ ├── database_manager.py # Gestión de la BD
│ │ ├── query_interface.py # Interfaz CLI
│ │ └── csv_importer.py # Importador CSV
│ ├── data/
│ │ ├── brands.csv # Datos de marcas
│ │ ├── engines.csv # Datos de motores
│ │ └── models.csv # Datos de modelos
│ ├── vehicle_database.db # Base de datos SQLite
│ └── setup.sh # Script de inicialización
├── dashboard/ # Interfaz web
│ ├── server.py # Backend Flask
│ ├── index.html # Frontend HTML
│ ├── dashboard.js # Lógica JavaScript
│ └── start_dashboard.sh # Script de inicio
├── console/ # Consola Pick/VT220
│ ├── main.py # Punto de entrada
│ ├── db.py # Capa de datos abstracta
│ ├── core/ # Framework (app, screens, nav, keys)
│ ├── screens/ # 14 pantallas (menú, CRUD, búsqueda)
│ ├── renderers/ # Renderer VT220 (curses)
│ ├── utils/ # Formato y API VIN
│ └── tests/ # 116 tests
├── vehicle_scraper/ # Herramientas de web scraping
│ ├── rockauto_scraper.py # Scraper RockAuto
│ ├── rockauto_scraper_v2.py # Scraper mejorado
│ ├── scrape_toyota.py # Scraper Toyota
│ ├── scrape_nissan_ford_chevrolet.py
│ └── manual_input.py # Ingreso manual
├── add_*.py # Scripts para agregar datos
├── remove_*.py # Scripts de limpieza
└── QUICK_START.sh # Guía rápida de inicio
```
## Consola Pick/VT220 ### Instalacion
Interfaz de terminal inspirada en los sistemas Pick/D3, 100% operada con teclado. Estética verde sobre negro con caracteres de caja, sin dependencias externas.
```bash ```bash
python -m console cd /home/Autopartes
pip install -r requirements.txt
``` ```
Funcionalidades: navegación por vehículo (marca→modelo→año→motor), búsqueda por número de parte, búsqueda full-text, decodificador VIN (NHTSA), catálogo por categorías, comparador OEM vs aftermarket, y administración CRUD completa. ### Ejecutar el servidor
116 tests automatizados. Ver [`console/README.md`](console/README.md) para documentación completa.
## Instalación
### Requisitos Previos
- Python 3.8 o superior
- pip (gestor de paquetes de Python)
### Pasos de Instalación
1. **Clonar el repositorio**
```bash
git clone https://git.consultoria-as.com/[usuario]/Nexus-Autoparts.git
cd Nexus-Autoparts
```
2. **Instalar dependencias**
```bash
pip install flask requests beautifulsoup4 lxml
```
3. **Inicializar la base de datos (opcional - ya incluye datos)**
```bash
cd vehicle_database
./setup.sh
```
## Uso
### Iniciar el Dashboard Web
```bash ```bash
cd dashboard cd /home/Autopartes/dashboard
python3 server.py python3 server.py
``` ```
El dashboard estará disponible en: `http://localhost:5000` El servidor arranca en `http://localhost:5000`.
### Iniciar la Consola Pick/VT220 ### Importar datos de TecDoc
```bash ```bash
python -m console # Fase 1: descargar datos de TecDoc a JSON
python3 scripts/import_tecdoc.py download
# Fase 2: importar JSON a PostgreSQL
python3 scripts/import_tecdoc.py import
# Ver progreso
python3 scripts/import_tecdoc.py status
``` ```
### Usar la Interfaz CLI Legacy ### Importar partes y linkar vehiculos
```bash ```bash
cd vehicle_database/scripts # Importar partes TecDoc (OEM + aftermarket)
python3 query_interface.py python3 scripts/import_tecdoc_parts.py
# Importar datos en vivo desde TecDoc API
python3 scripts/import_live.py
# Crear links vehiculo-parte (fitment masivo)
python3 scripts/link_vehicle_parts.py
# Migrar datos aftermarket
python3 scripts/migrate_aftermarket.py
# Aplicar schema SaaS (roles, users, inventory tables)
python3 scripts/migrate_saas_schema.py
``` ```
### Ejecutar Web Scraping ## Paginas del Dashboard
```bash | Ruta | Archivo | Descripcion |
cd vehicle_scraper |------|---------|-------------|
python3 rockauto_scraper_v2.py | `/login.html` | `login.html` | Login con JWT |
``` | `/demo.html` | `demo.html` | Catalogo publico / demo |
| `/admin` | `admin.html` | Panel de administracion (ADMIN/OWNER) |
| `/bodega.html` | `bodega.html` | Gestion de inventario para bodegas |
| `/tienda.html` | `tienda.html` | Vista de tienda/catalogo para talleres |
| `/pos.html` | `pos.html` | Punto de venta |
| `/captura.html` | `captura.html` | Captura de partes |
| `/cuentas.html` | `cuentas.html` | Gestion de cuentas |
### Agregar Datos Manualmente ## API Overview
```bash Documentacion completa en [`docs/API.md`](docs/API.md).
cd vehicle_scraper
python3 manual_input.py
```
## API REST ### Auth (`/api/auth/`)
- `POST /api/auth/register` - Registrar usuario (TALLER/BODEGA)
- `POST /api/auth/login` - Login, retorna access + refresh tokens
- `POST /api/auth/refresh` - Renovar access token
- `GET /api/auth/me` - Info del usuario autenticado
El dashboard expone los siguientes endpoints: ### Catalogo (`/api/`)
- `GET /api/brands` - Listar marcas
- `GET /api/models?brand=X` - Modelos por marca
- `GET /api/years?brand=X&model=Y` - Anos disponibles
- `GET /api/engines?brand=X&model=Y&year=Z` - Motores disponibles
- `GET /api/categories` - Categorias de partes (arbol jerarquico)
- `GET /api/parts?group_id=X` - Partes por grupo
- `GET /api/parts/{id}/alternatives` - Alternativas aftermarket
- `GET /api/parts/{id}/cross-references` - Cross-references
- `GET /api/search?q=...` - Busqueda combinada (vehiculos + partes + aftermarket)
| Endpoint | Método | Descripción | ### Inventario (`/api/inventory/`)
|----------|--------|-------------| - `GET/PUT /api/inventory/mapping` - Mapeo de columnas CSV
| `/api/brands` | GET | Obtiene todas las marcas | - `POST /api/inventory/upload` - Subir CSV/Excel de inventario
| `/api/models?brand=X` | GET | Obtiene modelos por marca | - `GET /api/inventory/items` - Listar inventario propio
| `/api/years` | GET | Obtiene años disponibles | - `DELETE /api/inventory/items` - Limpiar inventario
| `/api/engines` | GET | Obtiene motores disponibles |
| `/api/vehicles` | GET | Búsqueda con filtros |
### Ejemplo de Uso ### Disponibilidad y Aftermarket
- `GET /api/parts/{id}/availability` - Bodegas con stock (auth: TALLER/ADMIN/OWNER)
- `GET /api/parts/{id}/aftermarket` - Alternativas aftermarket + cross-refs (publico)
```bash ### Admin (`/api/admin/`)
# Obtener todas las marcas - `GET /api/admin/users` - Listar usuarios (auth: ADMIN/OWNER)
curl http://localhost:5000/api/brands - `PUT /api/admin/users/{id}/activate` - Activar/desactivar usuario
- `GET /api/admin/stats` - Estadisticas del catalogo
- CRUD completo: categories, groups, parts, manufacturers, aftermarket, crossref, fitment
- Import/Export CSV: `POST /api/admin/import/{type}`, `GET /api/admin/export/{type}`
# Buscar vehículos por marca y año ### VIN Decoder
curl "http://localhost:5000/api/vehicles?brand=Toyota&year=2020" - `GET /api/vin/decode/{vin}` - Decodificar VIN via NHTSA API
``` - `GET /api/vin/{vin}/parts` - Partes para un VIN decodificado
- `GET /api/vin/{vin}/match?mye_id=X` - Vincular VIN manualmente a vehiculo
## Esquema de Base de Datos ## Scripts
### Tablas | Script | Funcion |
|--------|---------|
| `import_tecdoc.py` | Descarga datos de TecDoc API (vehiculos, modelos, marcas) a JSON |
| `import_tecdoc_parts.py` | Importa partes OEM y aftermarket desde TecDoc |
| `import_live.py` | Importacion en vivo desde TecDoc API |
| `link_vehicle_parts.py` | Genera links vehiculo-parte (fitment masivo) |
| `migrate_aftermarket.py` | Migra datos aftermarket a la estructura normalizada |
| `migrate_saas_schema.py` | Crea tablas SaaS: sessions, warehouse_inventory, roles, etc. |
| `import_phase1.py` | Importacion inicial fase 1 |
| `run_all_brands.sh` | Script auxiliar para importar todas las marcas |
#### brands ## Configuracion
| Campo | Tipo | Descripción |
|-------|------|-------------|
| id | INTEGER | Clave primaria |
| name | TEXT | Nombre de la marca |
| country | TEXT | País de origen |
| founded_year | INTEGER | Año de fundación |
#### models Archivo principal: [`config.py`](config.py)
| Campo | Tipo | Descripción |
|-------|------|-------------|
| id | INTEGER | Clave primaria |
| brand_id | INTEGER | FK a brands |
| name | TEXT | Nombre del modelo |
| body_type | TEXT | Tipo de carrocería |
| generation | TEXT | Generación |
| production_start_year | INTEGER | Año inicio producción |
| production_end_year | INTEGER | Año fin producción |
#### engines | Variable | Default | Descripcion |
| Campo | Tipo | Descripción | |----------|---------|-------------|
|-------|------|-------------| | `DATABASE_URL` | `postgresql://nexus:...@localhost/nexus_autoparts` | PostgreSQL connection string |
| id | INTEGER | Clave primaria | | `JWT_SECRET` | `nexus-saas-secret-change-in-prod-2026` | Secreto para firmar tokens JWT |
| name | TEXT | Nombre del motor | | `JWT_ACCESS_EXPIRES` | `900` (15 min) | Duracion del access token en segundos |
| displacement_cc | INTEGER | Cilindrada en cc | | `JWT_REFRESH_EXPIRES` | `2592000` (30 dias) | Duracion del refresh token en segundos |
| cylinders | INTEGER | Número de cilindros |
| fuel_type | TEXT | Tipo de combustible |
| power_hp | INTEGER | Potencia en HP |
| torque_nm | INTEGER | Torque en Nm |
| engine_code | TEXT | Código del motor |
#### years ## Arquitectura
| Campo | Tipo | Descripción |
|-------|------|-------------|
| id | INTEGER | Clave primaria |
| year | INTEGER | Año |
#### model_year_engine Documentacion detallada en [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md).
| Campo | Tipo | Descripción |
|-------|------|-------------|
| id | INTEGER | Clave primaria |
| model_id | INTEGER | FK a models |
| year_id | INTEGER | FK a years |
| engine_id | INTEGER | FK a engines |
| trim_level | TEXT | Nivel de equipamiento |
| drivetrain | TEXT | Tracción |
| transmission | TEXT | Transmisión |
### Diagrama de Relaciones
``` ```
brands ──┐ +------------------+
| TecDoc (Apify) |
├──< models ──┐ +--------+---------+
|
years ───┼─────────────┼──< model_year_engine download/import
|
engines ─┴─────────────┘ v
+----------+ +--------+---------+ +----------------+
| Frontend |<--->| Flask Server |<--->| PostgreSQL |
| (HTML/JS)| | (server.py) | | nexus_autoparts|
+----------+ +--------+---------+ +----------------+
|
JWT auth (PyJWT)
|
+------------+------------+
| | |
TALLER BODEGA ADMIN
(consulta) (inventario) (gestion)
``` ```
## Scripts Disponibles
### Scripts de Datos
| Script | Descripción |
|--------|-------------|
| `add_toyota_data.py` | Agrega datos de Toyota |
| `add_honda_data.py` | Agrega datos de Honda |
| `add_nissan_data.py` | Agrega datos de Nissan |
| `add_ford_data.py` | Agrega datos de Ford |
| `add_chevrolet_data.py` | Agrega datos de Chevrolet |
| `add_audi_data.py` | Agrega datos de Audi |
| `add_acura_data.py` | Agrega datos de Acura |
| ... | Y más marcas |
### Scripts de Mantenimiento
| Script | Descripción |
|--------|-------------|
| `remove_brands_and_cleanup.py` | Limpia marcas innecesarias |
| `check_and_remove_brands.py` | Verifica y elimina marcas |
## Funcionalidades del Dashboard
### Panel de Filtros
- Selección de marca
- Selección de modelo (dinámico según marca)
- Filtro por año
- Filtro por motor
### Panel de Resultados
- Visualización en tarjetas
- Información detallada del vehículo
- Especificaciones del motor
- Datos de transmisión y tracción
### Características
- Diseño responsivo
- Actualización en tiempo real
- Animaciones y transiciones suaves
- Soporte para múltiples idiomas
## Arquitectura del Sistema
```
┌─────────────────┐ ┌──────────────────┐
│ RockAuto.com │────>│ Web Scraper │
└─────────────────┘ └────────┬─────────┘
v
┌─────────────────┐ ┌──────────────────┐
│ Manual Input │────>│ SQLite Database │
└─────────────────┘ └────────┬─────────┘
┌───────────────────────┼───────────────────────┐
│ │ │
v v v
┌─────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Flask API │ │ Pick Console │ │ CSV Importer │
└────────┬────────┘ │ (VT220/Rich) │ └──────────────────┘
│ └──────────────────┘
v
┌─────────────────┐
│ Web Dashboard │
│ (Browser) │
└─────────────────┘
```
## Contribuir
1. Fork el repositorio
2. Crea una rama para tu feature (`git checkout -b feature/nueva-funcionalidad`)
3. Commit tus cambios (`git commit -am 'Agrega nueva funcionalidad'`)
4. Push a la rama (`git push origin feature/nueva-funcionalidad`)
5. Crea un Pull Request
## Licencia
Este proyecto es de uso interno.
## Contacto
Para más información, contactar al equipo de desarrollo.
--- ---
**Nexus Autoparts** - Sistema de Gestión de Base de Datos de Vehículos **Nexus Autoparts** - Tu conexion directa con las partes que necesitas

File diff suppressed because it is too large Load Diff

449
docs/ARCHITECTURE.md Normal file
View File

@@ -0,0 +1,449 @@
# Arquitectura - Nexus Autoparts
## Vista General del Sistema
```
+-------------------+ +-------------------+ +-------------------+
| | | | | |
| TecDoc (Apify) | | NHTSA VIN API | | CSV/Excel |
| Actor API | | vpic.nhtsa.gov | | (Bodega upload) |
| | | | | |
+--------+----------+ +--------+----------+ +--------+----------+
| | |
| download/import | decode | upload
| | |
v v v
+--------+---------------------------+---------------------------+----------+
| |
| Flask Server (server.py) |
| Puerto 5000 |
| |
| +-------------+ +-------------+ +-------------+ +-----------------+ |
| | Auth Module | | Catalog API | | Inventory | | Admin CRUD | |
| | (auth.py) | | (publico) | | (BODEGA) | | (import/export) | |
| | JWT + bcrypt | | | | CSV mapping | | | |
| +------+------+ +------+------+ +------+------+ +--------+--------+ |
| | | | | |
+---------+----------------+----------------+-------------------+-----------+
| | | |
v v v v
+-------------------------------------------------------------------------+
| |
| PostgreSQL (nexus_autoparts) |
| SQLAlchemy text() raw SQL |
| |
| +----------+ +----------+ +----------+ +----------+ +---------------+ |
| | brands | | models | | years | | engines | | fuel_type | |
| +----+-----+ +----+-----+ +----+-----+ +----+-----+ | drivetrain | |
| | | | | | transmission | |
| +------+------+------------+------------+ +---------------+ |
| | |
| v |
| +-----------------------+ |
| | model_year_engine | (MYE - tabla central de vehiculos) |
| | PK: id_mye | |
| | UNIQUE(model,year, | |
| | engine,trim_level) | |
| +----------+------------+ |
| | |
| | 1:N |
| v |
| +---------------------+ +---------------------+ |
| | vehicle_parts | | vehicle_diagrams | |
| | (12B+ rows) | | | |
| | mye_id + part_id | | mye_id + diagram_id | |
| +----------+----------+ +----------+----------+ |
| | | |
| v v |
| +---------------------+ +---------------------+ |
| | parts (1.4M+ OEM) | | diagrams | |
| | oem_part_number | | image_path | |
| | group_id -> groups | | group_id -> groups | |
| +---+------+----------+ +-----+---------------+ |
| | | | |
| | v v |
| | +--------------------+ +---------------------+ |
| | | part_groups | | diagram_hotspots | |
| | | category_id | | part_id, coords | |
| | +--------+-----------+ +---------------------+ |
| | | |
| | v |
| | +--------------------+ |
| | | part_categories | |
| | | (arbol jerarquico) | |
| | | parent_id -> self | |
| | +--------------------+ |
| | |
| +----------+-----------+ |
| | | |
| v v |
| +---------------------+ +------------------------+ |
| | aftermarket_parts | | part_cross_references | |
| | (300K+) | | (13M+) | |
| | oem_part_id -> parts| | part_id -> parts | |
| | manufacturer_id | | reference_type | |
| +----------+----------+ +------------------------+ |
| | |
| v |
| +---------------------+ |
| | manufacturers | |
| | type, quality_tier | |
| +---------------------+ |
| |
| === SaaS Tables === |
| |
| +----------+ +----------+ +---------------------+ +-------------+ |
| | users | | roles | | warehouse_inventory | | sessions | |
| | id_user | | ADMIN | | user_id + part_id | | refresh | |
| | id_rol | | OWNER | | price, stock | | token | |
| | email | | TALLER | | location | | expires_at | |
| | pass | | BODEGA | +---------------------+ +-------------+ |
| +----------+ +----------+ |
| +------------------------+ |
| | inventory_uploads | |
| | inventory_col_mappings | |
| +------------------------+ |
| |
| === Lookup Tables === |
| countries, materials, shapes, position_part, reference_type, |
| manufacture_type, quality_tier |
| |
+-------------------------------------------------------------------------+
| | | |
v v v v
+-------------------+ +----------+ +-------------+ +----------------+
| login.html | | demo.html| | admin.html | | bodega.html |
| tienda.html | | (catalog)| | (CRUD + | | (inventory |
| pos.html | | | | users) | | upload/manage) |
| cuentas.html | | | | | | |
| captura.html | | | | | | |
+-------------------+ +----------+ +-------------+ +----------------+
Frontend: HTML/CSS/JS vanilla (sin framework)
Shared: nav.js, shared.css
```
---
## Database Schema Overview
### Tablas principales y sus relaciones
**Vehiculos (jerarquia):**
```
brands (id_brand, name_brand, country, region)
|
+--< models (id_model, brand_id, name_model, body_type)
|
+--< model_year_engine (id_mye, model_id, year_id, engine_id, trim_level)
| | |
| | +-- engines (id_engine, name_engine, displacement_cc, cylinders, power_hp)
| +-------- years (id_year, year_car)
|
+--< vehicle_parts (mye_id, part_id, quantity, position)
+--< vehicle_diagrams (mye_id, diagram_id)
```
**Partes (jerarquia):**
```
part_categories (id, name, parent_id) <-- arbol recursivo
|
+--< part_groups (id, category_id, name)
|
+--< parts (id_part, oem_part_number, name, group_id)
|
+--< aftermarket_parts (oem_part_id -> parts, manufacturer_id, part_number)
+--< part_cross_references (part_id -> parts, cross_reference_number, type)
+--< vehicle_parts (part_id -> parts, mye_id)
```
**SaaS / Multi-tenant:**
```
roles (id_rol: 1=ADMIN, 2=OWNER, 3=TALLER, 4=BODEGA)
|
+--< users (id_user, email, pass, id_rol, business_name, is_active)
|
+--< sessions (refresh_token, expires_at)
+--< warehouse_inventory (user_id, part_id, price, stock, location)
+--< inventory_uploads (user_id, filename, status, rows_imported)
+--< inventory_column_mappings (user_id, mapping JSON)
```
### Convenciones de nombres en PostgreSQL
| Tabla | PK | Naming pattern |
|-------|-----|---------------|
| brands | `id_brand` | `name_brand` |
| models | `id_model` | `name_model` |
| years | `id_year` | `year_car` |
| engines | `id_engine` | `name_engine` |
| model_year_engine | `id_mye` | Tabla pivote central |
| parts | `id_part` | `name_part`, `oem_part_number` |
| part_categories | `id_part_category` | `name_part_category` |
| part_groups | `id_part_group` | `name_part_group` |
| manufacturers | `id_manufacture` | `name_manufacture` |
---
## TecDoc Data Pipeline
Pipeline de 3 fases para importar datos de TecDoc (el catalogo europeo de autopartes).
```
Fase 1: DOWNLOAD Fase 2: IMPORT Fase 3: LINK
(import_tecdoc.py download) (import_tecdoc.py import) (link_vehicle_parts.py)
+------------------+ +------------------+ +------------------+
| Apify TecDoc | | JSON files | | parts + |
| Actor API | | data/tecdoc/ | | model_year_engine|
| $69/month | | | | |
| HTTP 201 = run | | manufacturers/ | | Genera links |
| | --------> | models/ | ---------> | masivos en |
| typeId=1 (cars) | JSON | vehicles/ | INSERT | vehicle_parts |
| langId=4 (EN) | files | | partes + | (12B+ filas) |
| countryId=153(MX)| | Resumable: | vehiculos | |
+------------------+ | skips existing | +------------------+
+------------------+
```
### Scripts adicionales
- **`import_tecdoc_parts.py`**: Importa partes OEM y aftermarket desde TecDoc
- **`import_live.py`**: Importa datos en tiempo real (sin bajar a JSON primero)
- **`migrate_aftermarket.py`**: Normaliza datos aftermarket a la estructura con `quality_tier`, `manufacturers`
### Filtros de importacion
- Se descartan variantes regionales (e.g., "TOYOTA (GAC)")
- `countryFilterId=153` limita a vehiculos vendidos en Mexico
- El script es resumable: si un JSON ya existe en `data/tecdoc/`, se salta
---
## Auth Flow
Flujo de autenticacion basado en JWT con refresh tokens.
```
Cliente Servidor PostgreSQL
| | |
| POST /api/auth/register | |
| {name, email, pass, role} | |
|------------------------------>| bcrypt.hash(pass) |
| |----------------------------->|
| | INSERT users (is_active=F) |
| 201 "pending activation" | |
|<------------------------------| |
| | |
| (Admin activa la cuenta) | |
| | |
| POST /api/auth/login | |
| {email, password} | |
|------------------------------>| SELECT users WHERE email |
| |<-----------------------------|
| | bcrypt.check(pass) |
| | Verify is_active=true |
| | |
| | jwt.encode(user_id, role, |
| | business_name, exp=15min) |
| | |
| | secrets.token_urlsafe(48) |
| | INSERT sessions |
| |----------------------------->|
| | |
| {access_token, refresh_token,| |
| user: {id, name, role}} | |
|<------------------------------| |
| | |
| GET /api/... (protected) | |
| Authorization: Bearer <AT> | |
|------------------------------>| jwt.decode(AT) |
| | Check role in allowed_roles |
| | Set g.user = {user_id, role}|
| 200 {data} | |
|<------------------------------| |
| | |
| (Access token expires) | |
| | |
| POST /api/auth/refresh | |
| {refresh_token} | |
|------------------------------>| SELECT sessions |
| |<-----------------------------|
| | Check expires_at > now() |
| | jwt.encode(new access_token)|
| {access_token} | |
|<------------------------------| |
```
### Roles y permisos
| Rol | ID | Permisos |
|-----|----|----------|
| `ADMIN` | 1 | Todo: gestionar usuarios, catalogo, inventario |
| `OWNER` | 2 | Gestionar usuarios, ver estadisticas |
| `TALLER` | 3 | Consultar catalogo, ver disponibilidad en bodegas |
| `BODEGA` | 4 | Gestionar inventario propio, subir CSV/Excel |
### JWT Token payload
```json
{
"user_id": 1,
"role": "TALLER",
"business_name": "Taller Perez",
"type": "access",
"exp": 1742300000,
"iat": 1742299100
}
```
---
## Inventory Flow (Bodega)
Flujo para que una bodega suba su inventario via CSV/Excel.
```
Bodega (Browser) Servidor PostgreSQL
| | |
| 1. PUT /api/inventory/mapping| |
| {part_number: "NUM_PARTE", | |
| price: "PRECIO", | |
| stock: "EXISTENCIA", | UPSERT inventory_col_map |
| location: "ALMACEN"} |----------------------------->|
|<------------------------------| |
| | |
| 2. POST /api/inventory/upload| |
| multipart/form-data: file | |
|------------------------------>| |
| | a) Read mapping |
| |<-----------------------------|
| | |
| | b) Parse CSV/Excel |
| | (openpyxl or csv module) |
| | |
| | c) For each row: |
| | - Extract part_number |
| | using mapping |
| | - Find part by OEM # |
| | - If not found, try |
| | aftermarket_parts |
| | - UPSERT warehouse_inv |
| |----------------------------->|
| | |
| {imported: 450, errors: 12} | d) Update inventory_uploads |
|<------------------------------|----------------------------->|
```
### Tabla `warehouse_inventory`
```sql
warehouse_inventory (
id_inventory BIGSERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users,
part_id INTEGER REFERENCES parts,
price NUMERIC(12,2),
stock_quantity INTEGER DEFAULT 0,
warehouse_location VARCHAR(100) DEFAULT 'Principal',
updated_at TIMESTAMP,
UNIQUE(user_id, part_id, warehouse_location)
)
```
El UNIQUE constraint permite que una bodega tenga la misma parte en multiples ubicaciones (e.g., "Principal", "Sucursal Norte").
---
## Aftermarket Linking
Como se relacionan partes OEM con alternativas aftermarket y cross-references.
```
+--------------------+
| parts |
| (OEM catalog) |
| id_part: 500 |
| oem_part_number: |
| "04152-YZZA1" |
+--------+-----------+
|
+--------------+--------------+
| |
v v
+----------------------------+ +----------------------------+
| aftermarket_parts | | part_cross_references |
| (alternativas) | | (numeros alternos) |
| | | |
| oem_part_id: 500 | | part_id: 500 |
| manufacturer_id: -> DENSO | | cross_reference_number: |
| part_number: "DXP-1234" | | "90915-YZZF1" |
| quality_tier: "premium" | | reference_type: |
| price_usd: 12.50 | | "oem_alternate" |
| warranty_months: 24 | | source: "TecDoc" |
+----------------------------+ +----------------------------+
```
### Tipos de cross-reference
| Tipo | Descripcion |
|------|-------------|
| `oem_alternate` | Otro numero OEM para la misma parte (mismo fabricante) |
| `supersession` | La parte fue reemplazada por un numero nuevo |
| `interchange` | Numero de un competidor que es equivalente |
| `competitor` | Referencia cruzada a otra marca |
### Flujo de busqueda por numero de parte
Cuando un taller busca un numero de parte, el sistema busca en 3 lugares:
1. **`parts.oem_part_number`** - Match directo OEM
2. **`aftermarket_parts.part_number`** - Match en parte aftermarket, retorna el OEM original
3. **`part_cross_references.cross_reference_number`** - Match en cross-ref, retorna el OEM original
Esto permite que el taller encuentre la parte sin importar que numero use (OEM, aftermarket, o numero alterno).
### Calidad (quality_tier)
| Tier | Descripcion | Ejemplo |
|------|-------------|---------|
| `economy` | Precio bajo, calidad basica | Marcas genericas |
| `standard` | Calidad media, buen balance | Monroe, Moog |
| `premium` | Calidad alta, cercana a OEM | Denso, Bosch |
---
## Stack Frontend
El frontend es HTML/CSS/JS vanilla sin framework. Cada pagina es independiente.
```
dashboard/
+-- shared.css # Estilos compartidos (colores, layout, cards)
+-- nav.js # Navegacion compartida (inyecta sidebar/header)
+-- login.html + .css + .js
+-- demo.html # Catalogo publico
+-- admin.html + .js # Panel admin (CRUD, users, import/export)
+-- bodega.html + .css + .js # Inventory management
+-- tienda.html + .css + .js # Store view para talleres
+-- pos.html + .css + .js # Point of sale
+-- captura.html + .css + .js # Captura de partes
+-- cuentas.html + .css + .js # Gestion de cuentas
+-- dashboard.js # Logica del catalogo principal
+-- enhanced-search.js # Busqueda avanzada
```
### Patron de comunicacion con API
Todas las paginas usan `fetch()` con el patron:
```javascript
const token = localStorage.getItem('access_token');
const res = await fetch('/api/...', {
headers: { 'Authorization': `Bearer ${token}` }
});
const data = await res.json();
```
### Nota sobre NUMERIC de PostgreSQL
PostgreSQL retorna valores `NUMERIC` como strings. Todas las funciones de formato en JS usan `parseFloat()` para convertir antes de mostrar.