# Addon Studio

> Overview e regras universais do projeto Sankhya Addon Studio 2.0 (Wildfly/EJB + JAPE SDK) — Java 8 strict, Lombok, ISO-8859-1, Guice DI, MapStruct, JapeRepository, convenção de nomenclatura `<PRX><MOD3><CTX>` e fluxo de feature CRUD end-to-end. Use ao planejar ou implementar feature/MVP/módulo/cadastro, ao receber spec end-to-end, ao definir naming convention, ao orientar trabalho multi-artefato…

- **Type:** Skill
- **Install:** `agentstack add skill-snk-devcenter-addon-studio-addon-studio`
- **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/addon-studio

## Install

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

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

## About

# Sankhya Addon Studio 2.0 — Overview

Skill orienta projetos **Sankhya Addon Studio 2.0** (Wildfly/EJB + SDK Java JAPE). Foco: stack, regras universais, convenção de nomenclatura, fluxo CRUD. **Sem opinião arquitetural** — pacotes, camadas, design = decisão dev/projeto.

Para tópicos específicos (entidades, controllers, repositories, jobs, etc.), invoque a skill focada correspondente — ver "Skills do plugin" abaixo.

---

## Como detectar projeto Sankhya Addon Studio

Marca registrada: `build.gradle` ou `build.gradle.kts` aplica o plugin Gradle do SDK Sankhya.

```groovy
// build.gradle (Groovy DSL)
apply plugin: "br.com.sankhya.addonstudio"
```

```kotlin
// build.gradle.kts (Kotlin DSL)
plugins {
    id("br.com.sankhya.addonstudio")
}
```

**Se o projeto aplica esse plugin, este plugin Claude Code (`addon-studio`) é a fonte de verdade — siga as skills daqui.** Antes de gerar/alterar código:

1. Identifique o domínio (entity, repository, retrofit, controller, controller-advice, dbscript, dicionário de dados, mapstruct, dependency-injection, action-button, business-rule, listener, before-load-listener, job, type-adapter, value, macros, tela HTML5 do addon, encoding, build, test).
2. Invoque a skill focada correspondente — não improvise nem misture convenções de outros stacks (Spring Boot, Quarkus, JPA padrão, etc.) **nem decompile o `.jar` do SDK** para "descobrir" a anotação/assinatura: a skill é a referência de API (imports e assinaturas reais do SDK). Jar é artefato de build, não fonte de convenção.
3. Para regras universais (Java 8, Lombok, encoding ISO-8859-1, naming ``), volte neste overview.

> Conflito entre convenção do projeto e skill: **prevalece a skill** (a não ser que o projeto declare regra explícita em `CLAUDE.md` na raiz).

### Setup do projeto consumidor

Plugin entrega um arquivo `ADDON.md` pronto com as instruções acima formatadas para o agente. Setup é feito pela skill dedicada **`/addon-studio:init`**, que:

1. Copia `ADDON.md` (fonte canônica: `/skills/addon-studio/assets/ADDON.md`) para `docs/ADDON.md` no projeto.
2. Cria ou atualiza o `CLAUDE.md` da raiz com a linha `@docs/ADDON.md` (idempotente).

Se o usuário pedir "configurar `CLAUDE.md`", "setup do projeto", "atualizar `ADDON.md`" ou similar, **delegue para `/addon-studio:init`** — não copie manualmente.

---

## Stack tecnológica

| Item            | Versão / Detalhe                                                |
|:----------------|:----------------------------------------------------------------|
| Linguagem       | **Java 8 estrito**                                              |
| Container       | Wildfly + EJB                                                   |
| DI              | Google Guice (`com.google.inject.Inject`)                       |
| Persistência    | JAPE (SDK Sankhya) via `@JapeEntity` + `JapeRepository`         |
| ORM             | JAPE (NÃO usar JPA padrão `javax.persistence.@Entity`)          |
| Logging         | `java.util.logging` via `@Log` Lombok                           |
| Boilerplate     | Lombok (`@Data`, `@Builder`, `@AllArgsConstructor`, etc.)       |
| Mapeamento      | MapStruct 1.5.5+ (`componentModel=jakarta` global)              |
| HTTP externo    | Retrofit + Moshi + OkHttp (ver skill `retrofit`)                |
| Validação       | Bean Validation (`javax.validation.*`) + `@Valid`               |
| Testes          | JUnit 5 + Mockito 4.11 (5.x exige Java 11+)                     |
| Build           | Gradle (`gradle deployAddon`)                                   |

---

## Restrições Java 8

**NÃO use APIs pós-Java 8:**

- `var` (use tipagem explícita)
- `List.of(...)`, `Map.of(...)`, `Set.of(...)` (use `Arrays.asList`, `Collections.unmodifiableMap`)
- `String.isBlank()` (use `s == null || s.trim().isEmpty()`)
- `Files.readString(...)` (use `Files.readAllBytes` + `new String(...)`)
- `Optional.ifPresentOrElse(...)`, `Optional.or(...)`, `Optional.stream()`
- `Stream.toList()` (use `.collect(Collectors.toList())`)
- Records, sealed classes, pattern matching, text blocks

---

## Estilo de código

### Lombok obrigatório

- `@Data` em entidades, DTOs, VOs
- `@NoArgsConstructor` + `@AllArgsConstructor` em entidades JAPE (framework precisa)
- `@Builder` quando construção programática fizer sentido
- `@Log` para acesso a `java.util.logging.Logger` como `log`
- `@Getter`, `@Setter`, `@AllArgsConstructor` em enums com `value`

### Logging

- **Sempre** `@Log` Lombok + `java.util.logging`.
- **Nunca** SLF4J (`org.slf4j.*`). **Nunca** `System.out.println`.
- Níveis: `INFO`, `WARNING`, `SEVERE`.

```java
@Log
public class Exemplo {
    public void executar() {
        log.log(Level.INFO, "Iniciando processo");
        try {
            // ...
        } catch (Exception e) {
            log.log(Level.SEVERE, "Falha ao executar: " + e.getMessage(), e);
        }
    }
}
```

### Injeção de dependência

- Sempre `@Inject` via construtor. Nunca em campo (exceção: mappers MapStruct `abstract class` com repository — ver skill `mapstruct`).
- `@Inject` de **`com.google.inject.Inject`**. Nunca `javax.inject.Inject`.
- Dependências declaradas `private final`.
- Nunca usar `new` para criar dependência gerenciada.

### Tipagem em campos numéricos

| Contexto                                       | Tipo Java                  |
|:-----------------------------------------------|:---------------------------|
| PK de tabelas do addon (`COD*`/`NU*` própria)  | `Integer`                  |
| PK de tabelas nativas Sankhya (NUNOTA, CODPARC, etc.) | `BigDecimal`        |
| Valores monetários, quantidades                | `BigDecimal`               |
| Flags S/N (mapeadas com `dataType="CHECKBOX"`) | `Boolean`                  |
| Datas com hora                                 | `Timestamp` (`java.sql.Timestamp`) |

---

## Exceções

- **Nunca** lançar `RuntimeException` cru.
- Definir hierarquia de exceções tipadas estendendo `RuntimeException`.
- Mensagens voltadas a usuário de negócio (sem detalhes de infra/stack).

```java
public class IntegrationApiException extends RuntimeException {
    public IntegrationApiException(String message, Throwable cause) {
        super(message, cause);
    }
}
```

Tratamento centralizado em controllers — ver skill `controller-advice`.

---

## O que NÃO fazer

| Anti-pattern                                                     | Correção                                                |
|:-----------------------------------------------------------------|:--------------------------------------------------------|
| Usar `var`                                                       | Tipagem explícita sempre                                |
| Usar JPA padrão (`javax.persistence.@Entity`, `@Table`)          | Usar `@JapeEntity` (SDK Sankhya)                        |
| Implementação manual de Repository                               | Usar interface estendendo `JapeRepository`  |
| Usar `JapeWrapper` ou `EntityFacade` direto em controllers       | Sempre via Repository / `JapeRepository`                |
| Mapper escrito a mão (`new Dto(); dto.setX(...)`)                | Usar MapStruct                                          |
| `HttpClient` nativo / `URLConnection` para integração externa    | Usar Retrofit + Moshi + OkHttp (skill `retrofit`)       |
| Logger SLF4J ou `System.out`                                     | `@Log` Lombok + `java.util.logging`                     |
| `new` para instanciar dependência gerenciada                     | `@Inject` via construtor                                |
| Metadata UI (description, dataType, order) em entidade Java      | Vai no XML do dicionário de dados                       |
| `@Inject` de `javax.inject`                                      | Usar `com.google.inject.Inject`                         |
| `throw new RuntimeException(...)` cru                            | Exceção tipada                                          |
| Improvisar com convenções de Spring Boot, Quarkus, Micronaut     | Seguir as skills do plugin (`@JapeEntity`, `@Controller serviceName SP`, Guice, etc.) |
| Decompilar/`javap`/`unzip` no `.jar` do SDK p/ achar **qualquer** símbolo (anotação, classe, interface, enum, assinatura — `@JapeEntity`, `@Controller`, `IJob`, …) | Invocar a skill focada — ela fixa imports e assinaturas reais do SDK. Símbolo sem skill: perguntar ao dev, não ir ao jar |
| Em ``, raiz com `CODIGOPAI = NULL` ou `GRAU = 0`      | Sentinela `CODIGOPAI = -999999999` e `GRAU = 1` (ver skill `data-dictionary` → `tree-table.md`) |
| APIs Java 11+ (`var`, `List.of`, `String.isBlank`, records, etc.) | Equivalentes Java 8 — ver "Restrições Java 8" acima      |

---

## Convenção de nomenclatura (parametrizada por projeto)

Aplica a tabelas/entities do addon. Padrão parametrizado por dois tokens — `` (prefixo) + `` (módulo) — definidos pelo projeto:

| Artefato                              | Padrão                            | Exemplo (PRX=TDC, MOD3=XYZ)  |
|:--------------------------------------|:----------------------------------|:-----------------------------|
| Tabela do addon                       | `` UPPER          | `TDCXYZCAB`                  |
| `@JapeEntity(entity = "...")`         | `` Pascal          | `TdcXyzCabecalho`            |
| Coluna custom em tabela nativa Sankhya| `_NOMECAMPO` UPPER          | `XYZ_STATUS`                 |

- `` / `` = prefixo fixo do projeto (ex.: `TDC`, `APP`, `CST` — UPPER 3-4 chars).
- `` / `` = sigla 3 chars do módulo (ex.: `XYZ`, `FIN`, `FAT`).
- `` / `` = contexto/entidade da tabela (ex.: `CAB`/`Cabecalho`, `ITE`/`Item`, `CFG`/`Configuracao`).

### Descobrir convenção do projeto

Antes de criar tabela/entity nova:

1. **Inspecionar projeto existente:** procurar `@JapeEntity(table = "...")` em arquivos `.java`, `` em `datadictionary/*.xml`, ou `CREATE TABLE` em `dbscripts/*.xml`. Se houver padrão consistente (ex.: todas tabelas começam com `TDC`), reusar.
2. **Se não houver padrão detectável ou projeto for novo:** **perguntar ao dev** explicitamente:
   - "Qual prefixo (``) usar para tabelas custom deste projeto? Ex.: `TDC`, `APP`, `CST`."
   - "Qual sigla de 3 chars (``) representa este módulo? Ex.: `XYZ`, `FIN`, `FAT`."
3. **Confirmar nome final** antes de gerar artefatos: ``.

---

## Quando perguntar antes de criar

- **Nome tabela nova:** descobrir/confirmar `` + `` + `` + nome final ``.
- **Campos auditoria** (`DHALTER`, `DHCREATE`, `CODUSU`): perguntar se inclui.
- **Convenção pacote / organização camadas:** **não opinar.** Dev decide.

---

## Fluxo típico de criação de feature CRUD

1. XML dicionário de dados em `datadictionary/.xml` (skill `data-dictionary`).
2. Script banco em `dbscripts/V-CREATE_TABLE_.xml` (skill `database`).
3. Entidade `@JapeEntity` Java (skill `entity`).
4. Repository estendendo `JapeRepository` (skill `repository`).
5. Service `Service` (`@Component`) com a regra de negócio — skill `dependency-injection`.
6. Controller REST `@Controller(serviceName = "...SP")` (skill `controller`).
7. Request/Response DTOs + Mapper MapStruct (skill `mapstruct`).
8. Testes JUnit + Mockito (skill `test`).
9. Tela HTML5, quando o cadastro precisar de UI própria (skill `sankhya-js`) — CRUD simples resolve com `` no menu.
10. Build: `gradle deployAddon` (skill `build`).

> **Delegação obrigatória aos sub-agents (Claude Code only):** tabela de delegação: ver `ADDON.md` (always-on no projeto).

---

## Skills do plugin

Para tópicos específicos, invoke skill direta:

- `init` — setup inicial: copia `ADDON.md` pra `docs/` + import no `CLAUDE.md`
- `entity` — entidades `@JapeEntity`
- `repository` — `@Repository` / `JapeRepository`
- `retrofit` — integração HTTP externa (Retrofit + Moshi + OkHttp)
- `controller` — `@Controller` REST
- `controller-advice` — `@ControllerAdvice` / `@ExceptionHandler`
- `data-dictionary` — XML dicionário de dados
- `database` — `dbscripts/V-*.xml`
- `dependency-injection` — Guice DI
- `mapstruct` — MapStruct mappers
- `test` — JUnit + Mockito
- `action-button` — `@ActionButton`
- `business-rule` — `@BusinessRule`
- `listener` — `@Listener` (**escrita**: eventos CRUD before/after insert/update/delete — não confundir com `before-load-listener`)
- `before-load-listener` — `@BeforeLoadListener` (**leitura**: intercepta buscas do Finder JAPE — não confundir com `listener`)
- `job` — `@Job`
- `type-adapter` — `@GlobalTypeAdapter`
- `value` — `@Value` / `ValueType`
- `macros` — MacroTranslator SQL macros
- `sankhya-utils` — utilitários `com.sankhya.util` já no classpath (null-safety, `BigDecimal`, data, XML/JSON)
- `sankhya-js` — telas HTML5 do módulo `-vc` (AngularJS 1.x: `sk-application`, `sk-dynaform`, `ServiceProxy`, `gerarTela`)
- `encoding` — ISO-8859-1
- `build` — `gradle deployAddon`

---

## Skills relacionadas

- `entity` — primeiro artefato de uma feature CRUD
- `data-dictionary` — XML metadata da tabela
- `database` — dbscript de migration
- `controller` — endpoint REST que consome a feature
- `encoding` — regra crítica de Latin-1 aplicada em todo arquivo `.java`/`.xml`/`.kt`/`.properties`

## 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-addon-studio
- 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%.
