# Ryans Recruit Firm - AI Recruitment Site A professional recruitment website built with Node.js, Express, and PostgreSQL. Features include job listings, application management, CV storage, and admin dashboard. ## Features ### Public Features - **Job Listings** - Browse open positions with detailed information - **Online Applications** - Submit applications with CV upload - **Contact Form** - Get in touch with the recruitment team - **Responsive Design** - Works on desktop, tablet, and mobile ### Admin Features - **Dashboard** - Overview statistics and quick access - **Application Management** - View, filter, and manage applicants - **CV Downloads** - Download applicant CVs directly - **Job Management** - Create, edit, and manage job postings - **First-time Setup** - Automatic admin account creation on first login ## Technology Stack - **Backend**: Node.js + Express - **Database**: PostgreSQL with BYTEA for CV storage - **Authentication**: Session-based with bcrypt - **File Upload**: Multer (PDF, DOC, DOCX support) - **Deployment**: Docker + Docker Compose + Coolify ## Quick Start ### Local Development 1. **Clone the repository** ```bash git clone cd ai-recruit-site-template ``` 2. **Install dependencies** ```bash npm install ``` 3. **Set up environment** ```bash cp .env.example .env # Edit .env with your configuration ``` 4. **Start PostgreSQL** (if not using Docker) ```bash # Install PostgreSQL and create database 'recruitment' psql -U postgres -c "CREATE DATABASE recruitment;" ``` 5. **Run migrations** ```bash psql -U postgres -d recruitment -f migrations/001_init_schema.sql psql -U postgres -d recruitment -f migrations/002_seed_data.sql ``` 6. **Start the application** ```bash npm start ``` 7. **Access the site** - Public site: http://localhost:3000 - Admin panel: http://localhost:3000/admin/login ### Docker Development 1. **Start all services** ```bash docker-compose up -d ``` 2. **View logs** ```bash docker-compose logs -f app ``` 3. **Stop services** ```bash docker-compose down ``` ## Deployment to Coolify ### Prerequisites - Coolify account and API token - Gitea repository - Cloudflare account (for DNS) ### Environment Variables ```bash export COOLIFY_TOKEN="your-coolify-api-token" export GITEA_TOKEN="your-gitea-access-token" export CLOUDFLARE_TOKEN="your-cloudflare-api-token" export COOLIFY_API="https://app.coolify.io/api/v1" export GITEA_API="https://git.startanaicompany.com/api/v1" export CLOUDFLARE_API="https://api.cloudflare.com/client/v4" ``` ### Step 1: Generate SSH Deploy Keys ```bash ssh-keygen -t ed25519 -f /tmp/recruitai_deploy_key -C "coolify-recruitai-deploy" -N "" ``` ### Step 2: Create Coolify Project ```bash curl -s -X POST "${COOLIFY_API}/projects" \ -H "Authorization: Bearer ${COOLIFY_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "name": "RecruitAI", "description": "AI Recruitment Site" }' ``` ### Step 3: Add Deploy Key to Coolify ```bash PRIVATE_KEY=$(cat /tmp/recruitai_deploy_key | jq -R -s .) curl -s -X POST "${COOLIFY_API}/private-keys" \ -H "Authorization: Bearer ${COOLIFY_TOKEN}" \ -H "Content-Type: application/json" \ -d "{ \"name\": \"recruitai-deploy-key\", \"description\": \"Deploy key for recruitai repository\", \"private_key\": ${PRIVATE_KEY} }" ``` ### Step 4: Push to Gitea ```bash git remote add origin git@git.startanaicompany.com:username/ai-recruit-site-template.git git add . git commit -m "Initial commit: AI Recruitment Site" git push -u origin main ``` ### Step 5: Add Deploy Key to Gitea ```bash cat > /tmp/gitea_deploy_key.json << EOF { "title": "Coolify Deploy Key", "key": "$(cat /tmp/recruitai_deploy_key.pub)", "read_only": true } EOF curl -s -X POST "${GITEA_API}/repos/username/ai-recruit-site-template/keys" \ -H "Authorization: token ${GITEA_TOKEN}" \ -H "Content-Type: application/json" \ -d @/tmp/gitea_deploy_key.json ``` ### Step 6: Create Coolify Application ```bash curl -s -X POST "${COOLIFY_API}/applications/public" \ -H "Authorization: Bearer ${COOLIFY_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "project_uuid": "YOUR_PROJECT_UUID", "environment_name": "production", "server_uuid": 0, "type": "public", "source": { "type": "git", "url": "git@git.startanaicompany.com:username/ai-recruit-site-template", "branch": "main", "private_key_uuid": "YOUR_PRIVATE_KEY_UUID" }, "build_pack": "dockerfile", "ports_exposes": "3000", "name": "recruitai" }' ``` ### Step 7: Add Webhook to Gitea ```bash curl -s -X POST "${GITEA_API}/repos/username/ai-recruit-site-template/hooks" \ -H "Authorization: token ${GITEA_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "type": "gitea", "config": { "url": "https://app.coolify.io/api/v1/deploy?uuid=YOUR_APP_UUID", "content_type": "json", "http_method": "GET" }, "events": ["push"], "active": true }' ``` ### Step 8: Configure Cloudflare DNS ```bash curl -s -X POST "${CLOUDFLARE_API}/zones/YOUR_ZONE_ID/dns_records" \ -H "Authorization: Bearer ${CLOUDFLARE_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "type": "CNAME", "name": "recruitai", "content": "YOUR_COOLIFY_FQDN", "ttl": 1, "proxied": false }' ``` ### Step 9: Update Application Domain ```bash curl -s -X PATCH "${COOLIFY_API}/applications/YOUR_APP_UUID" \ -H "Authorization: Bearer ${COOLIFY_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "domains": "http://recruitai.startanaicompany.com" }' ``` ### Step 10: Deploy ```bash curl -s -X GET "${COOLIFY_API}/deploy?uuid=YOUR_APP_UUID&force=true" \ -H "Authorization: Bearer ${COOLIFY_TOKEN}" ``` ## First Time Setup ### Admin Account 1. Navigate to `/admin/login` 2. On first visit, you'll be prompted to create an admin account 3. Enter your email, password, and full name 4. Click "Create Admin Account" 5. You'll be logged in automatically ### Add Jobs 1. Go to Admin Dashboard → Jobs 2. Click "Create New Job" 3. Fill in job details 4. Click "Save" ## Database Schema ### Tables - **admins** - Admin user accounts - **job_postings** - Job listings - **applicants** - Applicant information - **applications** - Application submissions with CV storage (BYTEA) - **contact_submissions** - Contact form messages ### Migrations Migrations are located in `/migrations/` and run automatically on first Docker startup. ## API Endpoints ### Public APIs - `GET /api/jobs` - List all active jobs - `GET /api/jobs/:id` - Get job details - `POST /api/apply` - Submit application (multipart/form-data) - `POST /api/contact` - Submit contact form ### Admin APIs (Authentication Required) - `POST /api/admin/login` - Login / Create first admin - `GET /api/admin/check` - Check auth status - `POST /api/admin/logout` - Logout - `GET /api/admin/stats` - Dashboard statistics - `GET /api/admin/applications` - List applications - `GET /api/admin/applications/:id` - Get application details - `GET /api/admin/applications/:id/cv` - Download CV - `PATCH /api/admin/applications/:id` - Update application - `GET /api/admin/jobs` - List all jobs - `POST /api/admin/jobs` - Create job - `PATCH /api/admin/jobs/:id` - Update job - `DELETE /api/admin/jobs/:id` - Delete job ## Security Features - **Password Hashing** - bcrypt with 10 rounds - **Session Management** - Secure HTTP-only cookies - **SQL Injection Protection** - Parameterized queries - **File Upload Validation** - Type and size checks - **CSRF Protection** - Session-based authentication - **Rate Limiting** - (Recommended to add in production) ## Environment Variables | Variable | Description | Default | |----------|-------------|---------| | `DB_HOST` | PostgreSQL host | `postgres` | | `DB_PORT` | PostgreSQL port | `5432` | | `DB_NAME` | Database name | `recruitment` | | `DB_USER` | Database user | `postgres` | | `DB_PASSWORD` | Database password | `changeme123` | | `PORT` | Application port | `3000` | | `NODE_ENV` | Environment | `production` | | `SESSION_SECRET` | Session encryption key | *(required)* | ## File Upload Limits - **Max CV Size**: 5MB - **Allowed Types**: PDF, DOC, DOCX - **Storage**: PostgreSQL BYTEA column ## Troubleshooting ### Database Connection Issues ```bash # Check if PostgreSQL is running docker-compose ps # View PostgreSQL logs docker-compose logs postgres # Restart PostgreSQL docker-compose restart postgres ``` ### Migration Errors ```bash # Connect to database docker-compose exec postgres psql -U postgres -d recruitment # Check tables \dt # Re-run migrations manually docker-compose exec postgres psql -U postgres -d recruitment -f /docker-entrypoint-initdb.d/001_init_schema.sql ``` ### Application Won't Start ```bash # Check application logs docker-compose logs app # Rebuild and restart docker-compose down docker-compose build --no-cache docker-compose up -d ``` ## License MIT ## Support For issues or questions, contact: info@ryansrecruit.com