Skip to content

Job Detail Page

Chazona Baum edited this page Jun 24, 2026 · 1 revision

Relevant source files

The Job Detail route (src/routes/jobs/[slug]/+page.svelte) serves as the "Decision Brief" for a specific role src/lib/styles/layout/jobs.css#1 It aggregates structured data from the job's Markdown frontmatter, narrative analysis from the pipeline's LLM steps, and fit scoring metrics into a unified workspace for evaluating and tracking a job application.

Data Flow & Implementation

The page is a client-side SPA route that loads data via Tauri IPC commands based on the URL slug src/routes/jobs/[slug]/+page.ts:1-2. It relies on the companiesStore to provide the current vaultPathsrc/routes/jobs/[slug]/+page.svelte:34-38.

Data Loading Architecture

The page reactively reloads whenever the slug or vaultPath changes using Svelte 5 runes ($derived and $effect) src/routes/jobs/[slug]/+page.svelte:24-53.

  1. Initial Load: Calls getJob(vaultPath, slug) to retrieve the JobDetail object src/routes/jobs/[slug]/+page.svelte:38-38.
  2. Section Parsing: The Markdown body is parsed into distinct sections (Alignment, Fit Flags, Research, JD) using jobSections()src/lib/jobDetail.ts#48-60
  3. Live Updates: The page subscribes to pipeline events (onRunStep, onRunFinished) to show real-time progress if a re-score or detail-fetch run is active for the current job src/routes/jobs/[slug]/+page.svelte:133-158.

Code Entity Mapping: UI to Logic

The following diagram bridges the visual components of the Job Detail page to the underlying TypeScript helpers and state.

Job Detail Entity Mapping

flowchart LR
    subgraph subGraph1 ["Logic & State (TypeScript)"]
        E["src/lib/fit.ts"]
        F["src/lib/jobStatus.ts"]
        G["src/lib/jobDetail.ts"]
        H["src/lib/jobDetail.ts"]
        I["src/lib/job.ts"]
    end
    subgraph subGraph0 ["UI Surface (Svelte)"]
        A["Score Block"]
        B["Status Selector"]
        C["Narrative Sections"]
        D["Details Grid"]
    end
    A --> E
    B --> F
    C --> G
    D --> H
    D --> I
Loading

Sources:src/routes/jobs/[slug]/+page.svelte:58-62, src/lib/jobDetail.ts#1-85src/lib/jobStatus.ts#24-36

Structured Content Parsing

Because Lodestar stores narrative analysis within the Markdown body of the job note, the frontend must extract specific sections for display in the UI. This is handled by extractSection, which mirrors the Rust backend's logic: it searches for a specific ## heading and collects lines until the next ## heading, ignoring ### subheadings src/lib/jobDetail.ts#15-40

Section Key Heading in Markdown Purpose
alignment ## Alignment analysis Narrative LLM summary of why the job fits.
fitFlags ## Fit flags Bullet points with [DEALBREAKER] or [CAUTION] tags.
research ## Research notes Evidence found during the gap-research phase.
jdStructured ## JD — structured LLM-cleaned version of the raw job description.

Sources:src/lib/jobDetail.ts#48-60src/lib/jobDetail.test.ts#92-112

Fit Scoring & Visualization

The page visualizes the five dimensions of fit scoring defined in the FitWeights model.

Sub-score Rows

The subScoreRows function generates a stable display order for the five sub-scores: Seniority, Skills, Comp, Arrangement, and Domain src/lib/jobDetail.ts#66-76 These are rendered as a list of progress bars (.jobs__bar-track) with color-coded fills src/lib/styles/layout/jobs.css#131-170

Band Coloring

The UI applies semantic coloring based on the fit_score using the bandClass helper src/routes/jobs/[slug]/+page.svelte:85-98:

  • Good/Strong: var(--good) (Green)
  • Partial/Weak: var(--warn) (Yellow/Orange)
  • Mismatch: var(--danger) (Red)
  • Unscored: var(--faint) (Gray)

Sources:src/lib/styles/layout/jobs.css#62-75src/routes/jobs/[slug]/+page.svelte:59-60

Status Transitions & Lifecycle

The Job Detail page enforces the Job lifecycle state machine. The classifyStatus function handles raw string values from frontmatter, identifying "anomalies" if the status is missing or unrecognized src/lib/jobStatus.ts#24-36

Legal Transitions

The nextHumanStatuses function dictates which buttons are available to the user src/lib/jobStatus.ts#59-75:

Current Status Legal Human Transitions
new skipped
detailed skipped
scored selected, skipped
selected applied
applied (Terminal)
skipped (Terminal)

Sources:src/lib/jobStatus.ts#59-75src/lib/jobStatus.test.ts#93-125

Inline Editing & Re-scoring

Users can manually edit structured fields (e.g., comp_low, remote, yoe_min) via a "Details" panel src/routes/jobs/[slug]/+page.svelte:194-205.

  1. Field Updates: Changes are persisted to the Markdown frontmatter via updateJobField or setJobListFieldsrc/routes/jobs/[slug]/+page.svelte:216-228.
  2. Triggered Re-score: After editing a field that affects fit, the page calls maybeRescore(). This invokes the rescoreJob Tauri command src/routes/jobs/[slug]/+page.svelte:162-177.
  3. Visual Feedback: While re-scoring, a scoringInFlight flag displays a "Re-scoring..." indicator, which updates dynamically based on pipeline step events src/routes/jobs/[slug]/+page.svelte:114-159.

Interaction Flow: Field Edit to Re-score

sequenceDiagram
    participant UI as Job Detail Page
    participant Store as companiesStore
    participant Core as Rust Backend (Tauri)
    participant Watcher as Vault Watcher
    UI->>Core: updateJobField(vaultPath | slug | "comp_low" | 150000)
    Core->>Core: write_note (Markdown Frontmatter)
    Watcher->>Store: record:changed (slug)
    Store->>UI: trigger reload()
    UI->>Core: rescoreJob(vaultPath | slug)
    Core->>UI: onRunStep (stage: "fit-score")
    UI->>UI: Set rescorePhase = "Scoring..."
    Core->>UI: onRunFinished
    UI->>UI: reload() & Clear indicators
Loading

Sources:src/routes/jobs/[slug]/+page.svelte:162-188, src/routes/jobs/[slug]/+page.svelte:216-228

Clone this wiki locally