Skip to content

Repository files navigation

Placement Portal

Campus placements, organised — one place for students, companies, and placement teams.

CI

Vue 3 Vite Bootstrap 5 Python 3.13 Flask 3 Celery Redis SQLite


Placement Portal landing page

A role-based placement management system for students, recruiting companies, and placement administrators. The application supports company and drive approval, student eligibility checks, application tracking, offer-letter delivery, CSV exports, deadline reminders, and monthly reports.

Features

For students

  • Browse drives matched to CGPA, branch (with abbreviation handling), and year of study
  • Apply with a single tap and track every application through shortlisting, interviews, offers, and placement
  • Skill tags, closing-soon deadline indicators, recruiter feedback, and CSV export of the full application history

For companies

  • Publish drives with packages, skills, benefits, and eligibility filters
  • Review applicants with resumes in hand and advance them through a clear hiring pipeline
  • Schedule interviews, attach offer letters, and export applications to CSV

For administrators

  • Approval queues for companies and drives with pending counts at a glance
  • Platform-wide statistics, application oversight with filtering, and account controls
  • Automatically generated monthly placement reports

Interface

  • An animated WebGL backdrop behind the whole application, loaded on demand and paused when off screen, in a backgrounded tab, or when the visitor prefers reduced motion
  • Translucent "liquid glass" navigation and cards layered over that backdrop, with counters that roll up and cards that light up under the cursor
  • Light and dark appearance, persisted per user and applied before first paint
  • Toast notifications, confirmation dialogs, skeleton loading states, and debounced search throughout
  • A shared design-token system layered over Bootstrap 5 color modes

Screenshots

Student dashboard

Eligibility at a glance, skill tags, closing-soon indicators, and one-tap applications.

Student dashboard

Admin control center

Platform statistics with pending approval queues for companies and drives.

Admin control center

Account creation

One registration flow for students and companies, with inline guidance.

Registration screen

Architecture

Browser
  |
  +-- Vue/Vite :5173
          |
          +-- /api proxy --> Flask :5001
                                |
                                +-- SQLite
                                +-- Redis (cache, broker, results)
                                +-- local uploads, exports, and reports
                                +-- SMTP through Flask-Mail

Celery worker <---- Redis ----> Celery Beat
  • Vue 3, Vue Router, Axios, Bootstrap 5, and Vite
  • three.js for the animated backdrop, code-split and imported on demand
  • Flask, Flask-SQLAlchemy, and Flask-JWT-Extended
  • SQLite for application data
  • Redis for response caching, Celery transport, and task results
  • Celery worker and Beat for exports, reminders, and reports
  • Flask-Mail for SMTP delivery

The frontend runs on port 5173 during development and proxies /api requests to Flask on port 5001. For the domain model, API inventory, runtime behavior, and known implementation constraints, see docs/engineering-guide.md.

Repository layout

backend/
  app.py             Flask application factory and HTTP routes
  models.py          SQLAlchemy models and development seed data
  tasks.py           Celery exports, reminders, and reporting jobs
  celery_app.py      Celery configuration and Beat schedule
  email_helper.py    Flask-Mail adapter
  wsgi.py            Gunicorn entry point
  seed_demo.py       Optional demo dataset for local screenshots
  tests/             Integration, authorization, and file-access suites
frontend/
  src/views/         Role-specific pages
  src/components/    Shared interface components and the WebGL backdrop
  src/utils/         API client, auth state, theming, and helpers
  src/assets/        Design tokens and theme overrides
  tests/             Vitest component, service, and router suites
scripts/
  api-smoke.sh       Curl smoke test against a running backend
.github/workflows/   Continuous integration pipeline
Dockerfile           Multi-stage production image
docker-compose.yml   Web, worker, Beat, and Redis stack
run.sh               Multi-process local launcher

Getting started

Prerequisites:

  • Python 3.13
  • uv
  • Node.js 20.19+ or 22.12+
  • Redis

Install dependencies:

cd backend
uv sync --locked

cd ../frontend
npm ci

Configure the environment. .env.example documents every supported setting:

cp .env.example backend/.env

Signing keys are never compiled into the source. Generate them with:

python -c "import secrets; print(secrets.token_urlsafe(32))"

With APP_ENV=production the application refuses to start unless FLASK_SECRET_KEY and JWT_SECRET_KEY are both set and at least 32 characters long. In any other environment a random per-process secret is generated and a warning is logged. Mail delivery is suppressed when MAIL_USERNAME is empty.

With Redis running, start all application services from the repository root:

./run.sh

run.sh writes backend/.env with freshly generated development secrets if the file does not exist yet.

Then open http://localhost:5173.

Use separate terminals when working on an individual service:

cd backend
uv run app.py
cd frontend
npm run dev -- --host 0.0.0.0
cd backend
uv run celery -A celery_app.celery worker --loglevel=info
cd backend
uv run celery -A celery_app.celery beat --loglevel=info

Running with Docker

The image compiles the single-page application, installs the locked Python environment, and serves both from Gunicorn as an unprivileged user. Compose adds Redis, a Celery worker, and Beat on the same image.

cp .env.example .env      # set APP_ENV=production and both secrets
docker compose up --build

The API and the compiled front end are served together on http://localhost:5001, with GET /api/health as the readiness probe. Application data, uploads, exports, and reports live in named volumes so they survive a rebuild.

Security model

  • Every protected route is authenticated with a bearer token and re-checks the caller's role in the backend. Browser route guards are convenience only.
  • Deactivating or removing an account invalidates its outstanding tokens on the next request.
  • Resumes are readable by the owning student, an administrator, and only those companies the student has actually applied to. Offer letters are readable by the recipient, the issuing company, and administrators. Monthly reports are administrator-only.
  • Stored files are resolved from the database record that references them, so a guessed or crafted filename grants nothing, and every path is confined to its upload directory.
  • Export ownership is recorded in the database when the job is queued. A task identifier is not a credential: only the requester and administrators can read a task's state or download its output.
  • Secrets are read from the environment with no fallback value in the source tree, and production start-up fails closed when they are missing.

Development accounts

First startup creates three local demo users:

Role Email Password
Admin admin@ppa.com root
Company testcompany@ppa.com test123
Student teststudent@ppa.com test123

These credentials are a development convenience. They must be removed or changed before the application is exposed outside a trusted local environment.

A richer demo dataset — companies, students, drives, and applications across the whole pipeline — can be added to a local database for demos and screenshots:

cd backend
uv run python seed_demo.py

All accounts created by the script share the password demo123.

Quality checks

Every push and pull request runs the same checks through GitHub Actions (.github/workflows/ci.yml): backend lint and tests under a coverage gate, the authorization and file-access boundaries as a dedicated job, a scan for committed secrets, frontend lint, build, and dependency audit, shell script analysis, and a container build that is booted and health-checked.

Backend lint and tests with the coverage gate:

cd backend
uv run ruff check .
uv run coverage run -m unittest discover -s tests -v
uv run coverage report

Frontend lint, tests, build, and audit:

cd frontend
npm run lint
npm run test:coverage
npm run build
npm audit --omit=dev

With the backend running, the curl-based smoke script exercises authentication, role boundaries, and the company approval gate end to end:

./scripts/api-smoke.sh

Project status

The backend suite covers registration, drive deadlines, eligibility, application-state transitions, role boundaries, tenant isolation, protected file access, and secret handling, held to a coverage floor on the request-handling path. The frontend is linted, built, and dependency-audited in CI. Notable changes are recorded in CHANGELOG.md; database migrations and pagination remain planned improvements — see the roadmap in the engineering guide.

About

placementPortalApplication - App dev 2 project - IIT Madras

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages