# Enrichment Workflow - PharmData Design System

> Padrões de interface para enriquecimento assistido de dados com validação por curador

---

## Filosofia

O enriquecimento de dados no PharmData não é automático - é **assistido**. O sistema sugere, mas **o curador decide** com base em sua expertise farmacêutica.

### Princípios

1. **Curador no Controle**: Enriquecimento é sugestão, não imposição
2. **Transparência de Fonte**: Sempre mostrar de onde veio a informação
3. **Confiança Visível**: Score de confiança baseado em matching
4. **Reversível**: Curador pode rejeitar ou modificar
5. **Rastreável**: Registrar fonte e decisão do curador

---

## Padrão: Botão de Enriquecimento por Campo

### Quando Usar

- Campo vazio ou incompleto
- Existem APIs externas disponíveis (SPOR, SNOMED, PubChem, etc.)
- Curador pode se beneficiar de sugestão especializada

### Anatomia

```html
<div class="field-with-enrichment">
    <label>UNII Code</label>

    <div class="input-group">
        <input type="text"
               name="unii_code"
               placeholder="FDA Unique Ingredient Identifier"
               value="">

        <button class="btn-enrich"
                onclick="enrichField('unii', 'spor')">
            <i class="fas fa-magic"></i>
            Enriquecer
        </button>
    </div>

    <small class="field-hint">
        Buscar em SPOR/EMA com base no nome da substância
    </small>
</div>
```

---

## Estados do Workflow

### 1. Estado Inicial (Campo Vazio)

```html
<div class="field-with-enrichment">
    <label>CAS Number</label>

    <div class="input-group">
        <input type="text"
               name="cas_number"
               placeholder="Chemical Abstracts Service Registry Number"
               value="">

        <button class="btn-enrich">
            <i class="fas fa-magic"></i>
            Enriquecer
        </button>
    </div>
</div>
```

**CSS**:
```css
.btn-enrich {
    padding: 8px 16px;
    font-size: 0.875rem;
    color: var(--teal-intense);
    background: transparent;
    border: 1px solid rgba(42, 161, 152, 0.3);
    border-radius: 6px;
    cursor: pointer;
    transition: all 0.2s ease;
}

.btn-enrich:hover {
    background: rgba(42, 161, 152, 0.05);
    border-color: var(--teal-intense);
}

.btn-enrich i {
    margin-right: 6px;
}
```

---

### 2. Estado Loading (Buscando)

```html
<div class="field-with-enrichment">
    <label>CAS Number</label>

    <div class="input-group">
        <input type="text"
               name="cas_number"
               disabled>

        <button class="btn-enrich" disabled>
            <i class="fas fa-spinner fa-spin"></i>
            Buscando...
        </button>
    </div>

    <small class="loading-hint">
        <i class="fas fa-search"></i>
        Consultando PubChem API...
    </small>
</div>
```

**CSS**:
```css
.btn-enrich:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

.loading-hint {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--soft-steel);
    font-size: 0.8rem;
    margin-top: 8px;
}
```

---

### 3. Estado Sugestão (Resultado Encontrado)

```html
<div class="enrichment-suggestion">
    <div class="suggestion-header">
        <div class="source-badge">
            <span class="drop drop-pubchem">PubChem</span>
            <span class="confidence-score">
                <i class="fas fa-chart-line"></i>
                95% confiança
            </span>
        </div>
    </div>

    <div class="suggestion-body">
        <div class="comparison">
            <div class="before">
                <label>Atual</label>
                <span class="empty-state">—</span>
            </div>

            <div class="arrow">
                <i class="fas fa-arrow-right"></i>
            </div>

            <div class="after">
                <label>Sugestão</label>
                <span class="suggested-value">103-90-2</span>
            </div>
        </div>

        <div class="suggestion-details">
            <small>
                <i class="fas fa-info-circle"></i>
                Encontrado por matching: "Paracetamol" → CID 1983
            </small>
        </div>
    </div>

    <div class="suggestion-actions">
        <button class="btn-approve" onclick="approveSuggestion()">
            <i class="fas fa-check"></i>
            Aprovar e Aplicar
        </button>
        <button class="btn-reject" onclick="rejectSuggestion()">
            <i class="fas fa-times"></i>
            Rejeitar
        </button>
        <button class="btn-modify" onclick="modifySuggestion()">
            <i class="fas fa-edit"></i>
            Modificar
        </button>
    </div>
</div>
```

**CSS**:
```css
.enrichment-suggestion {
    background: white;
    border: 2px solid var(--teal-intense);
    border-radius: 8px;
    padding: 16px;
    margin-top: 12px;
    animation: slideDown 0.3s ease-out;
}

@keyframes slideDown {
    from {
        opacity: 0;
        transform: translateY(-10px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.suggestion-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--soft-arctic);
}

.source-badge {
    display: flex;
    align-items: center;
    gap: 12px;
}

.confidence-score {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.875rem;
    color: var(--teal-intense);
    font-weight: 600;
}

.comparison {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    gap: 16px;
    align-items: center;
    margin-bottom: 12px;
}

.before, .after {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.before label, .after label {
    font-size: 0.75rem;
    text-transform: uppercase;
    color: var(--soft-steel);
    font-weight: 600;
}

.empty-state {
    color: var(--soft-steel);
    font-size: 1.5rem;
}

.suggested-value {
    font-size: 1.125rem;
    font-weight: 600;
    color: var(--graphite-depth);
    font-family: 'Courier New', monospace;
}

.arrow {
    color: var(--teal-intense);
    font-size: 1.25rem;
}

.suggestion-details {
    padding: 12px;
    background: rgba(42, 161, 152, 0.05);
    border-radius: 6px;
    margin-bottom: 16px;
}

.suggestion-details small {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--soft-steel);
}

.suggestion-actions {
    display: flex;
    gap: 8px;
}

.btn-approve {
    flex: 1;
    padding: 10px 16px;
    background: var(--teal-intense);
    color: white;
    border: none;
    border-radius: 6px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.2s ease;
}

.btn-approve:hover {
    background: var(--emerald-abyss);
}

.btn-reject {
    padding: 10px 16px;
    background: transparent;
    color: var(--soft-steel);
    border: 1px solid var(--soft-arctic);
    border-radius: 6px;
    cursor: pointer;
    transition: all 0.2s ease;
}

.btn-reject:hover {
    background: rgba(239, 83, 80, 0.05);
    border-color: #EF5350;
    color: #EF5350;
}

.btn-modify {
    padding: 10px 16px;
    background: transparent;
    color: var(--teal-intense);
    border: 1px solid rgba(42, 161, 152, 0.3);
    border-radius: 6px;
    cursor: pointer;
    transition: all 0.2s ease;
}

.btn-modify:hover {
    background: rgba(42, 161, 152, 0.05);
    border-color: var(--teal-intense);
}
```

---

### 4. Estado Aprovado

```html
<div class="field-with-enrichment">
    <label>CAS Number</label>

    <div class="input-group">
        <input type="text"
               name="cas_number"
               value="103-90-2"
               class="enriched-field">

        <span class="enrichment-badge">
            <i class="fas fa-check-circle"></i>
            Enriquecido por PubChem
        </span>
    </div>
</div>
```

**CSS**:
```css
.enriched-field {
    border-color: rgba(76, 175, 80, 0.5) !important;
    background: rgba(76, 175, 80, 0.02);
}

.enrichment-badge {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    font-size: 0.75rem;
    color: #4CAF50;
    background: rgba(76, 175, 80, 0.1);
    border: 1px solid rgba(76, 175, 80, 0.3);
    border-radius: 6px;
}
```

---

### 5. Estado Não Encontrado

```html
<div class="enrichment-not-found">
    <div class="not-found-icon">
        <i class="fas fa-search-minus"></i>
    </div>
    <div class="not-found-message">
        <strong>Nenhuma sugestão encontrada</strong>
        <p>Não foi possível encontrar correspondência em PubChem para "Paracetamol XYZ".</p>
    </div>
    <div class="not-found-actions">
        <button class="btn-try-another" onclick="tryAnotherSource()">
            <i class="fas fa-sync"></i>
            Tentar outra fonte
        </button>
        <button class="btn-manual" onclick="closeEnrichment()">
            <i class="fas fa-pencil"></i>
            Preencher manualmente
        </button>
    </div>
</div>
```

**CSS**:
```css
.enrichment-not-found {
    background: rgba(158, 158, 158, 0.05);
    border: 1px solid rgba(158, 158, 158, 0.2);
    border-radius: 8px;
    padding: 20px;
    margin-top: 12px;
    text-align: center;
}

.not-found-icon {
    font-size: 2rem;
    color: var(--soft-steel);
    margin-bottom: 12px;
}

.not-found-message strong {
    display: block;
    color: var(--graphite-depth);
    margin-bottom: 8px;
}

.not-found-message p {
    color: var(--soft-steel);
    font-size: 0.875rem;
    margin-bottom: 16px;
}

.not-found-actions {
    display: flex;
    justify-content: center;
    gap: 12px;
}
```

---

## Enriquecimento em Lote (Batch)

Para enriquecer múltiplos campos de uma vez:

```html
<div class="batch-enrichment">
    <div class="batch-header">
        <h3>
            <i class="fas fa-magic"></i>
            Enriquecimento Inteligente
        </h3>
        <p>Preencher automaticamente campos vazios usando bases externas</p>
    </div>

    <div class="enrichment-sources">
        <label class="source-option">
            <input type="checkbox" name="sources" value="spor" checked>
            <span class="drop drop-spor">SPOR/EMA</span>
            <small>Identificadores, classificações ATC</small>
        </label>

        <label class="source-option">
            <input type="checkbox" name="sources" value="snomed" checked>
            <span class="drop drop-snomed">SNOMED CT</span>
            <small>Termos clínicos, hierarquias</small>
        </label>

        <label class="source-option">
            <input type="checkbox" name="sources" value="pubchem">
            <span class="drop drop-pubchem">PubChem</span>
            <small>Propriedades físico-químicas, estruturas</small>
        </label>
    </div>

    <div class="enrichment-preview">
        <strong>Campos a enriquecer:</strong>
        <ul>
            <li><i class="fas fa-check"></i> UNII Code</li>
            <li><i class="fas fa-check"></i> CAS Number</li>
            <li><i class="fas fa-check"></i> ATC Classification</li>
            <li><i class="fas fa-check"></i> SNOMED CT Concept ID</li>
        </ul>
    </div>

    <div class="batch-actions">
        <button class="btn-primary" onclick="runBatchEnrichment()">
            <i class="fas fa-play"></i>
            Iniciar Enriquecimento
        </button>
        <button class="btn-secondary" onclick="cancelBatch()">
            Cancelar
        </button>
    </div>
</div>
```

---

## Linguagem e Tom de Voz

### ✅ Usar (Respeito e Expertise)

- "Enriquecer" (não "auto-fill" ou "preencher automaticamente")
- "Sugestão baseada em matching" (não "resultado automático")
- "Aprovar e aplicar" (não "aceitar")
- "Validar com sua expertise" (não "revisar")
- "Fonte: PubChem" (sempre transparente)

### ❌ Evitar (Condescendência)

- "O sistema preencheu para você"
- "Dados corretos encontrados"
- "Aceitar sugestão"
- "Auto-complete"

---

## Integração Backend

### Flask Route Pattern

```python
@app.route('/api/enrich/<field>/<source>', methods=['POST'])
def enrich_field(field, source):
    """
    Endpoint para enriquecimento de campo individual

    Args:
        field: nome do campo (unii_code, cas_number, etc.)
        source: fonte externa (spor, snomed, pubchem, etc.)

    Returns:
        JSON com sugestão, confiança e metadados
    """
    data = request.get_json()
    substance_name = data.get('substance_name')
    current_value = data.get('current_value')

    # Buscar na API externa
    if source == 'pubchem':
        result = pubchem_api.search_by_name(substance_name)
    elif source == 'spor':
        result = spor_api.search_substance(substance_name)

    if result:
        return jsonify({
            'success': True,
            'suggestion': result.get(field),
            'confidence': result.confidence_score,
            'source': source,
            'match_method': result.match_method,
            'metadata': {
                'external_id': result.external_id,
                'matched_term': result.matched_term
            }
        })
    else:
        return jsonify({
            'success': False,
            'message': f'Nenhuma correspondência encontrada em {source}'
        }), 404
```

### JavaScript Frontend

```javascript
async function enrichField(fieldName, source) {
    const substanceName = document.querySelector('input[name="name"]').value;
    const currentValue = document.querySelector(`input[name="${fieldName}"]`).value;

    // Mostrar loading
    showLoadingState(fieldName);

    try {
        const response = await fetch(`/api/enrich/${fieldName}/${source}`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                substance_name: substanceName,
                current_value: currentValue
            })
        });

        const data = await response.json();

        if (data.success) {
            showSuggestion(fieldName, data);
        } else {
            showNotFound(fieldName, data.message);
        }
    } catch (error) {
        showError(fieldName, 'Erro ao consultar API');
    }
}

function approveSuggestion(fieldName, suggestion) {
    // Aplicar valor ao campo
    document.querySelector(`input[name="${fieldName}"]`).value = suggestion.value;

    // Registrar metadados
    document.querySelector(`input[name="${fieldName}_source"]`).value = suggestion.source;
    document.querySelector(`input[name="${fieldName}_confidence"]`).value = suggestion.confidence;

    // Mostrar badge de enriquecido
    showEnrichedBadge(fieldName, suggestion.source);

    // Feedback para o curador
    showToast('success', 'Campo enriquecido com sucesso');
}
```

---

## Rastreabilidade

Sempre registrar metadados do enriquecimento:

```sql
-- Tabela de auditoria
CREATE TABLE enrichment_log (
    id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    substance_id NUMBER NOT NULL,
    field_name VARCHAR2(100) NOT NULL,
    source VARCHAR2(50) NOT NULL,
    suggested_value VARCHAR2(500),
    confidence_score NUMBER(5,2),
    curator_action VARCHAR2(20), -- 'approved', 'rejected', 'modified'
    curator_id NUMBER,
    enriched_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,

    CONSTRAINT fk_enrichment_substance FOREIGN KEY (substance_id)
        REFERENCES substances(id),
    CONSTRAINT fk_enrichment_curator FOREIGN KEY (curator_id)
        REFERENCES users(id)
);
```

---

## Exemplo Completo

Ver implementação completa em: [examples/enrichment-demo.html](../examples/enrichment-demo.html)

---

## Boas Práticas

### ✅ Fazer

- Sempre mostrar fonte e confiança
- Permitir modificação antes de aplicar
- Registrar decisão do curador (aprovar/rejeitar)
- Feedback visual claro de campos enriquecidos
- Permitir reversão (desfazer enriquecimento)
- Transparência sobre método de matching

### ❌ Evitar

- Enriquecimento automático sem validação
- Substituir valores existentes sem confirmação
- Ocultar fonte dos dados
- Linguagem que sugere "correção automática"
- Forçar aprovação de sugestões

---

*Ver também*:
- [CURATOR_EXPERIENCE.md](../CURATOR_EXPERIENCE.md) - Princípios de empoderamento
- [VIEW_PATTERNS.md](VIEW_PATTERNS.md) - Padrões de visualização
- [COMPOSITIONAL_FORMS.md](forms/COMPOSITIONAL_FORMS.md) - Formulários composicionais
