Skip to content

oluwatimilehinawoniyi/paladin-be

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

55 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Paladin - AI-Powered Job Application Assistant

A comprehensive backend system that streamlines job applications by leveraging AI to analyze CVs, generate tailored cover letters, and manage job application workflows with automated email submission.

Features

Core Functionality

  • OAuth2 Authentication - Secure Google OAuth2 integration with token management
  • Profile Management - Create and manage multiple professional profiles with CVs
  • CV Storage - Secure S3-based CV storage with upload, download, and deletion
  • AI Job Analysis - Claude AI integration for intelligent CV-job description matching
  • Smart Cover Letter Generation - AI-powered personalized cover letters
  • Automated Email Sending - Direct job application submission via Gmail API
  • Application Tracking - Track application status (SENT, INTERVIEW, REJECTED, ACCEPTED, FOLLOW_UP)

Technical Highlights

  • Spring Boot 3.x with modern Java practices
  • JPA/Hibernate for robust data management
  • AWS S3 integration for file storage
  • Anthropic Claude AI for intelligent analysis
  • Gmail API for automated email sending
  • Scheduled token refresh to maintain OAuth2 sessions
  • RESTful API design with comprehensive error handling

Resilience & Reliability Features

Built with production-grade resilience patterns to handle external service failures gracefully:

Async Processing

  • Non-blocking email sending with custom thread pool (5-10 threads)
  • Instant API responses while operations complete in background
  • Configurable queue capacity (50 tasks) for load management

Automatic Retry Logic

  • Gmail API: 3 retries with exponential backoff (2s → 4s → 8s)
  • Claude AI: 3 retries with exponential backoff (1s → 2s → 4s)
  • Intelligent exception classification (retry transient failures only)

Circuit Breakers (Resilience4j)

  • Gmail Service Circuit:
    • Opens after 50% failure rate (10 call sliding window)
    • 30s recovery wait period
    • Automatic half-open testing (3 calls)
  • Claude AI Service Circuit:
    • Opens after 60% failure rate (10 call sliding window)
    • 60s recovery wait period (AI services need more time)
    • Automatic half-open testing (2 calls)
  • Fast-fail when services are down (no wasted retries)
  • Automatic recovery detection

Production-Ready Fallbacks

  • Gmail Failures: Updates job application status to FAILED_TO_SEND
    • Users see failed applications in dashboard
    • Manual retry available when service recovers
    • No silent failures
  • AI Failures: Returns professional template cover letter
    • Users can still submit applications
    • Clear warning message about AI unavailability
    • Customizable template response

Monitoring & Observability

  • Circuit breaker health indicators via Spring Actuator
  • Real-time circuit state monitoring
  • Circuit breaker events tracking
  • Detailed metrics for failure rates and response times
  • Comprehensive logging

Status Tracking

Application statuses include:

  • SENT - Successfully delivered
  • FAILED_TO_SEND - Delivery failed (circuit open or retries exhausted)
  • INTERVIEW - Interview scheduled
  • REJECTED - Application rejected
  • ACCEPTED - Offer received
  • FOLLOW_UP - Awaiting response

Prerequisites

  • Java 17 or higher
  • Maven 3.6+
  • PostgreSQL (or your preferred database)
  • AWS Account (for S3)
  • Google Cloud Console project (for OAuth2 and Gmail API)
  • Anthropic API key (for Claude AI)

️ Installation & Setup

1. Clone the Repository

git clone https://github.com/oluwatimilehinawoniyi/paladin-be.git
cd paladin-be

2. Configure Environment Variables

Create application.yml in src/main/resources/:

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/paladin_db
    username: your_db_username
    password: your_db_password
    
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: ${GOOGLE_CLIENT_ID}
            client-secret: ${GOOGLE_CLIENT_SECRET}
            redirect-uri: "{baseUrl}/oauth2/callback/google"
            scope:
              - email
              - profile
              - https://www.googleapis.com/auth/gmail.send

  ai:
    anthropic:
      api-key: ${ANTHROPIC_API_KEY}
      chat:
        options:
          model: claude-sonnet-4-5-20250929

aws:
  access-key-id: ${AWS_ACCESS_KEY}
  secret-access-key: ${AWS_SECRET_KEY}
  s3:
    bucket-name: ${AWS_S3_BUCKET}
    region: ${AWS_REGION}

app:
  frontend:
    url: http://localhost:5173

3. Set Up Google OAuth2

  1. Go to Google Cloud Console
  2. Create a new project or select existing
  3. Enable Google+ API and Gmail API
  4. Create OAuth 2.0 credentials
  5. Add authorized redirect URIs:
    • http://localhost:8080/oauth2/callback/google
    • Your production URL

4. Set Up AWS S3

  1. Create an S3 bucket
  2. Configure CORS policy:
[
  {
    "AllowedHeaders": ["*"],
    "AllowedMethods": ["GET", "PUT", "POST", "DELETE"],
    "AllowedOrigins": ["*"],
    "ExposeHeaders": []
  }
]

5. Build & Run

# Build the project
mvn clean install

# Run the application
mvn spring-boot:run

The API will be available at http://localhost:8080

API Documentation

Authentication Endpoints

Login via Google

GET /oauth2/authorization/google

Get Current User

GET /api/auth/me

Logout

POST /api/auth/logout

Profile Management

Create Profile with CV

POST /api/v1/profiles
Content-Type: multipart/form-data

{
  "title": "Senior Software Engineer",
  "summary": "Experienced developer...",
  "skills": ["Java", "Spring Boot", "AWS"],
  "file": <CV_FILE>
}

Get User's Profiles

GET /api/v1/profiles/me

Get Profile by ID

GET /api/v1/profiles/{profileId}

Update Profile

PATCH /api/v1/profiles/{profileId}
Content-Type: application/json

{
  "title": "Updated Title",
  "summary": "Updated summary",
  "skills": ["New", "Skills"]
}

Delete Profile

DELETE /api/v1/profiles/{profileId}

CV Management

Upload CV

POST /api/v1/cv/upload
Content-Type: multipart/form-data

{
  "file": <CV_FILE>,
  "profileId": "uuid"
}

Download CV

GET /api/v1/cv/{cvId}/download

Update CV

PUT /api/v1/cv/{cvId}
Content-Type: multipart/form-data

{
  "file": <NEW_CV_FILE>
}

Delete CV

DELETE /api/v1/cv/{cvId}

Job Application

Analyze Job Application (AI-Powered)

POST /api/v1/job-applications/analyze-application
Content-Type: application/json

{
  "profileId": "uuid",
  "jobDescription": "Full job posting text..."
}

Response:

{
  "jobDetails": {
    "company": "Tech Corp",
    "position": "Senior Developer",
    "jobEmail": "hr@techcorp.com"
  },
  "coverLetter": "Dear Hiring Manager...",
  "matchAnalysis": {
    "overallMatchPercentage": 85,
    "strengths": ["Strong backend experience", "AWS expertise"],
    "gaps": ["Limited frontend experience"],
    "recommendation": "Highly recommended to apply",
    "confidenceLevel": "High"
  }
}

Send Job Application

POST /api/v1/job-applications/send
Content-Type: application/json

{
  "profileId": "uuid",
  "company": "Tech Corp",
  "jobTitle": "Senior Developer",
  "jobEmail": "hr@techcorp.com",
  "subject": "Application for Senior Developer",
  "bodyText": "Cover letter content..."
}

Get My Applications

GET /api/v1/job-applications/me

Update Application Status

PATCH /api/v1/job-applications/{applicationId}/status
Content-Type: application/json

"INTERVIEW"

Cover Letter Generation

Generate Cover Letter Template

GET /api/v1/cover-letters/generate/{category}?candidateName=John&companyName=TechCorp&position=Developer

Categories: professional, enthusiastic, results, conversational

User Management

Get Current User Details

GET /api/v1/users/me

Delete Account

DELETE /api/v1/users/me

This permanently deletes all user data including profiles, CVs, and applications

Monitoring & Health Checks

Check Application Health & Circuit Breaker Status

GET /actuator/health

Response:

{
  "status": "UP",
  "components": {
    "circuitBreakers": {
      "status": "UP",
      "details": {
        "gmailService": {
          "status": "UP",
          "state": "CLOSED",
          "failureRate": "0.0%",
          "slowCallRate": "0.0%",
          "bufferedCalls": 10,
          "failedCalls": 0
        },
        "claudeAIService": {
          "status": "UP",
          "state": "CLOSED",
          "failureRate": "0.0%",
          "slowCallRate": "0.0%",
          "bufferedCalls": 10,
          "failedCalls": 0
        }
      }
    },
    "db": {
      "status": "UP"
    }
  }
}

