docs: cut version 0.1.21

This commit is contained in:
github-actions[bot] 2026-02-16 00:44:09 +00:00
parent 7b159e81fe
commit 65c07b1fec
27 changed files with 2296 additions and 1 deletions

View File

@ -0,0 +1,46 @@
---
id: gradcracker
title: Gradcracker Extractor
description: How the Gradcracker crawler builds search URLs and extracts jobs.
sidebar_position: 2
---
A plain-English walkthrough of the Gradcracker extractor in `extractors/gradcracker`.
## Big picture
The crawler builds search URLs, scrapes listing pages, then opens job details for descriptions and apply URLs.
## 1) Build search URLs
- Combines UK regions with role terms.
- Defaults include roles such as `web-development` and `software-systems`.
- `GRADCRACKER_SEARCH_TERMS` overrides defaults.
## 2) Crawl list pages
- Waits for job cards (`article[wire:key]`).
- Extracts title, employer, discipline, deadline, salary, location, degree, start date.
- Queues job detail pages.
Controls:
- `GRADCRACKER_MAX_JOBS_PER_TERM`
- `JOBOPS_SKIP_APPLY_FOR_EXISTING=1`
- `JOBOPS_EXISTING_JOB_URLS` / `JOBOPS_EXISTING_JOB_URLS_FILE`
## 3) Crawl detail pages
- Waits for `.body-content`
- Captures full description text
- Clicks apply button to resolve final application URL
- Handles popup and same-tab redirects
## 4) Progress reporting
Set `JOBOPS_EMIT_PROGRESS=1` for structured progress lines consumable by orchestrator UI.
## Notes
- Uses Playwright + Crawlee via Camoufox.
- Low concurrency and longer timeouts for stability.

View File

@ -0,0 +1,47 @@
---
id: jobspy
title: JobSpy Extractor
description: How the JobSpy Python wrapper is orchestrated and normalized.
sidebar_position: 3
---
A walkthrough of the JobSpy extractor for Indeed, LinkedIn, and Glassdoor.
## Big picture
JobSpy runs as a Python script per search term, writes JSON, then orchestrator ingests and normalizes into internal job shape.
## 1) Inputs and defaults
Key environment variables:
- `JOBSPY_SITES` (default: `indeed,linkedin`)
- `JOBSPY_SEARCH_TERM` (default: `web developer`)
- `JOBSPY_LOCATION` (default: `UK`)
- `JOBSPY_RESULTS_WANTED` (default: `200`)
- `JOBSPY_HOURS_OLD` (default: `72`)
- `JOBSPY_COUNTRY_INDEED` (default: `UK`)
- `JOBSPY_LINKEDIN_FETCH_DESCRIPTION` (default: `true`)
## 2) Orchestrator flow
The service in `orchestrator/src/server/services/jobspy.ts`:
- Builds search-term list from UI or env
- Runs Python once per term with unique output file
- Reads JSON and maps to `CreateJobInput`
- De-dupes by `jobUrl`
- Deletes temp output files best-effort
## 3) Mapping and cleanup
- Normalizes salary ranges
- Converts empty values to null
- Keeps metadata like skills, ratings, remote flags when available
- Skips rows with invalid site or missing URL
## Notes
- `JOBSPY_SEARCH_TERMS` can be JSON array or `|`, comma, newline-delimited text.
- Set `JOBSPY_LINKEDIN_FETCH_DESCRIPTION=0` to speed runs.
- Temp output files are stored under `data/imports/`.

View File

@ -0,0 +1,61 @@
---
id: manual
title: Manual Import Extractor
description: Import jobs from pasted descriptions and run AI-assisted inference.
sidebar_position: 4
---
Manual import lets users add jobs that automated scrapers miss.
## Big picture
User pastes raw description, AI infers structure, user reviews edits, then import saves and scores the job.
## 1) Input
Manual import accepts:
- plain text job descriptions
- raw HTML job descriptions
- job links/URLs
When a URL is provided, backend fetch attempts depend on whether the page can be resolved with `curl`. Some job sites block or heavily script content, so certain links will not resolve cleanly.
## 2) AI inference
Endpoint:
- `POST /api/manual-jobs/infer`
Service:
- `orchestrator/src/server/services/manualJob.ts`
Behavior:
- Converts the provided input into text context and sends it to the configured LLM
- Extracts structured fields (title, employer, location, salary, etc.)
- Returns inferred JSON for user review
Practical limit:
- The inference quality ceiling is mostly the configured model capability and context behavior. Better model quality generally yields better field extraction.
If no LLM key is configured, inference is skipped and user can fill fields manually.
## 3) Review and edit
User reviews inferred fields and corrects missing/wrong values.
## 4) Storage and scoring
Import endpoint:
- `POST /api/manual-jobs/import`
On import:
- Generates unique job ID if URL absent
- Stores source as `manual`
- Triggers async suitability scoring
- Persists score and reason

View File

@ -0,0 +1,33 @@
---
id: overview
title: Extractors Overview
description: Technical index of supported extractors and how they work.
sidebar_position: 1
---
This page helps you choose the right extractor for your run, understand key constraints, and navigate to detailed technical guides.
## Extractor chooser
| Extractor | Best use case | Core constraints/dependencies | Notable controls | Output/behavior notes |
| --- | --- | --- | --- | --- |
| [Gradcracker](/docs/next/extractors/gradcracker) | UK graduate roles from Gradcracker | Crawling stability depends on page structure and anti-bot behavior; tuned for low concurrency | `GRADCRACKER_SEARCH_TERMS`, `GRADCRACKER_MAX_JOBS_PER_TERM`, `JOBOPS_SKIP_APPLY_FOR_EXISTING` | Scrapes listing metadata, then detail pages and apply URL resolution |
| [JobSpy](/docs/next/extractors/jobspy) | Multi-source discovery (Indeed, LinkedIn, Glassdoor) | Requires Python wrapper execution per term; source availability and quality vary by site/location | `JOBSPY_SITES`, `JOBSPY_SEARCH_TERMS`, `JOBSPY_RESULTS_WANTED`, `JOBSPY_HOURS_OLD`, `JOBSPY_LINKEDIN_FETCH_DESCRIPTION` | Produces JSON per term, then orchestrator normalizes and de-duplicates by `jobUrl` |
| [UKVisaJobs](/docs/next/extractors/ukvisajobs) | UK visa sponsorship-focused roles | Requires authenticated session and periodic token/cookie refresh | `UKVISAJOBS_EMAIL`, `UKVISAJOBS_PASSWORD`, `UKVISAJOBS_MAX_JOBS`, `UKVISAJOBS_SEARCH_KEYWORD` | API pagination + dataset output; orchestrator de-dupes and may fetch missing descriptions |
| [Manual Import](/docs/next/extractors/manual) | One-off jobs not covered by scrapers | Inference quality depends on model/provider and input quality; some URLs cannot be fetched reliably | App/API endpoints (`/api/manual-jobs/infer`, `/api/manual-jobs/import`) | Accepts text/HTML/URL, runs inference, then saves and scores job after review |
## Which extractor should I use?
- Use **JobSpy** for broad first-pass sourcing across common boards.
- Use **Gradcracker** when targeting graduate pipelines in the UK.
- Use **UKVisaJobs** for sponsorship-specific UK searches.
- Use **Manual Import** when you already have a specific posting and need direct import.
Many runs combine sources: broad discovery first, then manual import for high-priority jobs that scraping misses.
## Related extractor docs
- [Gradcracker](/docs/next/extractors/gradcracker)
- [JobSpy](/docs/next/extractors/jobspy)
- [UKVisaJobs](/docs/next/extractors/ukvisajobs)
- [Manual Import](/docs/next/extractors/manual)

View File

@ -0,0 +1,73 @@
---
id: ukvisajobs
title: UKVisaJobs Extractor
description: Authenticated session flow, API pagination, and orchestrator ingestion.
sidebar_position: 5
---
UKVisaJobs is the most complex extractor because authenticated sessions are required.
## Big picture
Two layers:
1. `extractors/ukvisajobs/src/main.ts` handles login/API calls and dataset output.
2. `orchestrator/src/server/services/ukvisajobs.ts` executes extractor and ingests/de-dupes output.
## 1) Authentication and session cache
Session cache file:
- `extractors/ukvisajobs/storage/ukvisajobs-auth.json`
Flow:
- Reuse cached token/cookies when valid
- Re-login with Playwright + Camoufox when needed
- Refresh and retry on token-expired responses
Force refresh:
- `UKVISAJOBS_REFRESH_ONLY=1`
## 2) API requests
Endpoint:
- `https://my.ukvisajobs.com/ukvisa-api/api/fetch-jobs-data`
Each request includes auth token + session cookies and paginates (15 jobs/page).
## 3) Mapping
- Normalizes salary from min/max/interval
- Builds fallback visa description when content missing
- Maps `job_link` to both `jobUrl` and `applicationLink`
## 4) Output dataset
Written to:
- `extractors/ukvisajobs/storage/datasets/default/`
Includes per-job JSON files and combined `jobs.json`.
## 5) Orchestrator flow
- Spawns extractor (`npx tsx src/main.ts`)
- Runs terms sequentially with delay
- De-dupes by `sourceJobId` (fallback `jobUrl`)
- Fetches detail pages when descriptions are too short
## Controls
- `UKVISAJOBS_EMAIL`, `UKVISAJOBS_PASSWORD`
- `UKVISAJOBS_HEADLESS`
- `UKVISAJOBS_MAX_JOBS` (default 50, max 200)
- `UKVISAJOBS_SEARCH_KEYWORD`
## Practical notes
- Deleting auth cache forces next run to re-login.
- Low-concurrency/polite scraping by design.
- If extractor breaks, check session refresh path first.

View File

@ -0,0 +1,91 @@
---
id: ghostwriter
title: Ghostwriter
description: Context-aware per-job AI chat assistant behavior and API surface.
sidebar_position: 2
---
## What it is
Ghostwriter is the per-job AI chat assistant in JobOps.
Ghostwriter uses:
- current job description and metadata
- reduced profile snapshot
- global writing style settings
The UI behavior is one persistent conversation per job, shown in the right-side drawer from job details.
## Why it exists
Ghostwriter helps you produce job-specific writing quickly while preserving consistency with your profile and style settings.
Typical use cases:
- role-specific answer drafting
- cover letter and outreach drafts
- interview prep tied to the job description
- rephrasing with tone constraints
## How to use it
1. Open a job in `discovered` or `ready`.
2. Open the Ghostwriter drawer.
3. Enter your prompt and stream a response.
4. Stop or regenerate responses when needed.
### Writing style settings impact
Global settings affecting generations:
- `Tone`
- `Formality`
- `Constraints`
- `Do-not-use terms`
Defaults:
- Tone: `professional`
- Formality: `medium`
- Constraints: empty
- Do-not-use terms: empty
### Context and safety model
- Job snapshot is truncated to fit prompt budget.
- Profile snapshot includes relevant slices only.
- System prompt enforces read-only assistant behavior.
- Logging stores metadata, not full prompt/response dumps.
### API surface
- `GET /api/jobs/:id/chat/messages`
- `POST /api/jobs/:id/chat/messages` (streaming)
- `POST /api/jobs/:id/chat/runs/:runId/cancel`
- `POST /api/jobs/:id/chat/messages/:assistantMessageId/regenerate` (streaming)
Compatibility thread endpoints remain, but UI behavior is one thread per job.
## Common problems
### Responses feel too generic
- Verify the job description is complete and current.
- Confirm style constraints in Settings are specific enough.
### Generation quality is lower than expected
- Check model/provider configuration in Settings.
- Tighten prompts with explicit output intent (for example, "3 bullet points for recruiter outreach").
### Missing context in answers
- Update profile data and relevant project details used by Ghostwriter context.
- Regenerate after updating job notes/description.
## Related pages
- [Settings](/docs/next/features/settings)
- [Reactive Resume](/docs/next/features/reactive-resume)
- [Orchestrator](/docs/next/features/orchestrator)

View File

@ -0,0 +1,90 @@
---
id: in-progress-board
title: In Progress Board
description: Post-application kanban board for tracking fewer, higher-attention jobs through interview and offer stages.
sidebar_position: 3
---
## What it is
The In Progress Board is a kanban view for jobs that have moved beyond initial application.
It groups jobs into post-application lanes:
- Recruiter Screen
- Assessment
- Team Match
- Technical Interview
- Final Round
- Offer
- Closed
## Why it exists
JobOps uses two operational modes:
- **Pre-application tracking** (`Jobs` page): large volume, pipeline and readiness focused.
- **Post-application tracking** (`In Progress Board`): smaller volume, higher attention per job.
Once a job enters the post-application phase, each opportunity usually needs tighter follow-up, interview prep, and deliberate stage management. A kanban board is better for that than a large list.
## How to use it
1. Open **In Progress Board**.
2. Review jobs by lane to see current stage distribution.
3. Drag a card to a new lane to log a stage transition.
4. Open a card to view full job details and timeline.
5. Use sorting (Recent / Title / Company) to prioritize review.
### Moving jobs into post-application
Jobs typically move into post-application tracking when they receive a response after applying.
This can happen via:
- Tracking Inbox review/automation (recommended)
- Manual stage transitions in job detail/timeline tools
### API examples
```bash
# List in-progress jobs
curl "http://localhost:3001/api/jobs?status=in_progress&view=list"
```
```bash
# Move a job to technical interview
curl -X POST "http://localhost:3001/api/jobs/<jobId>/stage-events" \
-H "content-type: application/json" \
-d '{
"toStage": "technical_interview",
"metadata": {
"actor": "user",
"eventType": "status_update",
"eventLabel": "Moved to Technical Interview"
}
}'
```
## Common problems
### Board is empty
- Confirm jobs have status `in_progress`.
- Confirm stage events exist for applied jobs expected on the board.
### A card appears in an unexpected lane
- The board uses the latest stage event as source of truth.
- Check timeline events for out-of-order or mistaken transitions.
### Drag-and-drop move failed
- Network/API error can roll back optimistic UI movement.
- Retry move and check server logs for validation errors.
## Related pages
- [Overview](/docs/next/features/overview)
- [Orchestrator](/docs/next/features/orchestrator)
- [Post-Application Tracking](/docs/next/features/post-application-tracking)

View File

@ -0,0 +1,73 @@
---
id: job-search-bar
title: Job Search Bar
description: Use the global job search/command bar to find and open jobs fast, with optional status locking.
sidebar_position: 3
---
The Job Search Bar is the quickest way to jump to any job from the Jobs page.
## Open it
Use either:
- keyboard shortcut: `Cmd+K` (macOS) or `Ctrl+K` (Windows/Linux)
- the **Search** button in the Jobs page filter row
## What it searches
Search matches job fields with fuzzy ranking:
- title
- company/employer
- location
Results are grouped by status sections:
- Ready
- Discovered
- Applied
- Other
Selecting a result opens that job in its correct tab automatically.
## Status lock (`@`)
You can lock the search scope to one status:
1. Type `@` plus a status prefix (example: `@rea`, `@app`).
2. Press `Tab` or `Enter` to apply the lock.
3. Continue typing your normal query.
Supported lock targets:
- `ready`
- `discovered`
- `applied`
- `skipped`
- `expired`
Common aliases:
- `ready`: `ready`, `rdy`
- `discovered`: `discovered`, `discover`, `disc`
- `applied`: `applied`, `apply`, `app`
- `skipped`: `skipped`, `skip`, `skp`
- `expired`: `expired`, `expire`, `exp`
## Lock controls
- `Backspace` on an empty query clears the active lock.
- `Esc` clears the active lock while the search dialog stays open.
- Closing the dialog resets lock state.
## When to use this vs filters
- Use **Search Bar** when you already know what role/company you want to jump to quickly.
- Use **Filters** when you want broad narrowing (source, salary, sponsor, sort) for browsing.
## Related pages
- [Orchestrator](./orchestrator)
- [Pipeline Run](./pipeline-run)
- [Find Jobs and Apply Workflow](../workflows/find-jobs-and-apply-workflow)

View File

@ -0,0 +1,79 @@
---
id: keyboard-shortcuts
title: Keyboard Shortcuts
description: Complete keyboard shortcut reference for the Jobs page, including tab-scoped actions and help/search toggles.
sidebar_position: 4
---
This page documents keyboard shortcuts available on the Jobs page.
## Open shortcut help
Use `?` to toggle the keyboard shortcut dialog.
The dialog:
- shows shortcuts for your current tab context
- groups shortcuts by Navigation, Actions, Tabs, and General
- is shown automatically once for first-time users
## Bottom shortcut hint bar
On desktop (`lg+`), hold `Control` to reveal the bottom shortcut hint bar.
It shows the same tab-scoped shortcuts in a compact layout.
## Global navigation shortcuts
- `j` or `ArrowDown`: next job
- `k` or `ArrowUp`: previous job
- `1`: Ready tab
- `2`: Discovered tab
- `3`: Applied tab
- `4`: All Jobs tab
- `ArrowLeft`: previous tab
- `ArrowRight`: next tab
## Search and help shortcuts
- `Cmd+K` / `Ctrl+K`: open job search bar
- `/`: open job search bar
- `?`: toggle keyboard shortcut help dialog
For search lock behavior (`@ready`, `@app`, etc.), see [Job Search Bar](./job-search-bar).
## Context action shortcuts
### Available in `discovered` and `ready`
- `s`: skip job
### Available in `discovered`
- `r`: move to Ready
Note: if you have multi-select active, `r` runs bulk move-to-ready.
### Available in `ready`
- `a`: mark applied
- `p`: view PDF
- `d`: download PDF
### Available in all tabs (when applicable)
- `o`: open job listing
- `x`: toggle select current job
- `Esc`: clear selection
## Shortcut availability rules
Shortcuts are disabled while blocking modals are open (for example Run modal, Filters, drawer states).
Search (`/`) and Help (`?`) can still open their own dialogs when other blocking dialogs are not active.
## Related pages
- [Job Search Bar](./job-search-bar)
- [Orchestrator](./orchestrator)
- [Pipeline Run](./pipeline-run)

View File

@ -0,0 +1,63 @@
---
id: multi-select-and-bulk-actions
title: Multi-Select and Bulk Actions
description: Select multiple jobs with mouse or keyboard and run bulk actions like Move to Ready, Skip, or Recalculate match.
sidebar_position: 5
---
Multi-select lets you process many jobs at once instead of repeating the same action one-by-one.
## Why this exists
When you run discovery at scale, you often need to:
- skip batches of low-priority jobs
- move a shortlist to Ready quickly
- recalculate fit scores after settings/profile changes
Bulk actions reduce repetitive clicks, keep momentum high, and make triage runs faster.
## Mouse workflow
### Select jobs
1. Use the checkbox on each row to include/exclude a job.
2. Use **Select all filtered** to select jobs currently visible in the active filtered list.
3. Check the selected count in the list header.
### Run bulk actions
When one or more jobs are selected, a floating action bar appears at the bottom.
Available actions depend on selected job statuses:
- **Move to Ready**
- **Skip selected**
- **Recalculate match**
- **Clear** (clears selection)
## Keyboard workflow
Use shortcuts from the Jobs page:
- `x`: toggle select on the currently focused job
- `Esc`: clear current selection
- `r`: in `discovered`, move to Ready
`r` behavior with selection:
- if you have a multi-selection active, `r` runs the bulk **Move to Ready** action
- if nothing is selected, `r` runs move-to-ready for the single current job
## Important limits and behavior
- Bulk actions are capped at **100 jobs per run**.
- `Select all filtered` also respects the same 100-job cap.
- Selection resets when you switch tabs.
- If jobs disappear from the active filtered list, they are removed from selection automatically.
## Related pages
- [Keyboard Shortcuts](./keyboard-shortcuts)
- [Orchestrator](./orchestrator)
- [Find Jobs and Apply Workflow](../workflows/find-jobs-and-apply-workflow)

View File

@ -0,0 +1,120 @@
---
id: orchestrator
title: Orchestrator
description: Job states, ready flow, and PDF generation/regeneration behavior.
sidebar_position: 1
---
## What it is
The Orchestrator is the primary jobs workspace in JobOps.
It controls:
- job lifecycle states
- manual and automatic ready flow
- PDF generation and regeneration
- handoff to post-application tracking
Job states:
- `discovered`: found by crawler/import, not tailored yet
- `processing`: tailoring and/or PDF generation in progress
- `ready`: tailored PDF generated and ready to apply
- `applied`: marked as applied
- `skipped`: explicitly excluded from active queue
- `expired`: deadline passed
## Why it exists
Orchestrator centralizes the transition from discovered opportunities to application-ready artifacts.
It exists to ensure:
- a consistent path from discovery to tailored output
- clear status transitions across manual and automated workflows
- predictable regeneration behavior when job data changes
## How to use it
### Intended ready flow
1. Manual flow:
1. Job starts in `discovered`.
2. Open the job and choose Tailor.
3. Edit JD/tailored fields/project picks.
4. Click **Finalize & Move to Ready**.
2. Auto flow:
1. Pipeline scores discovered jobs.
2. Top jobs above threshold are auto-processed.
3. Jobs move directly to `ready` with generated PDFs.
### Ghostwriter availability
Ghostwriter is available in `discovered` and `ready` job views.
For details, see [Ghostwriter](/docs/next/features/ghostwriter).
### Generating PDFs
PDF generation uses:
- base resume selected from RxResume
- job description
- tailored summary/headline/skills/projects
Common paths:
- Discovered to finalization: `POST /api/jobs/:id/process`
- Ready regeneration: `POST /api/jobs/:id/generate-pdf`
### Regenerating PDFs after edits (copy-pasteable examples)
If JD or tailoring changes, regenerate PDF to keep output in sync.
```bash
curl -X PATCH "http://localhost:3001/api/jobs/<jobId>" \
-H "content-type: application/json" \
-d '{
"jobDescription": "<new JD>",
"tailoredSummary": "<optional>",
"tailoredHeadline": "<optional>",
"tailoredSkills": [{"name":"Backend","keywords":["TypeScript","Node.js"]}],
"selectedProjectIds": "p1,p2"
}'
```
```bash
curl -X POST "http://localhost:3001/api/jobs/<jobId>/summarize?force=true"
curl -X POST "http://localhost:3001/api/jobs/<jobId>/generate-pdf"
```
### External payload and sanitization defaults
- LLM prompts send minimized profile/job fields.
- Webhooks are sanitized and whitelisted by default.
- Logs and error details are redacted/truncated by default.
- Correlation fields include `requestId`, and when available `pipelineRunId` and `jobId`.
## Common problems
### Job is stuck in `processing`
- `processing` is transient; failures generally revert the job to `discovered`.
- Check run logs and retry generation.
### PDF does not reflect recent edits
- Run summarize with `force=true` after changing the JD/tailoring.
- Regenerate PDF after summarize completes.
### Reopen skipped/applied jobs
- Patch `status` back to `discovered` to return the job to the active queue.
## Related pages
- [Pipeline Run](/docs/next/features/pipeline-run)
- [Ghostwriter](/docs/next/features/ghostwriter)
- [Reactive Resume](/docs/next/features/reactive-resume)
- [Post-Application Tracking](/docs/next/features/post-application-tracking)

View File

@ -0,0 +1,65 @@
---
id: overview
title: Overview
description: Dashboard analytics for application volume and conversion over selectable time windows.
sidebar_position: 1
---
## What it is
The Overview page is the analytics dashboard for your pipeline outcomes.
It visualizes:
- Applications per day
- Application-to-response conversion
- Funnel progression (Applied, Screening, Interview, Offer, Rejected)
## Why it exists
The page helps you measure whether your current sourcing and tailoring approach is producing responses, not just applications.
Use it to quickly answer:
- Are application volumes increasing or dropping?
- Is response conversion improving?
- Where are applications stalling in the funnel?
## How to use it
1. Open **Overview**.
2. Select a time window (`7d`, `14d`, `30d`, `90d`) in the top-right selector.
3. Review:
- **Applications per day** for volume trend
- **Application → Response Conversion** for quality/outcome trend
4. Compare periods and adjust your sourcing terms, filters, or tailoring strategy.
### Data and calculation defaults
- Default window is `30d`.
- Only jobs in statuses `applied` and `in_progress` are used as input.
- Conversion counts any positive response-stage event (for example recruiter screen, assessment, interview stages, or offer).
- Conversion trend chart uses a rolling window up to 7 days.
## Common problems
### Empty charts
- Verify you have jobs with `appliedAt` timestamps.
- The selected duration may exclude your recent activity.
### Conversion appears low
- Conversion only counts jobs that reached response stages.
- If stage events are missing or delayed, conversion will under-report.
### Trend icons look counterintuitive
- Volume trend compares first-half vs second-half averages in the selected window.
- Changing the time window can materially change trend direction.
## Related pages
- [Orchestrator](/docs/next/features/orchestrator)
- [Post-Application Tracking](/docs/next/features/post-application-tracking)
- [Troubleshooting](/docs/next/troubleshooting/common-problems)

View File

@ -0,0 +1,112 @@
---
id: pipeline-run
title: Pipeline Run
description: How to use Run Mode (Automatic vs Manual), presets, source controls, and advanced run settings.
sidebar_position: 2
---
## What it is
Pipeline Run is the Jobs-page run modal for starting either:
- an **Automatic** pipeline run
- a **Manual** one-job import
For end-to-end sequence, read [Find Jobs and Apply Workflow](/docs/next/workflows/find-jobs-and-apply-workflow).
For manual import internals, read [Manual Import Extractor](/docs/next/extractors/manual).
## Why it exists
The modal provides one place to control run volume, source compatibility, and processing aggressiveness before consuming compute/time.
It helps you:
- choose speed vs depth with presets
- avoid invalid source/country combinations
- understand estimated run cost before starting
## How to use it
1. Open the Jobs page and use the top-right run control.
2. Choose either **Automatic** or **Manual** tab.
3. Configure required inputs and start run.
### Automatic tab
#### Presets
Three presets set defaults for run aggressiveness:
- **Fast**: lower processing volume, higher score threshold
- **Balanced**: middle-ground defaults
- **Detailed**: higher processing volume, lower score threshold
If values are edited manually, the UI shows **Custom**.
#### Country and source compatibility
- Country selection affects which sources are available.
- UK-only sources are disabled for non-UK countries.
- Glassdoor can be enabled only when:
- selected country supports Glassdoor
- a **Glassdoor city** is set in Advanced settings
Incompatible sources are disabled with explanatory tooltips.
#### Advanced settings
- **Resumes tailored** (`topN`)
- **Min suitability score**
- **Max jobs discovered** (run budget cap)
- **Glassdoor city** (required only for Glassdoor)
#### Search terms
- Add terms with Enter or commas.
- Multiple terms increase discovery breadth and runtime.
- At least one search term is required.
#### Estimate and run gating
The footer estimate shows expected discovered jobs and resume-processing range.
`Start run now` is disabled when:
- a run is already in progress
- required save/run work is still in progress
- no compatible sources are selected
- no search terms are present
### Manual tab
Manual mode opens direct import flow in the same modal.
Use it when you already have a specific job description or link and do not want full discovery.
For accepted input formats, inference behavior, and limits, see [Manual Import Extractor](/docs/next/extractors/manual).
## Common problems
### Start button stays disabled
- Ensure at least one search term is present.
- Ensure at least one compatible source is selected.
- Wait for active save/run operations to finish.
### Glassdoor cannot be enabled
- Verify selected country supports Glassdoor.
- Set a Glassdoor city in Advanced settings.
### Run takes longer than expected
- Reduce term count.
- Use `Fast` preset or lower `Max jobs discovered`.
- Disable high-cost source combinations where acceptable.
## Related pages
- [Find Jobs and Apply Workflow](/docs/next/workflows/find-jobs-and-apply-workflow)
- [Manual Import Extractor](/docs/next/extractors/manual)
- [Orchestrator](/docs/next/features/orchestrator)
- [Overview](/docs/next/features/overview)

View File

@ -0,0 +1,86 @@
---
id: post-application-tracking
title: Post-Application Tracking
description: Gmail-based tracking inbox, smart routing, and review workflow.
sidebar_position: 3
---
The Tracking Inbox monitors Gmail for job-application responses and updates timelines.
## Overview
1. Scans Gmail for recruitment-related emails
2. Matches emails to tracked jobs using AI
3. Updates timeline/state when confidence is high
4. Queues uncertain matches for manual review
## Smart router flow
```mermaid
flowchart TD
A[Recruitment email arrives in Gmail] --> B[Smart Router AI analyzes content]
B --> C{How confident is the match?}
C -->|95-100%| D[Auto-linked to job]
D --> E[Timeline updated automatically]
C -->|50-94%| F[Goes to Inbox for review with suggested match]
C -->|<50%| G{Is it relevant?}
G -->|Yes| H[Goes to Inbox as orphan]
G -->|No| I[Ignored]
```
## Setup
### Prerequisites
1. Gmail account with application emails
2. Google OAuth credentials
### Configure OAuth
Set:
```bash
GMAIL_OAUTH_CLIENT_ID=your-client-id.apps.googleusercontent.com
GMAIL_OAUTH_CLIENT_SECRET=your-client-secret
GMAIL_OAUTH_REDIRECT_URI=https://your-domain.com/oauth/gmail/callback
```
Then connect in UI via **Tracking Inbox → Connect Gmail**.
## Using the inbox
- Review pending items in Tracking Inbox
- Approve to link/update timeline
- Ignore to mark non-relevant
Confidence interpretation:
- `95-100%`: auto-processed
- `50-94%`: pending review with suggestion
- `<50%`: pending review as orphan/ignored
## Privacy and security
- Scope requested: `gmail.readonly`
- Minimal metadata sent for matching
- Email data stays local in your instance
## API reference
| Method | Endpoint | Description |
| ------ | ----------------------------------------- | --------------------- |
| GET | `/api/post-application/inbox` | List pending messages |
| POST | `/api/post-application/inbox/:id/approve` | Approve message |
| POST | `/api/post-application/inbox/:id/deny` | Ignore message |
| GET | `/api/post-application/runs` | List sync runs |
| POST | `/api/post-application/gmail/connect` | Start OAuth flow |
| GET | `/api/post-application/gmail/callback` | OAuth callback |
## Common issues
- No refresh token: disconnect and reconnect Gmail.
- Emails not appearing: check runs, OAuth config, and recruitment subjects.
- Wrong matches: expected in lower-confidence buckets; use manual review.

View File

@ -0,0 +1,220 @@
---
id: reactive-resume
title: Reactive Resume
description: Configure RxResume integration, base resume selection, and project inclusion behavior for PDF generation.
sidebar_position: 4
---
## What it is
Reactive Resume integration powers JobOps PDF generation.
JobOps uses a selected RxResume base resume as the source of truth, then applies job-specific tailoring (summary, headline, skills, project visibility) before exporting a PDF.
## Why it exists
Most users need a repeatable resume pipeline:
- one canonical resume source
- controlled project inclusion rules
- per-job tailored output without manual copy/paste
Reactive Resume integration provides that workflow end-to-end.
### Why JobOps uses RxResume (instead of building a new editor)
RxResume is a mature, established resume product with strong PDF output quality.
Key reasons:
- ATS-friendly PDF generation is already excellent and battle-tested.
- The editor UX is strong and supports extensive user customization.
- It supports many themes out of the box.
- It has a JSON-native model (import/export), which is critical for JobOps automation.
Because RxResume uses structured JSON, JobOps can safely apply LLM-driven updates to specific sections before generating PDFs.
## Core concepts
### Base resume
Your **base resume** is selected in Settings and used for:
- profile extraction
- project catalog extraction
- PDF generation
If no base resume is selected, profile-dependent features and PDF generation cannot run.
### Project catalog
JobOps reads projects from `sections.projects.items` in the selected RxResume resume.
Each project is identified by:
- `id`
- `name`
- `description`
- `date`
- `visible` (visible in base resume)
### Project selection controls
The Settings UI supports 3 controls:
- **Must Include**: always include these projects.
- **AI Selectable**: pool of projects AI can pick from.
- **Max Projects**: final cap for included projects.
At generation time:
1. Must-include projects are added first.
2. AI picks up to remaining slots from AI-selectable projects.
3. Final visible projects are applied to the generated resume.
## Setup and configuration
### 1) Configure RxResume credentials
Configure in Settings:
- `rxresumeEmail`
- `rxresumePassword`
Or via environment variables:
- `RXRESUME_EMAIL`
- `RXRESUME_PASSWORD`
- optional `RXRESUME_URL` (defaults to `https://v4.rxresu.me`)
### 2) Select base resume
In **Settings → Reactive Resume**:
1. Click refresh to fetch resumes.
2. Select the template/base resume.
3. Save settings.
### 3) Configure project behavior
In the same section:
1. Set `Max projects`.
2. Mark projects as **Must Include** where needed.
3. Mark remaining projects as **AI selectable**.
4. Save settings.
## Runtime behavior
### During PDF generation
High-level flow:
1. Load selected base resume from RxResume.
2. Apply tailored summary/headline/skills.
3. Compute final visible projects from your selection rules.
4. Create temporary resume in RxResume.
5. Export PDF.
6. Delete temporary resume.
### What JobOps changes with AI
Current AI-driven edits are intentionally scoped:
- `summary`
- `headline/title`
- `skills` and keywords
- project **visibility** (enable/disable per project)
## API reference
```bash
# Get effective settings (includes resolved resumeProjects and base resume id)
curl "http://localhost:3001/api/settings"
```
```bash
# Save base resume and project controls
curl -X PATCH "http://localhost:3001/api/settings" \
-H "content-type: application/json" \
-d '{
"rxresumeBaseResumeId": "resume_id_here",
"resumeProjects": {
"maxProjects": 4,
"lockedProjectIds": ["proj_a"],
"aiSelectableProjectIds": ["proj_b","proj_c","proj_d"]
}
}'
```
```bash
# List available RxResume resumes
curl "http://localhost:3001/api/settings/rx-resumes"
```
```bash
# Fetch projects from one RxResume resume
curl "http://localhost:3001/api/settings/rx-resumes/<resumeId>/projects"
```
```bash
# Regenerate PDF for a job after changing settings or resume data
curl -X POST "http://localhost:3001/api/jobs/<jobId>/generate-pdf"
```
## Troubleshooting and FAQ
### RxResume controls are disabled
- Ensure RxResume credentials are configured.
- Save settings, then refresh resumes in the Reactive Resume section.
### No resumes appear in dropdown
- Confirm credentials are valid for `rxresu.me`/your configured RxResume URL.
- Confirm the selected RxResume account actually has resumes.
### Project list is empty in settings
- Root cause is usually the source resume on [rxresu.me](https://rxresu.me) having an empty **Projects** section.
- Add projects directly in RxResume first.
- Re-select/refresh the base resume in JobOps and regenerate the PDF.
### Project checkboxes look wrong after changing base resume
- Save after selecting the new base resume.
- Re-open Reactive Resume section and verify project IDs from that resume.
- Re-run PDF generation to apply the new project map.
### Changes did not affect an already generated PDF
- Settings changes apply to new generation runs.
- Regenerate PDFs for already-ready jobs.
## Best practices
- Keep base resume projects complete and up to date in RxResume.
- Use **Must Include** sparingly for cornerstone projects.
- Keep AI-selectable pool broad enough for job-specific relevance.
- After major resume edits, regenerate PDFs for active high-priority jobs.
### Add “context projects” even if they are usually hidden
The LLM only knows what exists in your resume data.
That means there is real value in adding additional projects in RxResume, even if you keep them hidden by default:
- They increase the AIs context about your skills and range.
- They can be toggled on only when relevant to a role.
Example:
- If your main background is not Android, but you have one credible Android side project, include it in RxResume, but keep it hidden by default.
- For a mobile role, the AI can enable that project automatically based on the job description.
## Related pages
- [Settings](./settings)
- [Orchestrator](./orchestrator)
- [Ghostwriter](./ghostwriter)
- [Self-Hosting](../getting-started/self-hosting)

View File

@ -0,0 +1,154 @@
---
id: settings
title: Settings
description: Configure models, webhooks, accounts, backup behavior, scoring, and safety controls.
sidebar_position: 2
---
## What it is
The Settings page is the control center for app-wide behavior.
It lets you configure:
- LLM provider and models
- Webhook destinations and secret
- Display and Ghostwriter defaults
- Service credentials and basic auth
- Reactive Resume project selection
- Backup and scoring rules
- Data-clearing actions in the Danger Zone
## Why it exists
Most teams want stable defaults for repeated workflows, without editing environment variables every time.
Settings gives you runtime overrides for the key parts of discovery, scoring, tailoring, and post-application automation.
## How to use it
1. Open **Settings**.
2. Expand each section you want to change.
3. Update values and click **Save Changes**.
4. Re-run the workflow that uses those settings (for example pipeline runs, Ghostwriter, or resume tailoring) to verify behavior.
## Section-by-section guide
### Model
- Choose provider (`openrouter`, `lmstudio`, `ollama`, `openai`, `gemini`)
- Set provider-specific base URL/API key when required
- Configure default model plus task-specific overrides:
- Scoring model
- Tailoring model
- Project-selection model
### Webhooks
- Pipeline status webhook: called on run completion/failure
- Job completion webhook: called when a job is marked applied
- Optional webhook secret (sent as bearer token)
### Display Settings
- Toggle visa sponsor badge visibility in job lists/details
### Ghostwriter
- Set global writing defaults:
- Tone
- Formality
- Constraints
- Do-not-use terms
### Reactive Resume
- Select a template/base resume
- Configure project selection behavior:
- Max projects
- Must-include projects
- AI-selectable projects
### Environment & Accounts
- Configure service accounts:
- RxResume email/password
- UKVisaJobs email/password
- Optional basic authentication for write operations
### Backup
- Enable/disable automatic daily backups
- Configure backup hour (UTC) and max retained backups
- Create or delete backups manually
- See [Database Backups](../getting-started/database-backups) for full backup/restore guidance.
### Scoring Settings
- Penalize missing salary data
- Set penalty amount
- Optional auto-skip threshold for low-score jobs
### Danger Zone
- Clear jobs by selected statuses
- Clear jobs below a score threshold
- Clear the full database
## API examples
```bash
# Get effective settings (defaults + overrides)
curl "http://localhost:3001/api/settings"
```
```bash
# Update settings overrides
curl -X PATCH "http://localhost:3001/api/settings" \
-H "content-type: application/json" \
-d '{
"llmProvider": "openrouter",
"model": "openai/gpt-4.1-mini",
"chatStyleTone": "concise",
"showSponsorInfo": true
}'
```
```bash
# List and create backups (used by the Backup section)
curl "http://localhost:3001/api/backups"
curl -X POST "http://localhost:3001/api/backups"
```
## Common problems
### Saved value does not seem to apply
- Some settings apply only to new runs/actions after save.
- Re-run scoring/tailoring/pipeline to validate effect.
### RxResume controls are disabled
- Configure RxResume credentials in Environment & Accounts first.
- Then refresh available resumes from the Reactive Resume section.
### RxResume projects look empty in the RxResume UI
- Root cause: your resume on [rxresu.me](https://rxresu.me) has an empty **Projects** section.
- Fix in RxResume first: add project entries to the base resume you selected in Settings.
- Then return to JobOps, refresh/select the same base resume in **Reactive Resume**, and regenerate the PDF.
- JobOps preserves current visibility state, but it cannot create missing project content if the source resume has no projects.
### Webhook calls fail
- Verify URL reachability from the server host.
- Confirm auth expectations on the receiver side (including secret/bearer token).
## Related pages
- [Reactive Resume](./reactive-resume)
- [Database Backups](../getting-started/database-backups)
- [Overview](./overview)
- [Orchestrator](./orchestrator)
- [Ghostwriter](./ghostwriter)
- [Self-Hosting](../getting-started/self-hosting)

View File

@ -0,0 +1,74 @@
---
id: visa-sponsors
title: Visa Sponsors
description: Search the UK licensed sponsor register and use sponsor matches in your job workflow.
sidebar_position: 4
---
## What it is
The Visa Sponsors page lets you search the UK Home Office licensed sponsor register from inside JobOps.
For each company, it shows:
- Match score against your query
- Company location (when available)
- Licensed routes and type/rating details
- Last data refresh time and sponsor count
## Why it exists
Many roles require sponsorship-ready employers. This page helps you quickly validate whether a target company appears on the official sponsor list, so you can prioritize applications and sourcing terms.
## How to use it
1. Open **Visa Sponsors** in the app.
2. Enter a company name in the search box.
3. Select a result to view sponsor details.
4. Use the score and route details to decide whether to prioritize that employer.
### Refresh schedule
- Automatic update runs daily at about **02:00** (server local time).
- Use the download/update button in the page header to fetch the latest register immediately.
### API examples
```bash
# Search sponsors
curl -X POST http://localhost:3001/api/visa-sponsors/search \
-H "content-type: application/json" \
-d '{"query":"Monzo","limit":100,"minScore":20}'
```
```bash
# Get one organization's entries (all licensed routes)
curl "http://localhost:3001/api/visa-sponsors/organization/Monzo%20Bank%20Ltd"
```
```bash
# Trigger manual refresh
curl -X POST http://localhost:3001/api/visa-sponsors/update
```
## Common problems
### No results found
- Try alternate legal names (`Ltd`, `Limited`, abbreviations).
- Reduce spelling strictness by searching a shorter core name.
### Sponsor data is empty
- Run a manual refresh with the header update button (or `POST /api/visa-sponsors/update`).
- Check that the server can reach `gov.uk` and `assets.publishing.service.gov.uk`.
### Company appears once but has multiple routes
- Open the detail panel for that company; route/type entries are shown there.
## Related pages
- [Orchestrator](/docs/next/features/orchestrator)
- [Post-Application Tracking](/docs/next/features/post-application-tracking)
- [Self-Hosting](/docs/next/getting-started/self-hosting)

View File

@ -0,0 +1,127 @@
---
id: database-backups
title: Database Backups
description: Configure, run, and restore JobOps database backups.
sidebar_position: 2
---
## What this covers
This page is about database backups:
- automatic backup schedule
- manual backup creation/deletion
- retention behavior
- restore workflow
- backup troubleshooting
## Backup behavior
JobOps stores backups in the same data directory as `jobs.db`.
Two backup types exist:
- **Automatic** backups
- **Manual** backups
### Automatic backups
- Scheduled daily.
- Filename format: `jobs_YYYY_MM_DD.db`
- Schedule hour is configured in Settings (**UTC hour**).
- Automatic retention is capped by `backupMaxCount`.
- If todays automatic backup already exists, JobOps skips creating a duplicate.
### Manual backups
- Triggered from Settings or `POST /api/backups`.
- Filename format: `jobs_manual_YYYY_MM_DD_HH_MM_SS.db`
- If a filename collision occurs, JobOps appends `_1`, `_2`, etc.
- Manual backups are **not** auto-deleted by automatic retention cleanup.
## Configure backups
In **Settings → Backup**:
1. Enable automatic backups.
2. Set backup hour (`0-23`, UTC).
3. Set max automatic backups to keep (`1-5`).
4. Save settings.
## API reference
```bash
# List backups + next scheduled run time
curl "http://localhost:3001/api/backups"
```
```bash
# Create a manual backup
curl -X POST "http://localhost:3001/api/backups"
```
```bash
# Delete a specific backup
curl -X DELETE "http://localhost:3001/api/backups/jobs_manual_2026_02_15_10_20_30.db"
```
```bash
# Update backup settings via Settings API
curl -X PATCH "http://localhost:3001/api/settings" \
-H "content-type: application/json" \
-d '{
"backupEnabled": true,
"backupHour": 2,
"backupMaxCount": 5
}'
```
## Restore workflow
To restore from a backup:
1. Stop JobOps.
2. Locate backup files in your data directory.
3. Copy the chosen backup over the main DB file (`jobs.db`).
4. Start JobOps.
5. Verify jobs/runs in the UI.
Example shell flow:
```bash
# Example only: adjust paths for your setup
cp /path/to/data/jobs_manual_2026_02_15_10_20_30.db /path/to/data/jobs.db
```
## Troubleshooting
### Backups are not running automatically
- Confirm `backupEnabled` is true.
- Confirm backup hour is set as intended (UTC, not local time).
- Verify the app process is running at scheduled time.
### `POST /api/backups` fails
- Confirm the data directory and `jobs.db` are writable/readable.
- Confirm `jobs.db` exists.
- In demo mode, manual backup creation is blocked.
### Cannot delete a backup
- Filename must match valid backup patterns.
- Invalid names and missing files return errors.
### Next scheduled time is null
- Automatic backups are currently disabled.
## Notes
- Backup cleanup applies only to automatic backups.
- Manual backups stay until you delete them.
## Related pages
- [Settings](../features/settings)
- [Self-Hosting](./self-hosting)

View File

@ -0,0 +1,122 @@
---
id: self-hosting
title: Self-Hosting (Docker Compose)
description: Deploy JobOps with Docker Compose and configure onboarding integrations.
sidebar_position: 1
---
The easiest way to run JobOps is via Docker Compose. The app is self-configuring and guides you through setup on first launch.
## Prerequisites
- Docker Desktop or Docker Engine + Compose v2
## 1) Start the stack
No environment variables are required to boot:
```bash
docker compose up -d
```
This pulls the pre-built image from GHCR and starts the API, UI, and scrapers in one container.
To build locally instead:
```bash
docker compose up -d --build
```
## 2) Access the app and onboard
Open:
- **Dashboard**: `http://localhost:3005`
The onboarding wizard helps you validate and save:
1. **LLM Provider**: OpenRouter by default (or OpenAI/Gemini/local URL).
2. **PDF Export**: RxResume credentials for PDF generation.
3. **Template Resume**: Choose a base resume from your RxResume account.
Settings are saved to the local database.
## Gmail OAuth (Tracking Inbox)
If you want Gmail integration, configure OAuth credentials.
### 1) Create Google OAuth credentials
In Google Cloud:
1. Configure OAuth consent screen.
2. Enable Gmail API.
3. Create OAuth client ID (`Web application`).
4. Add redirect URI:
- `http://localhost:3005/oauth/gmail/callback`
- Or your production URL, for example `https://your-domain.com/oauth/gmail/callback`
### 2) Configure environment variables
- `GMAIL_OAUTH_CLIENT_ID` (required)
- `GMAIL_OAUTH_CLIENT_SECRET` (required)
- `GMAIL_OAUTH_REDIRECT_URI` (optional, recommended in production)
### 3) Restart and connect
- Restart container
- Open Tracking Inbox and click **Connect Gmail**
## Email-to-job matching overview
```mermaid
flowchart TD
A[Recruitment email arrives in Gmail] --> B[Smart Router AI analyzes content]
B --> C{How confident is the match?}
C -->|95-100%| D[Auto-linked to job]
D --> E[Timeline updated automatically]
C -->|50-94%| F[Goes to Inbox for review with suggested job match]
C -->|<50%| G{Is it relevant?}
G -->|Yes| H[Goes to Inbox as orphan]
G -->|No| I[Ignored]
F --> J{User review}
H --> J
J -->|Approve| K[Linked to job + timeline update]
J -->|Ignore| L[Marked not relevant]
```
## Persistent data
`./data` bind-mount stores:
- SQLite DB: `data/jobs.db`
- Generated PDFs: `data/pdfs/`
## Public demo mode
Set `DEMO_MODE=true` for sandbox deployments.
Behavior in demo mode:
- Works locally: browsing/filtering/status/timeline edits
- Simulated: pipeline run/summarize/process/rescore/pdf/apply
- Blocked: settings writes, DB clear, backups
- Auto-reset: every 6 hours
## Updating
```bash
git pull
docker compose pull
docker compose up -d
```
## Self-hosted Reactive Resume
If you self-host Reactive Resume, set:
- `RXRESUME_URL=http://rxresume.local.net`

View File

@ -0,0 +1,139 @@
---
id: intro
title: JobOps Documentation
description: Documentation index for setup, features, extractors, and common problems.
sidebar_position: 1
slug: /
---
Welcome to the JobOps documentation. This site contains guides for setup, configuration, and day-to-day usage.
## Getting Started
- **[Self-Hosting Guide](/docs/next/getting-started/self-hosting)**
- Docker setup instructions
- Gmail OAuth configuration for email tracking
- Environment variables reference
- Demo mode deployment
- **[Database Backups](/docs/next/getting-started/database-backups)**
- Automatic backup scheduling and retention
- Manual backup creation/deletion
- Restore workflow and troubleshooting
## Workflows
- **[Find Jobs and Apply Workflow](/docs/next/workflows/find-jobs-and-apply-workflow)**
- Run pipeline first, then review discovered and ready jobs
- Use fit assessment and score to prioritize applications
- Mark jobs as applied to trigger webhooks and analytics
- **[Post-Application Workflow](/docs/next/workflows/post-application-workflow)**
- Track events manually for direct control
- Or configure automatic Gmail sync and inbox review
- Move confirmed updates into in-progress tracking
## Feature Documentation
- **[Orchestrator](/docs/next/features/orchestrator)**
- Job states explained (`discovered`, `ready`, `applied`, etc.)
- The ready flow (manual vs auto)
- PDF generation and regeneration
- Post-application tracking overview
- **[Pipeline Run](/docs/next/features/pipeline-run)**
- Run modal controls (`Automatic` vs `Manual`)
- Presets, source/country compatibility, and advanced settings
- Run estimate and start conditions
- **[Job Search Bar](/docs/next/features/job-search-bar)**
- Open with `Cmd+K` / `Ctrl+K` or the Search button
- Fuzzy search across title, company, and location
- Use `@status` lock syntax to scope results quickly
- **[Keyboard Shortcuts](/docs/next/features/keyboard-shortcuts)**
- Full Jobs-page shortcut reference by context
- `?` shortcut help dialog and `Control` hint bar behavior
- Tab-specific actions like skip, move to ready, and mark applied
- **[Multi-Select and Bulk Actions](/docs/next/features/multi-select-and-bulk-actions)**
- Select many jobs using row checkboxes or select-all
- Run bulk move, skip, and rescore actions from the floating action bar
- Keyboard support for select, clear, and fast bulk move-to-ready
- **[Settings](/docs/next/features/settings)**
- LLM provider/model and task-specific overrides
- Webhooks, service accounts, and basic auth controls
- Backup scheduling, scoring thresholds, and danger-zone cleanup tools
- **[Reactive Resume](/docs/next/features/reactive-resume)**
- Base resume selection and RxResume integration
- Project inclusion controls (must-include, AI-selectable, max)
- PDF generation behavior and troubleshooting
- **[Applications Overview](/docs/next/features/overview)**
- Applications-per-day trend
- Conversion analytics and funnel
- Duration window controls (`7d`, `14d`, `30d`, `90d`)
- **[In Progress Board](/docs/next/features/in-progress-board)**
- Pre-application vs post-application workflow split
- Kanban tracking for higher-attention opportunities
- Drag-and-drop stage management
- **[Ghostwriter](/docs/next/features/ghostwriter)**
- One persistent conversation per job
- Streaming responses, stop, and regenerate
- Markdown rendering and drawer behavior
- Writing style settings impact
- **[Post-Application Tracking](/docs/next/features/post-application-tracking)**
- How the Smart Router AI works
- Gmail integration setup
- Using the Tracking Inbox
- Privacy and security details
- API reference
- **[Visa Sponsors](/docs/next/features/visa-sponsors)**
- Search licensed UK sponsor organizations
- Review company routes and sponsor ratings
- Trigger manual data refresh
## Extractors
- **[Extractors Overview](/docs/next/extractors/overview)**
- **[Gradcracker](/docs/next/extractors/gradcracker)**
- **[UKVisaJobs](/docs/next/extractors/ukvisajobs)**
- **[JobSpy](/docs/next/extractors/jobspy)**
- **[Manual Import](/docs/next/extractors/manual)**
## Quick Reference
### Main Components
- **Orchestrator**: Main application (UI, API, database)
- **Extractors**: Specialized job crawlers
- **Shared**: Common types and utilities
### Key Features
1. **Job Discovery**: Automatically find jobs from multiple sources.
2. **AI Scoring**: Rank jobs by suitability for your profile.
3. **Resume Tailoring**: Generate custom resumes for each job.
4. **PDF Export**: Create tailored PDFs via RxResume integration.
5. **Application Tracking**: Monitor your applied jobs.
6. **Email Tracking**: Auto-track post-application responses.
## Contributing to Documentation
When adding user-visible behavior:
1. Update the relevant feature page in current docs.
2. Add API documentation where relevant.
3. Keep examples realistic and copy-pasteable.
4. Include diagrams for non-trivial workflows.
## Support
- Open an [issue](https://github.com/DaKheera47/job-ops/issues) for documentation errors.
- Check these docs before opening support requests.

View File

@ -0,0 +1,36 @@
---
id: documentation-style-guide
title: Documentation Style Guide
description: Standards for writing user-facing docs in this repository.
sidebar_position: 2
---
Use this structure for feature pages:
1. **What it is**
2. **Why it exists**
3. **How to use it**
4. **Common problems**
5. **Related pages**
## Frontmatter requirements
Every doc should include:
- `id`
- `title`
- `description`
- `sidebar_position`
## Writing rules
- Prefer concrete steps over abstract prose.
- Provide copy-pasteable examples.
- State defaults and constraints explicitly.
- Use absolute `/docs/...` URLs and include the version segment when needed.
- For current docs, use `/docs/next/...` links.
- For versioned docs, link within that version (for example `/docs/...` in `version-0.1.20`).
## PR expectations
Any user-visible behavior change should include matching docs updates.

View File

@ -0,0 +1,30 @@
---
id: faq
title: FAQ
description: Frequently asked questions about deployment, docs, and operations.
sidebar_position: 1
---
## Is docs content bundled for self-hosted installs?
Yes. The docs static build is bundled and served locally at `/docs`.
## How are docs versions managed?
Docs are versioned using Docusaurus versions, intended to map to release tags.
## Where should contributors edit docs?
Edit files under `docs-site/docs` for latest docs.
## What does this cost in practice?
Real-world reference: from early December 2025 to mid-February 2026, with heavy usage and testing (about 10 to 15 applications per day), easily more than 3000 jobs scored, total LLM spend was about **$12 USD** using Gemini 3 Flash through OpenRouter.
Cost varies by:
- selected model/provider
- prompt volume and size
- number of jobs scored/tailored per run
For this workload, Gemini 3 Flash has been low-cost while still producing high-quality outputs.

View File

@ -0,0 +1,41 @@
---
id: common-problems
title: Common Problems
description: Quick fixes for the most frequent setup and runtime issues.
sidebar_position: 1
---
## Docs site not loading at `/docs`
- Confirm docs build exists:
```bash
npm --workspace docs-site run build
```
- In production, ensure container includes docs build artifact.
## Deep links under `/docs/*` return 404
- Confirm Express is serving docs static mount before app SPA fallback.
- Confirm docs base URL is `/docs/` in `docs-site/docusaurus.config.ts`.
## Gmail OAuth callback fails
- Verify `GMAIL_OAUTH_CLIENT_ID`, `GMAIL_OAUTH_CLIENT_SECRET`.
- Ensure authorized redirect URI exactly matches deployment callback URL.
## No job scoring or AI inference
- Validate `LLM_API_KEY` and provider settings.
- Check settings page and API connectivity.
## PDF generation fails
- Verify RxResume credentials.
- Confirm selected base resume exists and is accessible.
## UKVisaJobs runs fail
- Re-authenticate by removing cached auth file or forcing refresh.
- Verify extractor credentials and API response behavior.

View File

@ -0,0 +1,96 @@
---
id: find-jobs-and-apply-workflow
title: Find Jobs and Apply Workflow
description: Recommended end-to-end pre-application workflow from pipeline run to marking jobs as applied.
sidebar_position: 1
---
## Goal
This guide documents the main intended pre-application workflow in JobOps.
If you follow this order, you get the strongest results from discovery, scoring, tailoring, and tracking.
## Recommended flow (in order)
### 1) Run a pipeline first
From the **Jobs** page, use the top-right pipeline/run control.
What this does:
- fetches jobs from enabled extractors
- scores relevance against your resume/profile
- optionally tailors top jobs and prepares PDFs
Important:
- Some scrapers are slower and can take significant time.
- Larger scrape ranges and more sources increase run duration.
### 2) Configure pipeline advanced settings
In pipeline advanced settings, configure:
- how many jobs to discover (approximate target)
- minimum score threshold for tailoring
- how many jobs should be tailored/generated
This directly controls how many jobs appear downstream in `discovered` and `ready`.
### 3) Review the `Discovered` column
After the run, `discovered` is populated with jobs found by extractors.
For each discovered job:
- review the suitability score
- read the AI fit justification in **Fit Assessment**
- decide whether the opportunity is worth advancing
### 4) Work from `Ready` for applications
`ready` jobs are the primary application queue.
These jobs already have tailored PDFs generated for the specific job description, using the workflow described in [Reactive Resume](../features/reactive-resume).
At this stage:
1. Open job details.
2. Download the tailored PDF.
3. Submit your application externally.
### 5) Mark jobs as applied in JobOps
After submitting, return to JobOps and mark the job as `applied`.
Effects:
- job moves to the `applied` state
- configured completion webhook(s) are triggered
- job is included in overview analytics
This completes the detailed pre-application loop.
## What happens next
Once a job is marked `applied`, it becomes part of:
- pipeline outcome analytics on [Overview](../features/overview)
- optional post-application workflows (inbox/review routing)
## Practical tips
- Start with conservative run sizes while tuning sources.
- Increase tailored-job count only after score thresholds feel calibrated.
- Expect scraper runtime variance by source.
- Keep resume/project context up to date so scoring/tailoring quality stays high.
## Related pages
- [Orchestrator](../features/orchestrator)
- [Reactive Resume](../features/reactive-resume)
- [Settings](../features/settings)
- [Overview](../features/overview)
- [Post-Application Workflow](./post-application-workflow)
- [Post-Application Tracking](../features/post-application-tracking)

View File

@ -0,0 +1,141 @@
---
id: post-application-workflow
title: Post-Application Workflow
description: Track post-application progress manually, or configure automatic Gmail syncing and inbox review.
sidebar_position: 2
---
## Goal
After a job is marked `applied`, use this workflow to track what happens next.
You have two valid paths:
- **Manual tracking**: update stages/events yourself.
- **Automatic Gmail sync**: let email ingestion route events into inbox/review flow.
## Option A: Manual event tracking
Use this when you want explicit, hands-on control for each job.
### Manual flow
1. Open an `applied` or `in_progress` job.
2. Record stage progress as events (screening, interview, offer, closed, etc.).
3. Keep notes/outcomes current as conversations progress.
4. Use In Progress Board for high-attention jobs in later stages.
### API example (manual stage transition)
```bash
curl -X POST "http://localhost:3001/api/jobs/<jobId>/stages" \
-H "content-type: application/json" \
-d '{
"toStage": "technical_interview",
"metadata": {
"actor": "user",
"eventType": "status_update",
"eventLabel": "Moved to Technical Interview"
}
}'
```
## Option B: Automatic Gmail syncing
Use this when you want JobOps to ingest recruitment emails and suggest/apply updates.
### High-level flow
1. Connect Gmail provider.
2. Run sync (or scheduled sync, depending on setup).
3. Smart router scores message-to-job match.
4. High confidence updates are auto-linked.
5. Mid/low confidence items go to inbox for review.
### Configure Gmail sync
Set OAuth variables:
```bash
GMAIL_OAUTH_CLIENT_ID=...
GMAIL_OAUTH_CLIENT_SECRET=...
GMAIL_OAUTH_REDIRECT_URI=https://your-domain.com/oauth/gmail/callback
```
Then in app:
1. Open Tracking Inbox / provider controls.
2. Start Gmail OAuth.
3. Complete consent.
4. Trigger sync and review inbox items.
### API examples (Gmail path)
```bash
# Start OAuth
curl "http://localhost:3001/api/post-application/providers/gmail/oauth/start?accountKey=default"
```
```bash
# Exchange authorization code
curl -X POST "http://localhost:3001/api/post-application/providers/gmail/oauth/exchange" \
-H "content-type: application/json" \
-d '{"accountKey":"default","state":"<state>","code":"<code>"}'
```
```bash
# Trigger provider sync action
curl -X POST "http://localhost:3001/api/post-application/providers/gmail/actions/sync" \
-H "content-type: application/json" \
-d '{"accountKey":"default","maxMessages":100,"searchDays":30}'
```
```bash
# Review inbox
curl "http://localhost:3001/api/post-application/inbox?provider=gmail&accountKey=default"
```
```bash
# Approve inbox item
curl -X POST "http://localhost:3001/api/post-application/inbox/<messageId>/approve" \
-H "content-type: application/json" \
-d '{"provider":"gmail","accountKey":"default"}'
```
```bash
# Deny inbox item
curl -X POST "http://localhost:3001/api/post-application/inbox/<messageId>/deny" \
-H "content-type: application/json" \
-d '{"provider":"gmail","accountKey":"default"}'
```
## Which option should you use?
- Choose **manual** if your volume is low and you want direct control.
- Choose **automatic Gmail sync** if your volume is higher and you want less repetitive triage.
- Many users combine both: auto-sync first, manual adjustments for edge cases.
## Common problems
### Gmail connected but no messages appear
- Verify OAuth credentials and redirect URI.
- Confirm you are syncing the intended account key.
- Check search window (`searchDays`) and message cap (`maxMessages`).
### Wrong job matched
- Expected in lower-confidence buckets.
- Deny incorrect inbox items and apply manual stage updates where needed.
### I prefer not to grant Gmail access
- Use the manual tracking path only.
- The post-application workflow still works without Gmail integration.
## Related pages
- [Find Jobs and Apply Workflow](./find-jobs-and-apply-workflow)
- [Post-Application Tracking](../features/post-application-tracking)
- [In Progress Board](../features/in-progress-board)
- [Overview](../features/overview)

View File

@ -0,0 +1,73 @@
{
"docsSidebar": [
"intro",
{
"type": "category",
"label": "Getting Started",
"items": [
"getting-started/self-hosting"
]
},
{
"type": "category",
"label": "Workflows",
"items": [
"workflows/find-jobs-and-apply-workflow",
"workflows/post-application-workflow"
]
},
{
"type": "category",
"label": "Core Features",
"items": [
"features/overview",
"features/pipeline-run",
"features/job-search-bar",
"features/keyboard-shortcuts",
"features/multi-select-and-bulk-actions",
"features/orchestrator",
"features/settings",
"features/reactive-resume",
"features/in-progress-board",
"features/ghostwriter",
"features/post-application-tracking",
"features/visa-sponsors"
]
},
{
"type": "category",
"label": "Extractors",
"items": [
"extractors/overview",
"extractors/gradcracker",
"extractors/jobspy",
"extractors/manual",
"extractors/ukvisajobs"
]
},
{
"type": "category",
"label": "Self-Hosting & Ops",
"items": [
"getting-started/self-hosting",
"getting-started/database-backups",
"troubleshooting/common-problems"
]
},
{
"type": "category",
"label": "Troubleshooting",
"items": [
"troubleshooting/common-problems"
]
},
{
"type": "category",
"label": "Reference / FAQ",
"items": [
"reference/faq",
"reference/documentation-style-guide"
]
}
]
}

View File

@ -1 +1,4 @@
["0.1.20"]
[
"0.1.21",
"0.1.20"
]