Skip to content

Feature: Hiring Pipeline (Stages + Kanban) with Scorecards & Email Notifications #1

Description

@hoangsonww

Feature: Hiring Pipeline (Stages + Kanban) with Scorecards & Email Notifications

Labels: feature frontend backend api ui/ux good first issue (subtasks)
Milestone: v0.2 (proposed)

Summary

Introduce a hiring pipeline so admins can move candidates through customizable stages (e.g., Applied → Phone Screen → Onsite → Offer → Hired/Rejected) using a drag-and-drop Kanban board. Each application gets a scorecard (structured feedback + rating), a timeline (stage history), and optional email notifications on stage changes. This builds on the current Jobs/Applications foundation.

Why

  • Today, applications are flat. A pipeline gives recruiters a clear view of status and velocity.
  • Scorecards standardize evaluations and reduce bias.
  • Notifications tighten candidate communication without leaving the app.

In Scope

  • Stage model + per-job stage presets.
  • Kanban for applications per job; search/filter (stage, rating, text).
  • Scorecard CRUD (per application).
  • Stage history timeline.
  • Email template triggers on stage changes (optional toggle per job).

Out of Scope (v1)

  • Calendar booking UI (can add ICS invites later).
  • Multi-org/tenant separation.
  • SSO / external HRIS sync.

Data Model (MongoDB / Mongoose)

Application (extend existing):

// backend/models/Application.js (additions)
{
  status: {
    type: String,
    enum: ['applied','phone_screen','onsite','offer','hired','rejected'],
    default: 'applied'
  },
  scorecard: {
    rating: { type: Number, min: 1, max: 5 },
    competencies: [{
      key: String,                 // e.g., "Communication"
      rating: { type: Number, min: 1, max: 5 },
      notes: String
    }],
    summary: String,               // overall feedback
    updatedAt: Date,
    updatedBy: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
  },
  stageHistory: [{
    from: String,
    to: String,
    changedAt: { type: Date, default: Date.now },
    changedBy: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
    note: String
  }]
}

Job (optional additions):

// backend/models/Job.js (additions)
{
  stages: {
    type: [String],
    default: ['applied','phone_screen','onsite','offer','hired','rejected']
  },
  emailTemplates: { // simple, optional
    phone_screen: { subject: String, body: String, enabled: Boolean },
    onsite:       { subject: String, body: String, enabled: Boolean },
    offer:        { subject: String, body: String, enabled: Boolean },
    rejected:     { subject: String, body: String, enabled: Boolean }
  }
}

API (Express)

# Applications
GET    /api/applications?jobId=&stage=&q=&minRating=
GET    /api/applications/:id
PATCH  /api/applications/:id/status         { to, note? }   // moves stage, appends stageHistory
PATCH  /api/applications/:id/scorecard      { rating, competencies[], summary }

# Jobs (for stage presets & templates)
GET    /api/jobs/:id/stages
PATCH  /api/jobs/:id/stages                 { stages[] }     // optional, to customize order/names
GET    /api/jobs/:id/email-templates
PATCH  /api/jobs/:id/email-templates        { ... }          // optional

# Notifications (optional server-side send)
POST   /api/applications/:id/notify         { templateKey, overrides? }

Notes

  • PATCH /status validates to ∈ job.stages and records history atomically.
  • If email templates enabled for the job + candidate has email, send via Nodemailer.

Frontend (React + MUI)

New Views

  • Pipeline Board /jobs/:jobId/pipeline

    • Columns = stages (ordered per job).
    • Cards = applications (name, role, tags, top skills, rating).
    • Drag & drop to move stages (fires PATCH /status).
    • Search bar + filters (stage, min rating, text).
  • Application Detail Drawer/Dialog

    • Tabs: Overview | Scorecard | Timeline
    • Scorecard: rating stars, competencies grid (configurable keys), free-text summary, Save.
    • Timeline: stage transitions with timestamp, who changed, optional notes.

Components

  • PipelineBoard (DND with @dnd-kit or react-beautiful-dnd)
  • ApplicationCard (compact)
  • ScorecardForm
  • TimelineList
  • EmailToggle (only if templates are configured)

Permissions & Security

  • Stage changes and scorecard edits are admin-only (or a new RECRUITER role).
  • Server validates allowed transitions; logs changedBy.
  • Rate-limit notification endpoint; sanitize template rendering (no raw HTML injection).

Acceptance Criteria

  • Drag a candidate card to another column → server updates status, adds stageHistory, UI refreshes without full reload.
  • Scorecard saves and persists (rating + competencies + summary) and displays last updated metadata.
  • Pipeline filters by stage and text; search matches candidate name or cover letter snippet.
  • If job templates enabled and stage changes to phone_screen, an email can be sent using the job’s template.
  • All new endpoints documented in README and return appropriate HTTP codes/errors.

Telemetry (optional)

  • Count moves per day per job, average time-in-stage.
  • Distribution of ratings by stage.

Task Breakdown

Backend

  • Extend Application schema (status, scorecard, stageHistory).
  • Add PATCH /applications/:id/status with validation + history append.
  • Add PATCH /applications/:id/scorecard.
  • Optional: job stages[] + emailTemplates fields and routes.
  • Wire Nodemailer (SMTP creds via env) for notifications.
  • Tests: unit for status transitions, scorecard persistence.

Frontend

  • Route /jobs/:jobId/pipeline.
  • Kanban board with DnD and optimistic UI.
  • Application detail drawer with Scorecard + Timeline tabs.
  • Filters (stage, text, min rating).
  • Optional: email send action (if templates enabled).

DevOps / Config

  • .env additions: SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS.
  • CI step for new backend tests.
  • Update README with pipeline screenshots/GIF.

Open Questions

  • Do we allow custom stage names per job by default? (Proposal: yes; provide sensible defaults.)
  • Minimal competency keys set? (e.g., Communication, Problem-Solving, Culture Add; make editable later.)
  • Should rejected candidates be hidden by default on the board? (Toggle “Show Rejected”.)

Small Follow-ups (separate issues)

  • Export pipeline to CSV (stage, days in stage, rating).
  • ICS invite generator for scheduled interviews.
  • Bulk actions (email, stage move).

Metadata

Metadata

Labels

documentationImprovements or additions to documentationenhancementNew feature or requestgood first issueGood for newcomershelp wantedExtra attention is neededquestionFurther information is requested

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions