Listings: a discarded listing moves to the Closed tab when its closing date passes, still labelled Discarded #529
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#529
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, comparing the three places that decide a listing's derived state.Checked again on 2026-10-01 against
mainat0a5cad587: still present. The code is now atjobs/models.py:723-744(state_condition),jobs/models.py:798-809(with_state_order) andjobs/models.py:1003-1011(derived_state); the callers injobs/listing_views.py,api/routers/listings.pyandapplications/analytics.pyhave not moved.Postulo decides twice, with two different orders, whether a discarded listing whose closing date has passed is discarded or closed. The word in the State cell and the State column's sort say discarded; the tabs, their counts, the API filter and the dashboard's count of listings let go say closed.
jobs/models.py:720-741(state_condition:closedisno_application & shutwith no exclusion of discarded rows, anddiscardedisQ(state=state) & no_application & ~shut); againstjobs/models.py:795-806(with_state_order, discarded before closed) andjobs/models.py:1000-1008(derived_state, discarded before closed).state_conditionfeedsin_stateandtab_counts, and through themjobs/listing_views.py:100and:115,api/routers/listings.py:81-86and:121, andapplications/analytics.py:405.closes_atyesterday hasderived_state == "discarded",in_state("discarded").count() == 0,in_state("closed").count() == 1andtab_counts()ofdiscarded: 0, closed: 1. The same listing is returned byGET /api/v1/listings?state=closedwith"state": "discarded", and not by?state=discarded. The insights figure for listings discarded falls day by day as closing dates pass.state_condition's docstring says it exists so that the places deciding closed agree (#231);derived_stateis the one it does not agree with.derived_state's precedence everywhere (a decision outlives a date): instate_condition, makeclosedno_application & shut & ~Q(state=ListingState.DISCARDED)anddiscardedQ(state=ListingState.DISCARDED) & no_application. Correct thewith_state_orderdocstring, which lists the order as "to decide, applied, closed, discarded" while the code tests discarded first.Done when
tests/test_listings.pythat, for every combination of stored state (new, shortlisted, discarded), open or past its closing date or closed, and with or without an application, checks thatderived_state, the one tab whosein_statecontains the row, and thewith_state_ordervalue agree.