Postal addresses: check an address against its country before keeping it, with the kind and Primary first #306

Closed
opened 2026-09-29 11:26:38 +00:00 by tiagoagueda · 0 comments
Owner

From the interface review of 2026-09-29:

  • The kind and Primary come first in the row.
  • The kind is chosen in Basecoat's select with an icon, and the country with its flag (#301).
  • An address is validated against its country before it is stored.

What is there today

  • In partials/postal_addresses.html the row begins with the address, then the postcode and the town, then the region and the country. The kind and Primary come after them.
  • Each part is named the way the address's own country names it, in the reader's language, by the Postal rules plugin (#147, core/postal.py::label_for).
  • The same plugin already knows what looks wrong for a country (postal.warnings_for) and says so, but it never refuses a save. The model says why: "Valid cannot mean verified" (core/models.py::PostalAddress). Postulo is not going to post anything, and an address typed oddly is still somebody's address.

Decisions to take

  1. What is refused and what is warned about. A postcode in a form its country never uses (Portugal's is NNNN-NNN, the Netherlands' NNNN AA) is certainly wrong, and cheap to refuse. Whether the town matches the postcode needs a reference database nobody here wants. Proposal: refuse what the country's format rules out, and warn about the rest as today.
  2. Where the formats come from. Google's address metadata (the data behind libaddressinput, a JSON document per country) carries each country's postcode pattern and the parts it requires; the plugin already has a table of its own. Either way, the data ships with the plugin and is never fetched.
  3. Addresses already stored that would now be refused stay as they are, marked, and are checked the next time they are saved.
  4. Kind first means the order #213 describes for telephone numbers, applied here, on the contact form as well as on Your details.

Done when

  • A refused address says which part is wrong and what its country expects, next to that part.
  • There are tests for each country the plugin covers, one per rule, and one for a country it does not cover, which stays free-form with nothing refused.
From the interface review of 2026-09-29: - The kind and *Primary* come first in the row. - The kind is chosen in Basecoat's select with an icon, and the country with its flag (#301). - An address is validated against its country before it is stored. ## What is there today - In `partials/postal_addresses.html` the row begins with the address, then the postcode and the town, then the region and the country. The kind and *Primary* come after them. - Each part is named the way the address's own country names it, in the reader's language, by the *Postal rules* plugin (#147, `core/postal.py::label_for`). - The same plugin already knows what looks wrong for a country (`postal.warnings_for`) and says so, but it **never refuses a save**. The model says why: "Valid cannot mean verified" (`core/models.py::PostalAddress`). Postulo is not going to post anything, and an address typed oddly is still somebody's address. ## Decisions to take 1. **What is refused and what is warned about.** A postcode in a form its country never uses (Portugal's is `NNNN-NNN`, the Netherlands' `NNNN AA`) is certainly wrong, and cheap to refuse. Whether the town matches the postcode needs a reference database nobody here wants. Proposal: refuse what the country's format rules out, and warn about the rest as today. 2. **Where the formats come from.** Google's address metadata (the data behind libaddressinput, a JSON document per country) carries each country's postcode pattern and the parts it requires; the plugin already has a table of its own. Either way, the data ships with the plugin and is never fetched. 3. **Addresses already stored** that would now be refused stay as they are, marked, and are checked the next time they are saved. 4. **Kind first** means the order #213 describes for telephone numbers, applied here, on the contact form as well as on *Your details*. ## Done when - A refused address says which part is wrong and what its country expects, next to that part. - There are tests for each country the plugin covers, one per rule, and one for a country it does not cover, which stays free-form with nothing refused.
tiagoagueda added this to the 0.5.0 milestone 2026-09-29 11:26:38 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Postulo/postulo#306
No description provided.