Insights, the report and salaries count the wrong things: quiet after interviews, withdrawals waiting, interviews missed, currencies mixed #224
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
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#224
Loading…
Add table
Add a link
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 in the 2026-09-15 code audit. Each item was checked by reading the code.
1. "Gone quiet" fires the day after an interview that has no outcome yet
quiet()requiresnext_interview_atto be null (applications/models.py:169-172).with_next_interviewcounts only interviews withends_at__gte=Now()(:180-189), so an interview waiting for its outcome is no longer "planned".services.py:267-277).quiet.py:58-92).with_next_interviewalso ignores itsatargument.Fix: treat any interview whose outcome is still SCHEDULED as planned, including past ones, or fold the interview's
ends_atinto last activity.2. Withdrawn applications count as "waiting on a reply" forever
analytics.py:254-261excludes only GHOSTED, so a withdrawal with no reply counts as waiting and appears on the Outcomes widget.Fix: restrict the count to
status in QUIET_STATUSES, and add a test next totests/test_insights.py:155-162.3. The report and Insights disagree on interviews
reports.py:448-453).analytics.py:179-202), and the wiki promises a typed-in interview "counts as much as one settled from the diary".Fix: count
EventKind.INTERVIEWevents byoccurred_atinside the period, deduplicated against diary interviews.4. A rescheduled interview's reminder keeps the old time
The reminder text includes the time when created (
services.py:281-293), andreschedule_interviewmovesdue_atbut not the text (:321-327).Fix: regenerate the text on reschedule, or build it from the interview when shown.
5. Salaries
CSV import (
core/csv_import.py)::813) while$and£are stripped (:601)."50-60k"imports as 50 to 60,000, because thekis applied per side (:600, 614-618).aanywhere (:614).Display and sorting:
salary_max(applications/tables.py:83-88), so €30 an hour sorts below €40,000 a year and USD mixes with EUR.salary_displayleaves out the period (jobs/models.py:751-774).Fix:
kto both sides, detect/h,/monthandpa, and split onaonly as a word.updated_at#245