# Value

> Configura, revisa e debuga injeção `@Value` Sankhya (`ValueType`, `Provider<T>` lazy/eager, `SANKHYA_PARAM`, `group`), declaração de parâmetro em `META-INF/parameter.xml` e feature flag togglável via `MGECoreParameter`. Use ao injetar, alterar, revisar ou auditar valores de configuração em componentes Guice, criar/editar parâmetro Sankhya (`parameter.xml`, key, cacheable), implementar feature fla…

- **Type:** Skill
- **Install:** `agentstack add skill-snk-devcenter-addon-studio-value`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [snk-devcenter](https://agentstack.voostack.com/s/snk-devcenter)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [snk-devcenter](https://github.com/snk-devcenter)
- **Source:** https://github.com/snk-devcenter/addon-studio/tree/main/plugins/addon-studio/skills/value

## Install

```sh
agentstack add skill-snk-devcenter-addon-studio-value
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Injecao de Valores (`@Value`) — Addon Studio 2.0

`@Value` injeta valores de configuracao (env vars, system properties, parametros Sankhya) diretamente em campos de componentes gerenciados pelo Guice. Conversao de tipo automatica. Thread-safe.

---

## 1. Atributos

| Atributo       | Obrigatorio | Descricao                                                                 |
|:---------------|:------------|:--------------------------------------------------------------------------|
| `value`        | Nao*        | Nome da propriedade. Alternativa a `param`.                               |
| `param`        | Nao*        | Nome do parametro. Alternativa a `value`. **Tem precedencia sobre `value`**. |
| `group`        | Nao         | Grupo do parametro — exclusivo de `SANKHYA_PARAM`.                        |
| `type`         | Sim         | Fonte: `ENV_VAR`, `SYSTEM_PROPERTY`, `SANKHYA_PARAM` ou `UNDEFINED`.      |
| `defaultValue` | Sim         | Fallback quando a propriedade nao e encontrada. Nunca deixar vazio.        |

> * Ao menos um entre `value` ou `param` e obrigatorio.

---

## 2. Eager vs Lazy

| Modo   | Sintaxe                        | Resolucao               | Quando usar                              |
|:-------|:-------------------------------|:------------------------|:-----------------------------------------|
| Eager  | `private Integer porta`        | Na criacao do objeto    | Valor sempre necessario                  |
| Lazy   | `private Provider porta` | Na primeira chamada `.get()`, **cacheado para sempre** | Valor opcional / custoso — config estavel |

```java
// Eager — resolvido na inicializacao
@Value(value = "server.port", type = ValueType.SYSTEM_PROPERTY, defaultValue = "8080")
private Integer serverPort;

// Lazy — resolvido so quando chamado, DEPOIS congela
@Value(param = "MAX_RETRIES", type = ValueType.SANKHYA_PARAM, defaultValue = "3")
private Provider maxRetries;

public void executar() {
    int retries = maxRetries.get();  // resolve na primeira chamada; das seguintes vem do cache
    // ...
}
```

> **Lazy adia a resolucao, mas NAO reflete mudanca posterior.** O `ValueProvider` do SDK resolve uma unica vez no primeiro `.get()` e cacheia para sempre (double-checked locking). Como componentes vivem em singletons ou presos em grafos de vida longa (interceptor dentro de `OkHttpClient` reutilizado, client `@Provides @Singleton`), o valor so muda com **restart**. Para toggle em runtime, ver secao "Feature flag togglavel".

---

## 3. Fontes (`ValueType`)

### `ENV_VAR` — variavel de ambiente

```java
@Value(value = "API_KEY", type = ValueType.ENV_VAR, defaultValue = "")
private String apiKey;
```

### `SYSTEM_PROPERTY` — propriedade Java (`-Dchave=valor`)

```java
@Value(value = "server.port", type = ValueType.SYSTEM_PROPERTY, defaultValue = "8080")
private Integer serverPort;
```

### `SANKHYA_PARAM` — parametro do sistema Sankhya

```java
// Sem grupo
@Value(param = "MAX_CONNECTIONS", type = ValueType.SANKHYA_PARAM, defaultValue = "10")
private Provider maxConnections;

// Com grupo
@Value(param = "TIMEOUT", group = "CONNECTION", type = ValueType.SANKHYA_PARAM, defaultValue = "30")
private Provider connectionTimeout;
```

### `UNDEFINED` — sempre usa o `defaultValue`

```java
@Value(value = "qualquer", type = ValueType.UNDEFINED, defaultValue = "valor-fixo")
private String valorFixo;
```

---

## 4. Tipos suportados

`String`, `Integer`/`int`, `Boolean`/`boolean`, `Long`/`long`, `Double`/`double`, `Float`/`float` — e `Provider` de qualquer um deles. Conversao de `String` para o tipo declarado e automatica.

---

## 5. Exemplo completo

```java
import br.com.sankhya.studio.stereotypes.Value;
import br.com.sankhya.internal.sdk.injectors.ValueType;
import br.com.sankhya.studio.stereotypes.Component;
import com.google.inject.Inject;
import com.google.inject.Provider;

@Component
public class IntegracaoConfig {

    @Value(value = "API_BASE_URL", type = ValueType.ENV_VAR, defaultValue = "http://localhost:8080")
    private Provider apiBaseUrl;

    @Value(value = "API_KEY", type = ValueType.ENV_VAR, defaultValue = "dev-key")
    private Provider apiKey;

    // ATENCAO: congela no primeiro get() — para toggle sem restart, ver secao "Feature flag togglavel"
    @Value(param = "INTEGRACAO_ATIVA", type = ValueType.SANKHYA_PARAM, defaultValue = "false")
    private Provider integracaoAtiva;

    @Value(value = "http.timeout", type = ValueType.SYSTEM_PROPERTY, defaultValue = "30000")
    private Integer timeout;

    private final IntegracaoHttpDispatcher dispatcher;

    @Inject
    public IntegracaoConfig(IntegracaoHttpDispatcher dispatcher) {
        this.dispatcher = dispatcher;
    }

    public void enviar(Payload payload) {
        if (!integracaoAtiva.get()) return;
        dispatcher.enviar(apiBaseUrl.get(), apiKey.get(), payload, timeout);
    }
}
```

---

## 6. Feature flag togglavel (sem restart)

`@Value` (eager OU lazy) **nao serve** para flag que precisa mudar em runtime: eager resolve na criacao, lazy congela no primeiro `.get()`. Para toggle refletir sem restart, leia o parametro direto a cada uso via `MGECoreParameter` (mesma API que o `PropertyResolver` do SDK chama por baixo):

```java
import br.com.sankhya.modelcore.util.MGECoreParameter;

private boolean flagAtiva() {
    try {
        return MGECoreParameter.getParameterAsBoolean("PRXMODMINHAFLAG");
    } catch (Exception e) {
        return false; // default seguro — fora do contexto do ERP a chamada lanca
    }
}
```

**Pre-requisitos:**

- Parametro declarado com `cacheable="false"` no `parameter.xml` (ver secao 7) — senao o proprio ERP cacheia o valor.
- `try/catch` com default seguro e obrigatorio — fora do contexto do ERP (e em teste) a chamada lanca.

> `ValueProvider.clearCache()` existe e e publico, mas a classe e interna (`br.com.sankhya.internal.*`) — documentado apenas como solucao para **testes**, nao para producao.

---

## 7. Declarando o parametro (`META-INF/parameter.xml`)

`@Value(type = SANKHYA_PARAM)` e `MGECoreParameter` pressupoem parametro **existente**. Declare em `src/main/resources/META-INF/parameter.xml` — o deploy registra e o valor fica editavel nas Preferencias do ERP:

```xml

```

Restricoes do XSD (`parameters.xsd`) que derrubam o build/deploy:

| Atributo | Restricao |
|:---------|:----------|
| `key` | 3–15 chars, `[a-zA-Z_]+` — **sem digitos** |
| `name` | `[a-zA-Z.]+` (pontuado, comeca com o modulo) |
| `description` | 3–50 chars |
| `type` | `integer` / `string` / `boolean` / `date` / `list` / `number` |
| `cacheable` | `false` para valor que muda em runtime (flags) |
| `module` | letra do modulo (ex.: `B` = Configuracao) |
| `list-content` | opcoes separadas por `\n` quando `type="list"` |

> `cacheable="false"` e pre-requisito do pattern de flag togglavel da secao 6.

---

## 8. Restricoes

- **Somente em classes gerenciadas pelo Guice** (`@Component`, `@Controller`, `@Repository`, etc.). Em classes criadas com `new`, o campo fica `null`.
- **Nao funciona em campos `final`**.
- `group` e exclusivo de `SANKHYA_PARAM` — ignorado nas outras fontes.

---

## 9. Anti-Patterns (PROIBIDO)

| Anti-Pattern                                       | Correcao                                          |
|:---------------------------------------------------|:--------------------------------------------------|
| Classe nao gerenciada com `@Value`                 | Anotar classe com `@Component` ou equivalente     |
| Campo `final` anotado com `@Value`                 | Remover `final`                                   |
| `defaultValue = ""` em valor critico               | Fornecer fallback significativo                   |
| `value` e `param` juntos (ambiguidade)             | Usar so `param` — tem precedencia de qualquer forma|
| `group` em `ENV_VAR` ou `SYSTEM_PROPERTY`          | `group` so funciona com `SANKHYA_PARAM`           |
| Eager em valor opcional/custoso                    | Usar `Provider` (Lazy)                         |
| `Provider` como feature flag togglavel          | Congela no primeiro `.get()` — ler `MGECoreParameter` a cada uso + `cacheable="false"` (secao 6) |
| `SANKHYA_PARAM` sem declarar no `parameter.xml`    | Declarar em `META-INF/parameter.xml` (secao 7)    |

---

## 10. Checklist: Novo `@Value`

1. [ ] Classe anotada com estereotipo Guice (`@Component`, `@Controller`, etc.).
2. [ ] Escolher fonte correta: `ENV_VAR`, `SYSTEM_PROPERTY` ou `SANKHYA_PARAM`.
3. [ ] Usar `param` para `SANKHYA_PARAM` (com `group` se necessario); `value` para as demais.
4. [ ] `SANKHYA_PARAM`: parametro declarado no `META-INF/parameter.xml` (secao 7).
5. [ ] Definir `defaultValue` com valor significativo — nunca string vazia em config critica.
6. [ ] Decidir Eager vs Lazy: `Provider` se o valor for opcional/custoso — lembrando que congela apos o primeiro `.get()`.
7. [ ] Flag que precisa mudar sem restart? **Nao** usar `@Value` — pattern da secao 6.
8. [ ] Campo nao e `final`.

## Skills relacionadas

- `dependency-injection` — wiring Guice que injeta os `@Value`; `@Value` só funciona em `@Component` (e demais estereótipos) gerenciados pelo Guice
- `addon-studio` — regras universais do projeto

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [snk-devcenter](https://github.com/snk-devcenter)
- **Source:** [snk-devcenter/addon-studio](https://github.com/snk-devcenter/addon-studio)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-snk-devcenter-addon-studio-value
- Seller: https://agentstack.voostack.com/s/snk-devcenter
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
