# Pick-Style Console System - Design Document

**Date:** 2026-02-14
**Status:** Approved

## Overview

Console-based autoparts catalog system inspired by Pick/D3 operating systems with VT220 terminal aesthetics. Runs entirely from keyboard in a real terminal (CLI), with two selectable rendering modes: classic VT220 (curses) and modern TUI (textual).

## Requirements

- **Platform:** Real CLI terminal (Python), no web browser
- **Users:** Sales counter staff AND warehouse/admin personnel
- **Style:** Pick-inspired with ANSI colors, box drawing, formatted tables
- **Data:** Abstract DB layer (SQLite today, PostgreSQL migration planned)
- **Renderers:** Two modes selectable via `--mode vt220|modern`
- **Input:** 100% keyboard-driven with F-keys, menus, and incremental search

## Architecture

```
┌─────────────────────────────────────┐
│        Capa de Presentación         │
│  ┌──────────┐    ┌───────────────┐  │
│  │  curses   │    │   textual     │  │
│  │ (VT220)   │    │  (moderno)    │  │
│  └─────┬─────┘    └──────┬────────┘  │
│        └────────┬────────┘           │
│           Interface común            │
├─────────────────────────────────────┤
│      Capa de Lógica / Screens       │
│  Menús, Navegación, Formularios,    │
│  Búsqueda, CRUD                     │
├─────────────────────────────────────┤
│         Capa de Datos (DB)          │
│  SQLite hoy → PostgreSQL mañana     │
└─────────────────────────────────────┘
```

## File Structure

```
console/
├── main.py                  # Entry point, --mode vt220|modern
├── config.py                # DB path, colors, key mappings
├── db.py                    # Abstract DB layer (SQLite/PostgreSQL)
│
├── core/
│   ├── screens.py           # Screen base class
│   ├── widgets.py           # Lista, Formulario, Tabla, Barra
│   ├── navigation.py        # Screen stack, breadcrumb, history
│   └── keybindings.py       # F-keys, ESC, TAB mappings
│
├── screens/
│   ├── menu_principal.py    # Main menu (9 options + exit)
│   ├── vehiculo_nav.py      # Drill-down: brand → model → year → engine
│   ├── buscar_parte.py      # Search by part number
│   ├── buscar_texto.py      # Full-text search (FTS)
│   ├── vin_decoder.py       # VIN decoder (NHTSA API)
│   ├── catalogo.py          # Categories → groups → parts
│   ├── parte_detalle.py     # Part detail with alternatives
│   ├── comparador.py        # OEM vs aftermarket comparison
│   ├── estadisticas.py      # System statistics dashboard
│   ├── admin_partes.py      # Parts CRUD
│   ├── admin_fabricantes.py # Manufacturers CRUD
│   ├── admin_crossref.py    # Cross-references CRUD
│   └── admin_import.py      # Import/Export CSV
│
├── renderers/
│   ├── curses_renderer.py   # VT220 mode (curses)
│   └── textual_renderer.py  # Modern mode (textual/rich)
│
└── utils/
    ├── formatting.py         # Table formatting, numbers, currency
    └── vin_api.py            # NHTSA VIN API client
```

## Screens

### Main Menu
- 9 numbered options + 0 to exit
- F-key bar at bottom
- Header with system name and version

### 1. Vehicle Navigation (Drill-Down)
- Sequential selection: Brand → Model → Year → Engine
- Each step shows filterable list with incremental search
- Arrow keys + ENTER to select, ESC to go back
- Leads to categories/groups/parts for selected vehicle

### 2. Part Number Search
- Single input field for part number
- Searches OEM, aftermarket, and cross-references
- Results show type, number, description, source
- Select result to see full detail

### 3. Text Search (FTS)
- Uses SQLite FTS5 full-text search
- Searches part names and descriptions
- Paginated results with relevance ranking

### 4. VIN Decoder
- Input 17-character VIN
- Calls NHTSA API (with cache)
- Shows decoded vehicle info
- Option to view compatible parts

### 5. Category Catalog
- Browse: Categories → Groups → Parts
- Independent of vehicle selection

### 6-9. Administration
- CRUD screens with Pick-style positional forms
- Numbered fields, TAB/arrow navigation
- F1 for lookup lists on foreign key fields
- F9 to save, ESC to cancel (with dirty check)
- Import/Export CSV with file path input

### 10. Part Detail
- Full part info in form layout (label.....: value)
- Aftermarket alternatives table below
- F4 for cross-references, F6 for vehicles

### 11. Part Comparator
- Side-by-side columns: OEM vs aftermarket alternatives
- Visual quality bars, savings percentage
- Cross-reference numbers at bottom
- Horizontal scroll if more than 3 columns

### 12. Statistics Dashboard
- Database counters (brands, models, parts, etc.)
- Coverage metrics (vehicles with parts, top brands)
- VIN cache status

## Key Bindings

| Key | Action |
|-----|--------|
| 0-9 | Select menu option / jump to field |
| ENTER | Confirm selection |
| ESC | Go back / Cancel |
| F1 | Help / Lookup list |
| F2 | Edit mode |
| F3 | Search |
| F4 | Cross-references |
| F5 | Refresh |
| F6 | Related vehicles |
| F9 | Save |
| F10 | Main menu |
| TAB / ↓ | Next field |
| ↑ | Previous field |
| PgUp/PgDn | Page navigation |
| ←→ | Scroll columns (comparator) |

## Data Layer

Abstract interface with two implementations:

```python
class Database:
    def get_brands() -> list
    def get_models(brand=None) -> list
    def get_vehicles(brand, model, year, engine) -> list
    def get_categories() -> list
    def get_groups(category_id) -> list
    def get_parts(group_id=None, mye_id=None) -> list
    def get_part(part_id) -> dict
    def get_alternatives(part_id) -> list
    def get_cross_references(part_id) -> list
    def search_parts(query) -> list
    def search_part_number(number) -> list
    def decode_vin(vin) -> dict
    def get_stats() -> dict
    # CRUD methods for admin...
```

SQLite implementation reads directly from `vehicle_database.db`. PostgreSQL implementation will use psycopg2 with same interface.

## Renderer Interface

```python
class Renderer:
    def init_screen()
    def clear()
    def draw_header(title, subtitle)
    def draw_footer(keys)
    def draw_menu(items, selected)
    def draw_table(headers, rows, page_info)
    def draw_form(fields, focused_field)
    def draw_detail(labels_values)
    def draw_comparison(columns)
    def draw_filter_list(items, filter_text, selected)
    def draw_stats(data)
    def get_key() -> key_event
    def show_message(text, type)  # info/error/confirm
```

Curses implementation uses box drawing chars, ANSI colors (green/amber on black). Textual implementation uses Rich widgets with modern styling.
