# Prompt Para Revisão Especializada: `tableEditorCapability`

## Contexto

Estamos evoluindo a arquitetura de edição de configuração dos componentes do ecossistema Praxis UI, com foco inicial em `praxis-table`, mas com intenção clara de estabelecer um padrão reaproveitável por `praxis-list`, `praxis-dynamic-form` e futuros componentes editáveis do playground.

O problema atual não é falta de editor JSON nem falta de editor visual. O problema é ausência de um protocolo canônico único entre as diferentes superfícies de autoria e o runtime real.

Hoje convivem, de forma parcialmente desconectada:

- editor visual embutido no componente
- editor JSON embutido no componente
- playground com apply simplificado
- apply por `@Input()`
- alguns fluxos com métodos públicos como `applyConfigFromAdapter(...)`

No caso de `praxis-table`, a situação é especialmente instrutiva:

- a tabela já possui um editor robusto
- o editor não trata o JSON como `TableConfig` cru
- ele usa `editedConfig`, dirty state, normalização, coerção por modo efetivo e reconciliação de campos auxiliares
- `resourcePath`, `idField` e `horizontalScroll` vivem fora do `TableConfig` puro
- o host/runtime reinterpreta campos internos como `__resourcePath__`, `__resourcePathIntent__`, `__idField__`, `__horizontalScroll__`

Ou seja: o componente já demonstra, na prática, que o modelo correto não é "editar JSON e repassar por input". O modelo correto é "editar um documento canônico de autoria e aplicar por um protocolo oficial".

## Motivação

Queremos transformar edição de configuração em uma capability formal do componente.

Objetivos centrais:

- round-trip confiável entre editor visual, editor JSON, playground e runtime
- separação clara entre `config` do componente e `hostInputs/contexto`
- normalização e validação centralizadas
- remoção de hacks específicos do playground
- remoção gradual de marcadores mágicos públicos como `__resourcePath__`
- base uniforme para consumo futuro por IA

O `praxis-table` será o blueprint inicial.

## Diagnóstico resumido do estado atual em `praxis-table`

### Editor

O editor atual concentra lógica relevante em:

- normalização de `TableConfig`
- dirty state comparando config normalizada + host inputs paralelos
- coerção de `pagination.strategy` e `sorting.strategy` para `client` em modo local
- reconciliação/preservação de `advancedFilters.settings`
- reconciliação visual de divergência com `serverIdField` e `serverSchemaHash`

### Runtime

O host (`PraxisTable`) hoje:

- abre o editor com `tableConfig`, `resourcePath`, `idField`, `horizontalScroll`, contexto CRUD e metadados de servidor
- recebe payload de volta
- lê marcadores internos
- reconcilia `resourcePath`, `idField`, `horizontalScroll`
- injeta metadados em `config.meta`
- remove marcadores internos
- finalmente chama `applyTableConfig(...)`

Esse fluxo funciona, mas o contrato entre editor e runtime é implícito, frágil e difícil de reutilizar no playground.

## Proposta arquitetural

Introduzir uma capability formal por componente, começando por `praxis-table`.

### Contrato base esperado

```ts
export interface EditorDiagnostic {
  level: 'error' | 'warning' | 'info';
  code: string;
  message: string;
  path?: string;
}

export interface ComponentEditorCapability<TDocument, TConfig, TTarget = unknown> {
  kind: string;
  version: 1;

  createDocument(source: {
    config?: unknown;
    hostInputs?: Record<string, unknown>;
    hostContext?: Record<string, unknown>;
  }): TDocument;

  normalizeDocument(raw: unknown): TDocument;
  validateDocument(doc: TDocument): EditorDiagnostic[];

  parseDocument(json: unknown): TDocument;
  serializeDocument(doc: TDocument): unknown;

  toCanonicalConfig(doc: TDocument): TConfig;

  applyDocument(
    target: TTarget,
    doc: TDocument,
    context?: unknown,
  ): void | Promise<void>;
}
```

### Documento canônico proposto para tabela

```ts
export type TableHorizontalScroll = 'auto' | 'wrap' | 'none';
export type ResourcePathIntent = 'set' | 'clear' | 'unchanged';
export type EffectiveDataMode = 'remote' | 'local' | 'empty';

export interface TableEditorHostInputs {
  resourcePath?: string;
  idField?: string;
  horizontalScroll?: TableHorizontalScroll;
}

export interface TableEditorHostContext {
  hasLocalDataInput?: boolean;
  localDataModeFlagEnabled?: boolean;
  serverIdField?: string;
  serverSchemaHash?: string;
  crudContext?: {
    tableId: string;
    componentKeyId?: string;
    resourcePath?: string;
    idField?: string;
  };
}

export interface TableEditorMeta {
  effectiveDataMode?: EffectiveDataMode;
  resourcePathIntent?: ResourcePathIntent;
}

export interface TableEditorDocument {
  config: TableConfig;
  hostInputs?: TableEditorHostInputs;
  hostContext?: TableEditorHostContext;
  editorMeta?: TableEditorMeta;
}
```

## Plano proposto para `tableEditorCapability`

### 1. `createDocument(source)`

Responsabilidade:

- criar o documento inicial a partir do estado real do host/editor
- derivar `resourcePath`, `idField`, `horizontalScroll`
- normalizar config de entrada
- preencher `editorMeta.effectiveDataMode`

Origem da lógica:

- `PraxisTable.openConfigEditor(...)`
- inicialização de `PraxisTableConfigEditor.ngOnInit()`

### 2. `normalizeDocument(raw)`

Responsabilidade:

- aceitar payload novo ou legado
- migrar `__resourcePath__`, `__idField__`, `__horizontalScroll__`, `__resourcePathIntent__`
- normalizar `config`
- normalizar `hostInputs`
- derivar `effectiveDataMode`
- aplicar coerções de estratégia em modo local
- estabilizar settings de filtros avançados

Essa é a peça principal da capability.

### 3. `validateDocument(doc)`

Responsabilidade:

- centralizar erros bloqueantes e warnings
- impedir apply inválido
- expor diagnósticos para editor visual, JSON editor e playground

Validações esperadas:

- `config.columns` deve ser array
- colunas devem ter `field`
- `horizontalScroll` deve estar no enum
- `resourcePathIntent=set` exige `resourcePath`
- `server pagination/sorting` não podem permanecer em modo local
- warning de divergência entre `hostInputs.idField` e `serverIdField`
- warning de divergência entre `config.meta.serverHash` e `serverSchemaHash`

### 4. `toCanonicalConfig(doc)`

Responsabilidade:

- projetar somente o `TableConfig` persistível/consumível pelo runtime
- não embutir `resourcePath` nem `horizontalScroll`
- opcionalmente persistir `meta.idField`
- nunca vazar marcadores internos

### 5. `serializeDocument(doc)` / `parseDocument(json)`

Responsabilidade:

- fazer do `TableEditorDocument` o JSON oficial de autoria
- permitir round-trip confiável entre editor visual e editor JSON
- aceitar payload legado na leitura, mas serializar só no formato novo

### 6. `applyDocument(target, doc, context?)`

Responsabilidade:

- encapsular o fluxo hoje espalhado no `PraxisTable`
- aplicar `resourcePath`, `idField`, `horizontalScroll`
- persistir inputs quando necessário
- compor `config.meta`
- persistir config quando necessário
- chamar o apply final do runtime

Contexto sugerido:

```ts
export interface TableApplyContext {
  trigger: 'applied' | 'saved' | 'adapter' | 'playground';
  persistConfig?: boolean;
  persistInputs?: boolean;
}
```

## Como isso substituiria o fluxo atual

### Hoje

O editor devolve algo próximo de `TableConfig`, mas injeta campos internos:

- `__resourcePath__`
- `__resourcePathIntent__`
- `__idField__`
- `__horizontalScroll__`

O host reinterpreta isso manualmente.

### Proposto

O editor devolve `TableEditorDocument`.

O host faz:

```ts
const doc = tableEditorCapability.parseDocument(value);
tableEditorCapability.applyDocument(this, doc, {
  trigger: 'saved',
  persistConfig: true,
  persistInputs: true,
});
```

## Compatibilidade

Queremos migração incremental, sem quebra abrupta.

Estratégia:

1. capability nova aceita payload legado
2. editor passa a produzir `TableEditorDocument`
3. runtime passa a preferir capability
4. fallback legado de `__...__` permanece temporariamente
5. playground passa a consumir capability
6. só depois removemos o protocolo mágico

## O que eu quero da revisão especializada

Quero uma revisão técnica rigorosa do desenho do `tableEditorCapability`, com foco em:

### 1. Contrato

- o `TableEditorDocument` está bem delimitado?
- `hostInputs`, `hostContext` e `editorMeta` estão bem separados?
- há campos demais ou de menos no documento?

### 2. Normalização

- a responsabilidade de `normalizeDocument()` está correta?
- alguma parte importante do comportamento atual da tabela ficaria fora?
- há risco de normalização com efeitos colaterais excessivos?

### 3. Apply

- `applyDocument()` deve chamar diretamente `applyTableConfig(...)`?
- a composição de `meta.idField`, `meta.version`, `meta.updatedAt`, `schemaId`, `serverHash` está no lugar certo?
- a persistência de `horizontalScroll` e `resourcePath` deveria ficar no capability ou no host?

### 4. Boundary público

- faz sentido expor `applyDocument()` como API oficial do componente?
- `toCanonicalConfig()` deve persistir `meta.idField` ou isso deve ser decisão só do host?
- `serverIdField` e `serverSchemaHash` devem existir no documento serializado ou apenas no contexto de sessão?

### 5. Migração

- a estratégia de compatibilidade com `__resourcePath__` etc. está adequada?
- existe uma abordagem melhor para migrar sem quebrar playground/editor atual?

### 6. Riscos

- riscos de drift que ainda permaneceriam
- riscos de acoplamento excessivo entre capability e classe Angular do componente
- riscos de versionamento do documento

## Critério de qualidade da revisão

Prefiro uma revisão em modo crítico, não superficial.

Se você enxergar fragilidade conceitual, ponto cego arquitetural, boundary errado ou risco de manutenção, aponte diretamente.

Quero principalmente saber:

- onde esse design ainda está fraco
- o que deveria ser movido de lugar
- o que ainda está dependente demais do estado atual do componente
- como deixar isso forte o suficiente para virar padrão do ecossistema

## Referências úteis no código atual

- `projects/praxis-table/src/lib/praxis-table-config-editor.ts`
- `projects/praxis-table/src/lib/praxis-table.ts`
- `projects/praxis-table/src/lib/json-config-editor/json-config-editor.component.ts`

Pontos mais relevantes observados no código atual:

- normalização/editor state no `PraxisTableConfigEditor`
- dirty state com `resourcePath`, `idField`, `horizontalScroll`
- coerção em modo local
- markers `__resourcePath__`, `__resourcePathIntent__`, `__idField__`, `__horizontalScroll__`
- apply final no runtime via `applyTableConfig(...)`

## Resultado esperado da revisão

Quero uma devolutiva estruturada contendo:

1. avaliação geral do desenho
2. falhas ou riscos mais importantes
3. mudanças recomendadas no contrato
4. mudanças recomendadas na estratégia de apply
5. recomendações de rollout/migração
6. se possível, uma proposta refinada do shape final da capability
