App: Peregrine Company: Circuit Forge LLC Source: github.com/pyr0ball/job-seeker (personal fork, not linked)
4.4 KiB
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.pyas 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 40–69, 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)