Stage history editor:
- The edit form's Pipeline section is now the application's history:
one row per step (stage + date), Add Step and Remove Step, kept in
date order. The last step is the current stage and the first step's
date the date applied, replacing the separate Stage and Date Applied
fields. An application logged after the fact (applied, interviewed,
rejected) keeps its whole path.
- JobsDatabase::replaceStageHistory() rewrites a job's history in one
transaction (sorted, repeats collapsed, stage and date applied kept in
step); StageHistoryModel backs the section; JobsModel::addJob() now
returns the new id so a new application's history can be saved.
- `kareer history <id> [Stage=YYYY-MM-DD ...]` shows or replaces it.
Auto-ghosting:
- Applications still at Applied with no activity (the later of the
date applied and the last stage change) for more than 30 days move to
Ghosted, recorded like any stage change. Runs at startup for GUI and
CLI, after switching databases, and shortly after the setting changes.
- Preferences gains an Applications section: on/off and the number of
days (kareerrc [AutoGhost]). The GUI shows a passive notification; the
CLI notes it on stderr so --json output stays clean.
Fixes:
- The Add Application form pre-filled empty text fields with the word
"undefined" (typing "a" gave "undefineda"): fields with no value
reached QML as undefined. Every field now gets a typed default.
- Embed the app icon as the window icon fallback, so the window and
About page show it when running uninstalled.
Tests: history replacement and the after-the-fact Allstate case, the
ghosting rules (fresh/stale/logged-late/reopened/threshold), and empty
new-form fields.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01BxDf7HqD1xPnsZP8wt3NTk
Changing an application's stage and pressing Save closed the form
without saving the stage: JobsDatabase::updateJob() deliberately skips
the stage column so every move lands in stage_history, but
JobEditModel::save() never followed up with setStage(). It now does,
as the CLI's update command always has.
Also:
- Validate that company and title are non-empty and say so, instead of
saving a blank field
- Always set lastError on failure, clear it on the next attempt, and
bind the page's error message to it
- Reload the form's values when jobsModel is assigned, since QML does
not guarantee it is set before editingJobId
- Bind the salary spin boxes to the model and write back only on user
edits; guard the notes field the same way
- Add jobeditmodeltest covering load order, edits, stage history,
salaries round-tripping, adding, and validation errors
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01BxDf7HqD1xPnsZP8wt3NTk