Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

Job Application Tracker

A small full-stack web application for tracking job applications through four hiring stages: applied, interview, rejected, and offer.

Project description

The app gives a job seeker one place to add, review, search, filter, edit, and delete applications. The dashboard counts are calculated from the same SQLite data used by the application list, so updates are immediately reflected in the UI.

Architecture

React + Vite browser
        │ Fetch API / JSON
        ▼
FastAPI REST API ── Pydantic validation
        │
        ▼
SQLAlchemy ORM ── SQLite (backend/job_tracker.db)

The backend uses a simple module layout: routes live in app/main.py, persistence configuration in app/database.py, the table mapping in app/models.py, validation/response types in app/schemas.py, and database operations in app/crud.py. The frontend keeps the API client in src/api.js and uses focused React components for the dashboard, list, form, and details view.

Tech stack

  • Python 3.12+
  • FastAPI and Uvicorn
  • SQLAlchemy 2.0
  • SQLite
  • Pydantic 2
  • Pytest and FastAPI TestClient
  • React 18
  • Vite
  • Plain CSS
  • Browser Fetch API

Installation and setup

From the project root:

cd backend
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install -r requirements.txt

In a second terminal:

cd frontend
npm install

backend/job_tracker.db is created automatically the first time the API starts. It is ignored by Git so local application data stays local.

Run the backend

cd backend
source .venv/bin/activate
uvicorn app.main:app --reload --port 8000

API base URL: http://127.0.0.1:8000

Swagger UI: http://127.0.0.1:8000/docs

Run the frontend

cd frontend
npm run dev

Open http://127.0.0.1:5173. The frontend defaults to http://127.0.0.1:8000 for the API. To use another API URL, create frontend/.env with:

VITE_API_URL=http://localhost:8000

The backend accepts FRONTEND_URL as a comma-separated list if the frontend is hosted at a different origin.

Run tests and build checks

cd backend
source .venv/bin/activate
python3 -m pytest -q

cd ../frontend
npm run build

API endpoints

Method Endpoint Purpose Success
POST /applications Create an application 201
GET /applications List all applications 200
GET /applications/{id} Read one application 200 / 404
PATCH /applications/{id} Partially update an application 200 / 404
DELETE /applications/{id} Delete an application 204 / 404
GET /applications?status=interview Filter by status 200
GET /applications?search=google Search company or role 200
GET /stats Read dashboard counts 200
GET /health Check API availability 200

Allowed statuses are applied, interview, rejected, and offer. Required fields are company, role, status, and applied_date; salary and notes are optional.

Screenshots

The main dashboard includes statistic cards, a search field, a status filter, and the application list. The add/edit form and details view are available from the same interface. To capture local screenshots, run both services and use the browser's screenshot tool on http://127.0.0.1:5173.

Design decisions

  • SQLite was chosen because the application needs persistence but no database server or Docker setup.
  • SQLAlchemy keeps SQL concerns out of route functions and gives a clear ORM model for a fresher to explain.
  • Pydantic create, update, and response schemas keep validation explicit and prevent the API from exposing ORM internals accidentally.
  • PATCH is used for editing because the form can send a partial update and the backend applies only supplied fields.
  • Search uses a case-insensitive match over both company and role.
  • The frontend re-fetches applications and stats after every mutation. This keeps the browser state aligned with the real backend and makes persistence behavior obvious.
  • Authentication, permissions, background jobs, and external integrations are intentionally out of scope.

Future improvements

  • Add pagination when the application list becomes large.
  • Add an optional follow-up date and reminders.
  • Add database migrations with Alembic for schema evolution.
  • Add frontend component tests and end-to-end tests in CI.
  • Add an export-to-CSV action.

Verified user flow

The local browser verification exercised:

  1. Start FastAPI and Vite.
  2. Create an application.
  3. Confirm it appears in the list and increments dashboard stats.
  4. Edit it from the details view.
  5. Filter it to interview.
  6. Search it by company.
  7. Confirm the updated status and stats are returned by the API and shown by React.
  8. Delete it with the confirmation dialog.
  9. Reload/restart and confirm SQLite persistence.

About

A full-stack job application tracker built with FastAPI, SQLAlchemy, SQLite, React, and Vite.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages