GuglielmoTor commited on
Commit
a69e5ba
·
verified ·
1 Parent(s): df26793

Update services/report_data_handler.py

Browse files
Files changed (1) hide show
  1. services/report_data_handler.py +178 -1
services/report_data_handler.py CHANGED
@@ -62,4 +62,181 @@ def save_report_results(
62
  return success_ids['id']
63
  else:
64
  logger.error(f"Failed to save agentic analysis to Bubble. {success_ids}")
65
- return False
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  return success_ids['id']
63
  else:
64
  logger.error(f"Failed to save agentic analysis to Bubble. {success_ids}")
65
+ return False
66
+
67
+
68
+ # --- Data Saving Functions ---
69
+
70
+ def save_objectives(
71
+ org_urn: str,
72
+ report_id
73
+ objectives_data: List[Dict[str, Any]]
74
+ ) -> Optional[List[str]]:
75
+ """
76
+ Saves Objective records to Bubble.
77
+
78
+ Args:
79
+ org_urn: The URN of the organization to associate these objectives with.
80
+ objectives_data: A list of objective dictionaries from the main data structure.
81
+
82
+ Returns:
83
+ A list of the newly created Bubble record IDs for the objectives, or None on failure.
84
+ """
85
+ if not objectives_data:
86
+ logger.info("No objectives to save.")
87
+ return []
88
+
89
+ payloads = []
90
+ for objective in objectives_data:
91
+ payloads.append({
92
+ #"organization_urn": org_urn,
93
+ "objective_description": objective.get("objective_description"),
94
+ "objective_timeline": objective.get("objective_timeline"),
95
+ "objective_owner": objective.get("objective_owner"),
96
+ "report": report_id
97
+ })
98
+
99
+ logger.info(f"Attempting to save {len(payloads)} objectives for org_urn: {org_urn}")
100
+ objective_ids = bulk_upload_to_bubble(payloads, BUBBLE_OBJECTIVES_TABLE_NAME)
101
+
102
+ if objective_ids is None:
103
+ logger.error("Failed to save objectives to Bubble.")
104
+ return None
105
+
106
+ logger.info(f"Successfully saved {len(objective_ids)} objectives.")
107
+ return objective_ids
108
+
109
+
110
+ def save_key_results(
111
+ org_urn: str,
112
+ objectives_with_ids: List[Tuple[Dict[str, Any], str]]
113
+ ) -> Optional[List[Tuple[Dict[str, Any], str]]]:
114
+ """
115
+ Saves Key Result records to Bubble, linking them to their parent objectives.
116
+
117
+ Args:
118
+ org_urn: The URN of the organization.
119
+ objectives_with_ids: A list of tuples, where each tuple contains an
120
+ original objective dictionary and its new Bubble ID.
121
+ Example: [(objective_dict, 'bubble_id_123'), ...]
122
+
123
+ Returns:
124
+ A list of tuples containing the original key result data and its new Bubble ID,
125
+ or None on failure. This is needed to save the tasks in the next step.
126
+ """
127
+ key_result_payloads = []
128
+ # This list preserves the original KR data in the correct order to match the returned IDs
129
+ key_results_to_process = []
130
+
131
+ for objective_data, parent_objective_id in objectives_with_ids:
132
+ for kr in objective_data.get("key_results", []):
133
+ key_results_to_process.append(kr)
134
+ key_result_payloads.append({
135
+ #"organization_urn": org_urn,
136
+ "okr": parent_objective_id, # Link to parent
137
+ "description": kr.get("key_result_description"),
138
+ "target_metric": kr.get("target_metric"),
139
+ "target_value": kr.get("target_value"),
140
+ "kr_type": kr.get("key_result_type"),
141
+ "data_subject": kr.get("data_subject"),
142
+ })
143
+
144
+ if not key_result_payloads:
145
+ logger.info("No key results to save.")
146
+ return []
147
+
148
+ logger.info(f"Attempting to save {len(key_result_payloads)} key results for org_urn: {org_urn}")
149
+ key_result_ids = bulk_upload_to_bubble(key_result_payloads, BUBBLE_KEY_RESULTS_TABLE_NAME)
150
+
151
+ if key_result_ids is None:
152
+ logger.error("Failed to save key results to Bubble.")
153
+ return None
154
+
155
+ logger.info(f"Successfully saved {len(key_result_ids)} key results.")
156
+ # Combine the original KR data with their new IDs
157
+ return list(zip(key_results_to_process, key_result_ids))
158
+
159
+
160
+ def save_tasks(
161
+ org_urn: str,
162
+ key_results_with_ids: List[Tuple[Dict[str, Any], str]]
163
+ ) -> Optional[List[str]]:
164
+ """
165
+ Saves Task records to Bubble, linking them to their parent key results.
166
+
167
+ Args:
168
+ org_urn: The URN of the organization.
169
+ key_results_with_ids: A list of tuples from the save_key_results function.
170
+ Example: [(key_result_dict, 'bubble_id_456'), ...]
171
+
172
+ Returns:
173
+ A list of the newly created Bubble record IDs for the tasks, or None on failure.
174
+ """
175
+ task_payloads = []
176
+ for key_result_data, parent_key_result_id in key_results_with_ids:
177
+ for task in key_result_data.get("tasks", []):
178
+ task_payloads.append({
179
+ #"organization_urn": org_urn,
180
+ "key_result": parent_key_result_id, # Link to parent
181
+ "description": task.get("task_description"),
182
+ "objective_deliverable": task.get("objective_deliverable"),
183
+ "category": task.get("task_category"),
184
+ #"task_type": task.get("task_type"),
185
+ "priority": task.get("priority"),
186
+ "priority_justification": task.get("priority_justification"),
187
+ "effort": task.get("effort"),
188
+ "timeline": task.get("timeline"),
189
+ #"data_subject": task.get("data_subject"),
190
+ "responsible_party": task.get("responsible_party"),
191
+ "success_criteria_metrics": task.get("success_criteria_metrics"),
192
+ "dependencies": task.get("dependencies_prerequisites"),
193
+ "why": task.get("why_proposed"),
194
+ })
195
+
196
+ if not task_payloads:
197
+ logger.info("No tasks to save.")
198
+ return []
199
+
200
+ logger.info(f"Attempting to save {len(task_payloads)} tasks for org_urn: {org_urn}")
201
+ task_ids = bulk_upload_to_bubble(task_payloads, BUBBLE_TASKS_TABLE_NAME)
202
+
203
+ if task_ids is None:
204
+ logger.error("Failed to save tasks to Bubble.")
205
+ return None
206
+
207
+ logger.info(f"Successfully saved {len(task_ids)} tasks.")
208
+ return task_ids
209
+
210
+
211
+ # --- Orchestrator Function ---
212
+
213
+ def save_actionable_okrs(org_urn: str, actionable_okrs: Dict[str, Any], report_id):
214
+ """
215
+ Orchestrates the sequential saving of objectives, key results, and tasks.
216
+
217
+ This function shows how to correctly call the individual save functions
218
+ in the right order, passing the IDs from one step to the next.
219
+ """
220
+ logger.info(f"--- Starting OKR save process for org_urn: {org_urn} ---")
221
+ objectives_data = actionable_okrs.get("okrs", [])
222
+
223
+ # Step 1: Save the top-level objectives
224
+ objective_ids = save_objectives(org_urn, objectives_data, report_id)
225
+ if objective_ids is None:
226
+ logger.error("OKR save process aborted due to failure in saving objectives.")
227
+ return
228
+
229
+ # Combine the original objective data with their new IDs for the next step
230
+ objectives_with_ids = list(zip(objectives_data, objective_ids))
231
+
232
+ # Step 2: Save the key results, linking them to the objectives
233
+ key_results_with_ids = save_key_results(org_urn, objectives_with_ids)
234
+ if key_results_with_ids is None:
235
+ logger.error("OKR save process aborted due to failure in saving key results.")
236
+ return
237
+
238
+ # Step 3: Save the tasks, linking them to the key results
239
+ save_tasks(org_urn, key_results_with_ids)
240
+
241
+ logger.info(f"--- OKR save process completed for org_urn: {org_urn} ---")
242
+