Shaheer Sarfaraz b18c2eccbb
Code cleanup (#218)
* chore: move @types/canvas-confetti to devDependencies, remove unused get-tsconfig direct dep

* chore: configure knip with workspace entry points for all packages

* refactor(shared): split 1119-line types.ts into domain modules under types/

* refactor: remove llm-service.ts shim, migrate all import sites to llm/service directly

* refactor(settings): migrate 4 manually-resolved settings into conversion registry

* refactor: split gmail-sync.ts into gmail-api, email-router, and thin orchestrator

* refactor(orchestrator): extract useKeyboardShortcuts and usePipelineControls from OrchestratorPage

Splits the 840-line OrchestratorPage into a thin orchestration shell (~480 lines) by
extracting keyboard shortcut handling into useKeyboardShortcuts.ts and pipeline
control logic into usePipelineControls.ts. Net negative line count across all files.

* feat: create settings registry (Step 1)

Introduces a single source of truth for all settings, combining schema definitions, default logic, parsing, and serialization into a single configuration object.

* feat: derive schema, keys, and types from settings registry (Step 2)

Derives AppSettings nested shape, SettingKey DB union, and updateSettingsSchema Zod shape automatically from the settings registry.

* refactor: gut envSettings and remove settings-conversion (Step 3)

Replaces manual env arrays with registry-driven maps in envSettings.ts.
Deletes settings-conversion.ts since all parsing/defaults now live in the registry.

* refactor: simplify getEffectiveSettings with generic loop (Step 4)

Replaces ~334 lines of manual key-by-key unpacking with a generic registry-driven iteration loop (~40 lines). Models, typed, string, and virtual kinds are automatically derived.

* refactor: simplify settingsUpdateRegistry (Step 5)

Replaces ~350 lines of explicit per-key update handlers with a dynamic generic loop over the settings registry, properly routing persistence and side effects.

* refactor(settings): implement nested settings registry and clean up tests

- Migrate settings system to use a centralized nested registry (`settings-schema.ts`, `registry.ts`)
- Remove obsolete flat-to-nested conversion logic (`settings-conversion.ts`)
- Address Biome warnings by explicitly ignoring intentional `any` usage in generic runtime schema builder and registry logic
- Clean up unused variables in test files (`SettingsPage.test.tsx`) to achieve a 100% green CI pipeline

* refactor(settings): address PR comments on env data and registry parsing

- Narrow `getEnvSettingsData` return type to `Partial<AppSettings>` to satisfy strict typing and omit 'typed' registry entries
- Introduce `parseNonEmptyStringOrNull` for typed string settings so empty-string overrides cleanly fall back to defaults (matching original `||` logic)
- Add missing unit tests for registry parse/serialize helpers (JSON, bools, numeric clamping)
2026-02-21 03:07:51 +00:00
2026-02-21 00:42:09 +00:00
2026-02-21 00:42:09 +00:00
2026-02-21 03:07:51 +00:00
2026-02-08 00:19:26 +00:00
2026-02-21 03:07:51 +00:00
2026-02-18 22:05:15 +00:00
2026-02-19 12:51:55 +00:00
2026-02-21 03:07:51 +00:00
2026-01-17 02:53:31 +00:00
2026-02-21 00:42:09 +00:00
2026-02-15 22:20:56 +00:00
2026-02-20 12:05:45 +00:00

JobOps: Your Ironman Suit for Job Hunting

Automate the hunt. Scrapes major job boards (LinkedIn, Indeed, Glassdoor), AI-scores suitability, tailors resumes (RxResume), and tracks application emails automatically.

Self-hosted. Docker-based. Stop applying manually.

Stars GHCR Release Contributors

40s Demo: Crawl → Score → PDF → Track

Pipeline Demo

https://github.com/user-attachments/assets/5b9157a9-13b0-4ec6-9bd2-a39dbc2b11c5

Apply & Track

https://github.com/user-attachments/assets/06e5e782-47f5-42d0-8b28-b89102d7ea1b

Documentation (Start Here)

JobOps ships with full docs for setup, architecture, extractors, and troubleshooting.

If you want the serious view of the project, start here:

Quick Start (10 Min)

Prefer guided setup? Follow the Self-Hosting Guide.

# 1. Download
git clone https://github.com/DaKheera47/job-ops.git
cd job-ops

# 2. Start (Pulls pre-built image)
docker compose up -d

# 3. Launch Dashboard
# Open http://localhost:3005 to start the onboarding wizard

Why JobOps?

  • Universal Scraping: Supports LinkedIn, Indeed, Glassdoor, Adzuna + specialized boards (Gradcracker, UK Visa Jobs).
  • AI Scoring: Ranks jobs by fit against your profile using your preferred LLM (OpenRouter/OpenAI/Gemini).
  • Auto-Tailoring: Generates custom resumes (PDFs) for every application using RxResume v4.
  • Email Tracking: Connect Gmail to auto-detect interviews, offers, and rejections.
  • Self-Hosted: Your data stays with you. SQLite database. No SaaS fees.

Workflow

  1. Search: Scrapes job boards for roles matching your criteria.
  2. Score: AI ranks jobs (0-100) based on your resume/profile.
  3. Tailor: Generates a custom resume summary & keyword optimization for top matches.
  4. Export: Uses RxResume v4 to create tailored PDFs.
  5. Track: "Smart Router" AI watches your inbox for recruiter replies.

Supported Extractors

Platform Focus
LinkedIn Global / General
Indeed Global / General
Glassdoor Global / General
Adzuna Multi-country API source
Gradcracker STEM / Grads (UK)
UK Visa Jobs Sponsorship (UK)

(More extractors can be added via TypeScript - see extractors documentation)

Post-App Tracking (Killer Feature)

Connect Gmail → AI routes emails to your applied jobs.

  • "We'd like to interview you..." → Status: Interviewing (Auto-updated)
  • "Unfortunately..." → Status: Rejected (Auto-updated)

See post-application tracking docs for setup.

Note on Analytics: The alpha version includes anonymous analytics (Umami) to help debug performance. To opt-out, block umami.dakheera47.com in your firewall/DNS.

Star History

Star History Chart

License

AGPLv3 - Free to use and modify.

Description
No description provided
Readme AGPL-3.0 6.7 MiB
Languages
TypeScript 98.6%
Python 0.4%
Shell 0.4%
CSS 0.3%
Dockerfile 0.2%