Skip to content

Contratos e adapters

Por que isso importa no produto

Como módulo central, a forecast-engine precisa trocar dados com outros serviços sem ambiguidade. Contratos e adapters são a barreira de segurança entre núcleo de domínio e infraestrutura externa.

Contratos (msgspec)

contracts/* define payloads canônicos para integração.

Características:

  • validação de tipo em runtime;
  • rejeição de campos desconhecidos (forbid_unknown_fields=True);
  • enums explícitos para granularidade e UOM.
  • configs de estratégia/métrica/evaluator aceitam árvores JSON-like aninhadas para transportar listas e objetos sem perder informação.
  • params_schema.execution.training_mode permite opt-in explícito para treino em lote sem alterar o contrato de predição.

Exemplo de decode seguro:

import msgspec
from contracts.demand import DemandSeriesContract
payload_bytes = b'...json...'
series_contract = msgspec.json.decode(payload_bytes, type=DemandSeriesContract)

Adapters de contrato <-> domínio

Módulos:

  • adapters.demand_adapter
  • adapters.modeling_adapter
  • adapters.forecasting_adapter

Responsabilidades:

  • normalização de period_start para UTC;
  • parse de Decimal a partir de str;
  • mapeamento de enums entre contrato e domínio;
  • preservação de metadados de auditoria (created_at, ids, status).

Adapter de leitura de config de estratégia

adapters.strategy_config oferece uma visão read-only e normalizada sobre StrategySpec.params_schema.

Peças principais:

  • StrategyConfigView: interface comum de leitura;
  • create_strategy_config_view(...): construtor read-only da view.

Garantias:

  • expõe training_mode com default estável em series;
  • valida execution.training_mode com erro explícito para valores fora de series / batch;
  • preserva a convenção aninhada em params_schema para uso de adapters concretos;
  • mantém known_future_features disponível no contrato, mesmo antes de uso por adapters concretos.

Adapters colunares

PolarsDomainMapper

Converte:

  • DemandSeries <-> polars.DataFrame
  • ForecastRun -> polars.DataFrame
  • DataFrame -> list[ForecastPoint]

Garantias:

  • colunas obrigatórias por contexto;
  • tipos esperados por coluna;
  • coerência de UOM e intervalos na volta para domínio.

PolarsParquetStore

Persistência Parquet com versionamento explícito de schema:

  • grava __schema_version;
  • valida versão ao ler;
  • falha em metadado ausente/incompatível.

Adapter de observabilidade

MlflowExperimentTracker

Implementa ExperimentTrackerPort e garante rastreabilidade:

  • cria/resolve experimento;
  • inicia run por série via start_run(...);
  • inicia run compartilhada por lote via start_batch_run(...);
  • registra parâmetros, tags de estratégia, métricas e artefato;
  • termina run com status normalizado.

MlflowModelRegistryAdapter

Responsável por operacionalizar a promoção decidida pelo domínio:

  • cria registered model automaticamente;
  • registra nova versão concreta por série/estratégia;
  • sincroniza alias champion;
  • resolve serving target por alias.

MlflowForecastObservabilityAdapter

Responsável por emitir telemetria de inferência:

  • uma run por execução de forecast;
  • tags para versão requisitada/executada e fallback;
  • métricas de duração, volume previsto e sucesso.

Adapters de persistência durável

FileSystemModelingRepository

  • persiste ModelDefinition via contratos msgspec;
  • persiste PromotionAuditRecord separado do agregado;
  • suporta reload seguro após restart do processo.

FileSystemForecastingRepository

  • persiste ForecastRun finalizado com metadados de fallback.

LocalArtifactStore

  • grava artefatos com convenção estável por organização, definição, série, estratégia e versão;
  • retorna URI file:// auditável.

Contratos de treino batch

application.engine.contracts agora inclui contratos aditivos para batch training:

  • BatchTrainItem
  • BatchTrainRequest
  • BatchTrainSeriesResult
  • BatchTrainResult

Regras relevantes:

  • BatchTrainRequest.items não pode ser vazio;
  • cada series_key aparece uma única vez por request/result;
  • sucesso por série pode referenciar artefato próprio ou artefato compartilhado do lote;
  • falha por série é explícita via error.