Skip to content

Fluxo de resolução de configurações (Railway/Roadway)

Esta documentação define a fonte de verdade para leitura de configurações (CAPEX + values_params) e como aplicar overrides e taxa de câmbio. Todos os repositórios que leem configurações devem seguir exatamente estas regras.

Objetivo

Garantir que: - haja um base único (versão 0.1) com todos os dados completos; - cada padrão (1, 2, 3, 4, 5...) armazene apenas diferenças (override); - cada configuração do usuário armazene apenas diferenças (override); - cada projeto armazene apenas diferenças (override); - a taxa de câmbio seja aplicada no momento correto, sem duplicar conversão.

Estrutura de dados no Firestore

Base (v0.1)

  • Path:
  • configs/{config_type}/base_v0_1/base
  • config_type:
  • railway (padrão)
  • roadway (quando aplicável)

Overrides de padrões (1..N)

  • Path:
  • configs/{config_type}/overrides/{pattern_id}
  • Conteúdo: apenas campos diferentes do base.

Overrides por idioma (i18n)

  • Path:
  • configs/i18n/{config_type}/pt-br
  • configs/i18n/{config_type}/en
  • Conteúdo:
  • CAPEX.Description
  • CAPEX.Unit
  • Variables (somente textos)
  • Campos fixos (não dependem de idioma):
  • Code
  • Code No Points
  • Code Up

Configuração do usuário

  • Path:
  • users/{user_id}/configs/{user_config_id}
  • Conteúdo: apenas campos diferentes do base + override de padrão.
  • Aqui o usuário escolhe moeda e taxa de conversão.

Configuração do projeto (override final)

  • Paths:
  • users/{user_id}/projects/{project_id}/params/values_params
  • users/{user_id}/projects/{project_id}/params/capex
  • Conteúdo: apenas campos alterados pelo usuário após criar o projeto.

Campos de referência no Project Doc

No documento do projeto: - config_type: railway ou roadway - config_base_ref: (opcional) path absoluto do base - config_pattern_id: id do padrão (1, 2, 3...) - config_pattern_ref: (opcional) path absoluto do override do padrão - user_config_id: id da configuração do usuário - user_config_ref: (opcional) path absoluto do config do usuário

Observação: se *_ref existir, ele sempre tem prioridade sobre o id.

Ordem de resolução (merge)

A resolução final e feita nesta ordem, com merge profundo (override sobrescreve base):

  1. Base: configs/{config_type}/base_v0_1/base
  2. Padrão: configs/{config_type}/overrides/{pattern_id} (ou config_pattern_ref)
  3. Usuário: users/{user_id}/configs/{user_config_id} (ou user_config_ref)
  4. Projeto: projects/{project_id}/params/values_params + params/capex

Regras de merge: - Objetos (map) sao mesclados recursivamente. - Arrays sao substituidos por completo.

Conversão de moeda (CAPEX)

Fonte da taxa

A taxa e buscada nesta ordem: - users/{user_id}/configs/{user_config_id} - projects/{project_id}/params/capex - project_doc - base (se existir em meta)

Chaves aceitas: - currency_rate, exchange_rate, fx_rate, rate - ou dentro de meta com esses mesmos nomes

Aplicação

A taxa só e aplicada no bloco CAPEX dos campos: - Unit Cost - Unit Cost With BDI - Unit Cost with BDI - unit_cost - unit_cost_with_bdi

Não aplicar a taxa em: - textos - unidades - chaves de i18n

Campos dinamicos

list_curves

values_params.axis_geometry.list_curves pode variar entre configs. Esse campo e o único array que pode ter comprimento diferente sem causar erro de compatibilidade.

Requisitos para compatibilidade entre repos

Qualquer repositorio que consuma esses dados deve: 1. Ler o base + overrides exatamente nessa ordem. 2. Aplicar taxa de câmbio somente depois de montar o CAPEX final. 3. Tratar arrays como substituição completa (não merge). 4. Não depender de campos duplicados entre pt-br e en (usar i18n).

Exemplo de resolução (pseudo)

  1. base = configs/railway/base_v0_1/base
  2. override_padrao = configs/railway/overrides/2
  3. override_usuario = users/{uid}/configs/{user_config_id}
  4. override_projeto = users/{uid}/projects/{pid}/params/*
  5. final = merge(base, padrão, usuário, projeto)
  6. aplicar taxa no CAPEX

Onde implementar

  • geoprocessing (config_service): endpoints HTTP e resolver central
  • path-finder-service: sempre receber o payload já resolvido
  • frontend: exibir dados resolvidos e permitir edits locais

Exemplo com paths reais

Projeto: - users/Z15G7BOL63VF7uFOtp1c34jjDkA3/projects/B8I95QcOz3N0azc45t3C

Config base: - configs/railway/base_v0_1/base

Override de padrão (exemplo padrão 2): - configs/railway/overrides/2

Config do usuário (exemplo): - users/Z15G7BOL63VF7uFOtp1c34jjDkA3/configs/1RQvOOJz6rTd13at27Kg

Overrides do projeto: - users/Z15G7BOL63VF7uFOtp1c34jjDkA3/projects/B8I95QcOz3N0azc45t3C/params/values_params - users/Z15G7BOL63VF7uFOtp1c34jjDkA3/projects/B8I95QcOz3N0azc45t3C/params/capex

Versão resumida (checklist rápido)

  1. Base sempre em configs/{config_type}/base_v0_1/base.
  2. Padrão usa configs/{config_type}/overrides/{pattern_id} (somente diff).
  3. Usuário usa users/{uid}/configs/{user_config_id} (somente diff).
  4. Projeto usa projects/{pid}/params/* (somente diff).
  5. Merge profundo na ordem base -> padrão -> usuário -> projeto.
  6. Aplicar taxa no CAPEX somente no final.
  7. Arrays substituem por completo (não mesclar).

Contratos de API (proposta oficial)

GET /configs/resolve

Resolve e retorna values_params + capex completos.

Request (JSON)

Campos aceitos: - config_type (opcional, default railway) - config_base_ref (opcional) - config_pattern_id (opcional) - config_pattern_ref (opcional) - user_id (opcional) - user_config_id (opcional) - user_config_ref (opcional) - project_id (opcional) - project_ref (opcional)

Prioridade: *_ref > *_id.

Response (JSON)

{
  "values_params": { ... },
  "capex": { "CAPEX": { ... } },
  "meta": {
    "base_ref": "configs/railway/base_v0_1/base",
    "pattern_ref": "configs/railway/overrides/2",
    "user_config_ref": "users/UID/configs/CFG",
    "project_ref": "users/UID/projects/PRJ",
    "rate": 5.75
  }
}

Exemplos

1) Somente base

{
  "config_type": "railway",
  "config_base_ref": "configs/railway/base_v0_1/base"
}

2) Base + padrão

{
  "config_type": "railway",
  "config_pattern_id": "2"
}

3) Base + padrão + usuário

{
  "user_id": "Z15G7BOL63VF7uFOtp1c34jjDkA3",
  "user_config_id": "1RQvOOJz6rTd13at27Kg"
}

4) Base + padrão + usuário + projeto

{
  "user_id": "Z15G7BOL63VF7uFOtp1c34jjDkA3",
  "project_id": "B8I95QcOz3N0azc45t3C"
}

POST /configs/override

Recebe um payload completo (ou parcial), calcula diff e salva somente o override.

Request (JSON)

Campos comuns: - target: "user_config" ou "project_params" - user_id - payload: objeto com valores alterados (pode conter values_params e/ou capex) - config_type / config_base_ref / config_pattern_id / user_config_id (para resolver o baseline)

Response (JSON)

{
  "ok": true,
  "target_path": "users/UID/configs/CFG",
  "saved_keys": ["values_params.axis_geometry", "capex.CAPEX"]
}

Exemplo — salvar override do usuário

{
  "target": "user_config",
  "user_id": "Z15G7BOL63VF7uFOtp1c34jjDkA3",
  "user_config_id": "1RQvOOJz6rTd13at27Kg",
  "config_pattern_id": "2",
  "payload": {
    "values_params": {
      "platform": { "platform_width": 7.5 }
    },
    "capex": {
      "CAPEX": {
        "Unit Cost With BDI": [1.0, 2.0, 3.0]
      },
      "currency_rate": 5.75
    }
  }
}

Exemplo — salvar override do projeto

{
  "target": "project_params",
  "user_id": "Z15G7BOL63VF7uFOtp1c34jjDkA3",
  "project_id": "B8I95QcOz3N0azc45t3C",
  "config_pattern_id": "2",
  "user_config_id": "1RQvOOJz6rTd13at27Kg",
  "payload": {
    "values_params": {
      "earthwork": { "max_cut": 30 }
    }
  }
}

Erros padrão

  • 400: payload invalido ou faltando campos obrigatorios
  • 404: docs não encontrados
  • 500: erro interno

Arquivos de apoio

  • Exemplos rápidos: docs/config_resolution_examples.md
  • Schema JSON: docs/config_resolution_contract.schema.json

Autenticação

Se CONFIGS_AUTH_REQUIRED=true, os endpoints exigem Authorization: Bearer <FIREBASE_ID_TOKEN>.