Finder is an open-source platform that analyzes candidate resumes, extracts structured career profiles, and recommends matching job opportunities through an interactive, chat-first workspace.
Unlike traditional job boards that require users to search through raw keyword listings, Finder acts as a personal AI career advisor. Candidates upload their resume (PDF), which the system analyzes using Groq-accelerated models (qwen/qwen3.8-27b, fallback openai/gpt-oss-20b). The platform identifies core strengths, detects skill gaps, curates matching active jobs via a resilient two-stage matching pipeline, and provides an interactive Career Copilot for technical interview preparation.
- Document Parsing & Text Extraction: Drag-and-drop PDF resume upload with magic bytes verification (
%PDF-), text extraction viapdf-parse, and storage in private Supabase buckets. - AI Candidate Profiling: Structured profile extraction powered by Groq (
qwen/qwen3.8-27b/ Prompt v2.7, fallbackopenai/gpt-oss-20b) into candidate skills, experience, education, and career level. - Two-Stage Job Matching Engine:
- Stage 1 (Deterministic): SQL skill-overlap pre-filter (limit 25) + weighted pre-ranking (Core: 2.0x, Supporting: 1.2x, General: 1.0x) to select the top 5 candidates.
- Stage 2 (Deterministic Re-score): Finder recomputes the final score deterministically from skill overlap and profile evidence, so the model never overrides the ranking.
- Conversational Career Copilot: Real-time multi-turn career consulting streaming via Server-Sent Events (SSE), pre-grounded with candidate strengths and active job requirements.
- Job Discovery & Detail Drawer: Curated job listings view with interactive match level, experience, and location filters, paired with an accessible WAI-ARIA detail drawer.
- Dual Authentication (Web2 + Web3):
- Standard email and password authentication with Supabase SSR session cookies.
- Cryptographic Sign-In with Sui (SIWS) personal message verification with in-memory challenge nonces and synthetic account abstraction.
- Sui Wallet linking and unlinking with unique address constraints.
- Automated External Job Ingestion: Scheduled job synchronization from Remotive API secured with timing-safe constant-time secret comparison.
| Layer | Technologies |
|---|---|
| Frontend Framework | Next.js 16 (App Router), React 19 |
| Styling & Components | Tailwind CSS 4, Base UI, Lucide React, Sonner |
| Backend & Runtime | Next.js Server & Edge Route Handlers, Node.js 22 |
| Database & Auth | Supabase (PostgreSQL 15+, Row Level Security, Auth SSR) |
| AI / LLM Acceleration | Groq SDK (qwen/qwen3.8-27b, fallback openai/gpt-oss-20b — Active Models) |
| Web3 Blockchain | @mysten/sui, @mysten/dapp-kit-react, @tanstack/react-query |
| Testing & Tooling | Vitest 5, ESLint 9, TypeScript 6 |
flowchart TD
subgraph Client ["Client Browser"]
UI["Next.js React 19 Frontend<br>(OmniPrompt, ChatTimeline, JobsView)"]
WalletKit["@mysten/dapp-kit-react<br>(Sui Wallet Connection)"]
SupabaseBrowser["@supabase/ssr Client<br>(Session State)"]
end
subgraph NextServer ["Next.js Server Runtime"]
Middleware["proxy.ts<br>(Auth Route Guard)"]
AuthRoutes["/api/auth/*<br>(Email Auth, SIWS Verifier, Wallet Link)"]
ChatRoutes["/api/chat/*<br>(SSE Message Stream, Sessions)"]
AnalysisRoutes["/api/upload-resume & /api/analyze<br>(PDF Parsing & Matching Orchestrator)"]
SyncRoute["/api/jobs/sync<br>(Remotive Ingestion & Timing-Safe Guard)"]
end
subgraph ExternalServices ["External Cloud Services"]
Supabase["Supabase Cloud<br>(PostgreSQL, Auth, RLS, Storage Bucket)"]
Groq["Groq Cloud API<br>(qwen/qwen3.8-27b / openai/gpt-oss-20b)"]
Remotive["Remotive Jobs API<br>(Remote Tech Jobs Feed)"]
SuiNetwork["Sui Network<br>(Testnet / Mainnet RPC)"]
end
UI --> Middleware
Middleware --> NextServer
UI --> AuthRoutes
UI --> ChatRoutes
UI --> AnalysisRoutes
WalletKit --> AuthRoutes
AuthRoutes --> Supabase
AuthRoutes --> SuiNetwork
ChatRoutes --> Supabase
ChatRoutes --> Groq
AnalysisRoutes --> Supabase
AnalysisRoutes --> Groq
SyncRoute --> Remotive
SyncRoute --> Supabase
- Node.js:
22.xor later. Verify with:node -v
- npm:
10.xor later. - Supabase Account: A Supabase project with PostgreSQL database and Storage.
- Groq API Key: Free API key from Groq Console. For active model choices, see Groq Supported Models.
git clone https://github.com/DafinCi/Finder.git
cd Finder
npm installCopy .env.example to .env.local:
cp .env.example .env.localFill in your configuration:
# Supabase
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
# Groq AI (Active models: https://console.groq.com/docs/models)
GROQ_API_KEY=gsk_your_groq_api_key
GROQ_MODEL=qwen/qwen3.8-27b
GROQ_FALLBACK_MODEL=openai/gpt-oss-20b
GROQ_MAX_TOKENS=2500
# Application Base URL
NEXT_PUBLIC_SITE_URL=http://localhost:3000
# Sui Web3 Network
NEXT_PUBLIC_SUI_NETWORK=mainnet
# Cron Sync Secret (optional in development)
CRON_SECRET=your_cron_secret- In your Supabase project dashboard, open the SQL Editor.
- Run
src/database/schema_v2.sqlto create all tables, indexes, and RLS policies. - Optional, for local demos only: run
src/database/seed-demo.sqlto add clearly marked sample companies and jobs. Skip this on production. - Run
src/database/triggerAuth.sqlto create the automated profile trigger. - In the Storage dashboard, create a private bucket named
resumes.
npm run devOpen http://localhost:3000 in your browser.
| Command | Purpose |
|---|---|
npm run dev |
Start Next.js development server on http://localhost:3000 |
npm run build |
Verify and build production bundle |
npm run start |
Start Next.js production server |
npm run lint |
Run ESLint code quality checks |
npx tsc --noEmit |
Execute static TypeScript type checking |
npm run test:unit |
Run hermetic unit tests |
npm run test:integration:mocked |
Run hermetic mocked integration tests |
npm run test:integration:live |
Run live Supabase integration tests (requires test DB) |
npm run test:coverage |
Run full test suite with V8 code coverage report |
Finder/
├── .github/
│ ├── workflows/ # GitHub Actions CI & Discord notification pipelines
│ └── ISSUE_TEMPLATE/ # Bug report and feature request templates
├── docs/ # Architectural, API, and database specifications
│ ├── architecture/ # System architecture & matching engine deep-dives
│ ├── api/ # API route handlers reference
│ ├── database/ # Schema ERD, RLS policies, and triggers
│ └── development/ # Setup and testing guides
├── src/
│ ├── app/ # Next.js App Router (Layouts, Pages, and API routes)
│ │ ├── (app)/ # Authenticated workspace routes (/, /c/[id], /jobs, /settings)
│ │ ├── (auth)/ # Auth routes (/login, /register)
│ │ └── api/ # 13 REST and SSE API route handlers
│ ├── components/ # Reusable UI widgets and application shell
│ ├── contexts/ # React context providers (Sidebar, etc.)
│ ├── database/ # SQL schemas, migration scripts, and auth triggers
│ ├── features/ # Feature-based domain slices
│ │ ├── ai-analysis/ # Resume extraction, orchestrator, summary cards
│ │ ├── auth/ # Email authentication hooks and forms
│ │ ├── chat/ # Timeline, omni-prompt, message dispatch, SSE parser
│ │ ├── jobs/ # Jobs view, filters, drawer, Remotive ingestion client
│ │ └── sui/ # Web3 wallet connection and SIWS linking cards
│ ├── lib/ # Infrastructure clients (Supabase, Groq, Sui, Rate Limiter)
│ ├── types/ # TypeScript interfaces (candidate, chat, database)
│ └── proxy.ts # Supabase SSR auth route guard middleware
└── test/ # 3-tier Vitest test suites
├── unit/ # Hermetic unit tests
├── integration/mocked/ # Hermetic mocked integration tests
├── integration/live/ # Live Supabase integration tests
└── mocks/ # In-memory Supabase and Groq mock adapters
Full index: docs/README.md.
- Architecture Overview
- System Architecture
- Domain Model
- Architecture Invariants
- Failure Semantics
- API Overview
- Database & RLS
- AI Agent Context
- Walrus & MemWal
- Local Setup
- Testing
- Coding Standards
- Change Map
- Design System
- Glossary
- Product Vision
- Roadmap
- Security Policy
- Resumes are stored privately in Supabase Storage and are never published to Walrus.
- Resume text is sent to Groq for extraction and matching. Groq is a third-party processor, so review your own compliance needs before real user data flows through it.
- Career memories live in Supabase and on Walrus through Walrus Memory. Walrus blobs are public by default, and Walrus Memory encrypts their contents with Seal so only the owner and authorized delegate keys can read them.
- The optional public career passport contains only skills, target roles, employment types, and career level. It excludes name, contact details, education, employers, salary, location, and account identifiers, and it publishes only after explicit confirmation.
- Forget hides a memory from chat recall and marks it forgotten in the database. It does not delete the encrypted blob already written to Walrus. Permanent blob deletion requires a separate deletion flow.
- Server logs record operational metadata such as IDs, model names, and durations. They are not intended to contain resume text, memory content, prompts, or credentials.
We welcome contributions! Please review our Contributing Guide and Code of Conduct before submitting pull requests.
This project is licensed under the MIT License.
