Automation

Job posting saver with Chrome extension and Python API

Chrome extension saves job postings from any site into a local tracker with status, notes, and follow-up reminders, backed by a FastAPI and SQLite server.

pythonfastapisqlitejavascriptchrome-extensionpytest

Built 1 time, downloaded 0 times.

Install from your terminal

Run this in your project folder. It signs you in, shows what changes and asks before it overwrites a file.

npx claude-lab add job-posting-saver-with-chrome-extension-and-python-api-4a3257
CLAUDE.md
# Job posting saver

Manifest V3 Chrome extension (plain JavaScript, no build step) that captures job postings from any site and POSTs them to a local FastAPI + SQLite backend. Solo user, runs on this machine only. Tracks status, notes and follow-up reminders.

@SPEC.md
@REVIEW.md

## Layout

- extension/: manifest.json, background.js (service worker), content.js (parser), popup.html and popup.js, options page, tracker page
- server/app/: main.py, models.py, db.py, schemas.py, reminders.py
- tests/: pytest suite; tests/fixtures/ holds saved posting HTML
- PLAN.md: phased build plan. Each phase ends with a /goal prompt.

## Commands

Run from the repo root unless noted.

- Install: `uv sync` or `pip install -r requirements.txt`
- Dev server (from server/): `uvicorn app.main:app --reload --port 8765`
- Tests: `pytest -q`
- Lint: `ruff check .`
- Format: `ruff format .`
- Types: `mypy server/app`
- Full check before calling work done: run the verify skill

## Gotchas

- MV3 service workers are killed when idle. Keep no state in globals; persist to chrome.storage.
- Reminders use chrome.alarms in the extension. The server only stores follow_up_at. Re-register all alarms on startup.
- Some page CSPs block localhost requests from content scripts. Fetch from background.js only.
- Extraction order: JSON-LD JobPosting first, then Open Graph and meta tags, then manual fields in the popup. Never fail a save because parsing failed.
- Parser logic lives in content.js. server/app/parse.py mirrors it for Python-side fixture tests, so change both together.

## Conventions

- Type hints everywhere. Pydantic models for all request and response bodies.
- Status is an enum: saved, applied, interviewing, offer, rejected, withdrawn.
- Timestamps are UTC ISO 8601.
- Dedupe by normalized URL: lowercase host, strip fragments and utm_* params, trim trailing slash.
- Tests use a temporary SQLite DB, never the dev database.
- Keep functions small.

## Security

- Server binds to 127.0.0.1 only.
- CORS allows only the extension origin, set by env var EXTENSION_ORIGIN.
- Optional API token is read from env API_TOKEN. Use the placeholder YOUR_API_TOKEN in docs and examples. Never commit a real token.
- Never log posting text or notes.

## Workflow

- Explore, plan, code, then run the verify skill before saying done.
- /clear between unrelated tasks. /compact at natural breaks.
- Hand test output to the test-runner subagent to keep context small.
- Phase 1 touches server/, tests/ and requirements.txt or pyproject.toml only. No extension code until its phase.
- Do not add dependencies or a JS build tool without asking.
Use for my project