# file: data_processor.py import json def process_law_data_to_chunks(structured_data_input): """ Xử lý dữ liệu luật từ cấu trúc JSON lồng nhau thành một danh sách phẳng các chunks. Mỗi chunk chứa text và metadata tương ứng. """ flat_list = [] # Đảm bảo đầu vào là một danh sách các điều luật (articles) if isinstance(structured_data_input, dict) and "article" in structured_data_input: articles_list = [structured_data_input] elif isinstance(structured_data_input, list): articles_list = structured_data_input else: print("Lỗi: Dữ liệu đầu vào không phải là danh sách các Điều luật hoặc một đối tượng Điều luật.") return flat_list for article_data in articles_list: if not isinstance(article_data, dict): print(f"Cảnh báo: Bỏ qua một mục trong danh sách điều luật vì không phải là dictionary: {article_data}") continue article_metadata_base = { "source_document": article_data.get("source_document"), "article": article_data.get("article"), "article_title": article_data.get("article_title") } clauses = article_data.get("clauses", []) if not isinstance(clauses, list): print(f"Cảnh báo: 'clauses' trong điều {article_metadata_base.get('article')} không phải là danh sách. Bỏ qua.") continue for clause_data in clauses: if not isinstance(clause_data, dict): print(f"Cảnh báo: Bỏ qua một mục trong 'clauses' vì không phải là dictionary: {clause_data}") continue clause_metadata_base = article_metadata_base.copy() clause_metadata_base.update({ "clause_number": clause_data.get("clause_number"), "clause_metadata_summary": clause_data.get("clause_metadata_summary") }) points_in_clause = clause_data.get("points_in_clause", []) if not isinstance(points_in_clause, list): print(f"Cảnh báo: 'points_in_clause' trong khoản {clause_metadata_base.get('clause_number')} của điều {article_metadata_base.get('article')} không phải là danh sách. Bỏ qua.") continue if points_in_clause: for point_data in points_in_clause: if not isinstance(point_data, dict): print(f"Cảnh báo: Bỏ qua một mục trong 'points_in_clause' vì không phải là dictionary: {point_data}") continue chunk_text = point_data.get("point_text_original") or point_data.get("violation_description_summary") if not chunk_text: continue current_point_metadata = clause_metadata_base.copy() point_specific_metadata = point_data.copy() if "point_text_original" in point_specific_metadata: del point_specific_metadata["point_text_original"] current_point_metadata.update(point_specific_metadata) final_metadata_cleaned = {k: v for k, v in current_point_metadata.items() if v is not None} flat_list.append({"text": chunk_text, "metadata": final_metadata_cleaned}) else: chunk_text = clause_data.get("clause_text_original") if chunk_text: current_clause_metadata = clause_metadata_base.copy() additional_clause_info = {} for key, value in clause_data.items(): if key not in ["clause_text_original", "points_in_clause", "clause_number", "clause_metadata_summary"]: additional_clause_info[key] = value if additional_clause_info: current_clause_metadata.update(additional_clause_info) final_metadata_cleaned = {k: v for k, v in current_clause_metadata.items() if v is not None} flat_list.append({"text": chunk_text, "metadata": final_metadata_cleaned}) return flat_list