Job Hunter

Forseti's job-seeking platform covering resume intake, discovery, application prep, submission support, and tracking.

40 Features
33 Shipped
7 In Progress
0 Backlog
✅ 33 Shipped (83%) 🔄 7 In Progress

Expand a group to inspect feature status from the live pipeline.

Profile & Resume 9 ✅ 2 �� 82%
  • ✅ Shipped
    Goal forseti-jobhunter-profile-refactor

    Extract two high-risk sections from `UserProfileForm.php` (7425 lines) into dedicated subforms/components: (1) education history section → `EducationHistorySubform`, (2) resume up…

  • ✅ Shipped
    Goal forseti-jobhunter-profile

    Improve the JobHunter profile page so resume upload/parsing and consolidated profile editing are correct, safe, and verifiable.

  • ✅ Shipped
    Summary forseti-jobhunter-cover-letter-display

    Users can trigger cover letter generation for a saved job. Users can view the generated cover letter and download it as PDF. Users can save the cover letter to their job applicati…

  • ✅ Shipped
    Summary forseti-jobhunter-profile-completeness

    Users always know their profile completeness percentage when visiting the profile or home dashboard. Users see which specific fields are missing with a one-click path to fix them.…

  • ✅ Shipped
    Summary forseti-jobhunter-profile-form-db-extraction

    Extract the 3 direct `$this->database` calls from `UserProfileForm.php` (6104 lines) into the existing `UserProfileService` or a new `UserProfileRepository`. This continues the DB…

  • ✅ Shipped
    Summary forseti-jobhunter-profile-form-static-db-extraction

    Extract or replace the 10 remaining `\Drupal::database()` static calls in `UserProfileForm.php`. These were out of scope for the release-j extraction (which targeted only the 2 `$…

  • ✅ Shipped
    Summary forseti-jobhunter-resume-tailoring-display

    Users can review the tailored resume side-by-side with the original before deciding to save or download. Users can download the PDF of their tailored resume directly. Users can sa…

  • ✅ Shipped
    Summary forseti-jobhunter-resume-tailoring-queue-hardening

    Harden the `ResumeTailoringWorker` queue processor to handle API failures gracefully — add retry backoff, dead-letter logging, and error recovery to prevent silent job drops when …

  • ✅ Shipped
    Summary forseti-jobhunter-tailoring-feedback

    After generating a tailored resume, the user can submit a 👍/👎 rating and an optional note. Rating is stored per `(uid, tailored_resume_id)`. The result page updates in-place via…

  • 🔄 In Progress
    Summary forseti-jobhunter-resume-version-labeling

    The `jobhunter_job_seeker_resumes` table supports multiple uploaded resume files (`resume_name`, `is_primary`) but provides no way to label them meaningfully (e.g., "Software Engi…

  • 🔄 In Progress
    Summary forseti-jobhunter-resume-version-tracker

    The `jobhunter_job_seeker_resumes` table already supports multiple resume files per user (with `resume_name` and `is_primary` flags). The `jobhunter_tailored_resumes` table stores…

Application Management 6 ✅ 2 �� 75%
  • ✅ Shipped
    Goal forseti-jobhunter-application-submission

    Formally track and test the 5-step Workday portal automation workflow shipped in commit `7dea91e8f` as `WorkdayWizardService` + `WorkdayPlaywrightRunner`. This feature was Phase 3…

  • ✅ Shipped
    Summary forseti-jobhunter-application-analytics

    Job seekers accumulate significant application data over time but have no visibility into their own effectiveness: how many applications were submitted, what percentage reached a …

  • ✅ Shipped
    Summary forseti-jobhunter-application-controller-db-extraction

    Extract all 54 direct `$this->database` calls from `JobApplicationController.php` (4177 lines) into `ApplicationSubmissionService` or a new `ApplicationAttemptRepository`. Phase 1…

  • ✅ Shipped
    Summary forseti-jobhunter-application-controller-split

    Reduce `JobApplicationController.php` from 4177 lines to < 800 lines per resulting controller file. No behavior changes — pure structural split. All public method signatures must …

  • ✅ Shipped
    Summary forseti-jobhunter-application-notes

    From the saved-job detail view, the user can: 1. Enter/edit: hiring manager name, contact email, last contact date, freetext notes 2. Save via CSRF-protected AJAX endpoint 3. See …

  • ✅ Shipped
    Summary forseti-jobhunter-application-status-dashboard

    Users can see their saved jobs organized by pipeline stage at a glance. Users can filter to a specific status or company. Users can bulk-archive completed/rejected applications to…

  • 🔄 In Progress
    Summary forseti-jobhunter-application-deadline-tracker

    Users can set application deadline and follow-up reminder dates per saved job. The application status dashboard displays urgency indicators for time-sensitive applications. Users …

  • 🔄 In Progress
    Summary forseti-jobhunter-bulk-status-update

    Users can select multiple applications in the dashboard and update their workflow status in a single action. Reduces friction for users managing 20+ active applications.

Job Discovery & Search 5 ✅ 1 �� 83%
  • ✅ Shipped
    Goal forseti-jobhunter-browser-automation

    BrowserAutomationService (Phase 1 + Phase 2) enables intelligent job application routing via smart strategy selection (direct apply vs. Playwright-assisted), attempt logging, cred…

  • ✅ Shipped
    OKR / Goal forseti-jobhunter-e2e-flow

    Fix/complete the process flow on the /jobhunter dashboard (step-based navigation) so all steps work. Ensure “submission” and “tracking” are persisted and visible. Prefer using exi…

  • ✅ Shipped
    Summary forseti-jobhunter-google-jobs-ux

    Users can page through Google Jobs search results without confusion. Users see how many results matched their query. Users get a clear message when the API is unavailable rather t…

  • ✅ Shipped
    Summary forseti-jobhunter-job-match-score

    On `/jobhunter/my-jobs` each saved-job card displays a match score badge ("78% match"). Score is computed server-side on page load (or on-demand per job) using keyword intersectio…

  • ✅ Shipped
    Summary forseti-jobhunter-saved-search

    Users can save a search and re-run it in one click on a future visit. Users can manage (rename, delete) their saved searches. Maximum 10 saved searches per user (to keep scope bou…

  • 🔄 In Progress
    Summary forseti-jobhunter-job-board-preferences

    The Job Hunter module currently uses multiple job sources (Google Jobs/Cloud Talent Solution, Adzuna API, AbbVie scraper, USA Jobs) but users have no way to configure which source…

Contacts & Companies 2 ✅ 2 �� 50%
  • ✅ Shipped
    Summary forseti-jobhunter-company-interest-tracker

    The global `jobhunter_companies` table is a reference catalog — it holds company metadata but has no per-user interest, culture-fit scoring, or watchlist status. This feature adds…

  • ✅ Shipped
    Summary forseti-jobhunter-contact-tracker

    Job seekers who have warm contacts or referrals at target companies have no structured way to track those relationships within the Job Hunter module. This feature adds a per-user …

  • 🔄 In Progress
    Summary forseti-jobhunter-company-research-tracker

    The `jobhunter_companies` table already exists and stores global company records (name, website, industry, careers page URL, notes). However, users have no per-user way to mark co…

  • 🔄 In Progress
    Summary forseti-jobhunter-contact-referral-tracker

    Job seekers often leverage professional contacts and referrals as their highest-value application channel, yet the Job Hunter module has no way to track contacts at target compani…

Interviews, Offers & Career 4 ✅ 100%
  • ✅ Shipped
    Summary forseti-jobhunter-follow-up-reminders

    Job seekers frequently lose track of applications that need a follow-up (e.g., "I applied 2 weeks ago and haven't heard back"). This feature adds per-saved-job follow-up reminders…

  • ✅ Shipped
    Summary forseti-jobhunter-interview-outcome-tracker

    The existing `forseti-jobhunter-interview-prep` feature (shipped release-j) lets users write interview notes for a saved job. However, there is no way to log the outcome of each i…

  • ✅ Shipped
    Summary forseti-jobhunter-interview-prep

    Users preparing for an interview can access a structured checklist and take notes on a per-job basis. Notes persist across sessions. Users can optionally request AI-generated inte…

  • ✅ Shipped
    Summary forseti-jobhunter-offer-tracker

    Job seekers often receive multiple offers simultaneously and have no structured place to track and compare them. This feature adds an offer tracking view to the Job Hunter module.…

Technical Infrastructure 7 ✅ 100%
  • ✅ Shipped
    Goal forseti-jobhunter-controller-extraction-phase1

    Phase 1 of `JobApplicationController` god-object refactor: move the 54 direct `$this->database` calls in `JobApplicationController.php` (4177 lines) into `ApplicationSubmissionSer…

  • ✅ Shipped
    Goal forseti-jobhunter-controller-refactor-phase2

    Extract the 54 direct `$this->database` calls from `JobApplicationController` (4177 lines) into `ApplicationSubmissionService` or a new `ApplicationAttemptService`. The controller…

  • ✅ Shipped
    Goal forseti-jobhunter-controller-refactor

    Begin extracting the `JobApplicationController` god object (4177 lines, 54 direct DB queries) into focused service classes. Phase 1 scope: extract the DB query layer into a `JobAp…

  • ✅ Shipped
    Goal forseti-jobhunter-hook-install-fix

    Add the two missing table creation calls to `job_hunter_install()` in `job_hunter.install`. The helper functions `_job_hunter_create_interview_notes_table()` and `_job_hunter_crea…

  • ✅ Shipped
    Goal forseti-jobhunter-return-to-open-redirect

    Fix the `return_to` parameter validation in `CompanyController.php` and `ApplicationActionController.php` to reject protocol-relative URLs (`//evil.com`) that bypass the current l…

  • ✅ Shipped
    Goal forseti-jobhunter-schema-fix

    Fix the `field_age_18_or_older` field definition in the `job_hunter` module which declares `db_column: 'age_18_or_older'` but the column does not exist in the database schema. Thi…

  • ✅ Shipped
    Goal forseti-jobhunter-twig-csrf-cleanup

    Remove ALL dead-code hidden CSRF token fields from job_hunter Twig templates. `CsrfAccessCheck` reads only the URL query string `?token=` (appended by `RouteProcessorCsrf`); hidde…

Project context & metadata

Current state

Active buildout. Release-h carries 4 features in_progress: `forseti-jobhunter-interview-outcome-tracker` (high), `forseti-jobhunter-offer-tracker` (high), `forseti-jobhunter-application-analytics` (medium), `forseti-jobhunter-follow-up-reminders` (medium). Seven additional groomed features re-baselined to `ready` for future releases: `contact-tracker`, `company-interest-tracker`, `company-research-tracker`, `contact-referral-tracker`, `job-board-preferences`, `resume-version-labeling`, `resume-version-tracker`.

Next step

Await dev-forseti completion + Gate 2 QA on 4 active release-h features. After coordinated push, activate next slice from 7 queued ready features by priority.

Queue status

4 features in_progress for `20260412-forseti-release-h`. Dev + QA inbox items dispatched 2026-04-13.

Metadata

Type: product line
Status: active_buildout
Priority: P1 — worker node
PM: pm-forseti
Lead: pm-forseti
Started: 2026-04-12
Product: forseti.life
Last scoped release: `20260412-forseti-release-h`
Progress SLA: 7 days without release-scoped work or a PM re-baseline/grooming update = breach
Progress status: SLA breach