Skip to content

fix: quick wins from the audit (#91, #92, #93, #94) - #102

Merged
dmartinezIPA merged 9 commits into
mainfrom
fix/quick-wins-91-94
Oct 13, 2026
Merged

dmartinezIPA merged 9 commits into
mainfrom
fix/quick-wins-91-94

Conversation

@dmartinezIPA

Copy link
Copy Markdown
Collaborator

What does this PR do? 📝

Closes #91, closes #92, closes #93, closes #94: the mechanical follow-ups from the pre-public audit.

  • Strict numeric parsing #94 An int or decimal column parses only the numbers the server writes: integers -?[0-9]+, and decimals with an optional exponent (1.0E-4, which the collection app writes for very large or small values). 1_0, nan, inf, 3 and +3 stay text with a cast_fallback.

  • Runnable SQL in the DB map's join lines #92 Join lines in <project>_db.json / _db.sql quote every name with the existing helpers. A test runs every line against DuckDB with hh-listing/roster.csv, visit-2, hh.id and order.

  • Errors name the input they reject #91 Errors name the input they reject:

    • a dataset CSV that is empty, repeats a column or is not UTF-8;
    • a malformed or repeated SCTO_SENTINELS / SCTO_DATE_SENTINELS pair;
    • an HTTP error, which carries the start of the server's reason;
    • a non-JSON success body, which names the URL, type and size but never quotes the body.

    The one runtime assert in src/ is now a ValueError.

  • Trim the contract module #93 xml_contract docstrings state what the code does. Node.pulldata (a duplicate of data_source), map_column's ambiguous and FormContract.to_dict are removed; nothing outside tests read them.

How to test or reproduce ? 🧪

uv run pytest -q passes 472 tests. Each behaviour change has a synthetic test that failed before its fix.

Checklist ✅

  • I have run and tested my changes locally
  • I have updated/added tests to cover my changes (if applicable)
  • I have run linting and formatting on any code changes (if applicable)
  • I have updated the documentation (README, etc.) accordingly

🤖 Generated with Claude Code

dmartinezIPA and others added 9 commits October 13, 2026 08:23
An int or decimal value must fullmatch ASCII digits with an optional minus
(and, for a decimal, a fraction and Java's exponent) before conversion, since
int() and float() also take "1_0", "nan" and " 3 ", which are text from an
earlier form version and now fall back with a cast_fallback.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every form, table, dataset and column name in a join line is quoted with the
helper the executed SQL uses, and an XPath string literal in a filter becomes
an SQL one, so a line pastes and runs when a name holds "/", "-", "." or a
reserved word. The form's schema map finds its joins by the quoted name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…le (#91)

An empty header, a column named twice and bytes that are not UTF-8 raise a
ValueError naming the CSV wherever a dataset is read, since a row read by name
keeps only the last of two columns and a bare StopIteration names nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A SCTO_SENTINELS or SCTO_DATE_SENTINELS pair whose code does not parse, or
whose code is given twice, raises naming the variable and the pair, since a
repeated code silently kept only the last meaning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A non-2xx response's error ends with the first 300 characters of its body,
where the server says why it refused (a 417 says how long to wait); the body
of an error response is the server's message, not submissions. A 2xx body
that is not JSON raises naming the URL, its type and size, never its text,
since a body cut short can hold submissions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The [datasets.<id>] key check raises a ValueError naming the config section,
since python -O strips an assert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Docstrings and comments describe the code, not its history. Node.pulldata
goes, since data_source holds the same pulldata() reading; map_column's
"ambiguous" and FormContract.to_dict go, since only tests read them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An Unreleased section records each fix, so the next release notes start from it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

# Conflicts:
#	CHANGELOG.md
@dmartinezIPA
dmartinezIPA requested a review from a team as a code owner October 13, 2026 14:08
@dmartinezIPA
dmartinezIPA merged commit d6f54f9 into main Oct 13, 2026
3 checks passed
@dmartinezIPA
dmartinezIPA deleted the fix/quick-wins-91-94 branch October 13, 2026 14:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Strict numeric parsing Trim the contract module Runnable SQL in the DB map's join lines Errors name the input they reject

1 participant