Skip to content

feat(columns): accept observations in three languages, like descriptions - #11

Merged
rdahis merged 1 commit into
mainfrom
feat/observations-per-language
Aug 27, 2026
Merged

feat(columns): accept observations in three languages, like descriptions#11
rdahis merged 1 commit into
mainfrom
feat/observations-per-language

Conversation

@rdahis

@rdahis rdahis commented Aug 27, 2026

Copy link
Copy Markdown
Member

The problem

Column.observations is three fields on the backend — observationsPt / observationsEn / observationsEs — exactly like the description fields. But all three column writers here took a single untagged observations argument, which lands in Portuguese only. There was no English or Spanish argument to pass: a translated note was impossible to express through the tool.

This is not a hypothetical gap. Surveyed on production 2026-08-27, of 3,980 columns with a non-empty observation, 3,022 across 46 datasets were Portuguese-only. None had English or Spanish alone, so the gap was total — and every one of them was written by these tools. Worst affected: piaac 734, open_payments 646, bankfind 231, cps 219, anes_time_series 185, pisa 146, usaspending_gov 124.

Those columns have since been backfilled on prod (3,022) and staging (3,066). This PR stops them being recreated.

The change

Tool New
bulk_upsert_columns observations_pt / observations_en / observations_es, in the sheet and in columns_json
upload_columns_from_sheet sheet columns observations_en and observations_es, alongside observations
update_column observations_pt, observations_en, observations_es arguments

All three now write observationsPt / observationsEn / observationsEs explicitly rather than the bare observations key. Introspecting CreateUpdateColumnInput confirms all four fields exist, so the bare key was reaching Portuguese via modeltranslation's default language — being explicit removes the ambiguity.

Backward compatible. A bare observations still means Portuguese everywhere, so existing callers keep working — and keep reproducing the original bug if they pass only it, which the docstrings now say plainly. Empty fields are still not written, so a partial call cannot blank a translation that is already stored.

Verification

Writing to the wrong field would be silent, so this was not left to an import check.

Live round-trip on staging, against a real column (elections.house_first_preference_division.ballot_position):

  1. bulk_upsert_columns with all three → all three fields set.
  2. bulk_upsert_columns with a bare observations → Portuguese updated, English and Spanish left untouched.
  3. update_column with the new arguments → all three fields set.
  4. Restored the original three values and confirmed byte-equality with the starting state.

order, descriptionPt and isPartition were unchanged throughout, confirming the partial input does not clobber neighbouring fields.

Stubbed-sheet test for upload_columns_from_sheet — that path needs a public Google Sheet, so the CSV download and the mutation POST were stubbed and the built payload inspected:

  • a row with all three → observationsPt / En / Es
  • a Portuguese-only row → observationsPt alone, no empty En / Es keys
  • a row with no notes → no observation fields at all
  • the bare observations key absent from every payload

Note for reviewers

A running MCP server holds the old module until it restarts, so the new arguments will not appear in a session started before this merges.

🤖 Generated with Claude Code

`Column.observations` has always been three fields on the backend
(`observationsPt`/`En`/`Es`), but all three column writers here took a
single `observations` argument that lands in Portuguese only. There was
no argument for the other two — a translation was impossible to express
through the tool.

Surveyed on production 2026-08-27: of 3,980 columns with a non-empty
observation, 3,022 across 46 datasets were Portuguese-only. None had
English or Spanish alone, so the gap was total, and it came from these
arguments.

- `upload_columns_from_sheet` reads `observations_en` and
  `observations_es` from the sheet alongside `observations`
- `bulk_upsert_columns` accepts `observations_pt/_en/_es` in both the
  sheet and `columns_json`
- `update_column` gains `observations_pt`, `observations_en` and
  `observations_es`

A bare `observations` still means Portuguese in all three, so existing
callers keep working. Empty fields are still not written, so a partial
call cannot blank a translation that is already stored.

Verified against staging: all three paths write all three fields, a
lone `observations` still goes to Portuguese without touching English
or Spanish, and `order`, the descriptions and `isPartition` are left
intact.
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.

1 participant