Files
santifer--career-ops/seeds/README.md
T
wehub-resource-sync d083df1fdb
CodeQL Analysis / Analyze (javascript-typescript) (push) Failing after 2s
Web CI / web typecheck + build (push) Failing after 1s
Release Please / release-please (push) Failing after 1s
CodeQL Analysis / Analyze (go) (push) Failing after 16s
chore: import upstream snapshot with attribution
2026-07-13 12:02:43 +08:00

98 lines
3.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# seeds/ — VC Portfolio Seed Fetchers
A complementary discovery path for startup job-seekers: pull a **public VC portfolio company list** and probe each company's ATS for openings, feeding results into the same pipeline as tracked companies in `portals.yml`.
## What this does
`scan-ats-full.mjs` normally discovers companies by walking public ATS directories (Greenhouse, Lever, Ashby, Workday). The `seeds/` layer adds a **high-signal starting point for startup roles**: rather than waiting for companies to appear in ATS directories, we seed the universe from well-known VC portfolios — giving you instant coverage of hundreds of YC/a16z-backed companies.
Flow:
```
VC portfolio API/page
↓ seeds/vc-portfolios.mjs
SeedCompany[]
↓ toPortalEntry()
PortalEntry (careers_url set to best-guess ATS URL)
↓ provider.detect() (same as portals.yml companies)
ATS provider fetches jobs
↓ title_filter / location_filter / dedup
data/pipeline.md
```
## Usage
### Via scan-ats-full.mjs (recommended)
```bash
# Seed from Y Combinator portfolio, last 7 days
node scan-ats-full.mjs --seeds yc --since 7
# Seed from both YC and a16z, dry-run preview
node scan-ats-full.mjs --seeds yc,a16z --dry-run
# Combine seeds + regular ATS sources
node scan-ats-full.mjs --seeds yc --ats greenhouse,lever --since 5
# npm shortcuts
npm run scan:seeds # yc + a16z
npm run scan:yc # YC only
```
### Programmatic
```js
import { fetchYCCompanies, fetchA16zCompanies, toPortalEntry, SEED_SOURCES } from './seeds/vc-portfolios.mjs';
// Fetch YC companies
const companies = await fetchYCCompanies();
console.log(companies[0]);
// → { name: 'Stripe', slug: 'stripe', url: 'https://stripe.com', source: 'yc', batch: 'W11' }
// Convert to a PortalEntry for ATS provider.detect()
const entry = toPortalEntry(companies[0]);
// → { name: 'Stripe', careers_url: 'https://job-boards.greenhouse.io/stripe', source: 'yc' }
// Using the registry
for (const [id, source] of Object.entries(SEED_SOURCES)) {
const companies = await source.fetch();
console.log(`${source.label}: ${companies.length} companies`);
}
```
## Data sources
| Source | URL | Format | Auth |
|--------|-----|--------|------|
| Y Combinator | `https://api.ycombinator.com/v0.1/companies` | JSON API | None |
| a16z | `https://a16z.com/portfolio/` | Public HTML page | None |
- **YC**: Fetches up to 3 pages × 1000 companies. Covers all public YC batches.
- **a16z**: Parses the public portfolio page. Falls back gracefully if the page structure changes.
## Security
- All slugs are validated against `SLUG_RE = /^[A-Za-z0-9._-]+$/` before any URL interpolation — consistent with the guard in `scan-ats-full.mjs`.
- Constructed ATS URLs go through the existing `entryOnHost()` SSRF guard before reaching any provider.
- No authentication tokens, no headless browser, no LLM API calls.
## Adding more VC portfolios
1. Add a `parseXyzPayload(payload)` pure function (no network — testable with inline fixtures).
2. Add a `fetchXyzCompanies(opts?)` async function that calls the public endpoint and returns `SeedCompany[]`.
3. Register it in `SEED_SOURCES`:
```js
export const SEED_SOURCES = {
yc: { fetch: fetchYCCompanies, label: 'Y Combinator Portfolio' },
a16z: { fetch: fetchA16zCompanies, label: 'Andreessen Horowitz (a16z) Portfolio' },
// Add yours:
sequoia: { fetch: fetchSequoiaCompanies, label: 'Sequoia Portfolio' },
};
```
4. Add test cases in `test-all.mjs` covering your `parseXyzPayload()` function.
## Prior art
The VC-portfolio seeding approach is inspired by [adityachaudhary99/job-hunt](https://github.com/adityachaudhary99/job-hunt) (`02-seeds/fetch_yc.py`, `fetch_a16z.py`), which was the original companion reference cited in issue #1370.