Skip to content

Commit 095fa02

Browse files
refactor(myopencre): move CSV validation to parser and detect noop imports
1 parent 09abd8c commit 095fa02

File tree

2 files changed

+3
-132
lines changed

2 files changed

+3
-132
lines changed

application/utils/spreadsheet_parsers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ def validate_export_csv_rows(rows: List[Dict[str, Any]]) -> List[Dict[str, Any]]
141141

142142
headers = list(rows[0].keys())
143143

144-
if not headers or len(headers) < 2:
145-
raise ValueError("Invalid CSV format or missing header row")
144+
if not headers:
145+
raise ValueError("CSV header row is missing")
146146

147147
if not any(h.startswith("CRE") for h in headers):
148148
raise ValueError("At least one CRE column is required")

application/web/web_main.py

Lines changed: 1 addition & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -844,136 +844,7 @@ def import_from_cre_csv() -> Any:
844844
rows = list(csv.DictReader(decoded_contents.splitlines()))
845845

846846
# ------------------------
847-
# Schema / header validation
848-
# ------------------------
849-
850-
headers = [h.strip() for h in csv_read.fieldnames]
851-
852-
if not headers:
853-
return (
854-
jsonify(
855-
{
856-
"success": False,
857-
"type": "SCHEMA_ERROR",
858-
"message": "CSV header row is missing",
859-
}
860-
),
861-
400,
862-
)
863-
864-
has_cre_column = any(h.startswith("CRE") for h in headers)
865-
if not has_cre_column:
866-
return (
867-
jsonify(
868-
{
869-
"success": False,
870-
"type": "SCHEMA_ERROR",
871-
"message": "At least one CRE column is required",
872-
}
873-
),
874-
400,
875-
)
876-
877-
required_columns = ["standard|name", "standard|id"]
878-
for col in required_columns:
879-
if col not in headers:
880-
return (
881-
jsonify(
882-
{
883-
"success": False,
884-
"type": "SCHEMA_ERROR",
885-
"message": f"Missing required column: {col}",
886-
}
887-
),
888-
400,
889-
)
890-
891-
# ------------------------
892-
# Row-level validation (export-compatible)
893-
# ------------------------
894-
895-
rows = list(csv_read)
896-
errors = []
897-
898-
# 🚨 NEW: guard against misaligned rows (extra columns)
899-
for row_index, row in enumerate(rows, start=2):
900-
if None in row:
901-
return (
902-
jsonify(
903-
{
904-
"success": False,
905-
"type": "SCHEMA_ERROR",
906-
"message": (
907-
f"Row {row_index} has more columns than header. "
908-
"Please ensure the CSV matches the exported template."
909-
),
910-
}
911-
),
912-
400,
913-
)
914-
915-
for row_index, row in enumerate(rows, start=2): # header is row 1
916-
normalized_row = {
917-
k: (v.strip() if isinstance(v, str) else v) for k, v in row.items()
918-
}
919-
920-
# Skip completely empty rows (exported templates contain them)
921-
if all(not v for v in normalized_row.values()):
922-
continue
923-
924-
cre_values = [normalized_row.get(h) for h in headers if h.startswith("CRE")]
925-
cre_values = [v for v in cre_values if v]
926-
927-
# Rows without CRE are allowed by export format → skip
928-
if not cre_values:
929-
continue
930-
931-
# Validate CRE format
932-
for cre in cre_values:
933-
if "|" not in cre:
934-
errors.append(
935-
{
936-
"row": row_index,
937-
"code": "INVALID_CRE_FORMAT",
938-
"message": (
939-
f"Invalid CRE entry '{cre}', expected '<CRE-ID>|<Name>'"
940-
),
941-
}
942-
)
943-
944-
if errors:
945-
return (
946-
jsonify(
947-
{
948-
"success": False,
949-
"type": "ROW_VALIDATION_ERROR",
950-
"errors": errors,
951-
}
952-
),
953-
400,
954-
)
955-
956-
# ------------------------
957-
# No-op import guard (IMPORTANT)
958-
# ------------------------
959-
960-
importable_rows = []
961-
for row in rows:
962-
if any(v for v in row.values()):
963-
importable_rows.append(row)
964-
965-
if not importable_rows:
966-
return jsonify(
967-
{
968-
"status": "success",
969-
"new_cres": [],
970-
"new_standards": 0,
971-
"import_type": "empty",
972-
}
973-
)
974-
975-
# ------------------------
976-
# Import execution
847+
# Delegate validation + parsing
977848
# ------------------------
978849

979850
try:

0 commit comments

Comments
 (0)