Some checks failed
Profile Linker Docker Build / Build and push Docker image (push) Failing after 3s
- Integrated Cloudflare R2 for template storage and converted file management - Added Google Gemini AI for resume parsing and HTML generation - Created backend API endpoints for templates, conversion, and history - Refactored frontend to use real API instead of mock data - Fixed Docker networking issues (IPv6/IPv4) for R2 connectivity - Added resumeService.ts for frontend API integration - Updated Vite configuration for proper asset serving in Docker - Successfully tested with 13 templates from R2 bucket
162 lines
6.9 KiB
Markdown
162 lines
6.9 KiB
Markdown
# Integration Complete! 🎉
|
|
|
|
## What We've Done:
|
|
|
|
### ✅ 1. Fixed Environment Variables
|
|
- Updated `.env` files with correct `APP_NAME=resumeformatter`
|
|
- Added Cloudflare R2 credentials to root `.env`
|
|
- Fixed frontend `.env` to use `VITE_APP_NAME=resumeformatter`
|
|
|
|
### ✅ 2. Added Backend Dependencies
|
|
Added to `requirements.txt`:
|
|
- `boto3==1.34.51` - AWS SDK (works with R2)
|
|
- `python-multipart==0.0.9` - For file uploads
|
|
- `google-generativeai==0.3.2` - Gemini AI SDK
|
|
|
|
### ✅ 3. Created R2 Service (`backend/app/services/r2_service.py`)
|
|
Functions:
|
|
- `list_templates()` - Get all templates from R2
|
|
- `get_template_content(name)` - Download template HTML
|
|
- `upload_converted_file()` - Upload HTML/PDF to R2
|
|
- `list_converted_resumes()` - Get conversion history
|
|
- `get_file_url()` - Generate presigned download URLs
|
|
|
|
### ✅ 4. Created AI Service (`backend/app/services/ai_service.py`)
|
|
Functions:
|
|
- `extract_text_from_resume()` - Extract text from PDF/DOCX using Gemini Vision
|
|
- `generate_html_from_template()` - Merge resume data into template using Gemini
|
|
|
|
### ✅ 5. Created Resume API Endpoints (`backend/app/api/endpoints/resumes.py`)
|
|
Endpoints:
|
|
- `GET /api/resumes/templates` - List available templates
|
|
- `GET /api/resumes/templates/{name}` - Get template content
|
|
- `POST /api/resumes/convert` - Convert resume (accepts file + template name)
|
|
- `GET /api/resumes/history` - Get conversion history
|
|
- `GET /api/resumes/download/{key}` - Get download URL
|
|
|
|
### ✅ 6. Updated Configuration
|
|
- Added R2 and Gemini settings to `backend/app/core/config.py`
|
|
- Updated `docker-compose.yml` to pass environment variables
|
|
- Registered resume endpoints in API router
|
|
|
|
## Next Steps:
|
|
|
|
### 🎯 Option 1: Test Docker Build (Recommended)
|
|
Since you don't have Node.js installed locally, use Docker:
|
|
|
|
```bash
|
|
# Build and run with Docker
|
|
docker-compose up --build
|
|
```
|
|
|
|
Then test at: http://localhost:8080/resumeformatter
|
|
|
|
### 🎯 Option 2: Update Frontend to Use Backend API
|
|
|
|
The frontend currently has mock R2 functions. We need to:
|
|
1. Create API service functions in frontend
|
|
2. Replace mock functions with real API calls
|
|
3. Remove AI logic from frontend (now handled by backend)
|
|
|
|
### 🎯 Option 3: Install Node.js for Local Development
|
|
|
|
If you want to develop locally:
|
|
```bash
|
|
# Install Node.js (macOS)
|
|
brew install node
|
|
|
|
# Then install frontend dependencies
|
|
cd frontend
|
|
npm install
|
|
```
|
|
|
|
## Architecture Summary:
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────┐
|
|
│ USER BROWSER │
|
|
│ http://localhost:8080 │
|
|
└──────────────────────┬──────────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────────────────────────┐
|
|
│ FRONTEND (React + Vite) │
|
|
│ - Upload resume file │
|
|
│ - Select template │
|
|
│ - Preview HTML │
|
|
│ - Download files │
|
|
└──────────────────────┬──────────────────────────────┘
|
|
│ API Calls
|
|
▼
|
|
┌─────────────────────────────────────────────────────┐
|
|
│ BACKEND (FastAPI + Python) │
|
|
│ │
|
|
│ ┌─────────────────────────────────────────┐ │
|
|
│ │ Resume Endpoints │ │
|
|
│ │ /api/resumes/* │ │
|
|
│ └──────────┬──────────────────────────────┘ │
|
|
│ │ │
|
|
│ ┌────────┴────────┐ │
|
|
│ ▼ ▼ │
|
|
│ ┌──────────┐ ┌──────────┐ │
|
|
│ │ R2 │ │ AI │ │
|
|
│ │ Service │ │ Service │ │
|
|
│ └──────────┘ └──────────┘ │
|
|
│ │ │ │
|
|
└───────┼────────────────┼────────────────────────────┘
|
|
│ │
|
|
▼ ▼
|
|
┌───────────────┐ ┌──────────────┐
|
|
│ Cloudflare R2 │ │ Gemini AI │
|
|
│ - Templates │ │ - Vision │
|
|
│ - Resumes │ │ - Text Gen │
|
|
└───────────────┘ └──────────────┘
|
|
```
|
|
|
|
## API Flow Example:
|
|
|
|
1. **User uploads resume.pdf + selects "Google" template**
|
|
2. **Frontend → POST /api/resumes/convert**
|
|
- Sends file + template_name
|
|
3. **Backend extracts text** → Gemini Vision API
|
|
4. **Backend fetches template** → R2 Storage
|
|
5. **Backend generates HTML** → Gemini Text API
|
|
6. **Backend uploads HTML** → R2 Storage
|
|
7. **Backend returns** → { html_content, html_url }
|
|
8. **Frontend displays preview** and allows download
|
|
|
|
## Environment Variables Reference:
|
|
|
|
```bash
|
|
# Root .env (for Docker)
|
|
APP_NAME=resumeformatter
|
|
GEMINI_API_KEY=AIzaSyB4Y9qrGynW3UNflYcQC-HGlJxOe_ty6VI
|
|
R2_ENDPOINT=https://cba4afd7666247724ece1f34e1aace6c.r2.cloudflarestorage.com
|
|
R2_ACCESS_KEY_ID=8f7244b0e7f9c8297a606af0073d4a5a
|
|
R2_SECRET_ACCESS_KEY=17845714ff4c2e5f33f09740112be47925d0fab93d27b26982964cd14808b60b
|
|
R2_BUCKET_NAME=e-teams
|
|
|
|
# Frontend .env (for Vite)
|
|
VITE_APP_NAME=resumeformatter
|
|
GEMINI_API_KEY=AIzaSyB4Y9qrGynW3UNflYcQC-HGlJxOe_ty6VI
|
|
```
|
|
|
|
## Testing Checklist:
|
|
|
|
- [ ] Docker builds successfully
|
|
- [ ] Can access app at http://localhost:8080/resumeformatter
|
|
- [ ] API docs at http://localhost:8080/resumeformatter/api/docs
|
|
- [ ] Can list templates from R2
|
|
- [ ] Can upload and convert resume
|
|
- [ ] Can view conversion history
|
|
- [ ] Can download HTML files
|
|
|
|
## What Would You Like to Do Next?
|
|
|
|
**A)** Test the Docker build now (`docker-compose up --build`)
|
|
**B)** Update frontend to use new backend API
|
|
**C)** Install Node.js for local development
|
|
**D)** Something else?
|
|
|
|
Let me know and I'll guide you through it! 🚀
|