hackclub / hackclub/theseus

Replicate USPS restricted country handling in batches rework

Open
#294 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.