> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devmob.app.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Vehicle Setup

> Cadastro de veículo com catálogo hierárquico de SeatTypes e Seats, atualização por substituição e ciclo de vida operacional.

## Overview

O setup de um veículo permite manter o veículo e o catálogo completo de assentos em uma única operação. `SeatType` e `Seat` são gerenciados dentro do contexto do veículo.

```mermaid theme={null}
erDiagram
    Vehicle ||--o{ SeatType : "has categories"
    Vehicle ||--o{ Seat : "has seats"
    SeatType ||--o{ Seat : "categorizes"
```

## Conteúdo hierárquico

`SeatType` carrega `name`, `color` e `price`. Cada categoria carrega o array de `Seat` que pertence a ela — assim o cliente não precisa referenciar IDs internos entre categoria e assento:

```mermaid theme={null}
flowchart LR
    V[Vehicle] --> ST1[SeatType: Executivo]
    V --> ST2[SeatType: Leito]
    ST1 --> S1[Seat 01]
    ST1 --> S2[Seat 02]
    ST2 --> SEAT3[Seat 03]
    ST2 --> S4[Seat 04]
```

Exemplo de conteúdo:

```json theme={null}
{
  "licensePlate": "ABC1D23",
  "model": "Sprinter",
  "manufacturer": "Mercedes-Benz",
  "year": 2024,
  "type": "VAN",
  "floorCount": "FIRST",
  "seatTypes": [
    {
      "name": "Executivo",
      "color": "#8B5CF6",
      "price": 8000,
      "seats": [
        { "label": "01", "floor": "FIRST", "row": 1, "column": "A", "side": "LEFT", "status": "AVAILABLE" },
        { "label": "02", "floor": "FIRST", "row": 1, "column": "B", "side": "RIGHT", "status": "AVAILABLE" }
      ]
    }
  ]
}
```

<Info>
  A `licensePlate` é normalizada em maiúscula, sem espaços e sem hífen. Unicidade é global. `seatTypes` é opcional no cadastro/atualização; quando um Seat omite `status`, o padrão é `AVAILABLE`.
</Info>

## Cadastro

```mermaid theme={null}
flowchart TD
    REQ["Operador envia veículo"] --> ORG["Organização define a company"]
    ORG --> PLATE["Placa é normalizada e validada"]
    PLATE --> VEHICLE["Vehicle disponível"]
    VEHICLE --> CATALOG["SeatTypes e Seats disponíveis quando enviados"]
    CATALOG --> DONE["Vehicle + catálogo prontos"]
```

## Atualização por substituição

A atualização é **substituição completa** quando o operador envia `seatTypes`. O catálogo anterior deixa de ser usado em novas vendas e o novo catálogo passa a valer. Se `seatTypes` for omitido do conteúdo, o catálogo permanece intacto e apenas os campos do veículo são atualizados.

```mermaid theme={null}
flowchart TD
    REQ["Operador atualiza veículo"] --> CHECK["Veículo pertence à organização"]
    CHECK --> PLATE["Placa é revalidada se mudou"]
    PLATE --> UPDATE["Campos do veículo são atualizados"]
    UPDATE --> CATALOG{"seatTypes enviado?"}
    CATALOG -->|Sim| REPLACE["Catálogo anterior é substituído"]
    CATALOG -->|Não| KEEP["Catálogo permanece"]
    REPLACE --> DONE["Vehicle atualizado"]
    KEEP --> DONE
```

<Warning>
  A substituição remove o catálogo anterior das listagens e vendas futuras, preservando histórico de tickets já emitidos.
</Warning>

## Vehicle Status Lifecycle

O `status` muda por ações próprias de ativação, desativação e remoção:

```mermaid theme={null}
stateDiagram-v2
    [*] --> ACTIVE: Cadastro
    ACTIVE --> INACTIVE: Desativação
    INACTIVE --> ACTIVE: Ativação
    ACTIVE --> [*]: Remoção
    INACTIVE --> [*]: Remoção
```

| Ação      | Validação                                                                   |
| --------- | --------------------------------------------------------------------------- |
| Ativar    | Veículo precisa estar `INACTIVE`                                            |
| Desativar | Veículo precisa estar `ACTIVE`; bloqueado se o veículo tiver viagens ativas |
| Remover   | Bloqueado se o veículo tiver viagens ativas                                 |

## SeatType Suggestions

As sugestões ajudam o cliente a oferecer opções no formulário de cadastro. A lista combina:

1. Categorias **já cadastradas** pela organização.
2. Um catálogo padrão (`Comum`, `Executivo`, `Leito`) para nomes ainda não usados na organização.

A deduplicação é por `name` em lowercase, com categorias da organização tendo precedência sobre o catálogo padrão.

```mermaid theme={null}
flowchart LR
    REQ["Solicita sugestões"] --> ORG[Categorias da organização]
    REQ --> STATIC[Catálogo estático<br/>Comum/Executivo/Leito]
    ORG --> MERGE[Merge dedup por name]
    STATIC --> MERGE
    MERGE --> RESP[Lista de sugestões]
```

## Multi-tenancy

Toda consulta e mutação é limitada à organização autenticada. Veículos de outras organizações não são expostos.

## Capacidades OPS

| Capacidade        | Permissão        | Descrição                                     |
| ----------------- | ---------------- | --------------------------------------------- |
| Listar veículos   | `read:vehicle`   | Lista paginada com filtros e ordenação        |
| Detalhar veículo  | `read:vehicle`   | Retorna veículo com catálogo                  |
| Cadastrar veículo | `create:vehicle` | Cadastra veículo e catálogo na mesma operação |
| Atualizar veículo | `update:vehicle` | Atualiza campos e/ou substitui catálogo       |
| Ativar veículo    | `update:vehicle` | Marca como `ACTIVE`                           |
| Desativar veículo | `update:vehicle` | Marca como `INACTIVE`                         |
| Remover veículo   | `delete:vehicle` | Remove veículo                                |
| Sugerir SeatTypes | `read:vehicle`   | Sugestões de SeatType para autocomplete       |

## Business Rules

| Regra                                          | Descrição                                                                                        |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| **Placa única e normalizada**                  | `licensePlate` é única globalmente, em maiúsculo e sem espaços.                                  |
| **Catálogo opcional**                          | Quando `seatTypes` é enviado, `SeatType` e `Seat` são criados/substituídos junto com o veículo.  |
| **SeatType/Seat no contexto do veículo**       | SeatTypes e Seats são mantidos junto com o veículo.                                              |
| **Substituição total**                         | Update do catálogo substitui o catálogo anterior.                                                |
| **Histórico preservado**                       | Tickets/TripSeatSegments existentes continuam associados ao assento usado no momento da venda.   |
| **Status separado do update**                  | `status` muda por ações próprias de ativação e desativação.                                      |
| **Pronto para escala**                         | Veículo escalável deve estar `ACTIVE` e possuir catálogo com assentos disponíveis.               |
| **Desativação/exclusão bloqueada por viagens** | `deactivate` e `DELETE` falham com `vehicle.has_active_trips` se o veículo tiver viagens ativas. |
| **Escopo por organização**                     | Veículos pertencem à organização da empresa.                                                     |

<Tip>
  A escolha por substituição total no update simplifica o cliente: ele envia o catálogo final desejado, sem precisar calcular diferenças entre versões.
</Tip>
