@gruncellka/porto-data 0.3.1 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +85 -1
- package/LICENSE +199 -5
- package/README.md +52 -39
- package/index.d.ts +35 -18
- package/index.js +2 -1
- package/package.json +23 -9
- package/porto_data/formats/envelopes.json +120 -0
- package/porto_data/formats/layouts.json +288 -0
- package/porto_data/mappings.json +65 -10
- package/porto_data/metadata.json +662 -125
- package/porto_data/policy/jurisdictions.json +839 -0
- package/porto_data/policy/markets.json +75 -0
- package/porto_data/policy/restrictions.json +668 -0
- package/porto_data/providers/deutschepost/features.json +42 -0
- package/porto_data/providers/deutschepost/graph.json +203 -0
- package/porto_data/providers/deutschepost/limits.json +17 -0
- package/porto_data/providers/deutschepost/marks.json +71 -0
- package/porto_data/providers/deutschepost/prices/products.json +239 -0
- package/porto_data/providers/deutschepost/prices/services.json +51 -0
- package/porto_data/providers/deutschepost/products.json +197 -0
- package/porto_data/providers/deutschepost/services.json +88 -0
- package/porto_data/providers/deutschepost/weights.json +46 -0
- package/porto_data/providers/deutschepost/zones.json +231 -0
- package/porto_data/providers/laposte/features.json +42 -0
- package/porto_data/providers/laposte/graph.json +234 -0
- package/porto_data/providers/laposte/limits.json +17 -0
- package/porto_data/providers/laposte/marks.json +39 -0
- package/porto_data/providers/laposte/prices/products.json +947 -0
- package/porto_data/providers/laposte/prices/services.json +41 -0
- package/porto_data/providers/laposte/products.json +276 -0
- package/porto_data/providers/laposte/services.json +63 -0
- package/porto_data/providers/laposte/weights.json +38 -0
- package/porto_data/providers/laposte/zones.json +230 -0
- package/porto_data/providers/swisspost/features.json +21 -0
- package/porto_data/providers/swisspost/graph.json +212 -0
- package/porto_data/providers/swisspost/limits.json +17 -0
- package/porto_data/providers/swisspost/marks.json +41 -0
- package/porto_data/providers/swisspost/prices/products.json +347 -0
- package/porto_data/providers/swisspost/prices/services.json +31 -0
- package/porto_data/providers/swisspost/products.json +193 -0
- package/porto_data/providers/swisspost/rules.json +25 -0
- package/porto_data/providers/swisspost/services.json +40 -0
- package/porto_data/providers/swisspost/weights.json +38 -0
- package/porto_data/providers/swisspost/zones.json +223 -0
- package/porto_data/providers/ukrposhta/features.json +28 -0
- package/porto_data/providers/ukrposhta/graph.json +148 -0
- package/porto_data/providers/ukrposhta/limits.json +17 -0
- package/porto_data/providers/ukrposhta/marks.json +25 -0
- package/porto_data/providers/ukrposhta/prices/products.json +123 -0
- package/porto_data/providers/ukrposhta/prices/services.json +42 -0
- package/porto_data/providers/ukrposhta/products.json +74 -0
- package/porto_data/providers/ukrposhta/services.json +40 -0
- package/porto_data/providers/ukrposhta/weights.json +26 -0
- package/porto_data/providers/ukrposhta/zones.json +226 -0
- package/porto_data/providers.json +37 -0
- package/porto_data/schemas/envelopes.schema.json +120 -0
- package/porto_data/schemas/features.schema.json +66 -55
- package/porto_data/schemas/graph.schema.json +189 -0
- package/porto_data/schemas/jurisdictions.schema.json +116 -0
- package/porto_data/schemas/layouts.schema.json +156 -0
- package/porto_data/schemas/limits.schema.json +253 -0
- package/porto_data/schemas/mappings.schema.json +73 -0
- package/porto_data/schemas/markets.schema.json +186 -0
- package/porto_data/schemas/marks.schema.json +127 -0
- package/porto_data/schemas/metadata.schema.json +183 -0
- package/porto_data/schemas/porto_ids.schema.json +45 -0
- package/porto_data/schemas/product_prices.schema.json +126 -0
- package/porto_data/schemas/products.schema.json +338 -110
- package/porto_data/schemas/providers.schema.json +71 -0
- package/porto_data/schemas/restrictions.schema.json +175 -355
- package/porto_data/schemas/rules.schema.json +104 -0
- package/porto_data/schemas/service_prices.schema.json +116 -0
- package/porto_data/schemas/services.schema.json +113 -70
- package/porto_data/schemas/weights.schema.json +70 -0
- package/porto_data/schemas/zones.schema.json +78 -72
- package/porto_data/data/data_links.json +0 -148
- package/porto_data/data/dimensions.json +0 -158
- package/porto_data/data/features.json +0 -66
- package/porto_data/data/prices.json +0 -242
- package/porto_data/data/products.json +0 -84
- package/porto_data/data/restrictions.json +0 -795
- package/porto_data/data/services.json +0 -61
- package/porto_data/data/weight_tiers.json +0 -54
- package/porto_data/data/zones.json +0 -230
- package/porto_data/schemas/data_links.schema.json +0 -223
- package/porto_data/schemas/dimensions.schema.json +0 -215
- package/porto_data/schemas/prices.schema.json +0 -180
- package/porto_data/schemas/weight_tiers.schema.json +0 -70
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://raw.githubusercontent.com/gruncellka/porto-data/refs/heads/main/porto_data/schemas/marks.schema.json",
|
|
4
|
+
"title": "Provider mark profiles",
|
|
5
|
+
"description": "Per-provider catalog of mark geometry and payload type. Profile size (width × height) is nominal footprint in mm. Resolution paths live in graph.json edges.marks.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"file_type",
|
|
9
|
+
"provider",
|
|
10
|
+
"default_profile",
|
|
11
|
+
"profiles"
|
|
12
|
+
],
|
|
13
|
+
"properties": {
|
|
14
|
+
"$schema": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"format": "uri",
|
|
17
|
+
"description": "JSON Schema URI reference"
|
|
18
|
+
},
|
|
19
|
+
"file_type": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"const": "marks",
|
|
22
|
+
"description": "File type identifier"
|
|
23
|
+
},
|
|
24
|
+
"provider": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"pattern": "^[a-z_]+$",
|
|
27
|
+
"description": "Provider id (must match path providers/<id>/)"
|
|
28
|
+
},
|
|
29
|
+
"unit": {
|
|
30
|
+
"type": "object",
|
|
31
|
+
"required": [
|
|
32
|
+
"dimension"
|
|
33
|
+
],
|
|
34
|
+
"properties": {
|
|
35
|
+
"dimension": {
|
|
36
|
+
"type": "string",
|
|
37
|
+
"const": "mm",
|
|
38
|
+
"description": "Intrinsic size and layout coordinates use millimetres"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"additionalProperties": false
|
|
42
|
+
},
|
|
43
|
+
"default_profile": {
|
|
44
|
+
"type": "string",
|
|
45
|
+
"pattern": "^[a-z0-9_]+$",
|
|
46
|
+
"description": "Fallback profile id when graph.edges.marks has no entry for a zone"
|
|
47
|
+
},
|
|
48
|
+
"profiles": {
|
|
49
|
+
"type": "array",
|
|
50
|
+
"minItems": 1,
|
|
51
|
+
"items": {
|
|
52
|
+
"type": "object",
|
|
53
|
+
"required": [
|
|
54
|
+
"id",
|
|
55
|
+
"mark_type",
|
|
56
|
+
"label"
|
|
57
|
+
],
|
|
58
|
+
"properties": {
|
|
59
|
+
"id": {
|
|
60
|
+
"type": "string",
|
|
61
|
+
"pattern": "^[a-z0-9_]+$",
|
|
62
|
+
"description": "Stable profile id; referenced from graph.edges.marks"
|
|
63
|
+
},
|
|
64
|
+
"mark_type": {
|
|
65
|
+
"type": "string",
|
|
66
|
+
"enum": [
|
|
67
|
+
"stamp",
|
|
68
|
+
"label"
|
|
69
|
+
],
|
|
70
|
+
"description": "Must match product.mark_type for products using this profile"
|
|
71
|
+
},
|
|
72
|
+
"label": {
|
|
73
|
+
"type": "string",
|
|
74
|
+
"minLength": 1,
|
|
75
|
+
"description": "English short name for tooling"
|
|
76
|
+
},
|
|
77
|
+
"description": {
|
|
78
|
+
"type": "string",
|
|
79
|
+
"minLength": 1,
|
|
80
|
+
"description": "When to use this profile vs others"
|
|
81
|
+
},
|
|
82
|
+
"scope_notes": {
|
|
83
|
+
"type": "string",
|
|
84
|
+
"minLength": 1,
|
|
85
|
+
"description": "Optional: domestic vs international, registered, channel notes"
|
|
86
|
+
},
|
|
87
|
+
"size": {
|
|
88
|
+
"type": "object",
|
|
89
|
+
"description": "Nominal width × height of the franking graphic in file unit.dimension (mm); optional until verified from API/spec",
|
|
90
|
+
"required": [
|
|
91
|
+
"width",
|
|
92
|
+
"height"
|
|
93
|
+
],
|
|
94
|
+
"properties": {
|
|
95
|
+
"width": {
|
|
96
|
+
"type": "integer",
|
|
97
|
+
"minimum": 1
|
|
98
|
+
},
|
|
99
|
+
"height": {
|
|
100
|
+
"type": "integer",
|
|
101
|
+
"minimum": 1
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
"additionalProperties": false
|
|
105
|
+
},
|
|
106
|
+
"mime_type": {
|
|
107
|
+
"type": "array",
|
|
108
|
+
"minItems": 1,
|
|
109
|
+
"uniqueItems": true,
|
|
110
|
+
"items": {
|
|
111
|
+
"type": "string",
|
|
112
|
+
"enum": [
|
|
113
|
+
"image/png",
|
|
114
|
+
"image/jpeg",
|
|
115
|
+
"application/pdf",
|
|
116
|
+
"application/octet-stream"
|
|
117
|
+
]
|
|
118
|
+
},
|
|
119
|
+
"description": "IANA media types the provider API may return for this profile; order is not significant"
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
"additionalProperties": false
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
"additionalProperties": false
|
|
127
|
+
}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://raw.githubusercontent.com/gruncellka/porto-data/refs/heads/main/porto_data/schemas/metadata.schema.json",
|
|
4
|
+
"title": "Porto-data bundle metadata",
|
|
5
|
+
"description": "Generated checksum manifest for schemas and data files (see scripts/generate_metadata.py). The bundle section records mappings.json and providers.json (plus schemas) explicitly.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"$schema",
|
|
9
|
+
"project",
|
|
10
|
+
"generated_at",
|
|
11
|
+
"policy",
|
|
12
|
+
"formats",
|
|
13
|
+
"registry",
|
|
14
|
+
"providers",
|
|
15
|
+
"checksums"
|
|
16
|
+
],
|
|
17
|
+
"additionalProperties": false,
|
|
18
|
+
"definitions": {
|
|
19
|
+
"fileInfo": {
|
|
20
|
+
"type": "object",
|
|
21
|
+
"required": [
|
|
22
|
+
"path",
|
|
23
|
+
"checksum",
|
|
24
|
+
"size"
|
|
25
|
+
],
|
|
26
|
+
"additionalProperties": false,
|
|
27
|
+
"properties": {
|
|
28
|
+
"path": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"minLength": 1
|
|
31
|
+
},
|
|
32
|
+
"checksum": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"pattern": "^[a-f0-9]{64}$"
|
|
35
|
+
},
|
|
36
|
+
"size": {
|
|
37
|
+
"type": "integer",
|
|
38
|
+
"minimum": 0
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"schemaInfo": {
|
|
43
|
+
"type": "object",
|
|
44
|
+
"required": [
|
|
45
|
+
"path",
|
|
46
|
+
"checksum",
|
|
47
|
+
"size",
|
|
48
|
+
"url"
|
|
49
|
+
],
|
|
50
|
+
"additionalProperties": false,
|
|
51
|
+
"properties": {
|
|
52
|
+
"path": {
|
|
53
|
+
"type": "string",
|
|
54
|
+
"minLength": 1
|
|
55
|
+
},
|
|
56
|
+
"checksum": {
|
|
57
|
+
"type": "string",
|
|
58
|
+
"pattern": "^[a-f0-9]{64}$"
|
|
59
|
+
},
|
|
60
|
+
"size": {
|
|
61
|
+
"type": "integer",
|
|
62
|
+
"minimum": 0
|
|
63
|
+
},
|
|
64
|
+
"url": {
|
|
65
|
+
"type": "string",
|
|
66
|
+
"description": "Schema $id URL when present; empty string if unavailable."
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"entityBundle": {
|
|
71
|
+
"type": "object",
|
|
72
|
+
"required": [
|
|
73
|
+
"data",
|
|
74
|
+
"schema"
|
|
75
|
+
],
|
|
76
|
+
"additionalProperties": false,
|
|
77
|
+
"properties": {
|
|
78
|
+
"data": {
|
|
79
|
+
"$ref": "#/definitions/fileInfo"
|
|
80
|
+
},
|
|
81
|
+
"schema": {
|
|
82
|
+
"$ref": "#/definitions/schemaInfo"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
"properties": {
|
|
88
|
+
"$schema": {
|
|
89
|
+
"type": "string",
|
|
90
|
+
"format": "uri"
|
|
91
|
+
},
|
|
92
|
+
"project": {
|
|
93
|
+
"type": "object",
|
|
94
|
+
"required": [
|
|
95
|
+
"name",
|
|
96
|
+
"version",
|
|
97
|
+
"description"
|
|
98
|
+
],
|
|
99
|
+
"additionalProperties": false,
|
|
100
|
+
"properties": {
|
|
101
|
+
"name": {
|
|
102
|
+
"type": "string",
|
|
103
|
+
"minLength": 1
|
|
104
|
+
},
|
|
105
|
+
"version": {
|
|
106
|
+
"type": "string",
|
|
107
|
+
"minLength": 1
|
|
108
|
+
},
|
|
109
|
+
"description": {
|
|
110
|
+
"type": "string"
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
"generated_at": {
|
|
115
|
+
"type": "string",
|
|
116
|
+
"minLength": 1,
|
|
117
|
+
"description": "ISO 8601 instant (UTC, Z suffix from generator)."
|
|
118
|
+
},
|
|
119
|
+
"policy": {
|
|
120
|
+
"type": "object",
|
|
121
|
+
"additionalProperties": {
|
|
122
|
+
"$ref": "#/definitions/entityBundle"
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
"formats": {
|
|
126
|
+
"type": "object",
|
|
127
|
+
"additionalProperties": {
|
|
128
|
+
"$ref": "#/definitions/entityBundle"
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
"registry": {
|
|
132
|
+
"type": "object",
|
|
133
|
+
"additionalProperties": {
|
|
134
|
+
"$ref": "#/definitions/entityBundle"
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
"providers": {
|
|
138
|
+
"type": "object",
|
|
139
|
+
"minProperties": 1,
|
|
140
|
+
"additionalProperties": {
|
|
141
|
+
"type": "object",
|
|
142
|
+
"minProperties": 1,
|
|
143
|
+
"additionalProperties": {
|
|
144
|
+
"$ref": "#/definitions/entityBundle"
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
"bundle": {
|
|
149
|
+
"type": "object",
|
|
150
|
+
"description": "Root manifest files: mappings (layout) and providers registry, each with data + schema checksums.",
|
|
151
|
+
"required": [
|
|
152
|
+
"mappings",
|
|
153
|
+
"providers_registry"
|
|
154
|
+
],
|
|
155
|
+
"additionalProperties": false,
|
|
156
|
+
"properties": {
|
|
157
|
+
"mappings": {
|
|
158
|
+
"$ref": "#/definitions/entityBundle"
|
|
159
|
+
},
|
|
160
|
+
"providers_registry": {
|
|
161
|
+
"$ref": "#/definitions/entityBundle"
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
"checksums": {
|
|
166
|
+
"type": "object",
|
|
167
|
+
"required": [
|
|
168
|
+
"algorithm",
|
|
169
|
+
"note"
|
|
170
|
+
],
|
|
171
|
+
"additionalProperties": false,
|
|
172
|
+
"properties": {
|
|
173
|
+
"algorithm": {
|
|
174
|
+
"type": "string",
|
|
175
|
+
"const": "SHA-256"
|
|
176
|
+
},
|
|
177
|
+
"note": {
|
|
178
|
+
"type": "string"
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://raw.githubusercontent.com/gruncellka/porto-data/refs/heads/main/porto_data/schemas/porto_ids.schema.json",
|
|
4
|
+
"title": "Porto ID vocabulary",
|
|
5
|
+
"description": "Canonical porto_id enums for cross-provider SDK normalization. Normative list: docs/id.md. Disjointness: product_porto_id (size buckets) must not overlap service_porto_id or feature_porto_id; service and feature may share tokens where capability and priced add-on align (see id.md). Do not add values without semver-major review.",
|
|
6
|
+
"definitions": {
|
|
7
|
+
"product_porto_id": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"enum": [
|
|
10
|
+
"small",
|
|
11
|
+
"medium",
|
|
12
|
+
"large",
|
|
13
|
+
"extra_large",
|
|
14
|
+
"postcard"
|
|
15
|
+
],
|
|
16
|
+
"description": "Letter size bucket for SDK product input only (no service semantics: registered, tracking, return_receipt, … belong on services/features)"
|
|
17
|
+
},
|
|
18
|
+
"service_porto_id": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"enum": [
|
|
21
|
+
"registered",
|
|
22
|
+
"registered_return_receipt",
|
|
23
|
+
"tracking",
|
|
24
|
+
"insurance",
|
|
25
|
+
"return_receipt",
|
|
26
|
+
"thickness",
|
|
27
|
+
"proof_of_mailing",
|
|
28
|
+
"proof_of_delivery"
|
|
29
|
+
],
|
|
30
|
+
"description": "Unified add-on service bucket for SDK input"
|
|
31
|
+
},
|
|
32
|
+
"feature_porto_id": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"enum": [
|
|
35
|
+
"tracking_number",
|
|
36
|
+
"proof_of_mailing",
|
|
37
|
+
"recipient_signature",
|
|
38
|
+
"return_receipt",
|
|
39
|
+
"proof_of_delivery",
|
|
40
|
+
"thickness_surcharge"
|
|
41
|
+
],
|
|
42
|
+
"description": "Unified capability feature bucket for cross-operator semantics"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://raw.githubusercontent.com/gruncellka/porto-data/refs/heads/main/porto_data/schemas/product_prices.schema.json",
|
|
4
|
+
"title": "Product postage prices",
|
|
5
|
+
"description": "Base letter/postage grid: product_id × zone × weight_tier. Amounts in cents. Convention: price[].effective_from uses the catalog baseline date (currently 2026-01-01) as bundle snapshot start, not carrier historical introduction dates.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"file_type",
|
|
9
|
+
"provider",
|
|
10
|
+
"unit",
|
|
11
|
+
"product_prices"
|
|
12
|
+
],
|
|
13
|
+
"properties": {
|
|
14
|
+
"$schema": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"format": "uri"
|
|
17
|
+
},
|
|
18
|
+
"file_type": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"const": "product_prices"
|
|
21
|
+
},
|
|
22
|
+
"provider": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"pattern": "^[a-z_]+$",
|
|
25
|
+
"description": "Provider identifier"
|
|
26
|
+
},
|
|
27
|
+
"unit": {
|
|
28
|
+
"type": "object",
|
|
29
|
+
"required": [
|
|
30
|
+
"price",
|
|
31
|
+
"currency"
|
|
32
|
+
],
|
|
33
|
+
"properties": {
|
|
34
|
+
"price": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"const": "cents"
|
|
37
|
+
},
|
|
38
|
+
"currency": {
|
|
39
|
+
"type": "string",
|
|
40
|
+
"enum": [
|
|
41
|
+
"EUR",
|
|
42
|
+
"CHF",
|
|
43
|
+
"UAH",
|
|
44
|
+
"USD"
|
|
45
|
+
],
|
|
46
|
+
"description": "Default currency for rows in this file. Set row.currency only when a row is quoted in another currency (must differ from this default)."
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"additionalProperties": false
|
|
50
|
+
},
|
|
51
|
+
"product_prices": {
|
|
52
|
+
"type": "array",
|
|
53
|
+
"minItems": 1,
|
|
54
|
+
"items": {
|
|
55
|
+
"type": "object",
|
|
56
|
+
"required": [
|
|
57
|
+
"product_id",
|
|
58
|
+
"zone",
|
|
59
|
+
"weight_tier",
|
|
60
|
+
"price"
|
|
61
|
+
],
|
|
62
|
+
"properties": {
|
|
63
|
+
"product_id": {
|
|
64
|
+
"type": "string",
|
|
65
|
+
"pattern": "^[a-z_]+$",
|
|
66
|
+
"description": "Must match products.json id"
|
|
67
|
+
},
|
|
68
|
+
"zone": {
|
|
69
|
+
"type": "string",
|
|
70
|
+
"pattern": "^[a-z0-9_]+$"
|
|
71
|
+
},
|
|
72
|
+
"weight_tier": {
|
|
73
|
+
"type": "string",
|
|
74
|
+
"pattern": "^W[0-9]+$"
|
|
75
|
+
},
|
|
76
|
+
"currency": {
|
|
77
|
+
"type": "string",
|
|
78
|
+
"enum": [
|
|
79
|
+
"EUR",
|
|
80
|
+
"CHF",
|
|
81
|
+
"UAH",
|
|
82
|
+
"USD"
|
|
83
|
+
],
|
|
84
|
+
"description": "Row override when this amount is not in unit.currency. Omit when same as file default. SDK priority: row → file unit → markets[country].currency."
|
|
85
|
+
},
|
|
86
|
+
"price": {
|
|
87
|
+
"type": "array",
|
|
88
|
+
"minItems": 1,
|
|
89
|
+
"items": {
|
|
90
|
+
"type": "object",
|
|
91
|
+
"required": [
|
|
92
|
+
"amount",
|
|
93
|
+
"effective_from"
|
|
94
|
+
],
|
|
95
|
+
"properties": {
|
|
96
|
+
"amount": {
|
|
97
|
+
"type": "integer",
|
|
98
|
+
"minimum": 0
|
|
99
|
+
},
|
|
100
|
+
"effective_from": {
|
|
101
|
+
"type": [
|
|
102
|
+
"string",
|
|
103
|
+
"null"
|
|
104
|
+
],
|
|
105
|
+
"format": "date",
|
|
106
|
+
"description": "Row valid from this date (ISO 8601). Provider bundles use the catalog baseline (e.g. 2026-01-01) unless superseding rows exist."
|
|
107
|
+
},
|
|
108
|
+
"effective_to": {
|
|
109
|
+
"type": [
|
|
110
|
+
"string",
|
|
111
|
+
"null"
|
|
112
|
+
],
|
|
113
|
+
"format": "date",
|
|
114
|
+
"description": "Null while current; set when a newer price row replaces this amount."
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
"additionalProperties": false
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
"additionalProperties": false
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
"additionalProperties": false
|
|
126
|
+
}
|