Skip to content

Latest commit

Β 

History

18 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ” KAIRO

An intelligent, real-time job monitoring platform that scrapes career pages and delivers instant Telegram alerts β€” so you never miss a job opening again.

Next.js TypeScript Supabase Python Telegram


πŸ“– What is KAIRO?

KAIRO is a full-stack job monitoring system built for job seekers who want to stay ahead. You add the career pages of companies you want to watch, and KAIRO automatically scrapes those pages in the background. The moment a new job link appears β€” matching roles like Software Engineer, Data Analyst, MTO, Management Trainee, or Corporate Officer β€” you instantly receive a notification directly in your personal Telegram account.

No more manually refreshing career pages. No more missing deadlines. KAIRO watches for you.


πŸ—οΈ Architecture Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     USER BROWSER                         β”‚
β”‚         Next.js Dashboard (localhost:3000)               β”‚
β”‚   Sign Up β†’ Add URLs β†’ Connect Telegram β†’ Done!         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚ Prisma ORM
                   β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              Supabase (PostgreSQL Cloud DB)              β”‚
β”‚   Tables: User, TrackedJobPage, JobListing              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚ psycopg2 (direct connection)
                   β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              Python Scraper (scraper/main.py)           β”‚
β”‚   Reads URLs β†’ Scrapes HTML β†’ Deduplicates β†’ Inserts    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚ Telegram Bot API
                   β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  Your Telegram Phone                     β”‚
β”‚           "🚨 NEW JOB FOUND β€” Apply Here β†’"            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ› οΈ Tech Stack

Layer Technology Purpose
Frontend Next.js 16, React 19 Dashboard UI, App Router
Styling Tailwind CSS 4 Utility-first styles
UI Components shadcn/ui, Radix UI Pre-built accessible components
Animations Framer Motion Smooth page transitions & effects
Icons Lucide React Consistent icon set
Database Supabase (PostgreSQL) Cloud-hosted relational database
ORM Prisma 5 Type-safe DB access for Next.js
Auth Custom JWT (jose) Signed session cookies
Password Hashing bcryptjs Secure credential storage
Scraping Python + BeautifulSoup 4 HTML parsing engine
HTTP Client Python requests Fetches career page HTML
Next.js Scraping cheerio Server-side HTML parsing in API
Notifications Telegram Bot API Instant push notifications
Env Management python-dotenv Secure credential loading

πŸ“ Project Structure

KAIRO/
β”œβ”€β”€ app/                          # Next.js App Router
β”‚   β”œβ”€β”€ page.tsx                  # Landing page
β”‚   β”œβ”€β”€ layout.tsx                # Root layout
β”‚   β”œβ”€β”€ globals.css               # Global styles
β”‚   β”œβ”€β”€ login/page.tsx            # Login page
β”‚   β”œβ”€β”€ signup/page.tsx           # Sign up page
β”‚   β”œβ”€β”€ api/
β”‚   β”‚   β”œβ”€β”€ auth/
β”‚   β”‚   β”‚   β”œβ”€β”€ signin/route.ts   # POST: authenticate user
β”‚   β”‚   β”‚   └── signup/route.ts   # POST: register user
β”‚   β”‚   β”œβ”€β”€ scrape/route.ts       # POST: trigger scraping for logged-in user
β”‚   β”‚   └── user/
β”‚   β”‚       └── telegram/route.ts # GET/POST: user's Telegram Chat ID
β”‚   └── dashboard/
β”‚       β”œβ”€β”€ page.tsx              # Main dashboard overview
β”‚       β”œβ”€β”€ layout.tsx            # Dashboard shell
β”‚       β”œβ”€β”€ jobs/page.tsx         # Tracked job listings
β”‚       β”œβ”€β”€ notifications/page.tsx# Notification history
β”‚       β”œβ”€β”€ preferences/page.tsx  # User preferences
β”‚       β”œβ”€β”€ telegram/page.tsx     # Telegram bot connection
β”‚       └── urls/page.tsx         # URL tracker management
β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ dashboard/
β”‚   β”‚   β”œβ”€β”€ header.tsx            # Dashboard top bar
β”‚   β”‚   β”œβ”€β”€ sidebar.tsx           # Navigation sidebar
β”‚   β”‚   β”œβ”€β”€ url-tracker.tsx       # URL management UI
β”‚   β”‚   β”œβ”€β”€ dashboard-client.tsx  # Client-side dashboard
β”‚   β”‚   β”œβ”€β”€ job-card.tsx          # Individual job display
β”‚   β”‚   β”œβ”€β”€ activity-feed.tsx     # Recent activity log
β”‚   β”‚   └── stats-card.tsx        # Summary stat cards
β”‚   └── ui/                       # shadcn/ui component library (57 components)
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ db.ts                     # Prisma client singleton
β”‚   β”œβ”€β”€ session.ts                # JWT session helpers
β”‚   β”œβ”€β”€ telegram.ts               # sendJobAlert() utility
β”‚   └── utils.ts                  # General utilities
β”œβ”€β”€ prisma/
β”‚   └── schema.prisma             # Database schema (3 models)
β”œβ”€β”€ scraper/
β”‚   β”œβ”€β”€ main.py                   # Python scraping engine
β”‚   └── requirements.txt          # Python dependencies
β”œβ”€β”€ middleware.ts                  # Route protection (auth guard)
β”œβ”€β”€ .env                          # Environment variables (git-ignored)
β”œβ”€β”€ README.md                     # This file
└── instructions.md               # AI coding SOPs

πŸ—„οΈ Database Schema

model User {
  id             String           @id @default(cuid())
  email          String           @unique
  passwordHash   String
  telegramChatId String?          // User's personal Telegram ID
  trackedPages   TrackedJobPage[]
  createdAt      DateTime         @default(now())
}

model TrackedJobPage {
  id          String       @id @default(cuid())
  url         String       // e.g. https://careers.brac.net
  companyName String
  lastScraped DateTime?
  userId      String
  user        User         @relation(...)
  jobs        JobListing[]
  createdAt   DateTime     @default(now())
}

model JobListing {
  id            String         @id @default(cuid())
  title         String         // e.g. "Senior Data Analyst"
  url           String         @unique
  trackedPageId String
  trackedPage   TrackedJobPage @relation(...)
  createdAt     DateTime       @default(now())
}

πŸš€ Getting Started

Prerequisites

  • Node.js 18+
  • Python 3.10+
  • A Supabase account (free tier works)
  • A Telegram account

1. Clone & Install

git clone https://github.com/ridhwankhan/JobPulse.git
cd JobPulse
npm install

2. Configure Environment Variables

Create a .env file in the root directory:

# Supabase / PostgreSQL
DATABASE_URL="postgresql://postgres:yourpassword@db.yourproject.supabase.co:5432/postgres"
DIRECT_URL="postgresql://postgres:yourpassword@db.yourproject.supabase.co:5432/postgres"

# Supabase Public Keys
NEXT_PUBLIC_SUPABASE_URL=https://yourproject.supabase.co
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=sb_publishable_...

# JWT Auth
JWT_SECRET=your_random_secret_here
NEXTAUTH_SECRET=your_random_secret_here
NEXTAUTH_URL=http://localhost:3000

# Telegram Bot
TELEGRAM_BOT_TOKEN="your_bot_token"

# Secure scheduled scraping (required for /api/cron/scrape)
CRON_SECRET="a_long_random_secret_value"

# Admin account email (required)
ADMIN_EMAIL="admin@example.com"

# SMTP for admin messaging (optional but recommended)
SMTP_HOST="smtp.gmail.com"
SMTP_PORT="587"
SMTP_SECURE="false"
SMTP_USER="your-email@gmail.com"
SMTP_PASS="your-app-password"
SMTP_FROM="KAIRO <your-email@gmail.com>"

⚠️ Special Character Warning: If your database password contains #, encode it as %23 in the URL (e.g., password123# β†’ password123%23).

3. Push Database Schema

npx prisma db push

4. Install Python Dependencies

cd scraper
pip install -r requirements.txt
cd ..

5. Run the Frontend

npm run dev

Open http://localhost:3000

5.1 Optional: Trigger Scheduled Scrape Locally

curl -H "Authorization: Bearer $CRON_SECRET" http://localhost:3000/api/cron/scrape

On Windows PowerShell:

Invoke-WebRequest -Uri "http://localhost:3000/api/cron/scrape" -Headers @{ Authorization = "Bearer $env:CRON_SECRET" }

6. Run the Python Scraper

python scraper/main.py

⏱️ Auto Scrape (Daily on Free Plan)

KAIRO now includes a built-in cron endpoint: GET /api/cron/scrape.

  • Add CRON_SECRET in your deployment environment variables.
  • Keep vercel.json in the repo with:
    • path: /api/cron/scrape
    • schedule: 0 9 * * *
  • Vercel Hobby supports once-daily cron. This schedule runs once per day.
  • The route scrapes all users who have tracked pages and sends Telegram alerts to each user's own chat ID.
  • Admin account is prioritized first in scheduled scrape order.

Manual Scrape Cooldown

  • Normal users: manual scrape allowed once every 20 minutes.
  • Admin user: no manual scrape cooldown.

If you deploy on another platform, set any scheduler (cron/job runner) to call:

  • URL: https://<your-domain>/api/cron/scrape
  • Header: Authorization: Bearer <CRON_SECRET>

πŸ” Account Recovery + Admin Features

  • Signup now collects two user-defined recovery prompts + answers.
  • Forgot password uses those saved recovery prompts:
    • POST /api/auth/request-password-reset-otp
    • POST /api/auth/verify-password-reset-otp
  • Account deletion now requires:
    • current password
    • typing DELETE confirmation text
  • Admin dashboard:
    • URL: /dashboard/admin
    • Access is restricted to ADMIN_EMAIL
    • Controls:
      • Toggle signup open/maintenance
      • View user details
      • Ban/restrict users
      • Force reset user password
      • Send email or direct Telegram message to users (if linked)

πŸ”” Setting Up Telegram Alerts

Each user connects their own personal Telegram for alerts:

  1. Open Telegram β†’ Search @userinfobot β†’ Start chat β†’ Copy your numeric ID
  2. Open Telegram β†’ Search your bot (e.g. @Kairo_Job_bot) β†’ Click Start
  3. Go to your KAIRO Dashboard β†’ Telegram page
  4. Click Connect Telegram β†’ Paste your Chat ID β†’ Click Save & Connect

βœ… From now on, every new job found for your tracked URLs will ping YOUR Telegram instantly.


πŸ” How the Scraper Works

