# CFDI: Export individual y filtros adicionales

## Resumen

Tres mejoras en la página `/cfdi`:

1. **Export a Excel por fila**: cada CFDI de la tabla tiene un botón de descarga que genera un `.xlsx` con los campos básicos de esa factura.
2. **Filtro por Tipo de Comprobante** (I/E/P/T/N) en la barra superior.
3. **Columna Tipo Comp.** en la tabla para dar correspondencia visual al filtro.

## Motivación

El export masivo existente sirve para análisis de rango, pero el contador frecuentemente necesita **una sola factura** en Excel para adjuntar a un correo, al expediente de un cliente o a una conciliación. Abrir el visor del CFDI y exportar desde ahí era fricción innecesaria.

El filtro por Tipo de Comprobante permite, por ejemplo, aislar sólo los complementos de Pago (tipo P) del mes — caso de uso habitual al cerrar el mes fiscal.

## Cambios en UI

### Barra de filtros

Antes:
```
[Buscar...] [🔍] | [Todos] [Emitidos] [Recibidos] | [Exportar] [Agregar] [Carga Masiva]
```

Después:
```
[Buscar...] [🔍] | [Todos] [Emitidos] [Recibidos] | [Tipo Comprobante ▼] | [Exportar] [Agregar] [Carga Masiva]
```

Valores del Select: `Todos los comprobantes`, `I - Ingreso`, `E - Egreso`, `P - Pago`, `T - Traslado`, `N - Nómina`.

### Tabla

Nueva columna **Tipo Comp.** entre "Tipo" y "UUID". Muestra la letra (I/E/P/T/N) con tooltip del nombre completo.

### Acción por fila

Nuevo botón `Download` junto al ojo de "Ver factura". Un clic → descarga `.xlsx` sin abrir modal, sin llamada al backend adicional.

## Estructura del Excel por fila

| Campo | Origen |
|-------|--------|
| Fecha Emisión | `cfdi.fechaEmision` formato `dd/mm/yyyy` es-MX |
| Tipo | `Emitido` / `Recibido` según `cfdi.type` |
| Tipo Comprobante | `I - Ingreso` / `E - Egreso` / etc. vía `formatTipoComprobante()` |
| Serie, Folio | Strings directos |
| RFC Emisor, Nombre Emisor | Strings directos |
| RFC Receptor, Nombre Receptor | Strings directos |
| Subtotal, IVA, Total | Números |
| Moneda | String |
| Estatus | `Vigente` / `Cancelado` normalizado desde `cfdi.status` |
| Fecha Cancelación | `dd/mm/yyyy` si el CFDI fue cancelado, vacío si vigente |
| UUID | String |

El export masivo usa exactamente la misma forma de columnas para que concatenar archivos posteriormente sea trivial.

**Nombre del archivo:** `cfdi_<serie>-<folio>.xlsx`, con fallback a los primeros 8 chars del UUID si el CFDI no tiene serie ni folio.

## Filtros ya existentes (no requirieron cambios)

Estos filtros ya funcionaban y cubren el resto del listado que pidió el usuario:

| Filtro | Dónde vive | Cómo funciona |
|--------|-----------|--------------|
| Fecha (rango) | Popover en cabecera columna "Fecha" | Inputs `fechaInicio` / `fechaFin`, se aplican juntos |
| Tipo (Emitido/Recibido) | Botones en barra superior | Filtro simple |
| RFC / Nombre Emisor | Popover en cabecera "Emisor" con autocomplete | Backend hace `rfc_emisor ILIKE OR nombre_emisor ILIKE`, acepta RFC o razón social |
| RFC / Nombre Receptor | Popover en cabecera "Receptor" con autocomplete | Igual que emisor pero contra `rfc_receptor` / `nombre_receptor` |

El backend ya exponía todos estos campos en `CfdiFilters` (ver `packages/shared/src/types/cfdi.ts`), así que los filtros antiguos sólo necesitaron UI; los de esta iteración (tipo de comprobante) tampoco requirieron cambios de backend porque `cfdi.service.ts:83` ya aplicaba `filters.tipoComprobante` al WHERE.

## Archivos modificados

| Archivo | Cambio |
|---------|--------|
| `apps/web/app/(dashboard)/cfdi/page.tsx` | `exportSingleCfdiToExcel`, helpers `TIPO_COMPROBANTE_LABELS` y `formatTipoComprobante`, `Select` de Tipo de Comprobante, columna en la tabla, columna `Fecha Cancelación` en ambos exports, rename `Estado` → `Estatus` |

## Decisiones de diseño

- **Sin llamada al backend para el export individual:** los datos ya están cargados en `data.data` vía `useCfdis()`. Llamar a `getCfdiById` sería latencia innecesaria.
- **`Estatus` vs `Estado`:** el SAT usa "Estatus SAT" como término oficial. El código interno mantiene `cfdi.status` pero la columna del Excel se renombró para alinear con terminología usuario/SAT.
- **Tipo de Comprobante como Select (no como botones):** 5 valores más "Todos" satura la barra si se usan botones. Un Select ocupa menos ancho y es más escaneable.
- **No agregué filtro de RFC separado:** los popovers existentes de Emisor/Receptor ya aceptan RFC (ILIKE sobre ambos campos), así que duplicarlo sería confuso.
