# Product Encoding System

## Overview

This document describes the hex-based encoding system for creating stable, bookmarkable URLs for product configurations. The system uses bit-packing to create compact strings that encode product type, color, material, and hardware options.

## Design Goals

1. **Stable URLs**: Old bookmarks continue to work even as new options are added
2. **Compact**: Keep URLs under 32-64 characters
3. **Extensible**: Reserve space for future expansion
4. **Reversible**: Each encoded string can be uniquely decoded back to its components
5. **Version-aware**: Support future format changes without breaking old URLs

## Encoding Format

```
Format: v-T-C-M-HHHH-HHHH-HHHH
        │ │ │ │ │    │    └── Hardware 3 (optional)
        │ │ │ │ │    └─────── Hardware 2 (optional)
        │ │ │ │ └──────────── Hardware 1
        │ │ │ └────────────── Material (1 hex char, 0-F)
        │ │ └──────────────── Color (1 hex char, 0-F)
        │ └────────────────── Type (1 hex char, 0-F)
        └──────────────────── Version (1 hex char, 0-F)

Example: "0-1-4-1-0D94"
- Version: 0 (using 5-bit encoding per field)
- Type: 1 (Patio Door)
- Color: 4 (White)
- Material: 1 (Aluminum)
- Hardware 1: 0D94 (Lever, Standard, Brass)

Max Length: ~24 characters (with 3 hardware items)
```

## Version 0 Encoding (Current)

### Main Product Attributes (Single Hex Character Each)

Each main attribute uses a single hex character (0-F = 0-15):

#### Type Values (1 hex char)
```
1  = Patio Door
2  = Reserved
3  = Storm Door
4  = Reserved
5  = Storm Window
6  = Reserved
7  = Primary Window
8-F = Reserved (8 slots for future door/window types)
```

#### Color Values (1 hex char)
```
1 = Black
2 = Bronze
3 = Sandstone
4 = White
5 = Tan
6 = Mill
7-F = Reserved (9 slots for future colors)
```

#### Material Values (1 hex char)
```
1 = Aluminum
2 = Vinyl
3-F = Reserved (13 slots for future materials)
```

### Hardware Encoding (4 Hex Characters = FFFF)

Each hardware item uses **4 hex characters** (16 bits) split into fields using **5 bits per field**:

```
16 bits total:
- Bits 10-14: Type (5 bits, 0-31 values)
- Bits 5-9:   Style (5 bits, 0-31 values)
- Bits 0-4:   Color (5 bits, 0-31 values)
- Bit 15:     Reserved (1 bit)
```

#### Hardware Type Values (5 bits = 0-31)
```
0  = None/Not Set
1  = Lever
2  = Pull
3  = Pull Handle
4  = Deadbolt
5  = Hinge
6-31 = Reserved (26 slots)
```

#### Hardware Style Values (5 bits = 0-31)
```
0  = None/Not Set
1  = Standard
2  = Push
3  = Alternative
4  = Contemporary
5  = Traditional
6-31 = Reserved (26 slots)
```

#### Hardware Color Values (5 bits = 0-31)
```
0  = None/Not Set
1  = Brass
2  = White
3  = Black
4  = Satin
5  = Nickel
6  = Bronze
7-31 = Reserved (25 slots)
```

## Bit Math Examples

### Encoding Hardware

```
Example: Lever, Standard, Brass
- Type: 1 (Lever)
- Style: 1 (Standard)
- Color: 1 (Brass)

Binary calculation:
Type (1)  = 00001 (bits 10-14)
Style (1) = 00001 (bits 5-9)
Color (1) = 00001 (bits 0-4)

Combined: 0000010000100001 = 0x0421
Hex: "0421"
```

```
Example: Pull Handle, Alternative, Satin
- Type: 3 (Pull Handle)
- Style: 3 (Alternative)
- Color: 4 (Satin)

Binary calculation:
Type (3)  = 00011 (bits 10-14)
Style (3) = 00011 (bits 5-9)
Color (4) = 00100 (bits 0-4)

Combined: 0000110001100100 = 0x0C64
Hex: "0C64"
```

### Decoding Hardware

```
Given hex: "0D94"
Binary: 0000110110010100

Extract fields:
Type  = bits 10-14 = 00011 = 3 (Pull Handle)
Style = bits 5-9   = 01100 = 12
Color = bits 0-4   = 10100 = 20
```

## URL Examples

### Simple Products (No Hardware)

```
"0-1-4-1" = Patio Door, White, Aluminum
"0-3-4-1" = Storm Door, White, Aluminum
"0-7-1-1" = Primary Window, Black, Aluminum
"0-5-2-2" = Storm Window, Bronze, Vinyl
```

### Products with Hardware

```
"0-3-4-1-0421" = Storm Door, White, Aluminum, Lever-Standard-Brass
"0-3-1-1-0421-0C64" = Storm Door, Black, Aluminum, 
                       Hardware1: Lever-Standard-Brass,
                       Hardware2: Pull Handle-Alternative-Satin
```

## Expansion Strategy

### Adding New Options (Compatible)

When adding new options within existing capacity (0-15 for main attributes, 0-31 for hardware fields):

```
Old system: Color 1-6 defined, 7-15 reserved
New system: Add Color 7 = Charcoal

Old URLs still work: "0-1-4-1" still means Patio Door, White, Aluminum
New URLs use new values: "0-1-7-1" means Patio Door, Charcoal, Aluminum
```

### Version 1 (Future Expansion)

If we exceed 16 main attribute values or 32 hardware field values:

```
Version 1: Use 6 bits per hardware field (64 values each)
Format: "1-TT-CC-MM-HHHHH-HHHHH"

Changes:
- Main attributes expand to 2 hex chars each (256 values)
- Hardware expands to 5 hex chars each (18 bits = 6 bits per field)
```

## Compatibility Rules

1. **Never reuse reserved values** until a new version is released
2. **Never change existing value meanings** (e.g., don't make "1" mean something else)
3. **Always decode based on version character**
4. **Maintain lookup tables** for each version

## Implementation Notes

- Use bit-shifting operators (`<<`, `>>`) for performance
- Use bitwise AND (`&`) with masks to extract fields
- Pad hex strings with leading zeros to fixed width
- Validate decoded values against valid ranges
- Return error for unknown version codes

## Benefits

✅ **Stable**: Values 0-15 remain the same even if we expand to 0-31  
✅ **Compact**: 13-24 characters for most products  
✅ **Readable**: Hex is human-debuggable  
✅ **Efficient**: Single parse operation, no string splitting  
✅ **Extensible**: Version prefix allows future format changes  
✅ **Reliable**: Bit operations are deterministic and reversible  

---

**Last Updated**: March 26, 2026  
**Current Version**: 0 (5-bit hardware encoding)
