fix: csv feed preview shows the header row as an importable attribute - #393
Merged
Merged
Conversation
2854af8 fixed the header skip in the ingestion task, but preview_csv_feed never had one: it ran process_csv_feed_row over every parsed line, so the feed wizard previewed the header as an importable attribute and showed one fewer data row than the configured limit. `rows` still carries the header -- AddFeedCsv.vue reads rows[0] for the column labels and slices it off itself -- so only `preview`, which is what would actually be imported, skips it. Both call sites now share csv_feed_has_header(), which also tolerates a csvConfig written before the flag existed. That KeyError used to escape fetch_csv_feed entirely: the guard sits outside the per-row try/except, so it killed the whole task rather than failing a single row. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
OpenAPI changesNo changes to the OpenAPI spec. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #393 +/- ##
==========================================
+ Coverage 84.56% 84.59% +0.03%
==========================================
Files 209 209
Lines 19425 19465 +40
==========================================
+ Hits 16427 16467 +40
Misses 2998 2998 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
BLUF
preview_csv_feednever had one, so the feed wizard previews the header row as a real attribute.KeyError: 'header'that escapesfetch_csv_feedentirely for acsvConfigwritten before the flag existed.What was wrong
1. The preview never skipped the header
preview_csv_feedranprocess_csv_feed_rowover every parsed line. Withheaderon or off the output was identical — the header came back as anip-dstattribute valued"value":The header also ate one of the
limitslots, so a 5-row preview showed 4 real rows.This matters because the frontend defaults the toggle on (
AddFeedCsv.vue:31,header: saved?.header ?? true), so it is the default path, andTestCSVFeedModal.vue:64renderstestResult.previewstraight from this endpoint.2.
KeyError: 'header'killed the whole ingestion taskdb_feed.settings["csvConfig"]["header"]sits outside the per-rowtry/except, so a config without the key did not degrade to a failed row — it propagated out offetch_csv_feed:What this changes
feeds_repository.csv_feed_has_header(), used by both the preview endpoint and the ingestion task, so the two can no longer disagree about whether row 0 is data. It reads the flag with.get(..., False).preview_csv_feedskips the header when buildingpreview, and reads one extra line so a header no longer costs a data row.rowsdeliberately still carries the header:AddFeedCsv.vue:73-75derives the column labels fromrows[0]and slices it off itself, so stripping it server-side would break the wizard. Onlypreview— what would actually be imported — skips it.CsvPreview.vuerendersrowsandpreviewas two independent tables, so the differing lengths are fine.After:
How it was verified
10 mock-only tests (no database, OpenSearch or network):
TestCsvFeedHasHeaderandTestPreviewCsvFeedinapi/app/tests/repositories/test_feeds.py, plus one case added toTestFetchCsvFeedTaskfrom #389.Each fix was reverted individually to confirm the tests discriminate rather than merely pass:
test_header_row_is_not_previewed_as_an_attribute→ failstest_a_header_does_not_cost_a_data_row→ failstest_a_missing_header_key_is_treated_as_no_header→ fails withKeyErrorThe other four pass before and after by design — they guard against an over-correcting fix (header still present in
rows, no-header path untouched).flake8 clean. No schema, route or migration change, so
docs/features/api/openapi.jsonis unaffected.🤖 Generated with Claude Code