LaunchPad is a recruitment platform for two primary user groups:
- students who want to create a detailed professional profile, browse opportunities, apply for roles, and track application progress
- recruiters or companies who want to create a hiring presence, publish jobs, review incoming applications, and manage hiring workflow in one place
This repository contains the full web application, including:
- the Next.js frontend
- authenticated API routes
- the Supabase PostgreSQL schema and RLS policies
- seed scripts for demo data
- profile, job, and application management flows
This README is the single source of documentation for the repository. It is intentionally detailed so that someone opening the repository can understand the platform, architecture, database design, and implementation choices without needing a stack of separate markdown files.
LaunchPad was created by:
- Bharath K
- Karthik S Gowda
- Lakshith S Lokesh
This application was built as part of IBM training focused on designing and delivering practical web applications. The current repository represents a working recruitment platform output from that training, and it is intentionally structured so future batches or reviewers can understand, extend, and iterate on it.
LaunchPad supports a full student-to-recruiter hiring workflow:
- A user signs up as either a
studentor acompany. - Students complete a recruiter-friendly profile with academic, personal, and professional details.
- Recruiters configure a company identity and publish jobs.
- Students browse jobs and apply.
- Recruiters review applications and update statuses.
- Students track progress from their dashboard.
The platform is a general recruitment platform for students and recruiters.
Students can:
- create an account
- select an avatar during onboarding
- edit a detailed profile
- browse jobs
- apply to jobs
- track applications
Recruiters can:
- create an account
- configure a company profile
- post jobs
- view applicants
- update application statuses
Admins exist in the schema for future operational controls and settings.
Authentication is powered by Supabase Auth.
Supported methods:
- email/password signup
- email/password login
- Google OAuth
On signup:
- an auth user is created
- a
profilesrow is created - a role-specific row is created in
student_profilesorcompanies - the user is redirected to profile setup
On first Google login:
- the callback route exchanges the auth code for a session
- if the user does not already exist in
profiles, a profile row is created - a student profile row is also created
- the user is redirected to
/profile?welcome=1
The /profile page is the main editable profile surface.
Shared profile fields:
- full name
- avatar
- bio
Student profile fields:
- university
- major
- graduation year
- professional headline
- date of birth
- phone
- location
- current title
- current company
- years of experience
- experience summary
- project highlights
- certifications
- languages
- availability / notice period
- skills
- preferred job types
- expected salary min/max
- resume URL
- GitHub URL
- LinkedIn URL
- portfolio URL
- Twitter / X URL
- Instagram URL
- LeetCode URL
- Devfolio URL
Company profile fields:
- company name
- industry
- location
- website
- size
- description
- logo URL
Students browse jobs from /browse.
Current features:
- search
- location filtering
- job type filtering
- detail pages at
/browse/[jobId]
Students apply through POST /api/applications.
Recruiters manage applications from the company dashboard and update status through PATCH /api/applications/[applicationId].
Student dashboard:
- shows the student's applications
- reflects application status changes
Company dashboard:
- shows the company's job postings
- links to application review pages
- Next.js 16 App Router
- React 19
- TypeScript
- Tailwind CSS v4
- shadcn/ui
- Supabase Auth
- Supabase Postgres
- Next.js App Router gives a strong foundation for building a modern React application with both client and server boundaries in one repository.
- TypeScript improves maintainability and makes the data contract between UI, API routes, and Supabase much safer.
- Tailwind CSS and shadcn/ui help standardize spacing, form controls, cards, and interaction states across the application.
- Supabase reduces setup overhead by combining authentication, PostgreSQL, SQL migrations, and policy-based data access in one platform.
- PostgreSQL works well for relational hiring data because users, companies, jobs, and applications are naturally interconnected.
Located primarily in:
app/components/
Responsibilities:
- render pages
- collect user input
- orchestrate client flows
- call Supabase or API routes
Located in:
app/api/
Responsibilities:
- privileged reads and writes
- role verification
- token-based authorization for protected mutations
- response shaping for frontend consumption
Defined in:
scripts/init-db.sqltypes/database.tslib/supabase.ts
Responsibilities:
- table design
- enum definitions
- RLS policy setup
- indexing
- typed database access
The project uses a hybrid approach:
- direct client-side Supabase access for user-owned profile reads and writes
- API routes with service-role access for privileged operations such as listing enriched jobs, creating jobs, and application orchestration
This structure works well for a Supabase-backed App Router application because:
- RLS protects user-owned updates
- server routes can safely aggregate cross-table data
- sensitive mutations can verify access tokens on the server
app/
api/
applications/
auth/
jobs/
auth/
callback/
login/
signup/
browse/
[jobId]/
dashboard/
company/
student/
profile/
globals.css
layout.tsx
page.tsx
components/
app-logo.tsx
job-card.tsx
navbar.tsx
status-badge.tsx
ui/
lib/
avatar-presets.ts
supabase.ts
utils.ts
scripts/
init-db.sql
seed-demo.sql
types/
database.ts
The platform uses a Supabase-managed PostgreSQL database under the public schema.
Purpose:
- canonical application-level identity record for every authenticated user
Key columns:
id: foreign key toauth.users.idemailfull_nameroleavatar_urlbiocreated_atupdated_at
Purpose:
- stores student-specific information recruiters need during evaluation
Key columns:
iduniversitymajorgraduation_yearheadlinedate_of_birthphonelocationcurrent_titlecurrent_companyyears_of_experienceexperience_summaryproject_highlightscertificationslanguagesavailability_notice_periodskills(TEXT[])preferred_job_types(TEXT[])expected_salary_minexpected_salary_maxresume_urlgithub_urllinkedin_urlportfolio_urltwitter_urlinstagram_urlleetcode_urldevfolio_urlcreated_atupdated_at
The core relational structure is:
auth.users->profilesprofiles->student_profilesfor student usersprofiles->companies.admin_idfor recruiter userscompanies->jobsjobs->applicationsstudent_profiles->applicationsprofiles->notifications
In practical terms:
- every authenticated person first exists in Supabase Auth
- every authenticated person also gets a
profilesrow for application-level identity - a recruiter controls one company record through
companies.admin_id - a company can publish many jobs
- a student can apply to many jobs
- each application joins one student and one job
This structure makes recruiter dashboards possible because the application can trace:
recruiter -> company -> jobs -> applications -> student
It also makes student dashboards straightforward:
student -> applications -> jobs -> company
Purpose:
- stores recruiter-facing organization details
Key columns:
idnamelogo_urldescriptionwebsitelocationindustrysizeadmin_idcreated_atupdated_at
Purpose:
- stores published job listings
Key columns:
idcompany_idtitledescriptionrequirementssalary_minsalary_maxjob_typelocationstatusdeadlinecreated_atupdated_at
Purpose:
- optional key/value extension table for additional job metadata
Key columns:
idjob_idkeyvaluecreated_at
Purpose:
- connects students to jobs and stores application lifecycle data
Key columns:
idjob_idstudent_idstatusresume_urlcover_lettercustom_responsecreated_atupdated_at
Constraint:
UNIQUE(job_id, student_id)ensures one application per student per job
Purpose:
- stores per-user notifications for workflow events
Key columns:
iduser_idtitlemessagetypereadcreated_at
Purpose:
- stores future platform-level configuration
Key columns:
idkeyvaluecreated_atupdated_at
RLS is enabled across the main tables.
Current intent:
- users can update their own
profilesrow - students can update their own
student_profilesrow - recruiter admins can update their own
companiesrow - only company admins can create and modify jobs for their company
- students can insert and read their own applications
- recruiters can read applications for their own jobs
RLS is important in this project because the frontend talks directly to Supabase for some profile operations. Policies help ensure that even if a malicious client tries to craft a manual request, they still cannot freely write to another user's row.
LaunchPad does not store raw passwords in the public schema.
For email and password authentication:
- credentials are managed by Supabase Auth
- password material is stored as a hash in the managed
auth.usersschema - application tables such as
profiles,student_profiles, andcompaniesdo not contain plaintext passwords
This is an important separation of responsibility:
- Supabase Auth handles identity and session security
- the
publicschema handles product data
The demo seed script inserts auth users for local or evaluation convenience, but even there the password is inserted in hashed form using PostgreSQL cryptographic helpers rather than as raw plaintext in an application table.
Google sign-in is implemented through Supabase OAuth.
High-level flow:
- The user chooses Google sign-in from the frontend.
- Supabase redirects the user to Google's consent screen.
- After Google authentication, the browser returns to the application callback route.
- The callback route exchanges the code for a Supabase session.
- The app ensures a
profilesrow exists. - If needed, it creates a matching
student_profilesrow for onboarding. - The user is redirected into the application, usually to
/profile?welcome=1.
This approach is simpler and safer than hand-rolling OAuth because session creation, token lifecycle, and provider integration are delegated to Supabase.
Creates:
- auth user
profilesrowstudent_profilesorcompaniesrow depending on role
Authenticates the user and returns session plus role information.
Supports:
- listing open jobs
- filtering by title
- filtering by location
- filtering by company
- fetching a single job by
jobId
Creates a job posting.
Security:
- verifies the caller's Supabase access token
- verifies the caller owns the company passed in the request
Returns application data enriched with related job, company, and student profile basics.
The response is intentionally enriched so recruiter screens can show:
- student identity
- academic background
- experience summary
- links such as GitHub, LinkedIn, portfolio, LeetCode, and other socials
- salary preference and availability context
Creates a new application if one does not already exist.
Updates application status.
Security:
- verifies the caller's Supabase access token
- verifies the caller owns the company related to the application's job
Demo data is provided in:
scripts/seed-demo.sql
The seed script creates:
- admin account
- recruiter accounts
- student accounts
- company records
- jobs
- applications
- notifications
The seeded student data is intentionally richer than a minimal demo. It includes academic information, professional context, social and portfolio links, compensation expectations, and summary fields so faculty and reviewers can inspect the full product experience.
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=pnpm installCreate .env.local with the required Supabase keys.
Run:
scripts/init-db.sql
Optional demo data:
scripts/seed-demo.sql
pnpm devpnpm buildNote:
- on this Windows environment, Next.js compilation succeeds but the process currently ends with a local
spawn EPERM - Vercel is the reliable production build environment
Implemented:
- auth
- avatar-based onboarding
- profile editing
- richer student profiles
- company profiles
- job browsing
- applications
- recruiter-side application management
Still worth improving:
- resume file uploads to Supabase Storage
- profile completion scoring
- recruiter analytics
- stronger automated test coverage
- more complete admin tooling
If you are new to the repository, start with:
README.mdscripts/init-db.sqlapp/profile/page.tsxapp/api/jobs/route.tsapp/api/applications/route.tsapp/api/auth/signup/route.ts
MIT