Pular para o conteúdo principal

Regras de deck pela API

As regras de deck (Cards) preparam e ajustam os decks NEWAVE e DECOMP. Esta página mostra como validar e enviar regras, usar Cards do catálogo, definir perfis e sequências de regras e conferir o deck montado pela API. O conceito de base e ajustes e o uso no Portal estão em Cards; os campos do YAML estão na referência do YAML. Autenticação, Operation e erros comuns estão na visão geral; os campos de cada rota, na referência interativa.

Toda regra usada numa sequência é uma referência imutável:

{"tipo": "upload", "id": "rules_0123456789abcdef0123456789abcdef", "sha256": "1111111111111111111111111111111111111111111111111111111111111111"}

Você obtém essa referência enviando um arquivo (POST /deck-rules/uploads) ou resolvendo um Card do catálogo (POST /deck-rules/catalog/{catalog_id}/resolve).

Validar e enviar​

Valide um arquivo sem salvá-lo:

curl -sS -X POST "$MYRIA_API/api/v1/deck-rules/validate" \
-H "Authorization: Bearer $MYRIA_TOKEN" \
-F "expected_document_type=ajuste" \
-F "file=@sensibilidade.yaml;type=application/yaml"

A validação aceita só YAML e sempre responde 200: um YAML inválido volta com valid: false e a lista errors, cada erro com o caminho como você escreveu no YAML (por exemplo, montar.decomp.DP.0.periodo). A resposta traz também sha256, size_bytes, document_type e summary. expected_document_type é opcional e aceita base ou ajuste. Na API, ajuste é o papel de um Card: um documento tipo: card tem document_type: "ajuste"; base corresponde a tipo: base. Essa rota não usa Idempotency-Key.

summary resume o documento na grafia do YAML:

{"avisos": [{"code": "carga_duplicada_newave_decomp", "message": "A carga do DECOMP e formada a partir da carga do NEWAVE; alterar as duas soma a variacao duas vezes.", "newave": "newave.SISTEMA.carga [submercado SE] mes_1 add", "decomp": "decomp.DP.carga [submercado SE] add"}], "versao": 5, "tipo": "card", "titulo": "Carga +1 GW no primeiro mês", "descricao": "...", "command_count": 2, "models": {"decomp": {"DP": 1}, "newave": {"SISTEMA": 1}}, "has_policies": false}

tipo é card ou base, e titulo/descricao são os do documento. command_count conta as operações depois da expansão do léxico, e models conta essas operações por modelo e família. has_policies indica se o documento declara politicas (só uma base pode declarar).

avisos lista o que o Card pode estar aplicando duas vezes. Não é erro: o upload continua válido, e a tela da rodada pede confirmação antes de pôr o Card na sequência. Os códigos são carga_duplicada_newave_decomp, carga_definida_no_dp, cvu_duplicado_newave_decomp e geracao_duplicada_newave_decomp (veja Blocos do DECOMP formados a partir do NEWAVE). Um Card sem nenhuma entrada em montar nem em antes_de_rodar recebe o aviso card_vazio, com newave e decomp vazios: ele não altera nenhum deck.

Verificar contra a rodada​

O esquema não confere usinas, restrições ou meses com um deck. Para conferir o Card com o deck de uma rodada, envie também study_key e round_key (os dois juntos; só um deles retorna 400 invalid_payload):

curl -sS -X POST "$MYRIA_API/api/v1/deck-rules/validate" \
-H "Authorization: Bearer $MYRIA_TOKEN" \
-F "study_key=$STUDY_KEY" \
-F "round_key=$ROUND_KEY" \
-F "file=@sensibilidade.yaml;type=application/yaml"

A conferência lê só os cadastros do deck (usinas, UTEs, REEs, submercados, rotas, restrições e horizonte), sem montar nada. O Card entra no fim da sequência salva da rodada: o que a base e os Cards anteriores criam conta como existente. O deck conferido é o de entrada, sobre o qual os Cards são aplicados: o deck de referência do PMO/RV da rodada; sem ele, o da própria rodada e, por fim, o da rodada anterior do mesmo modelo, sempre com o PMO e a revisão da rodada conferida.

Para um Card válido (document_type: "ajuste"), a resposta ganha verificacao; para uma base ou um YAML inválido, verificacao é null. Sem study_key/round_key o campo não aparece.

{"verificacao": {"round_key": "acme-12", "valido": false, "erros": 1, "avisos": 1, "modelo": "decomp", "preflight_dos_cards": "apply", "deck": {"disponivel": true, "origem": "rodada", "descricao": "Deck desta rodada", "indisponivel": [], "mensagem": null}, "achados": [{"severidade": "erro", "codigo": "ute_inexistente", "titulo": "Inflexibilidade", "caminho": "montar.decomp.CT.0", "entidade": "UTE 8888", "modelo": "decomp", "mensagem": "UTE 8888 nao existe no cadastro do DECOMP desta rodada", "texto": "Card \"Inflexibilidade\", montar.decomp.CT.0: UTE 8888 nao existe no cadastro do DECOMP desta rodada [ute_inexistente]"}, {"severidade": "aviso", "codigo": "restricao_ausente", "titulo": "Inflexibilidade", "caminho": "montar.decomp.RE.1.RE 447", "entidade": "RE 447", "modelo": "decomp", "mensagem": "RE 447 nao existe no DADGER desta rodada; a entrada sera ignorada nesta rodada", "texto": "..."}]}}

Cada achado traz severidade, codigo, o caminho da entrada como você escreveu no YAML, a entidade e a mensagem; texto junta tudo numa frase. valido: false quando há pelo menos um erro.

SeveridadeQuandoCódigos
erroEntidade de cadastro fora do deck, inclusive em termos de uma restrição criada; RI, IA ou HE alterado sem existir; restrição do DECOMP alterada só pelo nome sem criação nem número que a resolvauhe_inexistente, ute_inexistente, ree_inexistente, submercado_inexistente, rota_inexistente, restricao_estrutural_ausente, restricao_nome_nao_resolvido
avisoAlvo de vigência ausente: a entrada é ignorada nesta rodadarestricao_ausente, restricao_comentada, restricao_eletrica_ausente, agrint_grupo_ausente, periodo_anterior_ao_pmo, periodo_fora_do_horizonte, estagio_fora_do_horizonte, term_mes_fora_do_ano
avisoCard sem efeito nesta rodadacard_vazio, sem_efeito_no_modelo (só seções do outro modelo), preflight_desligado (só antes_de_rodar com o Preflight dos Cards em skip)

deck.disponivel: false quer dizer que não havia deck para ler (ou a leitura passou do prazo); deck.mensagem explica, e só os avisos de Card sem efeito são conferidos. deck.indisponivel lista os cadastros que não puderam ser lidos (por exemplo newave.agrint): o que depende deles fica sem conferência. A rodada de outra organização ou inexistente retorna 404 not_found.

Na tela da rodada, a mesma conferência roda ao adicionar um Card à sequência e no botão Verificar contra a rodada: erro impede adicionar o Card; aviso pede confirmação.

Para guardar o arquivo e obter a referência, use POST /deck-rules/uploads com Idempotency-Key:

curl -sS -X POST "$MYRIA_API/api/v1/deck-rules/uploads" \
-H "Authorization: Bearer $MYRIA_TOKEN" \
-H "Idempotency-Key: card-carga-alta-001" \
-F "expected_document_type=ajuste" \
-F "file=@sensibilidade.yaml;type=application/yaml"

O envio aceita YAML (versao: 5) e planilhas Excel de ajustes (.xlsx ou .xls). O formato é identificado pelo conteúdo e conferido com a extensão. Uma planilha é convertida para YAML e passa pelas mesmas validações; planilhas com macros, criptografia ou compressão suspeita são recusadas, e uma planilha que não seja claramente do modelo suportado retorna spreadsheet_dialect_ambiguous. O arquivo tem até 2 MiB (413 deck_rules_source_too_large) e nome de até 255 caracteres (400 invalid_original_name). Um documento inválido retorna 422 e não é guardado.

Os erros próprios de planilhas usam o prefixo spreadsheet_, por exemplo spreadsheet_dialect_ambiguous, spreadsheet_signature_mismatch, spreadsheet_macros_not_allowed, spreadsheet_encrypted_not_allowed, spreadsheet_zip_bomb e spreadsheet_invalid_xlsx. Desde outubro de 2026 esse é o único prefixo emitido para esses erros; se a sua integração compara códigos de planilha, use esses nomes.

A resposta é 201, com upload (a referência {tipo, id, sha256}), document_type, original_name, size_bytes, summary e created_at. O conteúdo não é devolvido. Repetir a chave com o mesmo arquivo devolve a mesma resposta; com outro arquivo, 409.

GET /deck-rules/catalog lista os Cards visíveis para a organização, com paginação por cursor. Filtros opcionais:

ParâmetroValores
modelnewave ou decomp
originmyria, organization ou study (este exige study_key)
study_keyInclui os Cards do estudo.
qBusca no título e na descrição.

Cada item traz catalog_id, title, description, tags, visibility, role (base ou ajuste, o papel de um Card), models, published_version e resolved_reference. Se resolved_reference vier preenchido, use-o diretamente. Se vier null, peça a resolução:

curl -sS -X POST "$MYRIA_API/api/v1/deck-rules/catalog/$CATALOG_ID/resolve" \
-H "Authorization: Bearer $MYRIA_TOKEN" \
-H "Idempotency-Key: resolver-$CATALOG_ID-1"

O pedido não precisa de corpo, exceto para um Card exclusivo de estudo: nesse caso envie {"study_key": "<study_key>"}. A resposta é 202 Operation. Em succeeded, result.deck_rules_reference traz a referência {tipo:"upload",id,sha256} e result.avisos traz os mesmos avisos do envio do Card (lista vazia quando não há). A versão publicada do Card é fixada quando o pedido é aceito, então repetir o pedido não troca de versão.

Perfis​

O perfil define a sequência de regras usada por padrão. Há um perfil da organização e um por estudo:

  • GET e PATCH /deck-rules/profile (organização);
  • GET e PATCH /studies/{study_key}/deck-rules-profile (estudo).

GET exige studies:read e PATCH, studies:write. A resposta traz scope, state, revision, ordered_source_items, model_defaults, phase_policy, phase_policy_provenance e composition_sha256. Sem perfil salvo, o GET responde state: "implicit" e revision: 0, só com a base do Myria, sem gravar nada.

O PATCH substitui o perfil inteiro. Exige Idempotency-Key e o número de revisão que você leu, em expected_revision ou no cabeçalho If-Match. O primeiro PATCH usa 0 e cria a revisão 1.

{
"expected_revision": 0,
"ordered_source_items": [
{"ordem": 1, "papel": "base", "proveniencia": "oficial", "tipo": "oficial", "modelo": ""},
{"ordem": 2, "papel": "ajuste", "proveniencia": "adicionado", "tipo": "upload",
"id": "rules_0123456789abcdef0123456789abcdef",
"sha256": "1111111111111111111111111111111111111111111111111111111111111111",
"modelo": "decomp"}
],
"model_defaults": {"newave": [1], "decomp": [1, 2]},
"phase_policy": {"source_declared_preflight": "apply"}
}
CampoUso
ordered_source_itemsA sequência completa. ordem começa em 1 e não pula números. Só pode haver uma base, e ela vem primeiro. tipo: "oficial" é a base do Myria e não leva id nem sha256; tipo: "upload" exige a referência. modelo é newave, decomp ou vazio (os dois).
model_defaultsPara cada modelo, as posições (ordem) usadas por padrão.
phase_policysource_declared_preflight: apply (padrão) ou skip. skip ignora só a seção antes_de_rodar dos Cards; o antes_de_rodar da base sempre roda. É o interruptor Ajustes condicionais da sequência no Portal.

Um número de revisão desatualizado retorna 409, mesmo que o conteúdo enviado seja igual ao atual. Mudar um perfil não altera rodadas já criadas nem regras já usadas numa execução.

As primeiras rodadas geradas a partir de uma base externa sem rodada consumidora recebem o perfil do estudo, com as posições padrão de cada modelo (model_defaults). Esse perfil inclui o padrão da organização copiado ao criar o estudo. Continuações com rodada de origem herdam a sequência de Cards dessa rodada; alterar o perfil depois não substitui essa herança. Se model_defaults mudar entre a prévia e a criação das primeiras rodadas, gere uma nova prévia. Na confirmação, reenvie origin_configuration_revision exatamente como recebido da prévia: esse valor identifica a origem e as posições padrão vistas na prévia.

skip não permite omitir condições DECOMP que fazem parte de uma criação. Se um Card cria uma restrição em montar e liga a ela condições no próprio antes_de_rodar, a operação falha com source_declared_preflight_required_for_creation e preserva o deck publicado. As condições da base nunca são afetadas por skip. Validações estruturais e limites físicos continuam obrigatórios.

Cards da rodada​

Cada rodada guarda a sua sequência de Cards: a mesma lista ordered_source_items dos perfis, com uma revisão por alteração. O padrão do estudo fica no perfil do estudo.

GET /studies/{study_key}/rodadas/{round_key}/deck-rules exige studies:read e devolve study_key, round (round_key e name), configuration_revision, rule_stack (revision, state, origin, study_profile_revision, composition_sha256 e ordered_source_items), admitted e admitted_at. state: "open" indica uma revisão que ainda não foi usada numa execução; admitted, a que foi fixada por uma execução.

PUT na mesma rota exige studies:write e Idempotency-Key e salva a sequência pelo mesmo caminho da tela, ou seja, uma nova revisão da configuração da rodada:

curl -sS -X PUT "$MYRIA_API/api/v1/studies/$STUDY_KEY/rodadas/$ROUND_KEY/deck-rules" \
-H "Authorization: Bearer $MYRIA_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: regras-206-001" \
-d '{
"expected_configuration_revision": 0,
"rule_stack": {
"origin": "round",
"ordered_source_items": [
{"ordem": 1, "papel": "base", "proveniencia": "oficial", "tipo": "oficial",
"id": null, "sha256": null, "modelo": ""},
{"ordem": 2, "papel": "ajuste", "proveniencia": "adicionado", "tipo": "upload",
"id": "rules_0123456789abcdef0123456789abcdef",
"sha256": "1111111111111111111111111111111111111111111111111111111111111111",
"modelo": ""}
]
}
}'

expected_configuration_revision é o configuration_revision lido no GET (0 quando a rodada ainda não tem revisão de configuração). Um número desatualizado retorna 409 configuration_revision_conflict e nada é sobrescrito. Para voltar ao perfil do estudo, envie "rule_stack": {"origin": "study_default"}, sem itens. Numa rodada que já executou, a sequência usada fica preservada: o PUT abre uma nova revisão, e as regras novas valem na próxima montagem. RV+ e M+ também herdam os Cards salvos da origem, e a origem mantém sua sequência salva depois da criação desses novos períodos. Para aplicar a configuração, use POST .../configuration/apply.

Prévia do deck montado​

POST /studies/{study_key}/rodadas/{round_key}/deck-rules/preview monta o deck da rodada com as regras atuais, compara com o deck antes das regras e descarta o resultado, sem publicar nada.

Para DECOMP RV0 formada a partir de um NEWAVE do mesmo estudo, a prévia lê o deck publicado desse NEWAVE em uma versão fixa. A referência entre as rodadas permanece inalterada, e a prévia não executa o NEWAVE.

curl -sS -X POST \
"$MYRIA_API/api/v1/studies/$STUDY_KEY/rodadas/$ROUND_KEY/deck-rules/preview" \
-H "Authorization: Bearer $MYRIA_TOKEN" \
-H "Idempotency-Key: previa-206-r3"

A rota exige studies:read, não tem corpo e exige Idempotency-Key (sem ele, 400 missing_idempotency_key). A resposta é 202 com a Operation. Repetir a chave devolve o mesmo pedido, sem montar de novo. Depois de mudar as regras ou a configuração da rodada, use uma chave nova: reaproveitar a anterior retorna 409 idempotency_key_reused.

A prévia considera a revisão atual das regras, inclusive quando ela foi salva depois de uma montagem anterior. Se a rodada ainda aguarda os volumes de armazenamento (EARM), os outros ajustes, como carga, continuam aparecendo na prévia e na aplicação da configuração; o armazenamento só é ajustado logo antes da execução.

Em succeeded, result.preview traz:

  • materialized: true e published: false;
  • os SHA-256 do pacote, do plano, das regras e das árvores de entrada e saída;
  • sources: as regras na ordem aplicada, com a referência de cada uma;
  • files: cada arquivo do deck, com seus blocos e o estado de cada um (created, removed, modified ou unchanged);
  • summary e diagnostics;
  • scenario, com o deck de partida e o efeito de cada Card (applied, shadowed, outside_horizon ou no_op).

Se uma fonte faltar ou divergir, o pedido termina com erro; o Myria não completa valores por conta própria.