Replicate USPS restricted country handling in batches rework
- Dominant language
- Ruby
- Stars
- 24
- Forks
- 18
- Avg merge
- 7h 11m
- Merged PRs (30d)
- 7
Description
## Context
Commits `1714e90` and `8cb9f5a` on `main` added handling for USPS-restricted countries (IR, CU, BY, KP, SD, SO, SS, SY, YE). This needs to be replicated in the batches rework branch.
## What was added
### `config/country_restrictions.yml`
Single source of truth with two lists:
- `usps_restricted`: countries where USPS has suspended international mail service
- `agh_restricted`: additional countries the AGH warehouse won't ship to (PS, RU)
Loaded via `config.country_restrictions = config_for(:country_restrictions)` in `application.rb`.
### Address validation (`app/models/address.rb`)
- `validate :country_not_usps_restricted` — rejects restricted countries with `"USPS does not currently deliver to {country}"`
- Error on `:base` so `full_messages` reads naturally in API responses
### Country dropdown filtering (`app/models/concerns/country_enumable.rb`)
- `countries_for_select` filters out `usps_restricted` countries so they don't appear in UI dropdowns
### CSV batch import (`app/models/batch.rb`)
- `run_map!` checks `usps_restricted?` after `build_address_attributes` and skips restricted rows
- Uses `Concurrent::Set` to collect skipped country codes (thread-safe for `Parallel.map`)
- Returns the list of skipped country codes
### Controller flash messages
Both `base_batches_controller.rb` and `warehouse/batches_controller.rb`:
- Capture `skipped_countries` from `run_map!`
- Append to flash notice: *"Addresses in Iran were skipped — USPS does not currently deliver there."*
### Warehouse order validation (`app/models/warehouse/order.rb`)
- `can_mail_parcels_to_country` now reads from `country_restrictions.yml` (both lists combined) instead of hardcoded `%i[IR PS CU KP RU]`
### Defensive rescue in `Letter::Batch`
- `postage_cost` and `postage_cost_difference` rescue `USPS::USPSError` per-letter, log a warning, skip unpriceable letters — belt-and-suspenders for newly suspended countries not yet in the yml
## Bug that triggered this
Batch 781 had a letter to Iran. The USPS international pricing API returns 400 for sanctioned destinations. Nothing caught the `USPS::USPSError`, so `@batch.postage_cost` in the process page view blew up with a 500.
Contributor guide
Research direction
Compare commits 1714e90 and 8cb9f5a with the batches rework branch, then read config/country_restrictions.yml, application.rb, and the listed address, country selection, batch, controller, warehouse order, and Letter::Batch files. Replicate the restricted-country handling across those entry points, including validation, filtering, batch skips, flash messages, warehouse checks, and defensive USPS errors; done means the rework branch matches the described behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ruby
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 52/100