boarddata 4.0.0__tar.gz → 4.0.2__tar.gz

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.
Files changed (56) hide show
  1. {boarddata-4.0.0 → boarddata-4.0.2}/PKG-INFO +1 -1
  2. {boarddata-4.0.0 → boarddata-4.0.2}/__init__.py +1 -1
  3. {boarddata-4.0.0 → boarddata-4.0.2}/_comex.py +3 -0
  4. boarddata-4.0.2/_criteria.py +68 -0
  5. {boarddata-4.0.0 → boarddata-4.0.2}/_esg.py +34 -1
  6. {boarddata-4.0.0 → boarddata-4.0.2}/boarddata.egg-info/PKG-INFO +1 -1
  7. {boarddata-4.0.0 → boarddata-4.0.2}/boarddata.egg-info/SOURCES.txt +4 -0
  8. {boarddata-4.0.0 → boarddata-4.0.2}/client.py +2 -0
  9. {boarddata-4.0.0 → boarddata-4.0.2}/pyproject.toml +1 -1
  10. {boarddata-4.0.0 → boarddata-4.0.2}/tests/test_comex.py +2 -0
  11. boarddata-4.0.2/tests/test_criteria.py +68 -0
  12. {boarddata-4.0.0 → boarddata-4.0.2}/types/__init__.py +4 -0
  13. {boarddata-4.0.0 → boarddata-4.0.2}/types/comex.py +4 -0
  14. boarddata-4.0.2/types/criteria.py +34 -0
  15. {boarddata-4.0.0 → boarddata-4.0.2}/types/esg.py +24 -0
  16. {boarddata-4.0.0 → boarddata-4.0.2}/CLAUDE.md +0 -0
  17. {boarddata-4.0.0 → boarddata-4.0.2}/README.md +0 -0
  18. {boarddata-4.0.0 → boarddata-4.0.2}/_assemblies.py +0 -0
  19. {boarddata-4.0.0 → boarddata-4.0.2}/_auditors.py +0 -0
  20. {boarddata-4.0.0 → boarddata-4.0.2}/_base.py +0 -0
  21. {boarddata-4.0.0 → boarddata-4.0.2}/_companies.py +0 -0
  22. {boarddata-4.0.0 → boarddata-4.0.2}/_directors.py +0 -0
  23. {boarddata-4.0.0 → boarddata-4.0.2}/_documents.py +0 -0
  24. {boarddata-4.0.0 → boarddata-4.0.2}/_persons.py +0 -0
  25. {boarddata-4.0.0 → boarddata-4.0.2}/_sentinel.py +0 -0
  26. {boarddata-4.0.0 → boarddata-4.0.2}/_utilities.py +0 -0
  27. {boarddata-4.0.0 → boarddata-4.0.2}/boarddata.egg-info/dependency_links.txt +0 -0
  28. {boarddata-4.0.0 → boarddata-4.0.2}/boarddata.egg-info/requires.txt +0 -0
  29. {boarddata-4.0.0 → boarddata-4.0.2}/boarddata.egg-info/top_level.txt +0 -0
  30. {boarddata-4.0.0 → boarddata-4.0.2}/cache.py +0 -0
  31. {boarddata-4.0.0 → boarddata-4.0.2}/errors.py +0 -0
  32. {boarddata-4.0.0 → boarddata-4.0.2}/py.typed +0 -0
  33. {boarddata-4.0.0 → boarddata-4.0.2}/setup.cfg +0 -0
  34. {boarddata-4.0.0 → boarddata-4.0.2}/tests/__init__.py +0 -0
  35. {boarddata-4.0.0 → boarddata-4.0.2}/tests/conftest.py +0 -0
  36. {boarddata-4.0.0 → boarddata-4.0.2}/tests/test_assemblies.py +0 -0
  37. {boarddata-4.0.0 → boarddata-4.0.2}/tests/test_auditors.py +0 -0
  38. {boarddata-4.0.0 → boarddata-4.0.2}/tests/test_base.py +0 -0
  39. {boarddata-4.0.0 → boarddata-4.0.2}/tests/test_build_payload.py +0 -0
  40. {boarddata-4.0.0 → boarddata-4.0.2}/tests/test_cache.py +0 -0
  41. {boarddata-4.0.0 → boarddata-4.0.2}/tests/test_companies.py +0 -0
  42. {boarddata-4.0.0 → boarddata-4.0.2}/tests/test_config.py +0 -0
  43. {boarddata-4.0.0 → boarddata-4.0.2}/tests/test_directors.py +0 -0
  44. {boarddata-4.0.0 → boarddata-4.0.2}/tests/test_documents.py +0 -0
  45. {boarddata-4.0.0 → boarddata-4.0.2}/tests/test_esg.py +0 -0
  46. {boarddata-4.0.0 → boarddata-4.0.2}/tests/test_persons.py +0 -0
  47. {boarddata-4.0.0 → boarddata-4.0.2}/tests/test_sentinel.py +0 -0
  48. {boarddata-4.0.0 → boarddata-4.0.2}/tests/test_utilities.py +0 -0
  49. {boarddata-4.0.0 → boarddata-4.0.2}/types/assemblies.py +0 -0
  50. {boarddata-4.0.0 → boarddata-4.0.2}/types/auditors.py +0 -0
  51. {boarddata-4.0.0 → boarddata-4.0.2}/types/companies.py +0 -0
  52. {boarddata-4.0.0 → boarddata-4.0.2}/types/core.py +0 -0
  53. {boarddata-4.0.0 → boarddata-4.0.2}/types/directors.py +0 -0
  54. {boarddata-4.0.0 → boarddata-4.0.2}/types/documents.py +0 -0
  55. {boarddata-4.0.0 → boarddata-4.0.2}/types/persons.py +0 -0
  56. {boarddata-4.0.0 → boarddata-4.0.2}/types/sentinel.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boarddata
3
- Version: 4.0.0
3
+ Version: 4.0.2
4
4
  Summary: Python SDK for the BoardData V2 REST API
5
5
  License: MIT
6
6
  Classifier: Development Status :: 4 - Beta
@@ -7,7 +7,7 @@ from .errors import BoardDataError
7
7
 
8
8
  from . import types as types # noqa: F401 — makes types accessible as boarddata.types
9
9
 
10
- __version__ = "4.0.0"
10
+ __version__ = "4.0.2"
11
11
  __all__ = [
12
12
  "Base",
13
13
  "BoardDataClient",
@@ -288,6 +288,7 @@ class ComexMixin:
288
288
  has_employment_contract: bool | None = None,
289
289
  discretionary_grant: bool | None = None,
290
290
  subsidiary_remuneration: str | None = None,
291
+ remuneration_via_holding: bool | None = None,
291
292
  currency: str | None = None,
292
293
  field_sources: list[FieldSourcePayload] | None = None,
293
294
  criteria: list[dict[str, Any]] | None = None,
@@ -335,6 +336,7 @@ class ComexMixin:
335
336
  has_employment_contract: Whether has employment contract.
336
337
  discretionary_grant: Whether discretionary grant applies.
337
338
  subsidiary_remuneration: Subsidiary remuneration (decimal).
339
+ remuneration_via_holding: Whether remuneration is provided via holding.
338
340
  currency: Currency code (e.g. ``"EUR"``).
339
341
  field_sources: Document provenance for fields.
340
342
  criteria: List of compensation criteria dicts.
@@ -385,6 +387,7 @@ class ComexMixin:
385
387
  has_employment_contract=has_employment_contract,
386
388
  discretionary_grant=discretionary_grant,
387
389
  subsidiary_remuneration=subsidiary_remuneration,
390
+ remuneration_via_holding=remuneration_via_holding,
388
391
  currency=currency,
389
392
  field_sources=field_sources,
390
393
  criteria=criteria,
@@ -0,0 +1,68 @@
1
+ """Criteria catalog and theme methods."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from .types.criteria import CriteriaCatalogItem, CriteriaThemeItem
8
+
9
+
10
+ class CriteriaMixin:
11
+ """Criteria catalog and theme API methods.
12
+
13
+ Provides access to the shared criteria catalog used by compensation
14
+ records across all comex mandates.
15
+ """
16
+
17
+ def list_criteria_themes(self) -> list[CriteriaThemeItem]:
18
+ """List all criteria themes.
19
+
20
+ Returns:
21
+ List of criteria themes (not paginated).
22
+
23
+ Raises:
24
+ BoardDataError: On non-2xx API response.
25
+ """
26
+ return self._get("criteria-themes/") # type: ignore[attr-defined]
27
+
28
+ def list_criteria(
29
+ self,
30
+ theme: str | None = None,
31
+ ) -> list[CriteriaCatalogItem]:
32
+ """List all criteria catalog entries.
33
+
34
+ Args:
35
+ theme: Filter by criteria theme UUID.
36
+
37
+ Returns:
38
+ List of criteria (not paginated).
39
+
40
+ Raises:
41
+ BoardDataError: On non-2xx API response.
42
+ """
43
+ params: dict[str, Any] = {}
44
+ if theme is not None:
45
+ params["theme"] = theme
46
+ return self._get("criteria/", **params) # type: ignore[attr-defined]
47
+
48
+ def create_criteria(
49
+ self,
50
+ name: str,
51
+ theme_id: str | None = None,
52
+ ) -> CriteriaCatalogItem:
53
+ """Create a criteria catalog entry.
54
+
55
+ Args:
56
+ name: Standardized criterion name (e.g. ``"Revenue Growth"``).
57
+ theme_id: UUID of the criteria theme.
58
+
59
+ Returns:
60
+ Created criteria entry.
61
+
62
+ Raises:
63
+ BoardDataError: On non-2xx API response.
64
+ """
65
+ payload: dict[str, Any] = {"name": name}
66
+ if theme_id is not None:
67
+ payload["theme_id"] = theme_id
68
+ return self._post("criteria/", payload) # type: ignore[attr-defined]
@@ -4,8 +4,10 @@ from __future__ import annotations
4
4
 
5
5
  from typing import Any
6
6
 
7
- from .types.core import PaginatedResponse
7
+ from .types.core import FieldSourcePayload, PaginatedResponse
8
8
  from .types.esg import (
9
+ IROBatchItemPayload,
10
+ IROBatchResultItem,
9
11
  IRODetail,
10
12
  TransitionFinancePayload,
11
13
  TransitionGovernancePayload,
@@ -56,6 +58,7 @@ class ESGMixin:
56
58
  iro_types: list[int] | None = None,
57
59
  page_number: int | None = None,
58
60
  evidence_text: str | None = None,
61
+ field_sources: list[FieldSourcePayload] | None = None,
59
62
  ) -> IRODetail:
60
63
  """Create an IRO.
61
64
 
@@ -68,6 +71,7 @@ class ESGMixin:
68
71
  iro_types: List of IROType IDs to associate.
69
72
  page_number: Source document page number.
70
73
  evidence_text: Supporting evidence text.
74
+ field_sources: List of field source entries for traceability.
71
75
 
72
76
  Returns:
73
77
  Created IRODetail.
@@ -84,6 +88,7 @@ class ESGMixin:
84
88
  iro_types=iro_types,
85
89
  page_number=page_number,
86
90
  evidence_text=evidence_text,
91
+ field_sources=field_sources,
87
92
  )
88
93
  return self._post("iros/", payload) # type: ignore[attr-defined]
89
94
 
@@ -99,6 +104,7 @@ class ESGMixin:
99
104
  iro_types: list[int] | None = None,
100
105
  page_number: int | None = None,
101
106
  evidence_text: str | None = None,
107
+ field_sources: list[FieldSourcePayload] | None = None,
102
108
  ) -> IRODetail:
103
109
  """Partial update an IRO."""
104
110
  payload = self._build_payload( # type: ignore[attr-defined]
@@ -110,6 +116,7 @@ class ESGMixin:
110
116
  iro_types=iro_types,
111
117
  page_number=page_number,
112
118
  evidence_text=evidence_text,
119
+ field_sources=field_sources,
113
120
  )
114
121
  return self._patch(f"iros/{uid}/", payload) # type: ignore[attr-defined]
115
122
 
@@ -117,6 +124,27 @@ class ESGMixin:
117
124
  """Delete an IRO."""
118
125
  self._delete(f"iros/{uid}/") # type: ignore[attr-defined]
119
126
 
127
+ def batch_create_iro(
128
+ self,
129
+ items: list[IROBatchItemPayload],
130
+ ) -> list[IROBatchResultItem]:
131
+ """Batch upsert IROs.
132
+
133
+ Each item is matched by ``(company, date_publication, name)``.
134
+ Existing records are updated; new ones are created.
135
+
136
+ Args:
137
+ items: List of IRO payloads to upsert.
138
+
139
+ Returns:
140
+ List of results with ``name``, ``iro_id``, and ``action``
141
+ (``"created"`` or ``"updated"``).
142
+
143
+ Raises:
144
+ BoardDataError: On non-2xx API response.
145
+ """
146
+ return self._post("iros/batch/", items) # type: ignore[attr-defined]
147
+
120
148
  # ------------------------------------------------------------------
121
149
  # Transition Plans
122
150
  # ------------------------------------------------------------------
@@ -159,6 +187,7 @@ class ESGMixin:
159
187
  levers: list[TransitionLeverPayload] | None = None,
160
188
  finances: list[TransitionFinancePayload] | None = None,
161
189
  governances: list[TransitionGovernancePayload] | None = None,
190
+ field_sources: list[FieldSourcePayload] | None = None,
162
191
  ) -> TransitionPlanDetail:
163
192
  """Create a transition plan with optional nested children.
164
193
 
@@ -176,6 +205,7 @@ class ESGMixin:
176
205
  levers: Nested decarbonisation levers.
177
206
  finances: Nested financial commitments.
178
207
  governances: Nested governance mechanisms.
208
+ field_sources: List of field source entries for traceability.
179
209
 
180
210
  Returns:
181
211
  Created TransitionPlanDetail with nested children.
@@ -197,6 +227,7 @@ class ESGMixin:
197
227
  levers=levers,
198
228
  finances=finances,
199
229
  governances=governances,
230
+ field_sources=field_sources,
200
231
  )
201
232
  return self._post("transition-plans/", payload) # type: ignore[attr-defined]
202
233
 
@@ -217,6 +248,7 @@ class ESGMixin:
217
248
  levers: list[TransitionLeverPayload] | None = None,
218
249
  finances: list[TransitionFinancePayload] | None = None,
219
250
  governances: list[TransitionGovernancePayload] | None = None,
251
+ field_sources: list[FieldSourcePayload] | None = None,
220
252
  ) -> TransitionPlanDetail:
221
253
  """Partial update a transition plan.
222
254
 
@@ -237,6 +269,7 @@ class ESGMixin:
237
269
  levers=levers,
238
270
  finances=finances,
239
271
  governances=governances,
272
+ field_sources=field_sources,
240
273
  )
241
274
  return self._patch(f"transition-plans/{uid}/", payload) # type: ignore[attr-defined]
242
275
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boarddata
3
- Version: 4.0.0
3
+ Version: 4.0.2
4
4
  Summary: Python SDK for the BoardData V2 REST API
5
5
  License: MIT
6
6
  Classifier: Development Status :: 4 - Beta
@@ -6,6 +6,7 @@ _auditors.py
6
6
  _base.py
7
7
  _comex.py
8
8
  _companies.py
9
+ _criteria.py
9
10
  _directors.py
10
11
  _documents.py
11
12
  _esg.py
@@ -24,6 +25,7 @@ pyproject.toml
24
25
  ./_base.py
25
26
  ./_comex.py
26
27
  ./_companies.py
28
+ ./_criteria.py
27
29
  ./_directors.py
28
30
  ./_documents.py
29
31
  ./_esg.py
@@ -49,6 +51,7 @@ tests/test_cache.py
49
51
  tests/test_comex.py
50
52
  tests/test_companies.py
51
53
  tests/test_config.py
54
+ tests/test_criteria.py
52
55
  tests/test_directors.py
53
56
  tests/test_documents.py
54
57
  tests/test_esg.py
@@ -61,6 +64,7 @@ types/auditors.py
61
64
  types/comex.py
62
65
  types/companies.py
63
66
  types/core.py
67
+ types/criteria.py
64
68
  types/directors.py
65
69
  types/documents.py
66
70
  types/esg.py
@@ -7,6 +7,7 @@ from ._auditors import AuditorMixin
7
7
  from ._base import Base
8
8
  from ._comex import ComexMixin
9
9
  from ._companies import CompanyMixin
10
+ from ._criteria import CriteriaMixin
10
11
  from ._directors import DirectorMixin
11
12
  from ._documents import DocumentMixin
12
13
  from ._esg import ESGMixin
@@ -25,6 +26,7 @@ class BoardDataClient(
25
26
  AssemblyMixin,
26
27
  ESGMixin,
27
28
  SentinelMixin,
29
+ CriteriaMixin,
28
30
  UtilitiesMixin,
29
31
  Base,
30
32
  ):
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "boarddata"
7
- version = "4.0.0"
7
+ version = "4.0.2"
8
8
  description = "Python SDK for the BoardData V2 REST API"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
@@ -26,12 +26,14 @@ class TestCreateComexCompensation:
26
26
  c.create_comex_compensation(
27
27
  "comex-uuid", 2024, "REAL",
28
28
  fixed="500000.00", variable="200000.00", currency="EUR",
29
+ remuneration_via_holding=True,
29
30
  )
30
31
  _, kwargs = c._request.call_args
31
32
  payload = kwargs["json"]
32
33
  assert payload["fixed"] == "500000.00"
33
34
  assert payload["variable"] == "200000.00"
34
35
  assert payload["currency"] == "EUR"
36
+ assert payload["remuneration_via_holding"] is True
35
37
  assert "token_personal" not in payload # board field, not comex
36
38
 
37
39
 
@@ -0,0 +1,68 @@
1
+ """Tests for CriteriaMixin methods."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from unittest.mock import MagicMock
6
+
7
+
8
+ def make_client():
9
+ from boarddata._criteria import CriteriaMixin
10
+ from boarddata._base import Base
11
+
12
+ class TestClient(CriteriaMixin, Base):
13
+ pass
14
+
15
+ client = TestClient.__new__(TestClient)
16
+ client._request = MagicMock()
17
+ client._get_token = MagicMock(return_value="fake-token")
18
+ client.base_url = "https://api.example.com"
19
+ client.timeout = 30
20
+ return client
21
+
22
+
23
+ class TestListCriteriaThemes:
24
+ def test_calls_correct_path(self):
25
+ c = make_client()
26
+ c._request.return_value = [{"id": "t1", "name": "Financial"}]
27
+ result = c.list_criteria_themes()
28
+ args, _ = c._request.call_args
29
+ assert args == ("GET", "criteria-themes/")
30
+ assert result[0]["name"] == "Financial"
31
+
32
+
33
+ class TestListCriteria:
34
+ def test_calls_correct_path(self):
35
+ c = make_client()
36
+ c._request.return_value = [{"id": "c1", "name": "Revenue Growth"}]
37
+ result = c.list_criteria()
38
+ args, _ = c._request.call_args
39
+ assert args == ("GET", "criteria/")
40
+ assert result[0]["name"] == "Revenue Growth"
41
+
42
+ def test_filters_by_theme(self):
43
+ c = make_client()
44
+ c._request.return_value = []
45
+ c.list_criteria(theme="theme-uuid")
46
+ _, kwargs = c._request.call_args
47
+ assert kwargs["params"]["theme"] == "theme-uuid"
48
+
49
+
50
+ class TestCreateCriteria:
51
+ def test_sends_payload(self):
52
+ c = make_client()
53
+ c._request.return_value = {"id": "c1", "name": "Revenue Growth"}
54
+ result = c.create_criteria("Revenue Growth", theme_id="theme-uuid")
55
+ _, kwargs = c._request.call_args
56
+ payload = kwargs["json"]
57
+ assert payload["name"] == "Revenue Growth"
58
+ assert payload["theme_id"] == "theme-uuid"
59
+ assert result["id"] == "c1"
60
+
61
+ def test_without_theme(self):
62
+ c = make_client()
63
+ c._request.return_value = {"id": "c2", "name": "Safety Rate"}
64
+ c.create_criteria("Safety Rate")
65
+ _, kwargs = c._request.call_args
66
+ payload = kwargs["json"]
67
+ assert payload["name"] == "Safety Rate"
68
+ assert "theme_id" not in payload
@@ -2,6 +2,8 @@
2
2
 
3
3
  from .esg import (
4
4
  CompanyESGBenchmarkItem,
5
+ IROBatchItemPayload,
6
+ IROBatchResultItem,
5
7
  IRODetail,
6
8
  IROTypeItem,
7
9
  TransitionFinanceItem,
@@ -117,6 +119,8 @@ from .sentinel import (
117
119
  __all__ = [
118
120
  # esg
119
121
  "CompanyESGBenchmarkItem",
122
+ "IROBatchItemPayload",
123
+ "IROBatchResultItem",
120
124
  "IRODetail",
121
125
  "IROTypeItem",
122
126
  "TransitionFinanceItem",
@@ -103,6 +103,7 @@ class ComexCompensationItem(TypedDict):
103
103
  subsidiary_remuneration: str | None
104
104
  holding: bool
105
105
  has_employment_contract: bool
106
+ remuneration_via_holding: bool
106
107
  total: str | None
107
108
  total_paid: str | None
108
109
  currency: str
@@ -149,6 +150,7 @@ class ComexCompensationDetail(TypedDict):
149
150
  has_employment_contract: bool
150
151
  discretionary_grant: bool
151
152
  subsidiary_remuneration: str | None
153
+ remuneration_via_holding: bool
152
154
  currency: str
153
155
  total: str | None
154
156
  total_paid: str | None
@@ -196,6 +198,7 @@ class CreateComexCompensationPayload(TypedDict):
196
198
  has_employment_contract: NotRequired[bool]
197
199
  discretionary_grant: NotRequired[bool]
198
200
  subsidiary_remuneration: NotRequired[str | None]
201
+ remuneration_via_holding: NotRequired[bool]
199
202
  currency: NotRequired[str]
200
203
  field_sources: NotRequired[list[FieldSourcePayload]]
201
204
  criteria: NotRequired[list[dict[str, Any]]]
@@ -241,6 +244,7 @@ class UpdateComexCompensationPayload(TypedDict, total=False):
241
244
  has_employment_contract: bool
242
245
  discretionary_grant: bool
243
246
  subsidiary_remuneration: str | None
247
+ remuneration_via_holding: bool
244
248
  currency: str
245
249
  field_sources: list[FieldSourcePayload]
246
250
  criteria: list[dict[str, Any]]
@@ -0,0 +1,34 @@
1
+ """Criteria catalog types."""
2
+
3
+ from __future__ import annotations
4
+
5
+ try:
6
+ from typing import NotRequired, TypedDict
7
+ except ImportError:
8
+ from typing_extensions import NotRequired, TypedDict
9
+
10
+
11
+ class CriteriaThemeItem(TypedDict):
12
+ """Criteria theme as returned by the criteria-themes endpoint."""
13
+
14
+ id: str
15
+ name: str
16
+ description: str
17
+ category: str
18
+
19
+
20
+ class CriteriaCatalogItem(TypedDict):
21
+ """Criteria catalog entry as returned by the criteria endpoint."""
22
+
23
+ id: str
24
+ name: str
25
+ theme_id: str | None
26
+ theme_name: str
27
+ theme_category: str
28
+
29
+
30
+ class CreateCriteriaPayload(TypedDict, total=False):
31
+ """Payload for creating a criteria catalog entry."""
32
+
33
+ name: str
34
+ theme_id: str | None
@@ -7,6 +7,8 @@ try:
7
7
  except ImportError:
8
8
  from typing_extensions import Any, NotRequired, TypedDict
9
9
 
10
+ from .core import FieldSourcePayload
11
+
10
12
 
11
13
  # -- IRO Types --
12
14
 
@@ -30,6 +32,24 @@ class IRODetail(TypedDict):
30
32
  evidence_text: str
31
33
 
32
34
 
35
+ class IROBatchItemPayload(TypedDict):
36
+ """Payload for a single item in a batch IRO upsert."""
37
+ company: str
38
+ date_publication: str
39
+ name: str
40
+ esg_type: str
41
+ description: NotRequired[str]
42
+ iro_types: NotRequired[list[int]]
43
+ field_sources: NotRequired[list[FieldSourcePayload]]
44
+
45
+
46
+ class IROBatchResultItem(TypedDict):
47
+ """Result for a single item in a batch IRO upsert response."""
48
+ name: str
49
+ iro_id: str
50
+ action: str
51
+
52
+
33
53
  # -- Transition Plan children --
34
54
 
35
55
  class TransitionTargetItem(TypedDict):
@@ -63,6 +83,7 @@ class TransitionTargetPayload(TypedDict):
63
83
  sbti_pathway: NotRequired[str]
64
84
  source_page: NotRequired[int | None]
65
85
  evidence_text: NotRequired[str]
86
+ field_sources: NotRequired[list[FieldSourcePayload]]
66
87
 
67
88
 
68
89
  class TransitionLeverItem(TypedDict):
@@ -88,6 +109,7 @@ class TransitionLeverPayload(TypedDict):
88
109
  kpi_or_milestone: NotRequired[str]
89
110
  source_page: NotRequired[int | None]
90
111
  evidence_text: NotRequired[str]
112
+ field_sources: NotRequired[list[FieldSourcePayload]]
91
113
 
92
114
 
93
115
  class TransitionFinanceItem(TypedDict):
@@ -117,6 +139,7 @@ class TransitionFinancePayload(TypedDict):
117
139
  description: NotRequired[str]
118
140
  source_page: NotRequired[int | None]
119
141
  evidence_text: NotRequired[str]
142
+ field_sources: NotRequired[list[FieldSourcePayload]]
120
143
 
121
144
 
122
145
  class TransitionGovernanceItem(TypedDict):
@@ -144,6 +167,7 @@ class TransitionGovernancePayload(TypedDict):
144
167
  metric: NotRequired[str]
145
168
  source_page: NotRequired[int | None]
146
169
  evidence_text: NotRequired[str]
170
+ field_sources: NotRequired[list[FieldSourcePayload]]
147
171
 
148
172
 
149
173
  # -- Transition Plan --
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes