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/baseconfig_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-brconfigs/i18n/{config_type}/en- Conteúdo:
CAPEX.DescriptionCAPEX.UnitVariables(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_paramsusers/{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
*_refexistir, 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):
- Base:
configs/{config_type}/base_v0_1/base - Padrão:
configs/{config_type}/overrides/{pattern_id}(ouconfig_pattern_ref) - Usuário:
users/{user_id}/configs/{user_config_id}(ouuser_config_ref) - 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)¶
- base = configs/railway/base_v0_1/base
- override_padrao = configs/railway/overrides/2
- override_usuario = users/{uid}/configs/{user_config_id}
- override_projeto = users/{uid}/projects/{pid}/params/*
- final = merge(base, padrão, usuário, projeto)
- 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)¶
- Base sempre em
configs/{config_type}/base_v0_1/base. - Padrão usa
configs/{config_type}/overrides/{pattern_id}(somente diff). - Usuário usa
users/{uid}/configs/{user_config_id}(somente diff). - Projeto usa
projects/{pid}/params/*(somente diff). - Merge profundo na ordem base -> padrão -> usuário -> projeto.
- Aplicar taxa no CAPEX somente no final.
- 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 obrigatorios404: docs não encontrados500: 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>.