Skip to content

venomyzer/f1-race-report

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

19 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

F1 Race Report Tool

🏎️ F1 Race Report Tool

AI-powered Formula 1 race analysis Β· Live charts Β· Journalist-style reports

Live Demo Backend Frontend Database License


ko-fi


Home Page


⚑ What is this?

Select any Formula 1 race from 1950 to 2026, and get an instant AI-generated race report written like a professional journalist β€” complete with lap charts, podium display, full results table, and championship standings.

Powered by:

  • 🏁 Jolpica F1 API β€” race data, lap times, standings
  • πŸ€– Groq AI (llama-3.3-70b-versatile) β€” journalist-style race reports
  • πŸ—„οΈ Neon PostgreSQL β€” persistent storage for races and reports

πŸ“Έ Screenshots

πŸ† Podium & Race Summary

Results Top

πŸ“‹ Full Race Results Table

Results Table

πŸ“ˆ Lap-by-Lap Position Tracker

Lap Chart

πŸ… Championship Standings

Standings Chart

πŸ€– AI Race Report

AI Report

πŸ“ Report History

Reports Page


🧠 Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        MONOREPO                             β”‚
β”‚                   f1-race-report/                           β”‚
β”‚              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                        β”‚
β”‚              β”‚ frontend β”‚ backend  β”‚                        β”‚
β”‚              β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚          β”‚
          Vercel    β”‚          β”‚   Render
     β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          └──────────────
     React + Vite                Spring Boot
     Tailwind CSS                Java 21
     Recharts                    PostgreSQL (Neon)
          β”‚                           β”‚
          β”‚      HTTPS / JSON         β”‚
          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚          β”‚
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          └──────────┐
          β”‚                              β”‚
   Jolpica F1 API               Groq AI API
   (Race Data)              (Report Generation)

Request Flow

User selects race
      β”‚
      β–Ό
React (Vercel) ──GET /api/race-data──► Spring Boot (Render)
                                              β”‚
                                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                    β”‚                    β”‚
                              Check Neon DB         Jolpica API
                              (cached?)             (if not cached)
                                    β”‚                    β”‚
                                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                              β”‚
                                    Assemble RaceDataDTO
                                              β”‚
                                    β—„β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    Return to React
                                              β”‚
User clicks "Generate AI Report"              β”‚
      β”‚                                       β”‚
      β–Ό                                       β”‚
POST /api/generate-report                     β”‚
      β”‚                                       β”‚
      β–Ό                                       β”‚
  Groq AI ──────────────────────────────────► β”‚
  (llama-3.3-70b-versatile)                   β”‚
      β”‚                                       β”‚
  Report stored in Neon DB                    β”‚
      β”‚                                       β”‚
  Returned to React ◄──────────────────────── β”˜

πŸ› οΈ Tech Stack

Backend

Technology Purpose
Spring Boot 3.2.5 REST API framework
Java 21 Runtime
Gradle Build tool
Spring Data JPA + Hibernate ORM / Database layer
PostgreSQL (Neon) Cloud database
HikariCP Connection pooling
Caffeine Cache In-memory caching
OpenPDF PDF report export
Groq API AI text generation
Jolpica F1 API Race data source
Lombok Boilerplate reduction

Frontend

Technology Purpose
React 18 UI framework
Vite Build tool & dev server
Tailwind CSS Styling
Recharts Data visualisation
React Router v6 Client-side routing
Axios HTTP client
react-markdown AI report rendering
react-hot-toast Notifications
lucide-react Icons

πŸš€ Getting Started (Local)

Prerequisites

1. Clone the repo

git clone https://github.com/venomyzer/f1-race-report.git
cd f1-race-report

2. Backend setup

cd backend

# Copy and configure properties
cp src/main/resources/application.properties.example \
   src/main/resources/application.properties

# Edit with your values
nano src/main/resources/application.properties

Set these values:

spring.datasource.url=jdbc:postgresql://localhost:5432/f1reportdb
spring.datasource.username=your_pg_username
spring.datasource.password=your_pg_password
groq.api.key=gsk_your_groq_key_here
# Create the database
createdb f1reportdb

# Run the backend
./gradlew bootRun

Backend starts at http://localhost:8080

3. Frontend setup

cd frontend

# Install dependencies
npm install

# Configure environment
cp .env.example .env
# Edit .env β†’ set VITE_API_BASE_URL=http://localhost:8080

# Start dev server
npm run dev

Frontend starts at http://localhost:5173


🌐 API Reference

All responses follow this shape:

{
  "success": true,
  "message": "OK",
  "data": { ... },
  "statusCode": 200
}
Method Endpoint Description
GET /api/seasons All F1 seasons (1950–2026)
GET /api/races?season=2024 All races for a season
GET /api/race-data?season=2024&round=1 Full race data payload
POST /api/generate-report Generate AI race report
GET /api/reports Recent 10 reports
GET /api/reports/{id} Specific report by ID
GET /api/export-pdf/{id} Download report as PDF
GET /actuator/health Health check

Example: Generate a report

curl -X POST https://your-backend.onrender.com/api/generate-report \
  -H "Content-Type: application/json" \
  -d '{"season": 2024, "round": 1, "forceRegenerate": false}'

πŸ—„οΈ Database Schema

drivers        β†’ F1 driver profiles
races          β†’ Grand Prix events (season + round)
race_results   β†’ Per-driver finishing data (FK β†’ races, drivers)
reports        β†’ AI-generated race reports (TEXT)

πŸ’Ύ Caching Strategy

Cache TTL Reason
seasons 24 hours Changes once a year
races 6 hours Stable during season
raceResults 12 hours Immutable after race
lapData 12 hours Immutable after race
standings 6 hours Updates each race

🚒 Deployment

Service Platform URL
Frontend Vercel https://f1-race-report.vercel.app
Backend Render your-backend.onrender.com
Database Neon PostgreSQL (Singapore region)

Environment Variables

Backend (Render):

DB_URL=jdbc:postgresql://...
DB_USERNAME=...
DB_PASSWORD=...
GROQ_API_KEY=gsk_...
GROQ_MODEL=llama-3.3-70b-versatile
PORT=10000

Frontend (Vercel):

VITE_API_BASE_URL=https://your-backend.onrender.com

πŸ“ Project Structure

f1-race-report/
β”œβ”€β”€ backend/
β”‚   β”œβ”€β”€ src/main/java/com/f1report/
β”‚   β”‚   β”œβ”€β”€ config/          # CORS, Cache, RestTemplate
β”‚   β”‚   β”œβ”€β”€ controller/      # REST endpoints
β”‚   β”‚   β”œβ”€β”€ service/         # Business logic + AI + PDF
β”‚   β”‚   β”œβ”€β”€ repository/      # Spring Data JPA
β”‚   β”‚   β”œβ”€β”€ model/           # JPA entities
β”‚   β”‚   └── dto/             # Request/Response objects
β”‚   β”œβ”€β”€ build.gradle
β”‚   └── Dockerfile
β”‚
β”œβ”€β”€ frontend/
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ components/      # UI components
β”‚   β”‚   β”œβ”€β”€ pages/           # Route pages
β”‚   β”‚   β”œβ”€β”€ hooks/           # Custom React hooks
β”‚   β”‚   β”œβ”€β”€ services/        # Axios API layer
β”‚   β”‚   └── utils/           # Helpers, formatters
β”‚   β”œβ”€β”€ package.json
β”‚   └── vite.config.js
β”‚
└── README.md

⚠️ Known Limitations

  • Render free tier spins down after inactivity β€” first request may take ~50 seconds to wake up
  • Lap data not available for races before ~2012 (Ergast API limitation)
  • 2026 season races not yet completed (future rounds return no data)

πŸ™ Credits

  • Jolpica F1 API β€” The open-source successor to Ergast
  • Groq β€” Ultra-fast LLM inference
  • Neon β€” Serverless PostgreSQL

Built with ❀️ and too much coffee by venomyzer

ko-fi

GitHub Live

Not affiliated with Formula 1, the FIA, or any F1 team.

About

A backend system that processes large-scale Formula 1 race data from external APIs and uses LLMs to automatically generate natural-language race reports, transforming structured data into readable insights.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors