# Tutorial · Roles y auto-roles

Tutorial paso a paso sobre cómo manejar **roles de pieza** (Puerta,
Lateral, Fondo, Estante…) en Despiece y cómo aplicar **auto-roles** por
nombre con aliases configurables y multi-locale.

El modelo de ejemplo es `CocinaV9.despiece`. Cualquier proyecto con piezas
nombradas en castellano sirve — el matcher pliega acentos y es
case-insensitive.

---

## 1. Cargar el modelo y abrir la lista plana

![Vista general al cargar el modelo](img/01-overview-roles.jpg)

Al importar el STEP/IGES/BREP/glTF/GLB, la sidebar izquierda muestra el
**árbol jerárquico** (assemblies / piezas). Para trabajar con roles lo
más cómodo es la **lista plana** (todas las piezas en un solo scroll,
sin anidar assemblies): botón de la topbar o atajo.

La cámara vuelve a vista isométrica con `Home`; el zoom encaja con `F`.

## 2. La lista plana y sus chips de rol

![Lista plana con filas de piezas y sus chips de rol](img/02-sidebar-roles.jpg)

Cada fila muestra:

- **Nombre** de la pieza (editable con doble click — paso 5).
- **Cotas** nominales `largo × ancho × espesor` (mm) derivadas del AABB en
  espacio de diseño.
- **Chip de rol** (1 letra dentro de un cuadrado de 26×26 px) — el glyph
  del rol asignado, ej. `P` para Puerta, `L` para Lateral, `·` para
  «Sin rol».
- **4 chips de cantos** L1 · L2 · A1 · A2 (rojo 0,45 mm / azul 2 mm).
- **Chip de veta** (H/V/—) y **chip de material** (color).
- **Visibilidad / zoom** del RMB sobre la fila o la pieza 3D.

## 3. Anatomía de un chip de rol

![Detalle de un chip de rol](img/03-role-chip.jpg)

El **chip de rol** es el primer elemento de la fila, antes de los cantos:

| Estado | Visual | Significado |
|--------|--------|-------------|
| `none` (sentinel) | cuadrado con borde `line-2`, glyph `·` en `ink-mute` | Pieza sin clasificar — auto-roles puede rellenarla. |
| asignado | cuadrado con borde `cobalt-tint`, fondo `cobalt-soft`, glyph del rol en `ink` | Click cicla al siguiente rol built-in/custom (Shift+R hace lo mismo sobre la selección). |
| removido | — | Imposible: `none` siempre está presente (es sentinel de runtime). |

A diferencia de cantos, los roles **no son máscaras**: cada pieza tiene
exactamente **un** rol (o `none`), no cuatro. Click → cicla al siguiente
rol del catálogo activo (`defaults − removedBuiltins + customs`).

## 4. Ciclar el rol a mano

![Tres estados del chip de rol: sin rol, asignado, removido](img/04-role-cycle.jpg)

Cada click sobre el chip cicla el rol. La secuencia por defecto (con
los 12 built-in) es:

```
· (Sin rol)  →  P (Puerta)  →  L (Lateral)  →  F (Fondo)  →  E (Estante)
→  T (Techo)  →  B (Base)  →  J (Faja)  →  O (Otro)  →  G (Gola)
→  Z (Zócalo)  →  R (Frente)  →  C (Lateral Cajón)  →  ·
```

Con el catálogo base el orden del ciclo es: `none` → `puerta` → `lateral`
→ `fondo` → `estante` → `techo` → `base` → `faja` → `otro` → `gola` →
`zocalo` → `frente` → `lateral_cajon` → `none`. Los customs (paso 8)
se insertan al final en orden de creación.

> **Importante:** con varias piezas seleccionadas, el ciclo se aplica a
> todas. Equivalente directo: `Shift+R` cicla el rol de toda la selección
> de una sola vez.

## 5. Renombrar una pieza

![Input inline de renombre](img/05-rename-roles.jpg)

Hacé **doble click** sobre el nombre de la pieza para entrar en modo
edición. Escribí el nuevo nombre, `Enter` confirma, `Esc` cancela.

El nombre es la **clave del auto-roles**: las keywords de cada rol
(label + key + aliases) matchean sobre él (con pliegue de acentos y
multi-locale). Renombrar `Pieza_23` a `Puerta alacena` hace que el rol
*Puerta* (`puerta`) la tome en el próximo `Shift+B`.

## 6. Aplicar auto-roles con `Shift+B`

![Modelo después de auto-roles](img/06-after-auto-roles.jpg)

![Sidebar después de auto-roles](img/06-sidebar-after-auto-roles.jpg)

El atajo **`Shift+B`** ejecuta **Auto-roles ✦** sobre todas las piezas
del proyecto (también accesible desde el botón Auto-roles de la topbar,
entre Auto-cantos y Auto-glued-up). La regla es:

> Para cada pieza, se matchea el **rol** cuyo label / key / alias (acorde
> a la jerarquía *longest-keyword-wins* / *first-def-wins*) aparezca en
> el nombre de la pieza. Solo se **rellenan piezas en «Sin rol»** — las
> que ya tienen rol asignado a mano **no se pisan**.

Roles built-in del catálogo default:

| Rol | Glyph | Aliases clave |
|-----|-------|----------------|
| Puerta | `P` | `puerta`, `puertas`, `abatible` |
| Lateral | `L` | `lateral`, `laterales`, `lat`, `parante` |
| Fondo | `F` | `fondo`, `fondos`, `trasera` |
| Estante | `E` | `estante`, `estantes`, `entrepaño` |
| Techo | `T` | `techo`, `tapa`, `tapas` |
| Base | `B` | `base`, `bases` |
| Faja | `J` | `faja`, `fajas`, `fyf` |
| Otro | `O` | `otro`, `t y e` |
| Gola | `G` | `gola`, `golas`, `perfil gola` |
| Zócalo | `Z` | `zócalo`, `zoc`, `lat zoc`, `f zoc` |
| Frente | `R` | `ff`, `frente`, `frente falso` |
| Lateral Cajón | `C` | `lat caj`, `lateral cajon`, `lateral cajón` |

Compará la sidebar antes/después: las piezas que matchearon cambiaron su
chip al rol detectado. Las que no matchearon quedan en `·` (sin rol) y
el toast distingue **unmatched** vs **skipped** vs **cambiadas**.

> **Cuidado:** «Sin rol» es sentinel de runtime — nunca se borra del
> catálogo. Si tu pieza no matchea ningún rol, queda en `none` y la
> columna *Rol* del BOM/Pedido la lista vacía o como «Sin clasificar».

## 7. Configuración → Roles

![Tabla de roles en Configuración](img/07-settings-roles.jpg)

`Configuración → Roles` (botón de la topbar) abre la lista de roles del
taller. Cada row expone:

- **Glyph** (1 carácter; se trunca si metés más).
- **Label** editable — el texto que ve el usuario y la keyword principal
  del matcher.
- **Preview de aliases** — keywords adicionales separadas por `·`; tope
  horizontal con `title` para ver el set completo.
- **Contador de uso** — cuántas piezas del proyecto activo están en ese
  rol (en vivo).
- **Acciones** — `✎` editar, `×` eliminar (con confirmación). `none`
  aparece como *fijo* sin botones.

## 8. Crear un rol nuevo

![Formulario de nuevo rol](img/08-role-form.jpg)

*+ Agregar rol* abre una card con:

1. **Glyph** (1 carácter; default `·`; se truncan los extras).
2. **Label** (1–40 chars; único entre todos los roles). Ej. *Cajón*.
3. **Aliases** — chips removibles; tipear y `Enter` o `,` para agregar.
   Cada alias es una keyword matchable más (sin acentos, minúsculas). Ej.
   `cajon`, `cajones`, `drawer`.

**Guardar** la deja persistida en `localStorage[despiece.roles.v1]` como
rol **custom** (no-builtin). Aparece al final del catálogo y participa
del próximo `Shift+B` como una keyword más.

> **Cuidado con colisiones entre aliases:** si tu nueva keyword ya está
> en uso por otro rol, el *Guardar* rechaza el alta y muestra cuál es el
> alias que choca. Ejemplo: agregar `puerta` a un rol custom falla porque
> *Puerta* ya tiene ese alias.

Los customs viven en `rolesCatalog.custom` del `.despiece`. Para volver
al catálogo built-in limpio: **Restablecer roles por defecto** (al pie
del tab) borra los customs y revierte los overrides de
labels/aliases/glyph que hubieras hecho sobre built-ins.

## 9. Catálogo y aliases por locale

![Aliases por locale](img/09-roles-locale.jpg)

Cada rol built-in carga 6 listas de aliases, una por locale soportado:
`es-AR`, `en-US`, `pt-BR`, `fr-FR`, `de-DE`, `it-IT`. La lista `es-AR`
es la fuente de verdad para legacy matching; las demás se usan por
auto-detect cross-locale.

Por ejemplo, para *Puerta* (`puerta`):

| Locale | Aliases |
|--------|---------|
| `es-AR` | `puerta`, `puertas`, `puerta batiente`, `abatible` |
| `en-US` | `door`, `doors`, `door leaf`, `front` |
| `pt-BR` | `porta`, `portas`, `folha de porta` |
| `fr-FR` | `porte`, `portes`, `porte battante` |
| `de-DE` | `Tür`, `Türen`, `Türblatt`, `Drehtür` |
| `it-IT` | `porta`, `porte`, `anta`, `anta battente` |

Cuando un modelo está en inglés y la UI en castellano, el matcher usa la
lista de aliases del locale activo (no del locale del modelo). Cambiar
idioma en la topbar re-machea automáticamente al próximo run; los roles
ya asignados se preservan porque **auto-roles solo rellena «Sin rol»**.

> Los roles custom aceptan aliases únicamente en `es-AR` (los demás
> locales heredan la lista es-AR por compatibilidad). Editar
> `aliasesByLocale` por código es soportado pero no expuesto en la UI.

## 10. Atajos de teclado

![Hoja de atajos](img/10-atajos-roles.jpg)

`Help` (botón de la topbar o `?`) abre la hoja completa. Los más usados
en el flujo de roles:

| Atajo | Acción |
|-------|--------|
| `Shift+B` | Auto-roles ✦ (sobre todo el proyecto, solo rellena «Sin rol») |
| Click en chip de rol | Cicla al siguiente rol del catálogo activo |
| `Shift+R` | Cicla el rol de toda la selección (equivalente a clicks encadenados) |
| Doble click en nombre | Renombrar pieza |
| `B` | Auto-cantos ✦ (sobre todo el proyecto, complementario) |
| `G` | Cicla veta en la selección |
| `I` | Aislar selección |
| `Esc` | Limpiar selección / salir de measure |
| `F` / `Home` | Fit / Fit + iso |

En Mac el modificador de sistema es `⌘`; en otros sistemas `Ctrl`.

---

## Ver también

- [Tutorial · Cantos y auto-cantos](cantos-y-auto-cantos.html) — la versión
  anterior de este tutorial; misma lógica, distinta salida.
- Spec
  [`2026-07-16-roles-tab.md`](../superpowers/specs/2026-07-16-roles-tab.md)
  — diseño del tab Roles y los 12 built-ins.
- Spec
  [`2026-07-17-editable-builtin-roles.md`](../superpowers/specs/2026-07-17-editable-builtin-roles.md)
  — overrides de label/glyph/aliases sobre built-ins.
- Spec
  [`2026-07-17-hardware-role-rules.md`](../superpowers/specs/2026-07-17-hardware-role-rules.md)
  — cómo los roles alimentan las reglas de herraje.
