New application, new listing and capture review store any three characters as the salary currency #446
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
performance
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo#446
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found on 2026-09-29 in a read-only review of postulo at
95348908d, followingsalary_currencyfrom each form to the database and checking the result with a unit test against the snapshot.Checked again on 2026-10-01 against
mainat0a5cad587: still present.#224 gave
JobPosting.salary_currencya validator,jobs.models.currency_code("three letters, upper case"). The forms that create most listings never run it:PostingIntakeFormdeclares its own plainCharField, andcreate_listingsaves withJobPosting.objects.create(), which does not call model validators. The API's listing schema has the same gap. A value the validator refuses is therefore stored, and the listing's own edit form then refuses to save until it is corrected.Related to #224 (closed), which asked for currency codes to be validated; the validator reached the model and
JobPostingForm, not these routes.applications/forms.py:148-154(PostingIntakeForm.salary_currency, no validator),applications/forms.py:208-227(posting_data),applications/services.py:245-248(create_listing); used byapplications:create(ApplicationIntakeForm),jobs/listing_views.py:210-225(new listing) andjobs/capture_views.py:198-200, 350(CaptureReviewForm). Alsoapi/schemas.py:279(ListingIn.salary_currency,max_length=3only), saved throughapi/routers/listings.py:181.eu1in the currency box when recording an application.JobPosting.saveupper-cases it andEU1is stored. Checked:applications:createwithsalary_currency="eu1"answered with a redirect and storedEU1;posting.full_clean()then raises "EU1 is not a currency code. Use three letters, like EUR."PostingIntakeForm.salary_currencyvalidators=[currency_code]and aclean_salary_currencythat strips and upper-cases the value before the validator runs (asOfferForm.clean_currencydoes); add the same check toListingInwith a field validator. Optionally callfull_clean()increate_listingso every route, including the CSV import, is held to the model.Done when
tests/test_applications.pyhas a test that postssalary_currency="eu1"toapplications:createand gets the form back with an error on the currency, and one that posts"eur"and storesEUR;tests/test_api.pyhas the same refusal for the listing endpoint.