Lalabase
Tickets, Doku, Zeiterfassung und Kundengespräche an einem Ort, durchsuchbar per KI. Für Softwarefirmen mit Kundenprojekten. Open Source: auf deinem eigenen Server oder in unserer Cloud in Deutschland.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证AI 求职代理——持续寻找、评分并解释与您个人资料匹配的职位,并起草您的申请。Next.js + SQLite。现场地址 opportunityhunter.xyz
AI 翻译
AI job-hunting agent — continuously finds, scores and explains jobs matched to your profile, and drafts your application. Next.js + SQLite. Live at opportunityhunter.xyz
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
An AI agent that hunts for jobs so you don't have to. Tell it what you want once — it continuously searches live listings, scores every match 0–100 against your profile, explains why it fits, and tracks each one from saved to offer.查看完整 README ↗An AI agent that hunts for jobs so you don't have to. Tell it what you want once — it continuously searches live listings, scores every match 0–100 against your profile, explains why it fits, and tracks each one from saved to offer.
🌐 Live: opportunityhunter.xyz
npm install
npm run dev
Open http://localhost:3000. Demo account: [email protected] / demo1234 (Pro plan, admin).
npm run check type-checks and runs the matching-engine self-test.
Next.js 15 (App Router, server actions) · SQLite via better-sqlite3 (file at ./data/app.db, schema auto-created) · Tailwind v4 · hand-rolled sessions (Node crypto.scrypt, httpOnly cookie).
| Path | What |
|---|---|
src/lib/ai/index.ts | parseSearchProfile, generateSearchQueries, normalizeOpportunity, deduplicateOpportunities, calculateMatchScore, generateMatchExplanation, recommendNextAction, generateDailyDigest — pure, deterministic, swappable for an LLM per function |
src/lib/agent.ts | The Opportunity Hunter Agent: profile → queries → sources → normalize → dedupe → score → explain → save → notify. Enforces free-plan limits server-side |
src/lib/sources/ | SourceAdapter interface + registry. jsearch.ts is the live feed; demo.ts (30 fictional listings) is now only the engine's test fixture |
src/lib/boot.ts | Seeds the demo account; runs due hunts every 15 min in-process. POST /api/cron/hunt (Bearer CRON_SECRET) for external schedulers |
src/lib/email.ts | EmailProvider — console by default, Resend when RESEND_API_KEY is set |
src/lib/plans.ts | Plan definitions and weekly discovery caps |
src/app/actions.ts | All server actions (auth, profile, save/reject/apply, tracker, alerts, billing, admin) |
.env.example)GOOGLE_CLIENT_ID + GOOGLE_CLIENT_SECRET. Button appears automatically.RESEND_API_KEY. Otherwise digests and reset links print to the server console.RAZORPAY_KEY_ID + RAZORPAY_KEY_SECRET turn on checkout. Pro is a 30-day pass (₹499, no auto-renew; buying again stacks), expired every 15 min in boot.ts. Add a Razorpay webhook to /api/razorpay/webhook for event order.paid with secret RAZORPAY_WEBHOOK_SECRET, so buyers who close the tab mid-payment still get Pro. Logic in src/lib/razorpay.ts; admins can still set plans manually at /admin.RAPIDAPI_KEY enables the JSearch adapter (src/lib/sources/jsearch.ts) — a licensed aggregator that includes LinkedIn, Indeed and Glassdoor postings. LinkedIn has no third-party search API and forbids scraping, so this is the legitimate route. Add further adapters in src/lib/sources/index.ts.VOYAGE_API_KEY upgrades the matcher from exact text to meaning (see below).calculateMatchScore (src/lib/ai/index.ts) is a deterministic, explainable scorer: skills, role,
experience, location and salary each produce a 0–100 sub-score, combined by fixed weights into one
number with a plain-English breakdown. It is synchronous and runs in a hot loop over every
candidate, so it never makes a network call.
By default skills and roles are matched by normalized text, which misses obvious equivalences —
"React" vs "Next.js", "Postgres" vs "PostgreSQL". Setting VOYAGE_API_KEY adds a semantic layer
(src/lib/ai/embeddings.ts):
embeddings table), keyed by text. Vectors are unit-normalized, so similarity is a dot product.warmForScoring(profile, opps) embeds any new strings up front (async, batched); callers await it
before scoring. The scorer then reads warmed vectors synchronously — it stays a pure function.SKILL_SIM cosine;
a title earns a semantic role floor above ROLE_SIM; and whole-profile-vs-listing similarity is a
small ±nudge on the final score. Cross-domain guards still apply (a doctor never matches a dev role).null and the matcher falls back to exact text, so the
app and its self-tests run fully offline. npm run check exercises the fallback; with a key set it
also asserts related skills out-score unrelated ones.Needs a long-running Node server with a persistent disk — Railway, Render, Fly.io or a VPS. It will not work on serverless hosts (Vercel, Netlify): the SQLite file would be wiped between invocations and the in-process scheduler would never fire.
npm ci && npm run build && npm start
Required settings:
| Variable | Why |
|---|---|
DATABASE_PATH | Point at a mounted volume, e.g. /data/app.db. Anything else is lost on redeploy. |
ADMIN_EMAILS | Your email. There is no default admin in production. |
APP_URL | Public URL — used in digest links and the Google OAuth callback. |
The app is a single Node process + persistent disk. Walk this list before inviting strangers.
DATABASE_PATH on a volume. Exactly one instance, or disable the in-process scheduler and hit POST /api/cron/hunt.RAPIDAPI_KEY. Without it the live pool is empty. Watch RAPIDAPI_MONTHLY_CALLS.EMAIL_FROM. Otherwise digests and reset links stay in the server log.ADMIN_EMAILS set; SEED_DEMO off unless you want the published demo password live.RAZORPAY_KEY_ID + RAZORPAY_KEY_SECRET + webhook secret on /api/razorpay/webhook for order.paid. RAZORPAY_INTERNATIONAL=true for $10 outside India.ANTHROPIC_API_KEY.Doctor, nurse and other non-software titles search JSearch as those titles (not as “X engineer”). Scoring will not treat a software listing as a match for a physician profile.
Run exactly one instance. The scheduler and rate limiter live in process, so a second instance would
double-hunt and halve the rate limits. To scale out, disable the in-process scheduler and drive
POST /api/cron/hunt (Bearer CRON_SECRET) from an external scheduler instead.
The demo account is not created in production unless SEED_DEMO=true; its password is published in this
repo, so treat any instance that enables it as public.
Public pages (/, /pricing, /terms, /privacy, /refunds, /contact) are listed in src/lib/site.ts with their
last-modified dates; that list feeds /sitemap.xml, canonical URLs and the structured data. Each public page passes its own
description to pageMetadata(). Login, sign-up, password resets, onboarding and everything behind login send noindex,
and /robots.txt (src/app/robots.ts) disallows them and /api/. htmlLimitedBots in next.config.ts makes Next put the
title, description and canonical in <head> for every user agent instead of streaming them into <body>. When you add a
public page, add it to PUBLIC_PAGES and link it from SiteFooter; when you change a public page's text, bump its
lastModified. To verify the site in Google Search Console with an HTML tag, set GOOGLE_SITE_VERIFICATION.
opportunities.category and search_profiles.category default to job. The agent, scoring and UI are category-agnostic apart from job-specific fields, so freelance/scholarship/grant sources can be added as new adapters later.