The Python scraper (scraper/main.py) runs these steps:

  1. Fetch: Reads all TrackedJobPage URLs and their owners' telegramChatId from Supabase.
  2. Scrape: Downloads each page's HTML using requests with a real browser User-Agent.
  3. Parse: Uses BeautifulSoup to extract all <a> tags.
  4. Filter: Keeps only links that:
    • Contain job-role keywords (engineer, manager, mto, data analyst, etc.)
    • Are NOT generic navigation phrases (learn more, seminar, login, etc.)
    • Are NOT anchor (#) or JavaScript links
  5. Deduplicate: Checks if the job URL already exists in JobListing.
  6. Alert: If it's new β†’ inserts into DB β†’ sends Telegram message to the user.
  7. Cleanup: Deletes job listings older than 10 days to keep the database lean.

Job Keywords Detected

engineer, developer, manager, mto, management trainee, data analyst, data scientist, corporate, associate, specialist, director, officer, executive, lead, coordinator


πŸ“‘ API Reference

Method Endpoint Description Auth
POST /api/auth/signup Direct signup with recovery prompts + answers ❌
POST /api/auth/request-password-reset-otp Load saved recovery prompts for email ❌
POST /api/auth/verify-password-reset-otp Verify prompt answers and reset password ❌
POST /api/auth/signin Login, sets session cookie ❌
DELETE /api/user/account Delete account (requires password + DELETE) βœ…
POST /api/scrape Scrape all user's URLs, send alerts βœ…
GET /api/user/telegram Get current user's Telegram Chat ID βœ…
POST /api/user/telegram Save user's Telegram Chat ID βœ…
GET /api/admin/users List users for admin dashboard βœ… Admin
POST /api/admin/users/status Ban/restrict user βœ… Admin
POST /api/admin/users/force-reset-password Admin force reset user password βœ… Admin
POST /api/admin/message Admin send email/Telegram to users βœ… Admin

πŸ—ΊοΈ Roadmap β€” Upcoming Features

πŸ”œ Version 1.1 β€” Stability & UX

  • Auto-Scrape Scheduler: Windows Task Scheduler / cron job guide to auto-run Python scraper daily
  • Scrape from Dashboard: "Scrape Now" button on the URL Tracker page calls /api/scrape
  • Real-time Job Feed: Dashboard Jobs page shows live data from Supabase instead of mock data
  • Pagination: Add pagination to job listings for users with many tracked URLs
  • Toast Notifications: In-app browser toasts when a new scrape completes

πŸ”œ Version 1.2 β€” Multi-User Polish

  • User-specific keyword filters: Each user can set custom keywords beyond the defaults
  • Company logos: Auto-fetch favicon/logo for each tracked company
  • Notification history: Store and display the last 30 Telegram alerts per user
  • Email digest: Daily email summary of new jobs found (optional alternative to Telegram)

πŸ”œ Version 2.0 β€” Intelligence Layer

  • AI Job Matching: Use a lightweight LLM to score job relevance against the user's profile/resume
  • Resume upload: Users can upload a PDF resume; the AI uses it to filter which jobs are actually relevant
  • Duplicate title detection: Fuzzy match job titles to prevent near-duplicate alerts
  • LinkedIn / Bdjobs integration: Native API connectors for major job boards
  • Browser extension: Chrome extension to add any page as a tracked URL in one click

πŸ”œ Version 2.1 β€” Analytics

  • Job trend charts: Track how many new jobs were found per company per week
  • Application tracker: Mark jobs as Applied / Interviewing / Rejected
  • Best time to apply: Analytics on when companies post new jobs (by day/hour)

πŸ”œ Version 3.0 β€” SaaS & Deployment

  • Vercel deployment: One-click deploy with environment variable guide
  • Subscription tiers: Free (5 tracked URLs), Pro (unlimited + AI matching)
  • Team accounts: Share a tracked URL list with a study group or team
  • Admin dashboard: Monitor all users, scraping health, and system metrics

πŸ”’ Security Notes

  • Passwords are hashed with bcrypt (10 salt rounds) β€” never stored in plain text.
  • Sessions use signed JWT tokens (HS256) stored in httpOnly cookies.
  • All dashboard routes are protected by middleware.ts β€” unauthenticated requests are redirected.
  • Recovery answers are hashed before storage and never exposed as plain text.
  • Accounts can be banned/restricted from admin dashboard.
  • Basic per-IP API rate limiting is enabled in middleware to reduce abuse/spam bursts.
  • .env and other local secret files are git-ignored β€” never commit credentials.
  • Supabase connection string is kept server-side only (not exposed to the browser).

Sensitive Data Safety Checklist

Before pushing to GitHub:

  1. Confirm .env is not tracked:
    • git status --short .env
  2. Verify no hardcoded secrets in code:
    • rg "postgresql://|TELEGRAM_BOT_TOKEN|SMTP_PASS|JWT_SECRET|sb_publishable_" .
  3. Use env variables for all runtime secrets:
    • DB, JWT, Telegram bot token, SMTP, admin email, cron secret.

πŸ“œ License

MIT License β€” feel free to fork, modify, and use this project.


Built with ❀️ to help job seekers in Bangladesh and beyond never miss an opportunity.

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages