Back to work

Recruitment operations · production-oriented system

Enterprise Hiring Automation

An Azure-backed recruitment operations platform that converts inconsistent Outlook requirements into structured roles, ranked candidate shortlists, controlled replies, and a recoverable processing history.

Product engineerLive private deployment

The production workspace and repositories are private because the system handles recruitment operations and candidate information. Historical implementation details are described separately from current enabled behavior.

architectureMicrosoft Graph → parser → weighted matcher → controlled reply → audit state

385

recognized skill families

1,165

skill aliases in the later codebase

5 min

Azure Functions intake schedule

60%

skills weight in candidate scoring

The system

From operational problem to reliable workflow.

Problem

Staffing requirements arrived through forwarded messages, conversational threads, inconsistent separators, copied recipients, and attachments. Manual processing caused slow responses, repeated work, weak matching, and a real risk of duplicate replies after restarts.

Approach

The platform evolved through two Harshitha-owned repositories: a PostgreSQL/Fastify foundation and a later Azure-native Next.js iteration. It ingests Outlook mail through Microsoft Graph, classifies and parses requirements, ranks candidates with skill-heavy scoring, reconstructs recipients, sends controlled replies, and persists processing state.

Outcome

Recruiters receive a centralized operating pipeline with structured requirements, candidate visibility, controlled communication, authentication, scheduled intake, error handling, and safeguards for long-running enterprise use.

Architecture

System architecture

The platform automates a real recruitment-operations loop: monitor a shared Outlook mailbox, identify requirements among unrelated mail, normalize inconsistent content, rank an internal candidate pool, reconstruct the correct recipients, and send or stage a controlled response without replying twice. Harshitha's Git history shows sustained implementation work from the initial monorepo through the later Azure-native application.

Mailbox intake

Polls the shared Outlook mailbox, acquires delegated OAuth tokens, fetches full message bodies, and retains provider identifiers needed for processing and deduplication.

Microsoft Graph · delegated OAuth · Azure Functions timer

Classification and parsing

Rejects notifications and self-loops, detects requirements and follow-ups, strips HTML, identifies forwarded-message boundaries, and extracts role, skills, experience, location, budget, client, and priority.

TypeScript · section-aware parsing · 385 skills / 1,165 aliases

Candidate matching

Ranks eligible candidates with skills weighted above role, experience, location, and availability; applies thresholds so weak role-word overlap cannot dominate missing required skills.

60/15/10/5/10 weighted scoring · candidate pool

Response engine

Builds shortlist or clarification replies, handles original sender and forwarded recipients, applies CC policy, and supported candidate resume attachments during the system's evolution.

Microsoft Graph replies · HTML composition · attachment encoding

Processing state

Stores requirements, candidates, sent/skipped outcomes, message identifiers, reply status, sync state, and dashboard records so a restart can resume safely.

PostgreSQL with pooling · later Azure Cosmos DB

Enterprise operations

Secures polling and dashboard access, schedules intake, surfaces failures, manages secrets, and deploys repeatably across Azure services.

App Service · Functions · Entra ID · NextAuth v5 · Key Vault · structured logs

Execution model

End-to-end execution

  1. 01

    Poll Outlook

    A secured Azure Functions timer calls the poll endpoint every five minutes; the Graph adapter refreshes delegated credentials and requests unread mail.

  2. 02

    Retrieve and normalize the thread

    The service fetches the full body, removes HTML noise, recognizes forwards and conversational phrasing, and discards system notifications or messages that would create a self-reply loop.

  3. 03

    Classify and extract

    Requirement and follow-up classification runs before section-aware extraction normalizes title, client, required skills, experience, location, budget, priority, and sender context.

  4. 04

    Check processing identity

    Provider message IDs, unread state, normalized identifiers, and persisted reply state are checked so an already handled message cannot be sent again after a process restart.

  5. 05

    Rank candidates

    The matcher scores skills at 60%, role at 15%, experience at 10%, location at 5%, and availability at 10%, then applies overall and skill-overlap thresholds.

  6. 06

    Construct the response

    The response engine prepares candidate profiles or a missing-information prompt, restores the correct original sender and copied recipients, and historically supported attached resumes where configured.

  7. 07

    Persist before and after sending

    Intent, result, status, and errors are recorded so retries and restart recovery can distinguish unsent, skipped, failed, and completed messages.

  8. 08

    Expose operations state

    Authenticated dashboard views show requirements, candidates, categories, sent responses, and failure states for manual follow-through.

Implementation

What Harshitha implemented

  • Replaced earlier IMAP and webhook experiments with Microsoft Graph inbox intake and hardened full-message retrieval for an Outlook mailbox.
  • Implemented HTML cleanup, forwarded-email detection, conversational/free-form parsing, separator normalization, explicit client and priority extraction, and system-notification filtering.
  • Expanded the later skills directory to 385 categorized skills with 1,165 aliases and fixed false SAP classification caused by overly broad token matching.
  • Changed candidate ranking to prioritize required-skill overlap over generic title words, using a 60% skills, 15% role, 10% experience, 5% location, and 10% availability model.
  • Added duplicate-reply protection across unread filtering, Graph/provider identifiers, persisted processing state, and an explicit replied marker.
  • Added restart recovery for unprocessed mail, shared PostgreSQL connection pooling in the first production implementation, retry/timeout/result checks, and date guards.
  • Implemented original-sender reconstruction, vendor and employee CC behavior, self-loop prevention, and safe validation for outbound recipients.
  • Implemented candidate resume attachments and automatic schema migration in the first repository; a later iteration removed PDF resume infrastructure, so this is historical implementation work rather than a current-state claim.
  • Migrated deployment through Azure PostgreSQL and standalone App Service toward an Azure-native stack using Cosmos DB, Azure Functions, Entra ID/NextAuth, Key Vault access, and reproducible lockfiles.
  • Added unit coverage for classification, parsing, matching, and auto-reply behavior, plus dashboard resilience and production error handling in the later application.

Contribution summary

  • Migrated inbound mailbox processing to Microsoft Graph and implemented full-message retrieval for forwarded and conversational threads.
  • Built section-aware requirement extraction and expanded recognition to 385 skills with 1,165 aliases in the later production codebase.
  • Improved candidate matching so required skills dominate generic role-word overlap, with explicit experience, location, and availability signals.
  • Implemented layered duplicate-reply prevention, persisted replied state, restart recovery, connection pooling, retries, timeouts, date guards, and result checking.
  • Implemented resume attachments during the system's evolution and repaired original-sender, forwarder, CC, and self-reply-loop behavior.
  • Built Azure deployment paths spanning App Service, Azure Functions timer polling, Cosmos DB in the later iteration, Entra ID/NextAuth, and Key Vault-backed secrets.

Failure design

Reliability engineering

R01

Risk

The process restarts after reading a message but before completing a reply.

Control

Persisted processing and replied state plus restart recovery distinguish work that still needs action from mail that has already produced a response.

R02

Risk

The same thread is fetched again and receives a duplicate response.

Control

Unread filtering, provider identifiers, normalized identity checks, and persisted reply state form layered duplicate-reply prevention.

R03

Risk

Forwarded mail sends a response to the wrong person or back to the monitored mailbox.

Control

Forward-boundary parsing, original-sender recovery, recipient validation, CC reconstruction, and self-loop detection run before sending.

R04

Risk

Generic role words rank technically unsuitable candidates.

Control

Skills carry the largest weight, skill-overlap thresholds gate inclusion, and the expanded alias directory normalizes equivalent technologies.

R05

Risk

Scheduled polling exhausts database connections or hangs on a provider call.

Control

The first implementation shares a PostgreSQL pool; provider operations use retry, timeout, result checking, and guarded scheduling.

R06

Risk

Deployment configuration or secrets are exposed to the client.

Control

Entra ID protects dashboard access, a poll API key protects scheduled intake, and provider credentials are held in Azure Key Vault/server configuration.

Tradeoffs

Technical decisions

Move mailbox intake to Microsoft Graph

Graph fits the Outlook environment, exposes stable message identity and reply semantics, and avoids keeping a fragile IMAP loop inside the Azure API process.

Weight skills above titles

Recruitment requirements frequently use broad titles; hard technical requirements are a stronger signal of actual candidate fit.

Persist processing state before trusting mailbox flags

Unread state alone does not survive every partial failure. Application state is needed to make restart and duplicate behavior explicit.

Separate scheduled triggers from the web process

Azure Functions can initiate polling on a fixed cadence without a self-restarting loop competing with the production application lifecycle.

Credibility

Evidence and scope

Harshitha-authored repository history

The private Git history records sustained work across the Microsoft Graph migration, extraction, matching, deduplication, restart recovery, pooling, forwarding, resume attachments, tests, and Azure deployment—not a single cosmetic commit.

Live authenticated platform

The current login surface is publicly reachable while operational data and source remain private.

Attribution boundary

The hiring case study is directly supported by Harshitha's sustained Git authorship across the private `esg-ai-automation` and `email-auto` repositories. The system changed architecture during development; PostgreSQL pooling and resume attachments are verified implementation work from the earlier stage, while Cosmos DB, Azure Functions, Entra ID, and Key Vault describe the later production iteration.

Technology

TypeScriptNext.jsFastifyMicrosoft GraphPostgreSQLAzure Cosmos DBAzure App ServiceAzure FunctionsMicrosoft Entra IDAzure Key VaultVitest