|
| 1 | +# Referência Visual de Tipos de Pino |
| 2 | + |
| 3 | +> Este documento é a fonte de verdade sobre o que cada cor e forma de pino representa no canvas. |
| 4 | +> Derivado do código em `PinViewModel.cs`, `PinShapeControl.cs` e `PinDataTypeExtensions.cs`. |
| 5 | +
|
| 6 | +--- |
| 7 | + |
| 8 | +## Gramática visual: forma + cor |
| 9 | + |
| 10 | +> **Forma = família semântica. Cor = tipo específico.** |
| 11 | +> |
| 12 | +> A forma permite identificar o que um pino representa sem ler o label — e sem depender de cor. |
| 13 | +> Isso torna o canvas acessível para usuários com daltonismo parcial. |
| 14 | +
|
| 15 | +--- |
| 16 | + |
| 17 | +## Tabela de referência rápida |
| 18 | + |
| 19 | +| Tipo | Forma | Cor | Hex | Label | Família | |
| 20 | +|---|---|---|---|---|---| |
| 21 | +| `Text` | Círculo | Azul | `#60A5FA` | `TXT` | Escalar | |
| 22 | +| `Integer` | Círculo | Esmeralda | `#34D399` | `INT` | Escalar | |
| 23 | +| `Decimal` | Círculo | Verde-lima | `#86EFAC` | `DEC` | Escalar | |
| 24 | +| `Number` | Círculo | Verde | `#4ADE80` | `NUM` | Escalar | |
| 25 | +| `Boolean` | Círculo | Âmbar | `#FCD34D` | `BOOL` | Escalar | |
| 26 | +| `DateTime` | Círculo | Azul-ciano | `#38BDF8` | `DT` | Escalar | |
| 27 | +| `Json` | Círculo | Índigo | `#818CF8` | `JSON` | Escalar | |
| 28 | +| `ColumnRef` | Losango sólido | Laranja | `#FB923C` | `INT↑` / `TXT↑` etc. | Estrutural | |
| 29 | +| `ColumnSet` | Losango com miolo vazado | Ouro | `#FBBF24` | `SET` | Estrutural | |
| 30 | +| `RowSet` | Losango achatado | Rosa-magenta | `#F472B6` | `ROWS` | Estrutural | |
| 31 | +| `Expression` | Círculo tracejado | Cinza-ardósia | `#6B7280` | `SQL` | Escape hatch | |
| 32 | + |
| 33 | +--- |
| 34 | + |
| 35 | +## Formas em detalhe |
| 36 | + |
| 37 | +### Círculo — tipos escalares |
| 38 | + |
| 39 | +Usado por todos os tipos que representam **um único valor por linha**: texto, números, booleano, data, JSON. |
| 40 | + |
| 41 | +``` |
| 42 | + ● |
| 43 | + (sólido quando conectado, |
| 44 | + apenas borda quando desconectado) |
| 45 | +``` |
| 46 | + |
| 47 | +O círculo tracejado (`Expression`) segue a mesma geometria, mas a borda é pontilhada `2 2` |
| 48 | +para indicar que não há garantia de tipo — é um fragmento SQL bruto. |
| 49 | + |
| 50 | +--- |
| 51 | + |
| 52 | +### Losango sólido — `ColumnRef` |
| 53 | + |
| 54 | +Representa uma **referência a uma coluna específica** — o equivalente a `tabela.coluna` no SQL. |
| 55 | +Carrega metadados: nome da coluna, alias da tabela, tipo escalar interno e se é nullable. |
| 56 | + |
| 57 | +``` |
| 58 | + ◆ |
| 59 | + (sólido quando conectado) |
| 60 | +``` |
| 61 | + |
| 62 | +O label exibe o tipo escalar interno com uma seta `↑` para indicar que é uma referência: |
| 63 | +`INT↑` significa "referência a uma coluna do tipo Integer". |
| 64 | + |
| 65 | +Tooltip ao hover: `u.user_id : Integer NOT NULL` |
| 66 | + |
| 67 | +--- |
| 68 | + |
| 69 | +### Losango com miolo vazado — `ColumnSet` |
| 70 | + |
| 71 | +Representa uma **lista ordenada de colunas** — o conjunto de colunas de um SELECT. |
| 72 | +É o tipo de primeira classe para conectar um `TableSource` a um `SelectOutput` sem |
| 73 | +precisar cabear cada coluna individualmente. |
| 74 | + |
| 75 | +``` |
| 76 | + ◇ |
| 77 | + (losango externo + losango interno recortado) |
| 78 | +``` |
| 79 | + |
| 80 | +Tooltip ao hover: `ColumnSet[4] id:INT, name:TXT, email:TXT, created_at:DT` |
| 81 | + |
| 82 | +--- |
| 83 | + |
| 84 | +### Losango achatado — `RowSet` |
| 85 | + |
| 86 | +Representa uma **tabela inteira** — resultado de uma query, tabela física, subquery ou CTE. |
| 87 | +É o tipo "mais pesado" do canvas: carrega o schema completo de linhas e colunas. |
| 88 | + |
| 89 | +``` |
| 90 | + ⬥ |
| 91 | + (losango com altura reduzida a ~70% da largura — visualmente "largo") |
| 92 | +``` |
| 93 | + |
| 94 | +Tooltip ao hover: `RowSet[5] id:INT, name:TXT, email:TXT, ...` |
| 95 | + |
| 96 | +--- |
| 97 | + |
| 98 | +## Estados visuais do pino |
| 99 | + |
| 100 | +| Estado | Aparência | |
| 101 | +|---|---| |
| 102 | +| **Desconectado** | Apenas a borda colorida; interior transparente (hollow) | |
| 103 | +| **Conectado** | Interior preenchido com a cor do tipo (solid) | |
| 104 | +| **Hover / drag sobre pino válido** | Escala ampliada + glow semitransparente na cor do tipo | |
| 105 | +| **Drop target válido** | Borda âmbar `#FBBF24` (independente do tipo) | |
| 106 | +| **Drop target inválido** | Pino fica apagado (opacity reduzida) — sem vermelho agressivo | |
| 107 | +| **Erro de validação** | Borda vermelha `#F87171` + indicador no label do pino | |
| 108 | + |
| 109 | +> O feedback de incompatibilidade é **subtração** (o pino some), não adição de cor de erro. |
| 110 | +> Vermelho é reservado exclusivamente para erros de validação estática (pino obrigatório sem conexão). |
| 111 | +
|
| 112 | +--- |
| 113 | + |
| 114 | +## Famílias semânticas e lógica de cor |
| 115 | + |
| 116 | +### Família fria — texto e tempo |
| 117 | + |
| 118 | +Tipos que carregam **informação descritiva**: texto, datas, JSON estruturado. |
| 119 | + |
| 120 | +| Tipo | Cor | Justificativa | |
| 121 | +|---|---|---| |
| 122 | +| `Text` | Azul `#60A5FA` | Azul informacional — texto como dado | |
| 123 | +| `DateTime` | Azul-ciano `#38BDF8` | Mais frio que o azul — fluxo de tempo | |
| 124 | +| `Json` | Índigo `#818CF8` | Estrutura complexa e opaca — roxo indica profundidade | |
| 125 | + |
| 126 | +### Família verde — dados quantitativos |
| 127 | + |
| 128 | +Tipos que representam **números**. |
| 129 | + |
| 130 | +| Tipo | Cor | Justificativa | |
| 131 | +|---|---|---| |
| 132 | +| `Integer` | Esmeralda `#34D399` | Verde vibrante — quantidade discreta | |
| 133 | +| `Decimal` | Verde-lima `#86EFAC` | Verde mais claro — quantidade contínua | |
| 134 | +| `Number` | Verde `#4ADE80` | Numérico genérico (interoperável com Integer e Decimal) | |
| 135 | + |
| 136 | +> `Number` existe como tipo de compatibilidade durante migração de grafos antigos e para nós |
| 137 | +> que operam em qualquer número sem distinção. É interoperável com `Integer` e `Decimal`. |
| 138 | +
|
| 139 | +### Família quente — lógica e estrutura |
| 140 | + |
| 141 | +Tipos que representam **decisões e agrupamentos** — os tipos que controlam o fluxo do dado. |
| 142 | + |
| 143 | +| Tipo | Cor | Justificativa | |
| 144 | +|---|---|---| |
| 145 | +| `Boolean` | Âmbar `#FCD34D` | Decisão binária — semáforo/alerta | |
| 146 | +| `ColumnRef` | Laranja `#FB923C` | Ponteiro — referência posicional a um dado | |
| 147 | +| `ColumnSet` | Ouro `#FBBF24` | Coleção de ponteiros — mais "cheio" que uma referência só | |
| 148 | +| `RowSet` | Rosa-magenta `#F472B6` | Nível de tabela — mais amplo que colunas | |
| 149 | + |
| 150 | +### Neutro — sem tipo garantido |
| 151 | + |
| 152 | +| Tipo | Cor | Justificativa | |
| 153 | +|---|---|---| |
| 154 | +| `Expression` | Cinza `#6B7280` | Fragmento SQL bruto sem garantia de tipo | |
| 155 | + |
| 156 | +--- |
| 157 | + |
| 158 | +## Regras de compatibilidade de conexão |
| 159 | + |
| 160 | +Dois pinos só podem ser conectados se forem compatíveis. As regras implementadas em `CanAccept`: |
| 161 | + |
| 162 | +| De | Para | Permitido? | Observação | |
| 163 | +|---|---|---|---| |
| 164 | +| Qualquer escalar | Mesmo escalar | Sim | Tipos idênticos sempre conectam | |
| 165 | +| `Integer` / `Decimal` / `Number` | Qualquer dos três | Sim | Família numérica é interoperável | |
| 166 | +| `ColumnRef` | `ColumnRef` (mesmo ScalarType) | Sim | Tipos escalares internos devem ser compatíveis | |
| 167 | +| `ColumnRef` | Qualquer escalar | Sim | Desempacota a referência para uso escalar | |
| 168 | +| `Expression` | Qualquer escalar | Sim | Escape hatch aceito em slots escalares | |
| 169 | +| `RowSet` | `RowSet` | Sim | Apenas com outro RowSet | |
| 170 | +| `ColumnSet` | `ColumnSet` | Sim | Apenas com outro ColumnSet | |
| 171 | +| `RowSet` | Escalar / ColumnRef / ColumnSet | Não | Tipos estruturalmente incompatíveis | |
| 172 | +| Escalar | `RowSet` ou `ColumnSet` | Não | Não há upcast implícito | |
| 173 | + |
| 174 | +> Para converter entre famílias incompatíveis, use nós explícitos: |
| 175 | +> `ColumnRefCast` para mudar o tipo escalar de uma referência de coluna, |
| 176 | +> `ScalarFromColumn` para extrair o valor escalar de um `ColumnRef`. |
| 177 | +
|
| 178 | +--- |
| 179 | + |
| 180 | +## `ColumnRef` e seus metadados |
| 181 | + |
| 182 | +Um pino `ColumnRef` carrega mais do que o tipo — carrega a **identidade da coluna**: |
| 183 | + |
| 184 | +``` |
| 185 | +alias_da_tabela . nome_da_coluna : ScalarType (nullable?) |
| 186 | +
|
| 187 | +Exemplo: u.user_id : Integer NOT NULL |
| 188 | +``` |
| 189 | + |
| 190 | +Campos em `ColumnRefMeta`: |
| 191 | +- `ColumnName` — ex: `user_id` |
| 192 | +- `TableAlias` — ex: `u` (de `users AS u`) |
| 193 | +- `ScalarType` — o tipo do valor: `Integer`, `Text`, `Decimal`, etc. |
| 194 | +- `IsNullable` — se a coluna aceita NULL |
| 195 | + |
| 196 | +Quando o `ScalarType` é conhecido, o label no canvas exibe o tipo com `↑`: |
| 197 | +`INT↑` = referência a uma coluna Integer. |
| 198 | + |
| 199 | +--- |
| 200 | + |
| 201 | +## `ColumnSet` e seus metadados |
| 202 | + |
| 203 | +Um pino `ColumnSet` carrega o **schema completo** da lista de colunas. |
| 204 | +O tooltip exibe as primeiras 4 colunas com seus tipos: |
| 205 | + |
| 206 | +``` |
| 207 | +ColumnSet[6] id:INT, name:TXT, email:TXT, created_at:DT, ... |
| 208 | +``` |
| 209 | + |
| 210 | +`ColumnSetMeta` é uma lista ordenada de `ColumnRefMeta` — a ordem é a mesma do SELECT gerado. |
| 211 | + |
| 212 | +--- |
| 213 | + |
| 214 | +## Onde cada tipo aparece no canvas |
| 215 | + |
| 216 | +| Situação | Tipo de pino | |
| 217 | +|---|---| |
| 218 | +| Output de `TableSource` por coluna | `ColumnRef(ScalarType)` | |
| 219 | +| Output `*` de `TableSource` | `ColumnSet` | |
| 220 | +| Output de `TableSource` como tabela | `RowSet` | |
| 221 | +| Input/Output de nós de string (`Upper`, `Trim`) | `Text` | |
| 222 | +| Input/Output de nós de data (`DateAdd`, `DatePart`) | `DateTime` | |
| 223 | +| Output de nós de comparação (`=`, `<`, `BETWEEN`) | `Boolean` | |
| 224 | +| Input de `AND`, `OR`, `NOT` | `Boolean` | |
| 225 | +| Input/Output de `ColumnSetBuilder` | `ColumnRef` (in) / `ColumnSet` (out) | |
| 226 | +| Input/Output de nós de join (`Join`, `RowSetJoin`) | `RowSet` | |
| 227 | +| Input de `SelectOutput` | `ColumnSet` ou `ColumnRef` | |
| 228 | +| Input de `WhereOutput` | `Boolean` | |
| 229 | +| Nós com fragmento SQL direto | `Expression` | |
0 commit comments