From 0de10c3302aebbbc8ab2e20ee9c232cff0ed62c6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 22 Feb 2026 13:34:01 +0000 Subject: [PATCH] docs: cut version 0.1.27 --- .../version-0.1.27/extractors/adzuna.md | 66 +++++ .../version-0.1.27/extractors/gradcracker.md | 48 ++++ .../version-0.1.27/extractors/hiring-cafe.md | 77 ++++++ .../version-0.1.27/extractors/jobspy.md | 52 ++++ .../version-0.1.27/extractors/manual.md | 61 +++++ .../version-0.1.27/extractors/overview.md | 42 +++ .../version-0.1.27/extractors/ukvisajobs.md | 75 ++++++ .../version-0.1.27/features/ghostwriter.md | 91 +++++++ .../features/in-progress-board.md | 92 +++++++ .../version-0.1.27/features/job-search-bar.md | 77 ++++++ .../features/keyboard-shortcuts.md | 79 ++++++ .../features/multi-select-and-bulk-actions.md | 63 +++++ .../version-0.1.27/features/orchestrator.md | 127 +++++++++ .../version-0.1.27/features/overview.md | 100 +++++++ .../version-0.1.27/features/pipeline-run.md | 118 +++++++++ .../features/post-application-tracking.md | 93 +++++++ .../features/reactive-resume.md | 249 ++++++++++++++++++ .../version-0.1.27/features/settings.md | 194 ++++++++++++++ .../version-0.1.27/features/tracer-links.md | 151 +++++++++++ .../version-0.1.27/features/visa-sponsors.md | 74 ++++++ .../getting-started/database-backups.md | 127 +++++++++ .../getting-started/gmail-oauth-setup.md | 96 +++++++ .../getting-started/self-hosting.md | 126 +++++++++ .../versioned_docs/version-0.1.27/intro.md | 139 ++++++++++ .../reference/documentation-style-guide.md | 36 +++ .../version-0.1.27/reference/faq.md | 30 +++ .../troubleshooting/common-problems.md | 41 +++ .../workflows/add-an-extractor.md | 95 +++++++ .../workflows/find-jobs-and-apply-workflow.md | 99 +++++++ .../workflows/post-application-workflow.md | 145 ++++++++++ .../version-0.1.27-sidebars.json | 74 ++++++ docs-site/versions.json | 2 +- 32 files changed, 2938 insertions(+), 1 deletion(-) create mode 100644 docs-site/versioned_docs/version-0.1.27/extractors/adzuna.md create mode 100644 docs-site/versioned_docs/version-0.1.27/extractors/gradcracker.md create mode 100644 docs-site/versioned_docs/version-0.1.27/extractors/hiring-cafe.md create mode 100644 docs-site/versioned_docs/version-0.1.27/extractors/jobspy.md create mode 100644 docs-site/versioned_docs/version-0.1.27/extractors/manual.md create mode 100644 docs-site/versioned_docs/version-0.1.27/extractors/overview.md create mode 100644 docs-site/versioned_docs/version-0.1.27/extractors/ukvisajobs.md create mode 100644 docs-site/versioned_docs/version-0.1.27/features/ghostwriter.md create mode 100644 docs-site/versioned_docs/version-0.1.27/features/in-progress-board.md create mode 100644 docs-site/versioned_docs/version-0.1.27/features/job-search-bar.md create mode 100644 docs-site/versioned_docs/version-0.1.27/features/keyboard-shortcuts.md create mode 100644 docs-site/versioned_docs/version-0.1.27/features/multi-select-and-bulk-actions.md create mode 100644 docs-site/versioned_docs/version-0.1.27/features/orchestrator.md create mode 100644 docs-site/versioned_docs/version-0.1.27/features/overview.md create mode 100644 docs-site/versioned_docs/version-0.1.27/features/pipeline-run.md create mode 100644 docs-site/versioned_docs/version-0.1.27/features/post-application-tracking.md create mode 100644 docs-site/versioned_docs/version-0.1.27/features/reactive-resume.md create mode 100644 docs-site/versioned_docs/version-0.1.27/features/settings.md create mode 100644 docs-site/versioned_docs/version-0.1.27/features/tracer-links.md create mode 100644 docs-site/versioned_docs/version-0.1.27/features/visa-sponsors.md create mode 100644 docs-site/versioned_docs/version-0.1.27/getting-started/database-backups.md create mode 100644 docs-site/versioned_docs/version-0.1.27/getting-started/gmail-oauth-setup.md create mode 100644 docs-site/versioned_docs/version-0.1.27/getting-started/self-hosting.md create mode 100644 docs-site/versioned_docs/version-0.1.27/intro.md create mode 100644 docs-site/versioned_docs/version-0.1.27/reference/documentation-style-guide.md create mode 100644 docs-site/versioned_docs/version-0.1.27/reference/faq.md create mode 100644 docs-site/versioned_docs/version-0.1.27/troubleshooting/common-problems.md create mode 100644 docs-site/versioned_docs/version-0.1.27/workflows/add-an-extractor.md create mode 100644 docs-site/versioned_docs/version-0.1.27/workflows/find-jobs-and-apply-workflow.md create mode 100644 docs-site/versioned_docs/version-0.1.27/workflows/post-application-workflow.md create mode 100644 docs-site/versioned_sidebars/version-0.1.27-sidebars.json diff --git a/docs-site/versioned_docs/version-0.1.27/extractors/adzuna.md b/docs-site/versioned_docs/version-0.1.27/extractors/adzuna.md new file mode 100644 index 0000000..e11e215 --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/extractors/adzuna.md @@ -0,0 +1,66 @@ +--- +id: adzuna +title: Adzuna Extractor +description: API-based Adzuna extraction with orchestrator ingestion and progress updates. +sidebar_position: 6 +--- + +## What it is + +Original website: [adzuna.com](https://www.adzuna.com) + +Adzuna is an API-backed extractor implemented in two lean pieces: + +1. `extractors/adzuna/src/main.ts` fetches paginated Adzuna search results and writes `jobs.json`. +2. `orchestrator/src/server/services/adzuna.ts` runs the extractor, parses progress lines, and maps rows into `CreateJobInput`. + +It de-duplicates in the existing repository path using `sourceJobId` fallback to `jobUrl`. + +## Why it exists + +Adzuna provides stable API discovery for countries that are not covered by UK-only sources. It adds a lower-maintenance source without introducing new API routes or UI sections. + +## How to use it + +1. Create an Adzuna developer account. +2. Open [Adzuna Access Details](https://developer.adzuna.com/admin/access_details). +3. Copy your **App ID** and **App Key**. +4. In Job Ops, open **Settings** and paste them into `Adzuna App ID` and `Adzuna App Key` under **Environment & Accounts**. +5. In **Pipeline Run** (Automatic tab), select a compatible country and enable **Adzuna** in Sources. +6. Start the run; Adzuna progress appears in the existing crawl progress stream. + +City behavior: + +- If **Search cities** are set in Automatic advanced settings, Adzuna runs once per city. +- City runs use strict post-filtering (`job.location` contains requested city) to avoid broad country-level spillover. + +Default controls: + +- `ADZUNA_APP_ID` +- `ADZUNA_APP_KEY` +- `ADZUNA_MAX_JOBS_PER_TERM` (default `50`) +- `ADZUNA_LOCATION_QUERY` (optional city/location text) + +Supported countries in this integration: + +- United Kingdom, United States, Austria, Australia, Belgium, Brazil, Canada, Switzerland, Germany, Spain, France, India, Italy, Mexico, Netherlands, New Zealand, Poland, Singapore, South Africa. + +## Common problems + +### Adzuna is disabled in source selection + +- `Adzuna App ID` and `Adzuna App Key` are missing from Settings (or env). + +### Adzuna is skipped for my selected country + +- The selected country is not in the supported list above. + +### Adzuna fails with authorization errors + +- Verify `ADZUNA_APP_ID` and `ADZUNA_APP_KEY` are valid and active in your Adzuna account. + +## Related pages + +- [Extractors Overview](/docs/next/extractors/overview) +- [Pipeline Run](/docs/next/features/pipeline-run) +- [Settings](/docs/next/features/settings) diff --git a/docs-site/versioned_docs/version-0.1.27/extractors/gradcracker.md b/docs-site/versioned_docs/version-0.1.27/extractors/gradcracker.md new file mode 100644 index 0000000..b04eec3 --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/extractors/gradcracker.md @@ -0,0 +1,48 @@ +--- +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`. + +Original website: [gradcracker.com](https://www.gradcracker.com) + +## 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. diff --git a/docs-site/versioned_docs/version-0.1.27/extractors/hiring-cafe.md b/docs-site/versioned_docs/version-0.1.27/extractors/hiring-cafe.md new file mode 100644 index 0000000..99c7e31 --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/extractors/hiring-cafe.md @@ -0,0 +1,77 @@ +--- +id: hiring-cafe +title: Hiring Cafe Extractor +description: Browser-backed Hiring Cafe extraction integrated into the pipeline source selector. +sidebar_position: 7 +--- + +## What it is + +Original website: [hiring.cafe](https://hiring.cafe) + +Special thanks: Initial implementation inspiration came from [umur957/hiring-cafe-job-scraper](https://github.com/umur957/hiring-cafe-job-scraper). + +Hiring Cafe is a browser-backed extractor that queries Hiring Cafe search APIs and maps results into the orchestrator `CreateJobInput` shape. + +Implementation split: + +1. `extractors/hiringcafe/src/main.ts` builds search state, calls Hiring Cafe APIs, and writes dataset JSON. +2. `orchestrator/src/server/services/hiring-cafe.ts` runs the extractor, streams progress events, and maps rows for pipeline import. + +## Why it exists + +Hiring Cafe adds another non-credentialed source that can be enabled from the existing source picker, without adding new settings UI. + +It also supports term-by-term search and country-aware search state using the same pipeline knobs you already set for automatic runs. + +## How to use it + +1. Open **Run jobs** and choose **Automatic**. +2. **Hiring Cafe** is enabled by default in **Sources** (toggle it off if you do not want it for this run). +3. Set your existing automatic run knobs: + - `searchTerms` drive per-term Hiring Cafe `searchQuery`. + - selected country maps into Hiring Cafe location search state. + - run budget path (`jobspyResultsWanted`) is reused as the max jobs-per-term cap. + - optional **Search cities** narrow results by city. +4. Start the run and watch progress in the pipeline progress card. + +Defaults and constraints: + +- No new Hiring Cafe settings fields were added. +- `worldwide` and `usa/ca` run in broad mode without a strict country location filter. +- Hiring Cafe is enabled by default in source selection. +- `HIRING_CAFE_DATE_FETCHED_PAST_N_DAYS` controls recency window when running extractor directly (default `7`). +- When a city is provided via `searchCities`, Hiring Cafe uses city radius search (default `1` mile) and strict city post-filtering. +- City geocoding is resolved through Nominatim (OpenStreetMap data); if you scale extractor traffic, add attribution and cache repeated city lookups. + +Local run example: + +```bash +HIRING_CAFE_SEARCH_TERMS='["backend engineer"]' \ +HIRING_CAFE_COUNTRY='united kingdom' \ +HIRING_CAFE_MAX_JOBS_PER_TERM='50' \ +npm --workspace hiringcafe-extractor run start +``` + +## Common problems + +### Hiring Cafe returns 429 / Vercel security checkpoint + +- The extractor first attempts Camoufox-backed Firefox and falls back to vanilla Firefox startup if Camoufox is unstable locally. +- If upstream blocks continue, retry later or reduce run concurrency at the pipeline level by selecting fewer sources. + +### Hiring Cafe does not appear in sources + +- Check that client is running on latest build containing the new source list. +- Hiring Cafe is source-only and does not require credentials, so it should appear once the new build is loaded. + +### Results are lower than expected + +- Cap is tied to automatic run budget path (`jobspyResultsWanted`) and search term count. +- Country mapping can narrow results when a strict country location is applied. + +## Related pages + +- [Extractors Overview](/docs/next/extractors/overview) +- [Pipeline Run](/docs/next/features/pipeline-run) +- [Settings](/docs/next/features/settings) diff --git a/docs-site/versioned_docs/version-0.1.27/extractors/jobspy.md b/docs-site/versioned_docs/version-0.1.27/extractors/jobspy.md new file mode 100644 index 0000000..9d55e91 --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/extractors/jobspy.md @@ -0,0 +1,52 @@ +--- +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. + +Original websites: +- [indeed.com](https://www.indeed.com) +- [linkedin.com/jobs](https://www.linkedin.com/jobs) +- [glassdoor.com](https://www.glassdoor.com) + +## 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/`. diff --git a/docs-site/versioned_docs/version-0.1.27/extractors/manual.md b/docs-site/versioned_docs/version-0.1.27/extractors/manual.md new file mode 100644 index 0000000..927fd6f --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/extractors/manual.md @@ -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 diff --git a/docs-site/versioned_docs/version-0.1.27/extractors/overview.md b/docs-site/versioned_docs/version-0.1.27/extractors/overview.md new file mode 100644 index 0000000..74eb009 --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/extractors/overview.md @@ -0,0 +1,42 @@ +--- +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 integrations are now registered through manifests and loaded automatically at orchestrator startup. Runtime discovery only scans `extractors/*/(manifest.ts|src/manifest.ts)` and does not read manifests from `orchestrator/**`. Extractor-specific run logic should also remain in `extractors//` so orchestrator stays source-agnostic. To add a new source, follow [Add an Extractor](/docs/next/workflows/add-an-extractor). + +## 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` | +| [Adzuna](/docs/next/extractors/adzuna) | API-based multi-country discovery with low scraping overhead | Requires valid App ID/App Key; country must be in Adzuna-supported list | `ADZUNA_APP_ID`, `ADZUNA_APP_KEY`, `ADZUNA_MAX_JOBS_PER_TERM` | API pagination to dataset output; orchestrator maps progress and de-duplicates by `sourceJobId`/`jobUrl` | +| [Hiring Cafe](/docs/next/extractors/hiring-cafe) | Browser-backed discovery using Hiring Cafe search APIs | Subject to upstream anti-bot checks; uses browser context and encoded search-state payloads | `HIRING_CAFE_SEARCH_TERMS`, `HIRING_CAFE_COUNTRY`, `HIRING_CAFE_MAX_JOBS_PER_TERM`, `HIRING_CAFE_DATE_FETCHED_PAST_N_DAYS` | Uses existing pipeline term/country/budget knobs and maps directly to normalized jobs | +| [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 **Adzuna** when you want API-first discovery in supported non-UK markets. +- Use **Hiring Cafe** when you want another term/country-driven source without adding credentials. +- 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) +- [Adzuna](/docs/next/extractors/adzuna) +- [Hiring Cafe](/docs/next/extractors/hiring-cafe) +- [UKVisaJobs](/docs/next/extractors/ukvisajobs) +- [Manual Import](/docs/next/extractors/manual) +- [Add an Extractor](/docs/next/workflows/add-an-extractor) diff --git a/docs-site/versioned_docs/version-0.1.27/extractors/ukvisajobs.md b/docs-site/versioned_docs/version-0.1.27/extractors/ukvisajobs.md new file mode 100644 index 0000000..96ad6bc --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/extractors/ukvisajobs.md @@ -0,0 +1,75 @@ +--- +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. + +Original website: [my.ukvisajobs.com](https://my.ukvisajobs.com) + +## 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. diff --git a/docs-site/versioned_docs/version-0.1.27/features/ghostwriter.md b/docs-site/versioned_docs/version-0.1.27/features/ghostwriter.md new file mode 100644 index 0000000..48e53b2 --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/features/ghostwriter.md @@ -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) diff --git a/docs-site/versioned_docs/version-0.1.27/features/in-progress-board.md b/docs-site/versioned_docs/version-0.1.27/features/in-progress-board.md new file mode 100644 index 0000000..0b45ed4 --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/features/in-progress-board.md @@ -0,0 +1,92 @@ +--- +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. + +![In Progress Board kanban lanes](/img/features/in-progress-board.png) + +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//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) diff --git a/docs-site/versioned_docs/version-0.1.27/features/job-search-bar.md b/docs-site/versioned_docs/version-0.1.27/features/job-search-bar.md new file mode 100644 index 0000000..e87a4c5 --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/features/job-search-bar.md @@ -0,0 +1,77 @@ +--- +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. + +![Job search command bar](/img/features/job-search-bar.png) + +## 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 + +By default, very low-relevance matches are hidden so results stay focused on likely intent. + +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) diff --git a/docs-site/versioned_docs/version-0.1.27/features/keyboard-shortcuts.md b/docs-site/versioned_docs/version-0.1.27/features/keyboard-shortcuts.md new file mode 100644 index 0000000..783b9c8 --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/features/keyboard-shortcuts.md @@ -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) diff --git a/docs-site/versioned_docs/version-0.1.27/features/multi-select-and-bulk-actions.md b/docs-site/versioned_docs/version-0.1.27/features/multi-select-and-bulk-actions.md new file mode 100644 index 0000000..7f0f0ea --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/features/multi-select-and-bulk-actions.md @@ -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) diff --git a/docs-site/versioned_docs/version-0.1.27/features/orchestrator.md b/docs-site/versioned_docs/version-0.1.27/features/orchestrator.md new file mode 100644 index 0000000..00b0a14 --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/features/orchestrator.md @@ -0,0 +1,127 @@ +--- +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. + +![Orchestrator jobs workspace](/img/features/orchestrator-jobs.png) + +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). + +### Opening documentation from the sidebar + +1. Open the sidebar menu. +2. In the footer section under `Version `, click **Documentation**, which opens the locally hosted docs in a new tab. + +### 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/actions` with `{ "action": "move_to_ready", "jobIds": [""] }` +- 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/" \ + -H "content-type: application/json" \ + -d '{ + "jobDescription": "", + "tailoredSummary": "", + "tailoredHeadline": "", + "tailoredSkills": [{"name":"Backend","keywords":["TypeScript","Node.js"]}], + "selectedProjectIds": "p1,p2" + }' +``` + +```bash +curl -X POST "http://localhost:3001/api/jobs//summarize?force=true" +curl -X POST "http://localhost:3001/api/jobs//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) diff --git a/docs-site/versioned_docs/version-0.1.27/features/overview.md b/docs-site/versioned_docs/version-0.1.27/features/overview.md new file mode 100644 index 0000000..f65797a --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/features/overview.md @@ -0,0 +1,100 @@ +--- +id: overview +title: Overview +description: Dashboard analytics for application volume, conversion, and response rate by source over selectable time windows. +sidebar_position: 1 +--- + +## What it is + +The Overview page is the analytics dashboard for your pipeline outcomes. + +![Overview dashboard](/img/features/overview-dashboard.png) + +It visualizes: + +- Applications per day +- Application-to-response conversion +- Funnel progression (Applied, Screening, Interview, Offer, Rejected) +- Response rate by source + +### Graph-level views + +![Applications per day graph](/img/features/overview-applications-graph.png) + +![Funnel progression graph](/img/features/overview-funnel-graph.png) + +## 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? +- Which job boards are actually generating responses? + +## 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 + - **Response Rate by Source** to compare job board effectiveness +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. +- Response rate by source is calculated across all time (not scoped to the duration selector), since response events may arrive well after the application window. +- Sources with fewer than 5 applications are hidden by default in the Response Rate by Source chart. Check **Include small samples** to show them. + +### Response Rate by Source + +The **Response Rate by Source** chart shows, for each job board (LinkedIn, Indeed, Gradcracker, etc.), what percentage of your applications received a non-rejection response. + +**What counts as a response:** the application reached at least one of these stages — recruiter screen, assessment, hiring manager screen, technical interview, onsite, or offer. Ghosted applications (no stage events) and rejected outcomes are both excluded from the numerator. + +Each bar is labelled `X% (n=Y)` where `n` is the number of applications from that source, so you can immediately tell whether a high rate comes from a meaningful sample or a single lucky application. The full breakdown (response rate, responded, applied) is also shown in the tooltip. + +Sources are sorted by response rate descending. Sources with fewer than 5 applications are hidden by default to avoid misleading percentages from tiny samples. Check **Include small samples** to show them. + +Use this chart to identify which sources produce genuine engagement versus silence, and concentrate future sourcing effort accordingly. + +## 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. + +### Response Rate by Source shows only one source + +- Only sources with at least one applied job appear in the chart. +- If all your applications come from a single board, only that board will be shown. + +### Response rate for a source looks too high or too low + +- Check the `n=` value in the bar label or tooltip. A small sample (e.g. n=2) will produce an unreliable rate. +- Sources with fewer than 5 applications are hidden by default. If you see a suspiciously high rate, you may be looking at a small-sample source — check the n. + +## Related pages + +- [Orchestrator](/docs/next/features/orchestrator) +- [Post-Application Tracking](/docs/next/features/post-application-tracking) +- [Troubleshooting](/docs/next/troubleshooting/common-problems) diff --git a/docs-site/versioned_docs/version-0.1.27/features/pipeline-run.md b/docs-site/versioned_docs/version-0.1.27/features/pipeline-run.md new file mode 100644 index 0000000..b6f028e --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/features/pipeline-run.md @@ -0,0 +1,118 @@ +--- +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. +- Adzuna is available only for its supported countries and when App ID/App Key are configured in Settings. +- Glassdoor can be enabled only when: + - selected country supports Glassdoor + - at least one **Search 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) +- **Search cities** (optional multi-city input; required 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 at least one Search city in Advanced settings. + +### Adzuna is not selectable + +- Set `Adzuna App ID` and `Adzuna App Key` in **Settings > Environment & Accounts**. +- Verify the selected country is one of Adzuna's supported markets. + +### 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) diff --git a/docs-site/versioned_docs/version-0.1.27/features/post-application-tracking.md b/docs-site/versioned_docs/version-0.1.27/features/post-application-tracking.md new file mode 100644 index 0000000..a4a67d9 --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/features/post-application-tracking.md @@ -0,0 +1,93 @@ +--- +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. + +![Tracking Inbox review queue](/img/features/tracking-inbox.png) + +## 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**. + +Detailed setup guide: + +- [Gmail OAuth Setup](/docs/next/getting-started/gmail-oauth-setup) + +## 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` +- Full scope: `https://www.googleapis.com/auth/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 | +| GET | `/api/post-application/providers/gmail/oauth/start` | Start OAuth flow | +| POST | `/api/post-application/providers/gmail/oauth/exchange` | Exchange OAuth code | + +## 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. diff --git a/docs-site/versioned_docs/version-0.1.27/features/reactive-resume.md b/docs-site/versioned_docs/version-0.1.27/features/reactive-resume.md new file mode 100644 index 0000000..fbded44 --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/features/reactive-resume.md @@ -0,0 +1,249 @@ +--- +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 + +### Account requirements (important) + +Before connecting Reactive Resume to JobOps: + +1. Create your account on **RxResume v4** at [v4.rxresu.me/auth/register](https://v4.rxresu.me/auth/register). +2. Use a **native email + password** account (not Google/GitHub/other OAuth login). +3. Generate/store that password so JobOps can use it for API login. + +JobOps cannot use OAuth-based RxResume logins for this integration. + +### 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. Optionally rewrite outbound links to tracer links (per-job toggle). +5. Create temporary resume in RxResume. +6. Export PDF. +7. Delete temporary resume. + +### Per-job tracer links + +Before generating a PDF, each job can enable/disable tracer links. + +- Disabled: original RxResume links remain unchanged. +- Enabled: eligible outbound links are rewritten to `https:///cv/-xx` (readable slug + 2-letter suffix). + +For background pipeline generation, configure: + +- `JOBOPS_PUBLIC_BASE_URL=https://your-host` + +Important: + +- tracer enablement is gated by readiness checks +- if public host verification fails, enable is blocked until host health is restored +- toggle changes apply on next PDF generation only + +### 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//projects" +``` + +```bash +# Regenerate PDF for a job after changing settings or resume data +curl -X POST "http://localhost:3001/api/jobs//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 [v4.rxresu.me](https://v4.rxresu.me)/your configured RxResume URL. +- Confirm the RxResume account is a native email/password account (not OAuth-only). +- 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 AI’s 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) diff --git a/docs-site/versioned_docs/version-0.1.27/features/settings.md b/docs-site/versioned_docs/version-0.1.27/features/settings.md new file mode 100644 index 0000000..ffd9025 --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/features/settings.md @@ -0,0 +1,194 @@ +--- +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. + +![Settings page sections](/img/features/settings.png) + +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 +- Tracer Links readiness verification +- 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 + +![Model settings section](/img/features/settings-model-section.png) + +- 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 + +![Webhooks settings section](/img/features/settings-webhooks-section.png) + +- 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 + +![Display settings section](/img/features/settings-display-section.png) + +- Toggle visa sponsor badge visibility in job lists/details + +### Ghostwriter + +![Ghostwriter settings section](/img/features/settings-ghostwriter-section.png) + +- Set global writing defaults: + - Tone + - Formality + - Constraints + - Do-not-use terms + +### Reactive Resume + +![Reactive Resume settings section](/img/features/settings-reactive-resume-section.png) + +- Select a template/base resume +- Configure project selection behavior: + - Max projects + - Must-include projects + - AI-selectable projects + +### Tracer Links + +- Verify tracer readiness before enabling per-job tracing +- Shows current status (`Ready`, `Unavailable`, `Unconfigured`, or stale state) +- Displays the effective public base URL and last check time +- Provides **Verify now** for an on-demand health check + +Readiness requires: + +- a valid public JobOps base URL +- successful reachability of `/health` +- non-localhost/non-private host setup for public redirect usage + +### Environment & Accounts + +- Configure service accounts: + - RxResume email/password + - UKVisaJobs email/password + - Adzuna app ID/app key + - Optional basic authentication for write operations + +### Backup + +![Backup settings section](/img/features/settings-backup-section.png) + +- 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 + +![Scoring settings section](/img/features/settings-scoring-section.png) + +- Penalize missing salary data +- Set penalty amount +- Optional auto-skip threshold for low-score jobs +- Block jobs from companies that match configured keyword tokens + +### Danger Zone + +![Danger Zone settings section](/img/features/settings-danger-zone-section.png) + +- 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). + +### Tracer links cannot be enabled + +- Open **Settings → Tracer Links** and click **Verify now**. +- Ensure `JOBOPS_PUBLIC_BASE_URL` is set for background/pipeline usage. +- Ensure the configured host is publicly reachable and `/health` responds. + +## Related pages + +- [Reactive Resume](./reactive-resume) +- [Database Backups](../getting-started/database-backups) +- [Overview](./overview) +- [Orchestrator](./orchestrator) +- [Ghostwriter](./ghostwriter) +- [Self-Hosting](../getting-started/self-hosting) diff --git a/docs-site/versioned_docs/version-0.1.27/features/tracer-links.md b/docs-site/versioned_docs/version-0.1.27/features/tracer-links.md new file mode 100644 index 0000000..32a5b36 --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/features/tracer-links.md @@ -0,0 +1,151 @@ +--- +id: tracer-links +title: Tracer Links +description: Track outbound resume-link clicks with per-job toggles and privacy-safe analytics. +sidebar_position: 8 +--- + +## What it is + +Tracer Links are per-job redirect links that are generated when a PDF is created. + +When enabled for a job, JobOps rewrites eligible outbound RxResume links to your JobOps host, then redirects to the original destination after recording a click event. + +Examples: + +- original: `https://github.com/yourname` +- traced: `https://jobops.dakheera47.com/cv/amazon-de` + +Format details: + +- path prefix is always `/cv/` +- token format is `-` +- `` is two lowercase letters (`a-z`) +- visible link text in the PDF is also updated to the traced URL + +## Why it exists + +Without tracer links, resume links are "fire and forget". + +Tracer links let you answer: + +- whether links in a specific job PDF were opened +- which destination links are being opened most +- rough human vs bot traffic split +- per-job and global engagement trends over time + +The feature is privacy-safe by design: + +- no raw IP is stored +- referrer host is stored (not full referrer URL) +- bot traffic is flagged and can be filtered in analytics + +## How to use it + +1. Open **Settings** and go to the **Tracer Links** section. +2. Click **Verify now** and confirm status is **Ready**. +3. Open a job in **Jobs**. +4. Enable **Tracer links for this job** in tailoring or job details. +5. Generate or regenerate the PDF. +6. Open **Tracer Links** in navigation to view: + - global totals + - top jobs and top links + - per-job drilldown by Job ID + +Important behavior: + +- Tracer links are **off by default** per job. +- Toggle changes apply on the **next PDF generation only**. +- Existing PDFs are not modified retroactively. +- Existing tracer URLs remain valid, even if a newer PDF generates new links. + +### Readiness and enable/disable behavior + +You can only turn tracer links **on** when readiness is healthy. + +Readiness checks: + +- a resolvable public base URL +- a successful health probe to `/health` +- a non-localhost/non-private host for public usage + +If readiness is unavailable, enable is blocked until verification passes. + +### Required background-run setting + +If PDFs are generated by background pipeline runs, set: + +```bash +JOBOPS_PUBLIC_BASE_URL=https://your-jobops-host +``` + +JobOps uses this URL when request host inference is not available. + +### URL uniqueness rules + +Tracer links are unique enough for tracking while still readable. + +- same job + same source path + same destination URL => token is reused +- same job + same source path + changed destination URL => new token +- old tokens continue to redirect (not retroactively deleted) + +### Risk and responsibility disclaimer + +Tracer links are redirect links. Some recruiters, companies, universities, or security tools may treat redirects as suspicious behavior and may whitelist, blacklist, filter, or flag these links as phishing-like. + +By enabling and using this feature, you accept full responsibility for any consequences that result from its use. Responsibility for policy, trust, and reputation outcomes sits with the user/operator of the instance, not with the app. + +## Common problems + +### I cannot enable tracer links + +Cause: + +- readiness is not **Ready** +- host is local/private or unreachable from the verifier + +Fix: + +- configure a real public host +- set `JOBOPS_PUBLIC_BASE_URL` for background flows +- make sure `/health` is reachable +- retry **Verify now** + +### Tracer links enabled but PDF generation fails + +Cause: + +- base URL cannot be resolved at generation time, or instance health is not reachable for that run + +Fix: + +- ensure `JOBOPS_PUBLIC_BASE_URL` is set correctly +- verify the deployment is publicly reachable +- regenerate the PDF + +### I enabled tracer links, but old PDF still has direct links + +Cause: + +- toggle changes only apply to newly generated PDFs + +Fix: + +- regenerate the PDF for that job + +### Analytics look inflated by scanners + +Cause: + +- link scanners and preview bots may open links automatically + +Fix: + +- use the **Include likely bots** filter in Tracer Links analytics + +## Related pages + +- [Settings](/docs/next/features/settings) +- [Reactive Resume](/docs/next/features/reactive-resume) +- [Find Jobs and Apply Workflow](/docs/next/workflows/find-jobs-and-apply-workflow) +- [Post-Application Tracking](/docs/next/features/post-application-tracking) diff --git a/docs-site/versioned_docs/version-0.1.27/features/visa-sponsors.md b/docs-site/versioned_docs/version-0.1.27/features/visa-sponsors.md new file mode 100644 index 0000000..e97d749 --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/features/visa-sponsors.md @@ -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) diff --git a/docs-site/versioned_docs/version-0.1.27/getting-started/database-backups.md b/docs-site/versioned_docs/version-0.1.27/getting-started/database-backups.md new file mode 100644 index 0000000..c49991c --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/getting-started/database-backups.md @@ -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 today’s 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) diff --git a/docs-site/versioned_docs/version-0.1.27/getting-started/gmail-oauth-setup.md b/docs-site/versioned_docs/version-0.1.27/getting-started/gmail-oauth-setup.md new file mode 100644 index 0000000..93ec413 --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/getting-started/gmail-oauth-setup.md @@ -0,0 +1,96 @@ +--- +id: gmail-oauth-setup +title: Gmail OAuth Setup +description: Step-by-step Google Cloud setup for JobOps Gmail tracking, with exact scopes and callback configuration. +sidebar_position: 2 +--- + +## What it is + +This guide configures Google OAuth so JobOps can read recruitment emails from Gmail for the Tracking Inbox. + +## Why it exists + +Gmail OAuth setup is easy to misconfigure (wrong redirect URI, missing refresh token, or unnecessary scopes). This page documents the exact defaults JobOps expects. + +## How to use it + +### 1) Create Google Cloud credentials + +In [Google Cloud Console](https://console.cloud.google.com/): + +1. Create (or select) a project. +2. Open **APIs & Services → Library** and enable **Gmail API**. +3. Open **APIs & Services → OAuth consent screen** and configure your app. +4. Open **APIs & Services → Credentials** and create **OAuth client ID**. +5. Choose **Web application**. +6. Add at least one authorized redirect URI: + - Local: `http://localhost:3005/oauth/gmail/callback` + - Production: `https://your-domain.com/oauth/gmail/callback` + +Notes: + +- If you set `GMAIL_OAUTH_REDIRECT_URI`, it must exactly match a redirect URI in Google Cloud. +- JobOps does not require JavaScript origins for this flow. + +### 2) Set environment variables + +Configure: + +```bash +GMAIL_OAUTH_CLIENT_ID=your-client-id.apps.googleusercontent.com +GMAIL_OAUTH_CLIENT_SECRET=your-client-secret +# Optional (recommended in production) +GMAIL_OAUTH_REDIRECT_URI=https://your-domain.com/oauth/gmail/callback +``` + +Then restart the container/app. + +### 3) Connect Gmail in JobOps + +1. Open **Tracking Inbox**. +2. Click **Connect Gmail**. +3. Complete Google consent. + +JobOps starts OAuth with: + +- Scope: `https://www.googleapis.com/auth/gmail.readonly` +- `access_type=offline` (requests refresh token) +- `prompt=consent` (forces consent screen so refresh token is returned reliably) + +### 4) Scope reference (required vs not required) + +Required by JobOps: + +- `https://www.googleapis.com/auth/gmail.readonly` + +Not required for JobOps Gmail ingestion: + +- `https://www.googleapis.com/auth/gmail.modify` +- `openid` +- `https://www.googleapis.com/auth/userinfo.email` +- `https://www.googleapis.com/auth/userinfo.profile` + +## Common problems + +### Redirect URI mismatch + +- Symptom: Google returns `redirect_uri_mismatch`. +- Fix: ensure the exact callback URL in `GMAIL_OAUTH_REDIRECT_URI` is also present in the OAuth client redirect URIs. + +### No refresh token returned + +- Symptom: connect fails after OAuth exchange. +- Fix: remove app access in your Google account, then reconnect so consent is re-granted. + +### Gmail connects but no inbox results + +- Check that your account actually has recruitment/application emails. +- Trigger a sync and increase `searchDays` if needed. + +## Related pages + +- [Self-Hosting (Docker Compose)](/docs/next/getting-started/self-hosting) +- [Post-Application Tracking](/docs/next/features/post-application-tracking) +- [Post-Application Workflow](/docs/next/workflows/post-application-workflow) +- [Common Problems](/docs/next/troubleshooting/common-problems) diff --git a/docs-site/versioned_docs/version-0.1.27/getting-started/self-hosting.md b/docs-site/versioned_docs/version-0.1.27/getting-started/self-hosting.md new file mode 100644 index 0000000..7884ab5 --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/getting-started/self-hosting.md @@ -0,0 +1,126 @@ +--- +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** + +For a full step-by-step setup, exact scope requirements, and troubleshooting, see: + +- [Gmail OAuth Setup](/docs/next/getting-started/gmail-oauth-setup) + +## 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` diff --git a/docs-site/versioned_docs/version-0.1.27/intro.md b/docs-site/versioned_docs/version-0.1.27/intro.md new file mode 100644 index 0000000..09b178c --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/intro.md @@ -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. diff --git a/docs-site/versioned_docs/version-0.1.27/reference/documentation-style-guide.md b/docs-site/versioned_docs/version-0.1.27/reference/documentation-style-guide.md new file mode 100644 index 0000000..0ddc409 --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/reference/documentation-style-guide.md @@ -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. diff --git a/docs-site/versioned_docs/version-0.1.27/reference/faq.md b/docs-site/versioned_docs/version-0.1.27/reference/faq.md new file mode 100644 index 0000000..db31800 --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/reference/faq.md @@ -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. diff --git a/docs-site/versioned_docs/version-0.1.27/troubleshooting/common-problems.md b/docs-site/versioned_docs/version-0.1.27/troubleshooting/common-problems.md new file mode 100644 index 0000000..7769d6e --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/troubleshooting/common-problems.md @@ -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. diff --git a/docs-site/versioned_docs/version-0.1.27/workflows/add-an-extractor.md b/docs-site/versioned_docs/version-0.1.27/workflows/add-an-extractor.md new file mode 100644 index 0000000..e03e4e0 --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/workflows/add-an-extractor.md @@ -0,0 +1,95 @@ +--- +id: add-an-extractor +title: Add an Extractor +description: How to add a new extractor using the manifest contract and shared extractor catalog. +sidebar_position: 2 +--- + +## What it is + +This guide explains how to add a new extractor that is auto-registered at orchestrator startup. + +The extractor runtime is discovered from a local `manifest.ts` file, and the source is type-safe across API/client through the shared catalog in `shared/src/extractors/index.ts`. + +Extractor manifests must live in extractor packages under `extractors//` only. Do not add manifest files inside `orchestrator/`. +Extractor run logic should also live in the extractor package so orchestrator stays extractor-agnostic. + +## Why it exists + +Without a manifest contract, adding extractors required touching multiple orchestrator files. + +With the manifest system, contributors only need to: + +1. Add a manifest in their extractor package. +2. Add the new source id to the shared typed catalog. + +That keeps runtime wiring dynamic while preserving compile-time safety in API and client code. + +## How to use it + +1. Create your extractor package under `extractors//`. +2. Add a `manifest.ts` in the extractor package root (or `src/manifest.ts`). + - Valid locations are only `extractors//manifest.ts` or `extractors//src/manifest.ts`. + - `orchestrator/**/manifest.ts` is not used for extractor discovery. +3. Export a manifest with: + - `id` + - `displayName` + - `providesSources` + - `requiredEnvVars` (optional) + - `run(context)` that returns `{ success, jobs, error? }` +4. Add the new source id to `shared/src/extractors/index.ts`: + - append to `EXTRACTOR_SOURCE_IDS` + - add an entry in `EXTRACTOR_SOURCE_METADATA` +5. Ensure your extractor maps output to `CreateJobInput[]`. +6. Run the full CI checks. + +Example manifest: + +```ts +import type { ExtractorManifest } from "@shared/types/extractors"; + +export const manifest: ExtractorManifest = { + id: "myextractor", + displayName: "My Extractor", + providesSources: ["myextractor"], + requiredEnvVars: ["MYEXTRACTOR_API_KEY"], + async run(context) { + // context.searchTerms, context.settings, context.onProgress, context.shouldCancel + const jobs = []; + return { success: true, jobs }; + }, +}; + +export default manifest; +``` + +Subprocess extractors are supported. Keep subprocess spawning inside `run(context)` so orchestrator only depends on the manifest contract. + +## Common problems + +### Extractor not discovered at startup + +- Check file path: `extractors//manifest.ts` or `extractors//src/manifest.ts`. +- Ensure the file exports `default` or named `manifest`. + +### Source compiles in extractor but fails in API/client + +- Add the new source id to `shared/src/extractors/index.ts`. +- Confirm metadata exists for that source id. + +### Source appears in shared catalog but is unavailable at runtime + +- The manifest was not loaded successfully. +- Check startup logs for registry warnings. + +### Source requires credentials but never returns jobs + +- Add and validate `requiredEnvVars`. +- Verify your manifest `run(context)` reads settings/env values correctly. + +## Related pages + +- [Extractors Overview](/docs/next/extractors/overview) +- [Adzuna Extractor](/docs/next/extractors/adzuna) +- [Hiring Cafe Extractor](/docs/next/extractors/hiring-cafe) +- [UKVisaJobs Extractor](/docs/next/extractors/ukvisajobs) diff --git a/docs-site/versioned_docs/version-0.1.27/workflows/find-jobs-and-apply-workflow.md b/docs-site/versioned_docs/version-0.1.27/workflows/find-jobs-and-apply-workflow.md new file mode 100644 index 0000000..2456bd6 --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/workflows/find-jobs-and-apply-workflow.md @@ -0,0 +1,99 @@ +--- +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. Optionally enable tracer links for that specific job. +3. Download the tailored PDF. +4. 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. +- Use per-job tracer links when you want measurable outbound-link analytics. +- If you use tracer links, review the risk note in [Tracer Links](../features/tracer-links): some recipients/security tools may treat redirects as suspicious. + +## 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) diff --git a/docs-site/versioned_docs/version-0.1.27/workflows/post-application-workflow.md b/docs-site/versioned_docs/version-0.1.27/workflows/post-application-workflow.md new file mode 100644 index 0000000..c6e87bc --- /dev/null +++ b/docs-site/versioned_docs/version-0.1.27/workflows/post-application-workflow.md @@ -0,0 +1,145 @@ +--- +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//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 +``` + +For exact Google Cloud steps and scope requirements, see: + +- [Gmail OAuth Setup](/docs/next/getting-started/gmail-oauth-setup) + +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":"","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//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//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) diff --git a/docs-site/versioned_sidebars/version-0.1.27-sidebars.json b/docs-site/versioned_sidebars/version-0.1.27-sidebars.json new file mode 100644 index 0000000..373ce79 --- /dev/null +++ b/docs-site/versioned_sidebars/version-0.1.27-sidebars.json @@ -0,0 +1,74 @@ +{ + "docsSidebar": [ + "intro", + { + "type": "category", + "label": "Getting Started", + "items": [ + "getting-started/self-hosting", + "getting-started/gmail-oauth-setup" + ] + }, + { + "type": "category", + "label": "Workflows", + "items": [ + "workflows/find-jobs-and-apply-workflow", + "workflows/post-application-workflow", + "workflows/add-an-extractor" + ] + }, + { + "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", + "features/tracer-links" + ] + }, + { + "type": "category", + "label": "Extractors", + "items": [ + "extractors/overview", + "extractors/gradcracker", + "extractors/jobspy", + "extractors/adzuna", + "extractors/hiring-cafe", + "extractors/manual", + "extractors/ukvisajobs" + ] + }, + { + "type": "category", + "label": "Self-Hosting & Ops", + "items": [ + "getting-started/self-hosting", + "getting-started/gmail-oauth-setup", + "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"] + } + ] +} diff --git a/docs-site/versions.json b/docs-site/versions.json index 44ddb43..2ef9518 100644 --- a/docs-site/versions.json +++ b/docs-site/versions.json @@ -1 +1 @@ -["0.1.26", "0.1.25", "0.1.24", "0.1.23", "0.1.22", "0.1.21", "0.1.20"] +["0.1.27", "0.1.26", "0.1.25", "0.1.24", "0.1.23", "0.1.22", "0.1.21", "0.1.20"]