A comprehensive job aggregation platform that consolidates job listings from multiple sources (LinkedIn, Upwork, Indeed, ZipRecruiter) into one unified search interface with AI-powered features.
NEW: Revolutionary search experience with sub-200ms response times - that's 4000%+ faster than traditional APIs!
- Direct Client Integration: Browser connects directly to Typesense server
- Secure Architecture: Scoped API keys with automatic rotation
- Zero Server Load: Search operations bypass Laravel entirely
- Real-time Suggestions: Instant search-as-you-type functionality
Architecture Comparison:
Traditional (SLOW - 8+ seconds):
User → Laravel API → Database Query → Response
Ultra-Fast (NEW - <200ms):
User → Direct Typesense Client → Instant Results ⚡
Ensure your system has:
- PHP 8.2 or higher
- Composer
- Node.js 18+ and npm
- MySQL 8.0+
- Redis server
- Typesense 27.1+ server (for ultra-fast search functionality)
git clone https://github.com/theihasan/geezap.git
cd geezap
composer install
npm installcp .env.example .env
php artisan key:generateCreate a MySQL database and update your .env file:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=geezap
DB_USERNAME=your_username
DB_PASSWORD=your_passwordRun database migrations:
php artisan migrate
php artisan db:seednpm run buildThe application requires multiple background services to function properly:
# Terminal 1 - Main application
php artisan serve
# Terminal 2 - Typesense server (required for ultra-fast search)
# If using Docker:
docker run -d --name typesense -p 8108:8108 -v typesense-data:/data typesense/typesense:27.1 --data-dir /data --api-key=your-api-key --enable-cors
# Or if installed directly:
./typesense-server --data-dir=/tmp/typesense-data --api-key=your-api-key
# Terminal 3 - Queue worker (required for job processing)
php artisan queue:work
# Terminal 4 - WebSocket server (required for real-time features)
php artisan reverb:start (### Currently Not Running)
# Terminal 5 - Scheduler (required for automated job fetching)
php artisan schedule:workAfter starting Typesense, index your job listings:
# Import job listings to Typesense for search functionality
php artisan scout:import "App\Models\JobListing"- Access admin panel at:
http://localhost:8000/geezap-Admin Email: [email protected]-password: password - Default admin credentials are created by the seeder
- Add job categories via:
/geezap/job-categories - Configure API keys via:
/geezap/api-keys
AI Service (Choose One):
# OpenAI (Recommended)
OPENAI_API_KEY=sk-your-openai-key
# Or Gemini
GEMINI_API_KEY=your-gemini-key
# Or DeepSeek
DEEPSEEK_API_KEY=your-deepseek-keyBot Protection (Required):
CLOUDFLARE_TURNSTILE_SITE_KEY=your-site-key
CLOUDFLARE_TURNSTILE_SECRET_KEY=your-secret-keyGet Cloudflare Turnstile keys from: https://dash.cloudflare.com/
Configure email service for user notifications:
# Primary email service (Brevo/Sendinblue)
BREVO_API_KEY=your-brevo-key
BREVO_SMTP_HOST=smtp-relay.brevo.com
BREVO_SMTP_PORT=587
BREVO_SMTP_ENCRYPTION=tls
BREVO_SMTP_USERNAME=your-brevo-username
BREVO_SMTP_PASSWORD=your-brevo-password
# Backup email service (Resend)
RESEND_KEY=your-resend-key
# Or use ZeptoMail
ZEPTO_SMTP_HOST=smtp.zeptomail.com
ZEPTO_SMTP_PORT=587
ZEPTO_SMTP_ENCRYPTION=tls
ZEPTO_SMTP_USERNAME=your-zepto-username
ZEPTO_SMTP_PASSWORD=your-zepto-passwordUltra-Fast Search Engine: Typesense provides instant search results with <200ms response times.
# Typesense Configuration (Required for search functionality)
TYPESENSE_API_KEY=your-typesense-admin-key
TYPESENSE_HOST=localhost
TYPESENSE_PORT=8108
TYPESENSE_PROTOCOL=http
# Optional: Search-only key for enhanced security
TYPESENSE_SEARCH_ONLY_API_KEY=your-read-only-keyTypesense Installation:
-
Install Typesense Server:
# Using Docker (Recommended) docker run -d \ --name typesense \ -p 8108:8108 \ -v typesense-data:/data \ typesense/typesense:27.1 \ --data-dir /data \ --api-key=your-api-key \ --enable-cors # Or install directly curl -O https://dl.typesense.org/releases/27.1/typesense-server-27.1-linux-amd64.tar.gz tar -xzf typesense-server-27.1-linux-amd64.tar.gz ./typesense-server --data-dir=/tmp/typesense-data --api-key=your-api-key
-
Configure Laravel Scout:
# Install required packages composer require laravel/scout typesense/typesense-php # Publish Scout configuration php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
-
Index Job Listings:
# Create the search index and import all job listings php artisan scout:import "App\Models\JobListing" # Check indexing status php artisan tinker >>> \App\Models\JobListing::search('*')->count()
Security Features:
- Scoped API Keys: Automatic generation of search-only keys with 24-hour TTL
- Admin Key Protection: Admin API keys are never exposed to frontend clients
- Role-Based Access: Admin-only endpoints for key management
- Secure Caching: Search keys cached for optimal performance with security
Search Performance:
- Direct Client Integration: Frontend bypasses slow server APIs for instant results
- Response Times: Sub-200ms search responses (4000%+ faster than traditional APIs)
- Real-time Suggestions: Ultra-fast search-as-you-type functionality
- Grouped Results: Organized search results with faceting support
API Endpoints:
GET /api/typesense/config- Public endpoint returning secure search configurationPOST /api/typesense/refresh-key- Admin-only endpoint for manual key refresh
Frontend Integration:
The application includes a TypesenseSearch JavaScript class that automatically:
- Fetches secure configuration from
/api/typesense/config - Initializes direct Typesense client connection
- Provides ultra-fast search suggestions on the homepage
- Handles errors gracefully with fallback mechanisms
# GitHub OAuth
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
# Google OAuth
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
For production environments with separate Redis instances:
REDIS_CLIENT=predis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
REDIS_SCHEME=tls- Web Server: Nginx with Laravel configuration
- PHP: 8.2+ with extensions: PDO, MySQL, Curl, OpenSSL, JSON, Tokenizer, XML, Ctype, BCMath
- Database: MySQL 8.0+ or MariaDB 10.3+
- Cache: Redis 6.0+
- Memory: Minimum 2GB RAM (4GB+ recommended)
- Storage: 10GB+ with room for growth
# Install dependencies
composer install --no-dev --optimize-autoloader
npm ci && npm run build
# Configure environment
cp .env.example .env
# Edit .env with production values
php artisan key:generate
# Database setup
php artisan migrate --force
# Cache optimization
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan optimizeCritical: Proper file permissions are essential for the application to function correctly. Run these commands on your production server:
# Set ownership of the application directory
sudo chown -R deploy:www-data /var/www/html/geezap
# Set base permissions for the entire application
sudo chmod -R 755 /var/www/html/geezap
# Set writable permissions for storage and cache directories
sudo chmod -R 775 /var/www/html/geezap/storage
sudo chmod -R 775 /var/www/html/geezap/bootstrap/cache
# Set permissions for public assets
sudo chmod -R 755 /var/www/html/geezap/public
# Ensure web server owns critical directories for write operations
sudo chown -R www-data:www-data /var/www/html/geezap/storage
sudo chown -R www-data:www-data /var/www/html/geezap/bootstrap/cachePermission Structure Explained:
- 755 (rwxr-xr-x): Owner can read/write/execute, group and others can read/execute
- 775 (rwxrwxr-x): Owner and group can read/write/execute, others can read/execute
- www-data: Web server user that needs write access to logs, cache, and uploaded files
- deploy: Deployment user that owns the application files
Required Directories with Write Permissions:
storage/- For logs, cache, sessions, and uploaded filesstorage/logs/- Application and error logsstorage/framework/cache/- Application cache filesstorage/framework/sessions/- User session datastorage/framework/views/- Compiled Blade templatesbootstrap/cache/- Configuration and route cache files
Verification: After setting permissions, verify they are correct:
# Check storage directory permissions
ls -la /var/www/html/geezap/storage
# Check bootstrap cache permissions
ls -la /var/www/html/geezap/bootstrap/cache
# Test write permissions
sudo -u www-data touch /var/www/html/geezap/storage/logs/test.log
sudo rm /var/www/html/geezap/storage/logs/test.logCommon Permission Issues:
- 500 Internal Server Error: Often caused by incorrect file ownership
- Permission Denied: Web server cannot write to storage or cache directories
- Failed to open stream: Log files or cache files cannot be created or accessed
Security Notes:
- Never set 777 permissions on any directory
- Ensure only necessary directories have write permissions
- Web server should not own the entire application directory
- Keep sensitive files (like
.env) readable only by owner
Use a process manager like Supervisor to manage background services:
Queue Worker Configuration:
[program:geezap-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/geezap/artisan queue:work --sleep=3 --tries=3
directory=/var/www/html/geezap
autostart=true
autorestart=true
user=www-data
numprocs=2
redirect_stderr=true
stdout_logfile=/var/www/html/geezap/storage/logs/worker.logScheduler Cron Job:
# Add to crontab
* * * * * cd /var/www/html/geezap && php artisan schedule:run >> /dev/null 2>&1Error: Class 'PDO' not found
Solution: Install PHP PDO extension: sudo apt-get install php8.2-mysql
Error: composer: command not found
Solution: Install Composer: https://getcomposer.org/download/
Error: npm: command not found
Solution: Install Node.js: https://nodejs.org/
Error: SQLSTATE[HY000] [2002] No such file or directory
Solution: Ensure MySQL service is running: sudo systemctl start mysql
Error: Access denied for user 'root'@'localhost'
Solution: Check database credentials in .env file and ensure user has proper permissions
Error: Base table or view not found
Solution: Run migrations: php artisan migrate
Error: 419 Page Expired
Solution: Clear cache and regenerate app key:
php artisan cache:clear
php artisan config:clear
php artisan key:generateError: Class 'Redis' not found
Solution: Install Redis PHP extension: sudo apt-get install php8.2-redis
Error: Jobs not processing
Solution: Ensure queue worker is running: php artisan queue:work
Error: Real-time features not working
Solution: Ensure Reverb WebSocket server is running: php artisan reverb:start
Error: Connection refused to Typesense server
Solution:
- Ensure Typesense server is running on configured host/port
- Check Typesense API key is correct in
.env - Verify firewall allows connections to Typesense port (default 8108)
Error: Search not working or returning empty results
Solution:
- Re-index job listings:
php artisan scout:import "App\Models\JobListing" - Check search index exists: Access Typesense dashboard at
http://localhost:8108 - Verify facet configuration is correct in
config/scout.php
Error: Unable to generate secure search key
Solution:
- Check admin API key permissions in Typesense
- Verify Typesense server supports scoped key generation
- Clear cache:
php artisan cache:clear
Error: Slow search performance
Solution:
- Ensure direct client connection is working (check browser network tab)
- Verify Typesense server has sufficient resources (CPU/RAM)
- Check if search keys are being cached properly
Error: API key exposed security warning
Solution:
- Verify scoped key system is working:
curl -H "Accept: application/json" http://localhost:8000/api/typesense/config - Ensure returned API key is different from admin key in
.env - Check security tests pass:
php artisan test tests/Feature/TypesenseConfigSecurityTest.php
Error: Cover letter generation fails
Solution: Verify AI service API key is set correctly in .env
Error: Bot protection not working Solution:
- Verify Cloudflare Turnstile keys are correct
- Ensure domain is properly configured in Cloudflare dashboard
Error: Social login not working Solution:
- Check OAuth credentials in
.env - Verify callback URLs are configured correctly in OAuth providers
- Ensure SSL is enabled for production domains
Error: Slow page loading Solution:
# Enable caching
php artisan config:cache
php artisan route:cache
php artisan view:cache
# Clear old cache if needed
php artisan cache:clearError: High memory usage Solution:
- Monitor queue worker memory with
php artisan horizon(if using Horizon) - Restart workers periodically:
php artisan queue:restart
Ultra-Fast Job Search:
- Visit the homepage and start typing in the search box
- Experience instant search suggestions in <200ms
- Results are fetched directly from Typesense server (bypassing Laravel API)
- Search results are grouped intelligently by job title and employer
Browse Jobs:
- Visit the homepage to see latest job listings
- Use search filters to narrow down results by location, category, and keywords
- Click on job titles to view detailed descriptions
Save and Apply:
- Create an account or log in
- Click "Save for Later" on interesting jobs
- Use "Apply" button to track your applications
- Access saved jobs from your dashboard
AI Cover Letter Generation:
- Open any job listing detail page
- Click "Generate Cover Letter" button
- AI will create a customized cover letter based on job requirements
- Edit and download the generated cover letter
Email Notifications:
- Set email preferences in your account settings
- Receive weekly job digest emails with personalized recommendations
- Get notifications about saved job deadlines
Admin Panel Access:
- Navigate to
/geezapfor admin dashboard - Requires admin credentials (created during seeding)
Manage Job Categories:
- Go to
/geezap/job-categories - Add, edit, or delete job categories
- Set category images and descriptions
Configure API Keys:
- Visit
/geezap/api-keys - Add API keys for different job platforms
- Monitor API usage and rate limits
Monitor System:
- Check queue jobs at
/horizon - View application logs in
storage/logs/ - Monitor user analytics and search patterns
Ultra-Fast Search:
- Instant Results: Sub-200ms search responses with direct Typesense integration
- Real-time Suggestions: Search-as-you-type with 300ms debouncing
- Secure Architecture: Scoped API keys with automatic 24-hour rotation
- Performance Breakthrough: 4000%+ faster than traditional server-side search APIs
- Grouped Results: Intelligent result grouping by job title and employer
Job Aggregation:
- Automatically collects jobs from LinkedIn, Upwork, Indeed, and ZipRecruiter
- Standardizes job data format for consistent display
- Real-time updates via WebSocket connections
- Advanced filtering and search capabilities
AI-Powered Tools:
- Intelligent cover letter generation based on job descriptions
- Personalized job recommendations
- Smart matching algorithms
User Management:
- Social authentication via GitHub, Google, and Facebook
- User preferences and notification settings
- Application tracking and history
Security Features:
- Bot protection using Cloudflare Turnstile
- Rate limiting and CSRF protection
- Secure API key management
Administrative Tools:
- Comprehensive admin dashboard using Filament
- Real-time monitoring with Laravel Horizon
- Analytics and reporting features
- Backup and maintenance tools
- Backend: Laravel 12, PHP 8.2+
- Frontend: Livewire 3, Alpine.js, TailwindCSS
- Database: MySQL 8.0+, Redis
- Search Engine: Typesense 27.1+ (ultra-fast search with <200ms responses)
- Queue: Laravel Horizon with Redis
- WebSockets: Laravel Reverb
- AI Integration: OpenAI/Gemini/DeepSeek APIs
- Admin Panel: Filament v3
Log Files:
- Application logs:
storage/logs/laravel.log - Queue logs: Check Horizon dashboard
- Web server logs: Check your web server configuration
Debug Mode:
For development only, enable debug mode in .env:
APP_DEBUG=true
APP_ENV=localCache Issues: Clear all caches when experiencing unexpected behavior:
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clearDatabase Issues: Reset database if needed (development only):
php artisan migrate:fresh --seedContributions are welcome. Please ensure all tests pass before submitting pull requests:
php artisan testThis project is licensed under the MIT License.