docs: cut version 0.1.28
This commit is contained in:
@@ -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/<name>/` 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/<name>/`.
|
||||
2. Add a `manifest.ts` in the extractor package root (or `src/manifest.ts`).
|
||||
- Valid locations are only `extractors/<name>/manifest.ts` or `extractors/<name>/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/<name>/manifest.ts` or `extractors/<name>/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)
|
||||
@@ -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)
|
||||
@@ -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/<jobId>/stages" \
|
||||
-H "content-type: application/json" \
|
||||
-d '{
|
||||
"toStage": "technical_interview",
|
||||
"metadata": {
|
||||
"actor": "user",
|
||||
"eventType": "status_update",
|
||||
"eventLabel": "Moved to Technical Interview"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
## Option B: Automatic Gmail syncing
|
||||
|
||||
Use this when you want JobOps to ingest recruitment emails and suggest/apply updates.
|
||||
|
||||
### High-level flow
|
||||
|
||||
1. Connect Gmail provider.
|
||||
2. Run sync (or scheduled sync, depending on setup).
|
||||
3. Smart router scores message-to-job match.
|
||||
4. High confidence updates are auto-linked.
|
||||
5. Mid/low confidence items go to inbox for review.
|
||||
|
||||
### Configure Gmail sync
|
||||
|
||||
Set OAuth variables:
|
||||
|
||||
```bash
|
||||
GMAIL_OAUTH_CLIENT_ID=...
|
||||
GMAIL_OAUTH_CLIENT_SECRET=...
|
||||
GMAIL_OAUTH_REDIRECT_URI=https://your-domain.com/oauth/gmail/callback
|
||||
```
|
||||
|
||||
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":"<state>","code":"<code>"}'
|
||||
```
|
||||
|
||||
```bash
|
||||
# Trigger provider sync action
|
||||
curl -X POST "http://localhost:3001/api/post-application/providers/gmail/actions/sync" \
|
||||
-H "content-type: application/json" \
|
||||
-d '{"accountKey":"default","maxMessages":100,"searchDays":30}'
|
||||
```
|
||||
|
||||
```bash
|
||||
# Review inbox
|
||||
curl "http://localhost:3001/api/post-application/inbox?provider=gmail&accountKey=default"
|
||||
```
|
||||
|
||||
```bash
|
||||
# Approve inbox item
|
||||
curl -X POST "http://localhost:3001/api/post-application/inbox/<messageId>/approve" \
|
||||
-H "content-type: application/json" \
|
||||
-d '{"provider":"gmail","accountKey":"default"}'
|
||||
```
|
||||
|
||||
```bash
|
||||
# Deny inbox item
|
||||
curl -X POST "http://localhost:3001/api/post-application/inbox/<messageId>/deny" \
|
||||
-H "content-type: application/json" \
|
||||
-d '{"provider":"gmail","accountKey":"default"}'
|
||||
```
|
||||
|
||||
## Which option should you use?
|
||||
|
||||
- Choose **manual** if your volume is low and you want direct control.
|
||||
- Choose **automatic Gmail sync** if your volume is higher and you want less repetitive triage.
|
||||
- Many users combine both: auto-sync first, manual adjustments for edge cases.
|
||||
|
||||
## Common problems
|
||||
|
||||
### Gmail connected but no messages appear
|
||||
|
||||
- Verify OAuth credentials and redirect URI.
|
||||
- Confirm you are syncing the intended account key.
|
||||
- Check search window (`searchDays`) and message cap (`maxMessages`).
|
||||
|
||||
### Wrong job matched
|
||||
|
||||
- Expected in lower-confidence buckets.
|
||||
- Deny incorrect inbox items and apply manual stage updates where needed.
|
||||
|
||||
### I prefer not to grant Gmail access
|
||||
|
||||
- Use the manual tracking path only.
|
||||
- The post-application workflow still works without Gmail integration.
|
||||
|
||||
## Related pages
|
||||
|
||||
- [Find Jobs and Apply Workflow](./find-jobs-and-apply-workflow)
|
||||
- [Post-Application Tracking](../features/post-application-tracking)
|
||||
- [In Progress Board](../features/in-progress-board)
|
||||
- [Overview](../features/overview)
|
||||
Reference in New Issue
Block a user