Circuit Breaker States:

  • CLOSED - Normal operation (service healthy) ✓
  • OPEN - Service failing, fast-failing requests ⊘
  • HALF_OPEN - Testing recovery after wait period
  • FORCED_OPEN - Manually disabled for maintenance

View Circuit Breaker Events

GET /actuator/circuitbreakerevents

Shows recent circuit breaker events including:

  • State transitions (CLOSED → OPEN → HALF_OPEN → CLOSED)
  • Success and failure events
  • Error details and timestamps

Example Response:

{
  "circuitBreakerEvents": [
    {
      "circuitBreakerName": "gmailService",
      "type": "SUCCESS",
      "creationTime": "2024-01-08T10:30:15.123Z"
    },
    {
      "circuitBreakerName": "claudeAIService",
      "type": "ERROR",
      "creationTime": "2024-01-08T10:31:20.456Z",
      "errorMessage": "Claude AI API call failed"
    }
  ]
}

View Detailed Metrics

GET /actuator/metrics/resilience4j.circuitbreaker.calls

Provides detailed metrics for circuit breaker calls:

  • Total calls
  • Successful calls
  • Failed calls
  • Call duration percentiles

Architecture

┌─────────────────┐
│   Frontend      │
│   (SvelteKit)   │
└────────┬────────┘
         │
         │ REST API
         │
┌────────▼───────────────────────────────────┐
│          Spring Boot Backend               │
│                                            │
│  ┌──────────────┐  ┌──────────────┐        │
│  │ Controllers  │  │   Services   │        │
│  └──────┬───────┘  └──────┬───────┘        │
│         │                 │                │
│  ┌──────▼─────────────────▼───────┐        │
│  │      Business Logic            │        │
│  │  - OAuth2 Management           │        │
│  │  - File Upload/Download        │        │
│  │  - AI Analysis                 │        │
│  │  - Email Automation            │        │
│  └──────┬─────────────────────────┘        │
│         │                                  │
│  ┌──────▼──────────┐  ┌─────────────┐      │
│  │   Repositories  │  │   Mappers   │      │
│  └──────┬──────────┘  └─────────────┘      │
└─────────┼──────────────────────────────────┘
          │
    ┌─────┴─────────────────────────┐
    │                               │
┌───▼────┐  ┌──────┐  ┌──────────┐ ┌▼─────┐
│   DB   │  │  S3  │  │ Gmail API│ │Claude│
└────────┘  └──────┘  └──────────┘ └──────┘

Security Features

  • OAuth2 Authentication with Google
  • Session Management with automatic token refresh
  • User Authorization - Users can only access their own data
  • Secure File Storage in AWS S3
  • CORS Configuration for frontend integration
  • CSRF Protection disabled for API-only backend
  • HTTPS Strict Transport Security headers

Database Schema

Users

  • OAuth2 user information
  • Token management (access token, refresh token, expiry)
  • Relationship to profiles

Profiles

  • Multiple profiles per user
  • Title, summary, skills
  • One-to-one relationship with CV

CVs

  • Stored in S3
  • Metadata in database (filename, URL, size, content type)

Job Applications

  • Track all applications
  • Status management
  • Linked to profiles

Deployment

Docker Deployment

FROM eclipse-temurin:17-jdk-alpine
WORKDIR /app
COPY target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
# Build
docker build -t paladin-be .

# Run
docker run -p 8080:8080 \
  -e GOOGLE_CLIENT_ID=your_client_id \
  -e GOOGLE_CLIENT_SECRET=your_secret \
  -e AWS_ACCESS_KEY=your_key \
  -e AWS_SECRET_KEY=your_secret \
  -e ANTHROPIC_API_KEY=your_key \
  paladin-backend

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/AmazingFeature)
  3. Commit changes (git commit -m 'Add AmazingFeature')
  4. Push to branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

Author

Your Name - Oluwatimilehin Awoniyi

About

A comprehensive backend system that streamlines job applications by leveraging AI to analyze CVs, generate tailored cover letters, managing multiple professional profiles each with its CV and manage job application workflows with automated email submission.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors