Files
Autoparts-DB/docs/plans/2026-03-15-saas-aftermarket-design.md
consultoria-as 5e6bf788db docs: add design and implementation plans
- SaaS + aftermarket design spec
- SaaS + aftermarket implementation plan (15 tasks)
- Captura partes design
- POS + cuentas design and plan

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 22:25:38 +00:00

7.3 KiB

Nexus Autoparts — SaaS + Aftermarket Design

Date: 2026-03-15 Status: Approved

Overview

Two features for Nexus Autoparts:

  1. SaaS user system — auth, roles (ADMIN, OWNER, TALLER, BODEGA), warehouse inventory uploads with flexible column mapping, availability/pricing visible to authenticated talleres.
  2. Aftermarket parts cleanup — migrate 357K AFT- prefixed parts from parts table into aftermarket_parts, link to OEM parts, fix import pipeline.

Architecture: Monolith approach — everything in the existing PostgreSQL DB and Flask backend.


Section 1: Authentication & Users

Tables

roles (existing, update names):

id_rol name_rol
1 ADMIN
2 OWNER
3 TALLER
4 BODEGA

users (existing, extend):

id_user (PK)
name_user (VARCHAR 200)
email (VARCHAR 200, UNIQUE)
pass (VARCHAR 200, bcrypt hash)
id_rol (FK → roles)
business_name (VARCHAR 200)
phone (VARCHAR 50)
address (TEXT)
is_active (BOOLEAN DEFAULT false)
created_at (TIMESTAMP DEFAULT now())
last_login (TIMESTAMP)

sessions (new):

id_session (PK)
user_id (FK → users)
refresh_token (VARCHAR 500, UNIQUE)
expires_at (TIMESTAMP)
created_at (TIMESTAMP DEFAULT now())

Auth Flow

  • Login: POST /api/auth/login → JWT access token (15 min) + refresh token (30 days)
  • Refresh: POST /api/auth/refresh → new access token
  • JWT payload: user_id, role, business_name
  • Public endpoints: catalog, landing, search, aftermarket list
  • Protected endpoints: pricing, inventory, admin, POS
  • Flask middleware validates JWT on protected routes

Registration

  • Bodegas and talleres register via form
  • ADMIN approves accounts (is_active = false by default)
  • ADMIN can create accounts directly

Section 2: Warehouse Inventory

Tables

warehouse_inventory (new):

id_inventory (PK, BIGINT)
user_id (FK → users)
part_id (FK → parts)
price (NUMERIC 12,2)
stock_quantity (INTEGER)
min_order_quantity (INTEGER DEFAULT 1)
warehouse_location (VARCHAR 100)
updated_at (TIMESTAMP DEFAULT now())
UNIQUE (user_id, part_id, warehouse_location)

inventory_uploads (new):

id_upload (PK)
user_id (FK → users)
filename (VARCHAR 200)
status (VARCHAR 20: pending, processing, completed, failed)
rows_total (INTEGER)
rows_imported (INTEGER)
rows_errors (INTEGER)
error_log (TEXT)
created_at (TIMESTAMP DEFAULT now())
completed_at (TIMESTAMP)

inventory_column_mappings (new):

id_mapping (PK)
user_id (FK → users, UNIQUE)
mapping (JSONB)

Example JSONB mapping:

{
  "part_number": "COLUMNA_A",
  "price": "PRECIO_VENTA",
  "stock": "EXISTENCIAS",
  "location": "SUCURSAL"
}

Upload Flow

  1. Bodega uploads CSV/Excel → POST /api/inventory/upload
  2. Backend reads file, applies JSONB mapping for that bodega
  3. Matches part numbers against parts.oem_part_number
  4. UPSERT into warehouse_inventory
  5. Records result in inventory_uploads

Catalog Display (authenticated TALLER)

Disponibilidad en bodegas:
  BODEGA CENTRAL MX     | $450.00 | 12 en stock | Guadalajara
  REFACCIONES DEL NORTE  | $485.00 | 3 en stock  | Monterrey
  • Only authenticated talleres see prices and stock
  • Public users see catalog without prices

Section 3: Aftermarket Parts Migration

Current Problem

  • 357,360 parts with AFT- prefix in parts table treated as OEM
  • Format: AFT-{articleNo}-{supplierName} (e.g., AFT-AC191-PARTQUIP)
  • Description: "Aftermarket PARTQUIP"
  • Have vehicle_parts linked
  • aftermarket_parts table exists but has only 1 record

Migration Steps

Step 1: Parse AFT- prefix

AFT-AC191-PARTQUIP → part_number: AC191, manufacturer: PARTQUIP
AFT-10-0058-Airstal → part_number: 10-0058, manufacturer: Airstal

Logic: last segment after last - that matches a manufacturers.name_manufacture is the manufacturer. The rest (without AFT-) is the part number.

Step 2: Find corresponding OEM part

  • Search part_cross_references where cross_reference_number = articleNo and source_ref = supplierName
  • That gives us the part_id of the real OEM part
  • If no cross-reference, search via vehicle_parts — OEM parts linked to same vehicles in same category

Step 3: Populate aftermarket_parts

oem_part_id → the OEM part found
manufacturer_id → FK to manufacturer (PARTQUIP, Airstal, etc.)
part_number → AC191 (clean, no prefix)
name_aftermarket_parts → original name_part

Step 4: Migrate vehicle_parts

  • vehicle_parts pointing to AFT- part get re-linked to the real OEM part
  • Or deleted if OEM already has that link (ON CONFLICT DO NOTHING)

Step 5: Delete AFT- parts from parts

  • Once migrated to aftermarket_parts and re-linked, remove from parts

Import Pipeline Changes

  • import_live.py and import_tecdoc_parts.py stop creating AFT- parts in parts
  • Instead insert directly into aftermarket_parts with clean manufacturer and part number
  • vehicle_parts only link to real OEM parts

Catalog Display

Alternativas aftermarket:
  PARTQUIP AC191         | Ver disponibilidad →
  BOSCH    0 986 AB2 854 | Ver disponibilidad →
  KAWE     6497 10       | Ver disponibilidad →

Section 4: API Endpoints & Pages

New Endpoints

Auth:

Method Route Access Description
POST /api/auth/register Public Register taller/bodega
POST /api/auth/login Public Login → JWT + refresh
POST /api/auth/refresh Authenticated Renew access token
GET /api/auth/me Authenticated User profile

Inventory (BODEGA):

Method Route Access Description
POST /api/inventory/upload BODEGA Upload CSV/Excel
GET /api/inventory/uploads BODEGA Upload history
GET /api/inventory/mapping BODEGA View column mapping
PUT /api/inventory/mapping BODEGA Configure mapping
GET /api/inventory/items BODEGA View own inventory
DELETE /api/inventory/items BODEGA Clear inventory

Availability (TALLER):

Method Route Access Description
GET /api/parts/{id}/availability TALLER Prices/stock from all bodegas
GET /api/parts/{id}/aftermarket Public Aftermarket alternatives list

Admin:

Method Route Access Description
GET /api/admin/users ADMIN List users
PUT /api/admin/users/{id}/activate ADMIN Approve/deactivate account

New Pages

login.html — Login/registration form. Redirects by role after login.

bodega.html — Warehouse panel:

  • Configure column mapping
  • Upload CSV/Excel
  • View upload history with status
  • View current inventory with search

Modified Pages

  • index.html / demo.html — Add "Disponibilidad en bodegas" section in part detail (TALLER only). Add "Alternativas aftermarket" section (public).
  • admin.html — Add "Usuarios" tab for account management.
  • nav.js — Add login/logout button, show username.

Auth Middleware

Public:        catalog, search, landing, login, aftermarket list
TALLER:        prices, availability, history
BODEGA:        upload, mapping, own inventory
ADMIN/OWNER:   all above + user management + admin panel