peregrine/docs/plans/2026-02-20-ui-design.md
pyr0ball c368c7a977 chore: seed Peregrine from personal job-seeker (pre-generalization)
App: Peregrine
Company: Circuit Forge LLC
Source: github.com/pyr0ball/job-seeker (personal fork, not linked)
2026-02-24 18:25:39 -08:00

4.4 KiB
Raw Blame History

Job Seeker Platform — Web UI Design

Date: 2026-02-20 Status: Approved

Overview

A Streamlit multi-page web UI that gives Meghan (and her partner) a friendly interface to review scraped job listings, curate them before they hit Notion, edit search/LLM/Notion settings, and fill out her AIHawk application profile. Designed to be usable by anyone — no technical knowledge required.


Architecture & Data Flow

discover.py → SQLite staging.db (status: pending)
                      ↓
              Streamlit UI
        review / approve / reject
                      ↓
         "Sync N approved jobs" button
                      ↓
              Notion DB (status: synced)

discover.py is modified to write to SQLite instead of directly to Notion. A new sync.py handles the approved → Notion push. db.py provides shared SQLite helpers used by both scripts and UI pages.

SQLite Schema (staging.db, gitignored)

CREATE TABLE jobs (
    id          INTEGER PRIMARY KEY AUTOINCREMENT,
    title       TEXT,
    company     TEXT,
    url         TEXT UNIQUE,
    source      TEXT,
    location    TEXT,
    is_remote   INTEGER,
    salary      TEXT,
    description TEXT,
    match_score REAL,
    keyword_gaps TEXT,
    date_found  TEXT,
    status      TEXT DEFAULT 'pending',  -- pending / approved / rejected / synced
    notion_page_id TEXT
);

Pages

Home (Dashboard)

  • Stat cards: Pending / Approved / Rejected / Synced counts
  • "Run Discovery" button — runs discover.py as subprocess, streams output
  • "Sync N approved jobs → Notion" button — visible only when approved count > 0
  • Recent activity list (last 10 jobs found)

Job Review

  • Filterable table/card view of pending jobs
  • Filters: source (LinkedIn/Indeed/etc), remote only toggle, minimum match score slider
  • Checkboxes for batch selection
  • "Approve Selected" / "Reject Selected" buttons
  • Rejected jobs hidden by default, togglable
  • Match score shown as colored badge (green ≥70, amber 4069, red <40)

Settings

Three tabs:

Search — edit config/search_profiles.yaml:

  • Job titles (add/remove tags)
  • Locations (add/remove)
  • Boards checkboxes
  • Hours old slider
  • Results per board slider

LLM Backends — edit config/llm.yaml:

  • Fallback order (drag or up/down arrows)
  • Per-backend: URL, model name, enabled toggle
  • "Test connection" button per backend

Notion — edit config/notion.yaml:

  • Token field (masked, show/hide toggle)
  • Database ID
  • "Test connection" button

Resume Editor

Sectioned form over aihawk/data_folder/plain_text_resume.yaml:

  • Personal Info — name, email, phone, LinkedIn, city, zip
  • Education — list of entries, add/remove buttons
  • Experience — list of entries, add/remove buttons
  • Skills & Interests — tag-style inputs
  • Preferences — salary range, notice period, remote/relocation toggles
  • Self-Identification — gender, pronouns, veteran, disability, ethnicity (with "prefer not to say" options)
  • Legal — work authorization checkboxes

FILL_IN fields highlighted in amber with "Needs your attention" note. Save button writes back to YAML. No raw YAML shown by default.


Theme & Styling

Central theme at app/.streamlit/config.toml:

  • Dark base, accent color teal/green (job search = growth)
  • Consistent font (Inter or system sans-serif)
  • Responsive column layouts — usable on tablet/mobile
  • No jargon — "Run Discovery" not "Execute scrape", "Sync to Notion" not "Push records"

File Layout

app/
├── .streamlit/
│   └── config.toml          # central theme
├── Home.py                  # dashboard
└── pages/
    ├── 1_Job_Review.py
    ├── 2_Settings.py
    └── 3_Resume_Editor.py
scripts/
├── db.py                    # new: SQLite helpers
├── sync.py                  # new: approved → Notion push
├── discover.py              # modified: write to SQLite not Notion
├── match.py                 # unchanged
└── llm_router.py            # unchanged

Run: conda run -n job-seeker streamlit run app/Home.py


New Dependencies

None — streamlit already installed via resume_matcher deps. sqlite3 is Python stdlib.


Out of Scope

  • Real-time collaboration
  • Mobile native app
  • Cover letter editor (handled separately via LoRA fine-tune task)
  • AIHawk trigger from UI (run manually for now)