Module: Timeprice::Schema
- Defined in:
- lib/timeprice/schema.rb
Overview
Single source of truth for the on-disk v4 CPI/manifest format. Both the reader (DataLoader) and the writer (today: pipeline ‘CountryFile`) route through here so the schema lives in exactly one place.
Constant Summary collapse
- CURRENT_VERSION =
4- SUPPORTED_VERSIONS =
[3, 4].freeze
- KEY_SCHEMA_VERSION =
"schema_version"- KEY_COUNTRY =
"country"- KEY_INDEX =
"index"- KEY_SERIES =
"series"- KEY_PROVENANCE =
"provenance"- KEY_PROVIDERS =
"providers"- GRANULARITIES =
%i[monthly quarterly annual].freeze
- BASE_YEAR_RE =
/\A(?<period>.+?)=100(?:\s*\(rebased\s+(?<rebased>\d{4}-\d{2}-\d{2})\))?\z/
Class Method Summary collapse
- .assert_supported!(version, path) ⇒ Object
- .deserialise_base_year(index) ⇒ Object
-
.dump_cpi(country:, base_year:, monthly:, annual:, providers:, provenance:, quarterly: {}) ⇒ Object
Build a CPI payload ready for JSON.dump.
-
.load_cpi(parsed, path:) ⇒ Object
Validate a parsed payload (read from disk) against the schema, then return it unchanged.
- .serialise_base_year(str) ⇒ Object
- .supported?(version) ⇒ Boolean
Class Method Details
.assert_supported!(version, path) ⇒ Object
30 31 32 33 34 |
# File 'lib/timeprice/schema.rb', line 30 def assert_supported!(version, path) return if supported?(version) fail UnsupportedSchemaVersion.new(version, path) end |
.deserialise_base_year(index) ⇒ Object
68 69 70 71 72 73 74 75 76 |
# File 'lib/timeprice/schema.rb', line 68 def deserialise_base_year(index) return nil unless index.is_a?(Hash) period = index["base_period"] rebased = index["rebased_at"] return nil if period.nil? rebased ? "#{period}=100 (rebased #{rebased})" : "#{period}=100" end |
.dump_cpi(country:, base_year:, monthly:, annual:, providers:, provenance:, quarterly: {}) ⇒ Object
Build a CPI payload ready for JSON.dump. Series keys are emitted in a stable order (annual, monthly[, quarterly]) so file diffs stay tight.
38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/timeprice/schema.rb', line 38 def dump_cpi(country:, base_year:, monthly:, annual:, providers:, provenance:, quarterly: {}) series = { "annual" => annual, "monthly" => monthly } series["quarterly"] = quarterly unless quarterly.empty? { KEY_SCHEMA_VERSION => CURRENT_VERSION, KEY_COUNTRY => country.to_s.upcase, KEY_INDEX => serialise_base_year(base_year), KEY_SERIES => series, KEY_PROVENANCE => provenance, KEY_PROVIDERS => providers, } end |
.load_cpi(parsed, path:) ⇒ Object
Validate a parsed payload (read from disk) against the schema, then return it unchanged. Raises UnsupportedSchemaVersion if the version field is missing or unknown.
54 55 56 57 |
# File 'lib/timeprice/schema.rb', line 54 def load_cpi(parsed, path:) assert_supported!(parsed[KEY_SCHEMA_VERSION], path) parsed end |
.serialise_base_year(str) ⇒ Object
59 60 61 62 63 64 65 66 |
# File 'lib/timeprice/schema.rb', line 59 def serialise_base_year(str) m = BASE_YEAR_RE.match(str.to_s) if m { "base_period" => m[:period], "rebased_at" => m[:rebased] } else { "base_period" => str.to_s, "rebased_at" => nil } end end |
.supported?(version) ⇒ Boolean
26 27 28 |
# File 'lib/timeprice/schema.rb', line 26 def supported?(version) SUPPORTED_VERSIONS.include?(version) end |