### Create Plugin Binary Source: https://github.com/magnusfroste/openjobs-api/blob/main/docs/microservices.md Example Go code for creating a new plugin binary. It initializes a connector and starts an HTTP server to handle requests. ```go // cmd/plugin-myclient/main.go func main() { connector := myclient.NewMyClientConnector(store) server := &PluginServer{connector: connector} http.ListenAndServe(":"+port, nil) } ``` -------------------------------- ### New Documentation Structure Example Source: https://github.com/magnusfroste/openjobs-api/blob/main/docs/CLEANUP_PLAN.md Illustrates the proposed directory and file structure for organizing project documentation, including sections for setup, architecture, connectors, and API references. ```tree /Users/mafr/Code/OpenJobs/ ├── README.md # Main overview ├── QUICKSTART.md # 5-minute setup ├── docs/ │ ├── README.md # Docs index │ ├── setup/ │ │ ├── local-development.md # Docker Compose setup │ │ ├── easypanel-deployment.md # Easypanel guide │ │ └── environment-variables.md # All env vars │ ├── architecture/ │ │ ├── overview.md # System architecture │ │ ├── connectors.md # Connector design │ │ └── incremental-sync.md # Sync mechanism │ ├── connectors/ │ │ ├── arbetsformedlingen.md # AF connector │ │ ├── eures.md # EURES/Adzuna │ │ ├── remotive.md # Remotive │ │ └── remoteok.md # RemoteOK │ └── api/ │ ├── endpoints.md # API reference │ └── plugin-protocol.md # HTTP plugin spec ``` -------------------------------- ### Full Job Post Example Source: https://github.com/magnusfroste/openjobs-api/blob/main/API_TROUBLESHOOTING.md A comprehensive example of a job post including all available fields. ```json { "title": "Senior React Developer", "company": "Tech AB", "description": "We are looking for an experienced React developer to join our team.", "location": "Stockholm, Sweden", "employment_type": "full-time", "salary_min": 50000, "salary_max": 70000, "salary_currency": "SEK", "is_remote": true, "url": "https://techab.com/careers/react-dev", "expires_date": "2025-12-31T23:59:59Z", "requirements": [ "5+ years React experience", "TypeScript proficiency", "Team leadership skills" ], "benefits": [ "Health insurance", "Remote work", "Flexible hours", "Professional development budget" ], "fields": { "tags": ["react", "typescript", "remote"] } } ``` -------------------------------- ### Fetch Jobs Endpoint Example Source: https://github.com/magnusfroste/openjobs-api/blob/main/docs/architecture/MICROSERVICES_MIGRATION.md Demonstrates how to fetch the latest jobs from a connector microservice without storing them, using a GET request. ```bash curl http://localhost:8084/jobs ``` -------------------------------- ### Install Go Dependencies Source: https://github.com/magnusfroste/openjobs-api/blob/main/connectors/indeed-chrome/README.md Installs the necessary Go dependency for headless Chrome automation. ```bash go get -u github.com/chromedp/chromedp ``` -------------------------------- ### Start OpenJobs API Source: https://github.com/magnusfroste/openjobs-api/blob/main/TEST_DATABASE.md After successful database tests, start the OpenJobs API by running the main Go program. ```bash go run cmd/openjobs/main.go ``` -------------------------------- ### Cron Schedule Examples Source: https://github.com/magnusfroste/openjobs-api/blob/main/FIX_CRON_ERROR.md Provides common examples of cron schedules for different frequencies and times. ```bash # Every day at 6:00 AM CRON_SCHEDULE=0 6 * * * ``` ```bash # Every day at 4:00 AM (UTC) CRON_SCHEDULE=0 4 * * * ``` ```bash # Every 6 hours CRON_SCHEDULE=0 */6 * * * ``` ```bash # Every day at midnight CRON_SCHEDULE=0 0 * * * ``` -------------------------------- ### Install Colly Source: https://github.com/magnusfroste/openjobs-api/blob/main/connectors/indeed-scraper/README.md Installs the Colly web scraping framework for Go. This is a prerequisite for running the scraper. ```bash go get -u github.com/gocolly/colly/v2 ``` -------------------------------- ### Minimal Job Post Example Source: https://github.com/magnusfroste/openjobs-api/blob/main/API_TROUBLESHOOTING.md A basic example of a job post containing only the required fields. ```json { "title": "Developer", "company": "Acme Inc", "description": "We are looking for a talented developer." } ``` -------------------------------- ### Start All Services with Docker Compose Source: https://github.com/magnusfroste/openjobs-api/blob/main/README.md This command starts all the necessary services for local development, including the main API and various job plugins. Access them via the provided local URLs. ```bash docker-compose -f docker-compose.plugins.yml up ``` -------------------------------- ### Copy .env.example to .env Source: https://github.com/magnusfroste/openjobs-api/blob/main/SETUP_GUIDE.md Copy the example environment file to a new file named .env. This file will store your application's configuration. ```bash cp .env.example .env ``` -------------------------------- ### Configure Environment Variables Source: https://github.com/magnusfroste/openjobs-api/blob/main/QUICKSTART.md Copy the example environment configuration file and update it with your Supabase credentials. This is a critical step before running the application. ```bash cp .env.example .env # Edit .env and add YOUR credentials: nano .env # or use your preferred editor SUPABASE_URL=https://your-actual-project.supabase.co SUPABASE_ANON_KEY=your-actual-anon-key-here ``` -------------------------------- ### Synchronization Response Example Source: https://github.com/magnusfroste/openjobs-api/blob/main/docs/architecture/MICROSERVICES_MIGRATION.md Provides an example of the JSON response after successfully triggering a synchronization, confirming the completion of the process. ```json { "success": true, "message": "RemoteOK sync completed successfully" } ``` -------------------------------- ### Install Dependencies and Download Colly Source: https://github.com/magnusfroste/openjobs-api/blob/main/INDEED_SCRAPER_READY.md Installs necessary dependencies and the Colly web scraping library for the project. ```bash cd /Users/mafr/Code/OpenJobs # Download Colly (web scraping library) go get -u github.com/gocolly/colly/v2 # Download all dependencies go mod download ``` -------------------------------- ### Clone and Setup Project Source: https://github.com/magnusfroste/openjobs-api/blob/main/README.md Follow these commands to clone the OpenJobs repository and set up the initial environment. Remember to edit the .env file with your specific Supabase credentials. ```bash git clone https://github.com/magnusfroste/openjobs.git cd openjobs cp .env.example .env # Edit .env with your Supabase credentials ``` -------------------------------- ### Test Local OpenJobs Setup Source: https://github.com/magnusfroste/openjobs-api/blob/main/QUICKSTART.md Execute the provided script to test if the local OpenJobs setup is working correctly. Alternatively, use curl commands for manual checks. ```bash ./test_local.sh ``` ```bash # Health check curl http://localhost:8080/health # Trigger job sync (fetches jobs from Arbetsförmedlingen) curl -X POST http://localhost:8080/sync/manual # View jobs curl http://localhost:8080/jobs ``` -------------------------------- ### Build and Run OpenJobs Locally Source: https://github.com/magnusfroste/openjobs-api/blob/main/SETUP_GUIDE.md Compile the Go application and then run the executable. This will start the OpenJobs API on the configured port. ```bash # Build the application go build -o openjobs ./cmd/openjobs # Run the application ./openjobs ``` -------------------------------- ### Start Indeed Chrome Plugin Source: https://github.com/magnusfroste/openjobs-api/blob/main/INDEED_CHROME_READY.md Use this command to start the Indeed Chrome plugin. Ensure you are in the project's root directory. The PORT environment variable can be set to change the listening port. ```bash cd /Users/mafr/Code/OpenJobs PORT=8087 go run cmd/plugin-indeed-chrome/main.go ``` -------------------------------- ### OpenJobs - Files to Keep Source: https://github.com/magnusfroste/openjobs-api/blob/main/CLEANUP_SUMMARY.md Lists essential files and directories to retain for the OpenJobs project, covering main documentation, setup guides, environment configuration, and deployment scripts. ```text README.md - Updated main documentation QUICKSTART.md - Quick start guide SETUP_GUIDE.md - Detailed setup EASYPANEL_ENV_SETUP.md - Deployment guide docs/ - Architecture documentation .env.example - Environment template Dockerfile - Container build docker-compose.plugins.yml - Local dev deploy-microservices.sh - Deployment script ``` -------------------------------- ### Run All Services with Docker Compose Source: https://github.com/magnusfroste/openjobs-api/blob/main/docs/README.md Starts all configured services using Docker Compose. Ensure you have the docker-compose.plugins.yml file available. ```bash docker-compose -f docker-compose.plugins.yml up -d ``` -------------------------------- ### Local Development Setup Source: https://github.com/magnusfroste/openjobs-api/blob/main/connectors/offentligajobb/README.md Set environment variables for Supabase and run the scraper locally. Ensure the PORT is set to 8089. ```bash export SUPABASE_URL=your_url export SUPABASE_ANON_KEY=your_key PORT=8089 go run cmd/plugin-offentligajobb/main.go ``` -------------------------------- ### Install Chrome via Homebrew Source: https://github.com/magnusfroste/openjobs-api/blob/main/connectors/indeed-chrome/README.md Use this command to install Google Chrome if it's not found by the scraper. Alternatively, set the CHROME_BIN environment variable. ```bash # Install Chrome brew install --cask google-chrome # Or set Chrome path export CHROME_BIN=/path/to/chrome ``` -------------------------------- ### Test Indeed Scraper (Experimental) Source: https://github.com/magnusfroste/openjobs-api/blob/main/CONNECTORS_SUMMARY.md Install dependencies, check robots.txt, and run the Indeed scraper. ```bash # Install dependencies go get -u github.com/gocolly/colly/v2 # Check robots.txt first! curl https://se.indeed.com/robots.txt # Run scraper go run cmd/plugin-indeed-scraper/main.go ``` -------------------------------- ### Run OpenJobs API Locally Source: https://github.com/magnusfroste/openjobs-api/blob/main/CORS_FIX.md Command to start the OpenJobs API server for local testing. ```bash cd /Users/mafr/Code/OpenJobs go run cmd/openjobs/main.go ``` -------------------------------- ### Direct Supabase Insert Example Source: https://github.com/magnusfroste/openjobs-api/blob/main/TIMESTAMP_BEHAVIOR_ANALYSIS.md Example `curl` command for directly inserting a job into the Supabase `job_posts` table. This method bypasses the Go application logic and relies entirely on Supabase's database constraints. ```bash curl -X POST "https://cmpnqpdxhmecptcbffmw.supabase.co/rest/v1/job_posts" \ -H "apikey: YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "id": "custom-123", "title": "Job Title", "company": "Company" }' ``` -------------------------------- ### Fetch Sync Logs Using Started At (Correct Ordering) Source: https://github.com/magnusfroste/openjobs-api/blob/main/SYNC_LOGS_STATUS.md Retrieves sync logs ordered by 'started_at' in descending order, which is the correct method for recent logs. ```bash # This works correctly curl "...sync_logs?order=started_at.desc" ``` -------------------------------- ### Sync Log Data Example with Zero Timestamp Source: https://github.com/magnusfroste/openjobs-api/blob/main/SYNC_LOGS_STATUS.md An example of a sync log entry showing the 'created_at' field with a zero timestamp, indicating a cosmetic issue. ```json { "connector_name": "arbetsformedlingen", "started_at": "2025-11-28T04:00:00.106827+00:00", // ✅ Correct "completed_at": "2025-11-28T04:00:06.15779+00:00", // ✅ Correct "created_at": "0001-01-01T00:00:00+00:00" // ❌ Zero time } ``` -------------------------------- ### Write Unit Tests for Connector Source: https://github.com/magnusfroste/openjobs-api/blob/main/docs/PLUGIN_DEVELOPMENT.md Include unit tests to verify your connector's functionality. This example demonstrates testing the `FetchJobs` method using a mock job store. ```go func TestFetchJobs(t *testing.T) { store := &mockJobStore{} connector := NewArbetsformedlingenConnector(store) obs, err := connector.FetchJobs() assert.NoError(t, err) assert.Greater(t, len(jobs), 0) } ``` -------------------------------- ### Run OpenJobs with Go Source: https://github.com/magnusfroste/openjobs-api/blob/main/QUICKSTART.md Build and run the OpenJobs application locally using Go for development purposes. Ensure you have Go 1.21+ installed. ```bash go build -o openjobs ./cmd/openjobs ./openjobs ``` -------------------------------- ### Development Environment Variables (.env file) Source: https://github.com/magnusfroste/openjobs-api/blob/main/PLUGIN_SCHEDULING_INVESTIGATION.md Example of environment variables typically found in a local .env file for development. ```bash SUPABASE_URL=https://supabase.froste.eu SUPABASE_ANON_KEY=eyJ... PORT=8080 ADZUNA_APP_ID=8d597455 ADZUNA_APP_KEY=b584de1fa3792bfd6d8f66e3ef975f4a SERVICE_ROLE_KEY=eyJ... ``` -------------------------------- ### Deploy OpenJobs from GitHub to Easypanel Source: https://github.com/magnusfroste/openjobs-api/blob/main/SETUP_GUIDE.md Alternative deployment method for Easypanel using a GitHub repository. Configure build and start commands, and set environment variables. ```bash # Set build command: docker build -t openjobs . # Set start command: Docker will use the CMD from Dockerfile # Add environment variables as above ``` -------------------------------- ### Example: Before Snippet Only Source: https://github.com/magnusfroste/openjobs-api/blob/main/FULL_DESCRIPTION_SCRAPING.md Illustrates the limited information captured by the previous scraping method, showing only a short snippet of the job details. ```text "Heltid" ``` -------------------------------- ### Get Job Analytics Summary Source: https://github.com/magnusfroste/openjobs-api/blob/main/ANALYTICS_REFRESH.md Example SQL query to retrieve a summary of job analytics data by calling the 'get_job_analytics_summary' function. ```sql SELECT * FROM get_job_analytics_summary(); ``` -------------------------------- ### Get Job Analytics by Source Source: https://github.com/magnusfroste/openjobs-api/blob/main/ANALYTICS_REFRESH.md Example SQL query to retrieve job analytics data categorized by source, by calling the 'get_job_analytics_by_source' function. ```sql SELECT * FROM get_job_analytics_by_source(); ``` -------------------------------- ### Check Service Health Source: https://github.com/magnusfroste/openjobs-api/blob/main/docs/README.md Verifies the operational status of various services by sending a GET request to their health endpoints. This is useful for confirming that services have started correctly. ```bash curl http://localhost:8080/health # Main API curl http://localhost:8081/health # Arbetsförmedlingen curl http://localhost:8082/health # EURES curl http://localhost:8083/health # Remotive curl http://localhost:8084/health # RemoteOK ``` -------------------------------- ### Core-to-Plugin Communication Example Source: https://github.com/magnusfroste/openjobs-api/blob/main/docs/microservices.md The core API discovers and communicates with plugins via environment variables defining their URLs. HTTP POST requests are used to trigger synchronization tasks. ```go // Environment-based discovery PLUGIN_ARBETSFORMEDLINGEN_URL=http://plugin-af:8081 PLUGIN_EURES_URL=http://plugin-eures:8082 // HTTP calls instead of direct method calls resp, _ := http.Post(pluginURL + "/sync", "application/json", nil) ``` -------------------------------- ### cURL Example for Creating a Job Posting Source: https://github.com/magnusfroste/openjobs-api/blob/main/API_SPEC.md This cURL command demonstrates how to make a POST request to create a new job posting with all necessary headers and a JSON payload. ```bash curl -X POST https://api.openjobs.ink/jobs \ -H "Content-Type: application/json" \ -H "X-API-Key: opj_your_api_key_here" \ -d '{ "title": "Senior Developer", "company": "Tech AB", "description": "We are hiring a senior developer...", "source": "greenhouse-api", "location": "Stockholm", "employment_type": "full-time", "salary_min": 50000, "salary_max": 70000, "salary_currency": "SEK", "is_remote": true, "requirements": ["React", "TypeScript", "Node.js"], "benefits": ["Health insurance", "Remote work"], "fields": { "ats_system": "greenhouse", "ats_job_id": "gh-123456" } }' ``` -------------------------------- ### Create Standalone Binary for New Connector Source: https://github.com/magnusfroste/openjobs-api/blob/main/docs/README.md Go code demonstrating how to create a standalone executable for a new connector. This typically involves setting up a storage layer and an HTTP server to expose the connector's functionality. ```go // cmd/plugin-mynewconnector/main.go func main() { store := storage.NewJobStore() connector := mynewconnector.NewMyConnector(store) // ... HTTP server setup } ``` -------------------------------- ### Kubernetes Deployment Configuration Source: https://github.com/magnusfroste/openjobs-api/blob/main/docs/deployment/CONTAINERS_OVERVIEW.md Example Kubernetes Deployment manifest for running a plugin container. This defines the desired state for the plugin, including the image and number of replicas. ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: plugin-remoteok spec: replicas: 2 template: spec: containers: - name: plugin-remoteok image: openjobs/plugin-remoteok:latest ports: - containerPort: 8084 ``` -------------------------------- ### Build and Run Indeed Connector Locally Source: https://github.com/magnusfroste/openjobs-api/blob/main/INDEED_CONNECTOR_READY.md Commands to download dependencies, build the plugin, and run it locally. ```bash cd /Users/mafr/Code/OpenJobs go mod download go build ./cmd/plugin-indeed ``` -------------------------------- ### Fetch Jobs Response Example Source: https://github.com/magnusfroste/openjobs-api/blob/main/docs/architecture/MICROSERVICES_MIGRATION.md Shows the expected JSON response when fetching jobs, including success status, job data, and the count of jobs retrieved. ```json { "success": true, "data": [...], "count": 96 } ``` -------------------------------- ### Run OpenJobs Docker Container Locally Source: https://github.com/magnusfroste/openjobs-api/blob/main/SETUP_GUIDE.md Start a Docker container from the 'openjobs:latest' image, mapping port 8080 and setting necessary environment variables for Supabase connection. ```bash docker run -p 8080:8080 \ -e SUPABASE_URL="https://your-project.supabase.co" \ -e SUPABASE_ANON_KEY="your-anon-key" \ openjobs:latest ``` -------------------------------- ### Example Output of Successful Scraping Source: https://github.com/magnusfroste/openjobs-api/blob/main/FULL_DESCRIPTION_SCRAPING.md Illustrates the expected log output after successfully scraping job details, including fetching full descriptions and counting unique jobs. ```text 🔍 Scraping Indeed for: 'developer' ✅ Fetched full description for: Senior React Developer ✅ Fetched full description for: Backend Engineer ✅ Fetched full description for: Full Stack Developer 📊 Scraped 60 unique jobs from Indeed ``` -------------------------------- ### Build and Run Standalone Arbetsformedlingen Connector Source: https://github.com/magnusfroste/openjobs-api/blob/main/docs/architecture/CONNECTOR_ARCHITECTURE.md Commands to build a Docker image for the standalone Arbetsformedlingen connector and run it as a container. Assumes Docker is installed and the Dockerfile is present. ```bash # Build standalone docker build -f connectors/arbetsformedlingen/Dockerfile -t plugin-af . # Run standalone docker run -p 8081:8081 plugin-af ``` -------------------------------- ### Install Chrome/Chromium Source: https://github.com/magnusfroste/openjobs-api/blob/main/connectors/indeed-chrome/README.md Installs Chrome or Chromium on macOS and Linux systems. This is a prerequisite for running the scraper. ```bash # macOS (if not already installed) brew install --cask google-chrome # Linux sudo apt-get install chromium-browser # Already installed on most systems ``` -------------------------------- ### Build and Run Indeed Connector (Demo Mode) Source: https://github.com/magnusfroste/openjobs-api/blob/main/INDEED_CONNECTOR_READY.md Use this command to build and run the Indeed connector in demo mode for initial testing without an API key. ```bash cd /Users/mafr/Code/OpenJobs # Build and run go run cmd/plugin-indeed/main.go ``` -------------------------------- ### Python Plugin Example (FastAPI) Source: https://github.com/magnusfroste/openjobs-api/blob/main/docs/microservices.md A basic FastAPI application for a Python plugin, including health check, sync, and job retrieval endpoints. Requires the 'openjobs_shared' types. ```python from fastapi import FastAPI import httpx import os from openjobs_shared import JobPost # Shared types app = FastAPI() @app.get("/health") async def health(): return {"status": "healthy", "plugin": "My Python Plugin"} @app.post("/sync") async def sync(): # Your Python plugin logic jobs = await fetch_jobs_python_style() return {"success": True} @app.get("/jobs") async def jobs(): jobs = await fetch_jobs_python_style() return {"success": True, "data": jobs} ``` -------------------------------- ### Implement New Connector Logic Source: https://github.com/magnusfroste/openjobs-api/blob/main/docs/README.md Example Go code for implementing a new connector. It shows the basic structure required by the PluginConnector interface, including methods for fetching and syncing jobs. ```go // connectors/mynewconnector/connector.go type MyConnector struct { store *storage.JobStore } func (c *MyConnector) GetID() string { return "mynewconnector" } func (c *MyConnector) GetName() string { return "My New Connector" } func (c *MyConnector) FetchJobs() ([]models.JobPost, error) { /* ... */ } func (c *MyConnector) SyncJobs() error { /* ... */ } ``` -------------------------------- ### Create Plugin Dockerfile Source: https://github.com/magnusfroste/openjobs-api/blob/main/docs/microservices.md A Dockerfile for building a plugin container. It sets up the Go environment, copies the source code, builds the binary, and defines the command to run the plugin. ```dockerfile # Dockerfile.plugin-myclient FROM golang:1.21-alpine WORKDIR /app COPY . . RUN go build -o plugin-myclient ./cmd/plugin-myclient EXPOSE 8083 CMD ["./plugin-myclient"] ``` -------------------------------- ### Add Indeed Publisher ID to .env Source: https://github.com/magnusfroste/openjobs-api/blob/main/INDEED_CONNECTOR_READY.md Configure your Indeed Publisher ID by copying the example environment file and editing it. This is required for testing with a real API key. ```bash # Copy example cp .env.example .env # Edit .env and add: INDEED_PUBLISHER_ID=your_publisher_id_here ``` -------------------------------- ### Get Specific Job API Endpoint Source: https://github.com/magnusfroste/openjobs-api/blob/main/README.md This bash snippet shows the GET request to retrieve a specific job by its ID. It is a public endpoint. ```bash GET /jobs/:id # Get specific job ``` -------------------------------- ### Build and Run OpenJobs Application Source: https://github.com/magnusfroste/openjobs-api/blob/main/docs/PLUGIN_DEVELOPMENT.md This bash script shows the commands to build the OpenJobs application binary and then run it from the command line. ```bash cd cmd/openjobs go build -o openjobs main.go ./openjobs ``` -------------------------------- ### Test Indeed API Connector (Demo Mode) Source: https://github.com/magnusfroste/openjobs-api/blob/main/CONNECTORS_SUMMARY.md Navigate to the project directory and run the Indeed API connector in demo mode. ```bash cd /Users/mafr/Code/OpenJobs go run cmd/plugin-indeed/main.go ``` -------------------------------- ### GET /health Source: https://github.com/magnusfroste/openjobs-api/blob/main/API_SPEC.md Check the health status of the API. ```APIDOC ## GET /health ### Description Check the health status of the API. ### Method GET ### Endpoint /health ### Response #### Success Response (200 OK) - **status** (string) - The health status of the API (e.g., "healthy"). - **timestamp** (string) - The timestamp when the health check was performed (ISO 8601 format). ```json { "status": "healthy", "timestamp": "2025-11-17T15:30:00Z" } ``` ``` -------------------------------- ### Connector Job Creation Example Source: https://github.com/magnusfroste/openjobs-api/blob/main/TIMESTAMP_BEHAVIOR_ANALYSIS.md Illustrates how a job is created using plugin connectors. Before the fix, zero timestamps were sent, overriding database defaults. After the fix, omitted timestamps allow the database to use its default `NOW()`. ```go // connectors/arbetsformedlingen/connector.go job := models.JobPost{ ID: "af-12345", Title: "Developer", Company: "ACME", PostedDate: time.Now(), // CreatedAt NOT SET (zero value) // UpdatedAt NOT SET (zero value) } store.CreateJob(&job) ``` -------------------------------- ### Build Plugin Locally Source: https://github.com/magnusfroste/openjobs-api/blob/main/docs/architecture/MICROSERVICES_MIGRATION.md Command to build the plugin executable locally using Go, specifying the output file and source directory. ```bash go build -o plugin-remoteok ./cmd/plugin-remoteok ``` -------------------------------- ### GET /jobs/:id Source: https://github.com/magnusfroste/openjobs-api/blob/main/API_SPEC.md Retrieve a specific job posting by its unique ID. ```APIDOC ## GET /jobs/:id ### Description Retrieve a specific job posting by its unique ID. ### Method GET ### Endpoint /jobs/:id ### URL Parameters - **id** (string) - Required - Job ID (e.g., `af-12345`) ### Request Example ```bash GET /jobs/af-12345 ``` ### Response #### Success Response (200 OK) - **success** (boolean) - Indicates if the request was successful. - **data** (object) - A single job object matching the provided ID. (Content structure is the same as a single job object in the `/jobs` response) ``` -------------------------------- ### Restart an Individual Container Source: https://github.com/magnusfroste/openjobs-api/blob/main/docs/deployment/CONTAINERS_OVERVIEW.md Restart a specific container, for example, 'plugin-remoteok', using the docker-compose command. ```bash docker-compose -f docker-compose.plugins.yml restart plugin-remoteok ``` -------------------------------- ### Job posting response format Source: https://github.com/magnusfroste/openjobs-api/blob/main/README.md Example JSON structure for a successful job posting response. ```json { "success": true, "data": [ { "id": "af-12345", "title": "Senior Developer", "company": "Tech AB", "description": "Job description...", "location": "Stockholm", "salary_min": 50000, "salary_max": 70000, "salary_currency": "SEK", "is_remote": false, "is_active": true, "url": "https://...", "posted_date": "2025-11-15T10:00:00Z", "created_at": "2025-11-17T06:15:23Z", "updated_at": "2025-11-17T06:15:23Z", "requirements": ["Python", "React"], "benefits": ["Remote work", "Health insurance"] } ] } ``` -------------------------------- ### Update Operation with UpdatedAt Source: https://github.com/magnusfroste/openjobs-api/blob/main/TIMESTAMP_BEHAVIOR_ANALYSIS.md Example of explicitly setting the UpdatedAt timestamp before updating a job record. ```go job.UpdatedAt = time.Now() store.UpdateJob(&job) ``` -------------------------------- ### Run Indeed Connector with Real API Key Source: https://github.com/magnusfroste/openjobs-api/blob/main/INDEED_CONNECTOR_READY.md Execute the Indeed connector using the Go run command after setting up your .env file with the Publisher ID. ```bash go run cmd/plugin-indeed/main.go ``` -------------------------------- ### Kubernetes Deployment for RemoteOK Plugin Source: https://github.com/magnusfroste/openjobs-api/blob/main/docs/architecture/MICROSERVICES_MIGRATION.md Example Kubernetes Deployment manifest for running the RemoteOK plugin as a microservice. ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: plugin-remoteok spec: replicas: 2 selector: matchLabels: app: plugin-remoteok template: metadata: labels: app: plugin-remoteok spec: containers: - name: plugin-remoteok image: openjobs/plugin-remoteok:latest ports: - containerPort: 8084 env: - name: DATABASE_URL valueFrom: secretKeyRef: name: openjobs-secrets key: database-url ``` -------------------------------- ### Recommended JobPost Model (Connector) Source: https://github.com/magnusfroste/openjobs-api/blob/main/TIMESTAMP_BEHAVIOR_ANALYSIS.md Shows the recommended way for connectors to define a JobPost, omitting timestamps to let the database handle defaults. ```go // GOOD ✅ job := models.JobPost{ ID: "af-123", Title: "Job", // CreatedAt not set } ``` -------------------------------- ### Troubleshooting: Go Version Check Source: https://github.com/magnusfroste/openjobs-api/blob/main/EASYPANEL_DEPLOYMENT_FIX.md If builds still fail, verify that the Docker image used is 'golang:1.23-alpine' and not an older version. ```text Should see: golang:1.23-alpine Not: golang:1.21-alpine ``` -------------------------------- ### Environment Variable for Indeed Chrome Source: https://github.com/magnusfroste/openjobs-api/blob/main/SCHEDULER_SETUP.md Example of setting the environment variable for the 'indeed-chrome' plugin URL in Easypanel. ```bash PLUGIN_INDEED_CHROME_URL=http://indeed-chrome:8087 ``` -------------------------------- ### API Response for Job Creation Source: https://github.com/magnusfroste/openjobs-api/blob/main/SETUP_GUIDE.md This is an example of a successful response (201 Created) when a job is created via the API. ```json { "success": true, "data": { "id": "web-123e4567-e89b-12d3-a456-426614174000", "title": "Senior React Developer", "company": "TechCorp", "is_active": true, "posted_date": "2025-11-19T00:00:00Z", ... }, "message": "Job created successfully" } ``` -------------------------------- ### Successful Test Output Example Source: https://github.com/magnusfroste/openjobs-api/blob/main/TEST_DATABASE.md This is the expected output when all database operations (read, write, update, delete) are successful. ```text 🧪 Testing OpenJobs → Supabase Connection ========================================== 📍 Supabase URL: https://cmpnqpdxhmecptcbffmw.supabase.co Test 1: Read Jobs from Database -------------------------------- ✅ Successfully read 5 jobs 1. Senior Developer - Tech AB (ID: af-12345) 2. React Engineer - Startup Inc (ID: ro-67890) ... Test 2: Get Total Job Count --------------------------- ✅ Total active jobs in database: 333 Test 3: Create Test Job ----------------------- ✅ Successfully created test job: test-1732012345 Test 4: Read Test Job Back -------------------------- ✅ Successfully read test job back Title: Test Job - Connection Check Company: OpenJobs Test Active: false Test 5: Update Test Job ----------------------- ✅ Successfully updated test job Test 6: Cleanup (Delete Test Job) --------------------------------- ✅ Successfully deleted test job 🧹 Test job cleaned up Test 7: Get Remote Job Count ---------------------------- ✅ Total remote jobs: 168 ========================================== 📊 Test Summary ========================================== ✅ All database operations working! ``` -------------------------------- ### Build Test Binary (Bash) Source: https://github.com/magnusfroste/openjobs-api/blob/main/BUGFIX-incremental-sync.md This bash command demonstrates how to build the test binary for the OpenJobs project. It is used to prepare for testing the fix before deployment. ```bash # Build test go build -o /tmp/openjobs-test ./cmd/openjobs/main.go ``` -------------------------------- ### Example Plugin Health Response Source: https://github.com/magnusfroste/openjobs-api/blob/main/EASYPANEL_ENV_SETUP.md This is the expected JSON response when a plugin's health endpoint is successfully reached. ```json { "status": "healthy", "plugin": "RemoteOK Connector", "plugin_id": "remoteok", "version": "1.0.0" } ``` -------------------------------- ### Build Docker Image for Deployment Source: https://github.com/magnusfroste/openjobs-api/blob/main/TEST_DATABASE.md Create a Docker image tagged as 'openjobs:latest' for deployment. ```bash # Rebuild Docker image docker build -t openjobs:latest . ``` -------------------------------- ### Successful Log Verification Messages Source: https://github.com/magnusfroste/openjobs-api/blob/main/FIX_CRON_ERROR.md These log messages confirm that the cron scheduler has started successfully with a valid schedule. ```text ✅ ⏰ Starting job ingestion with cron schedule: 00 4 * * * ✅ Cron scheduler started ``` -------------------------------- ### Configure Environment Variables for Connectors Source: https://github.com/magnusfroste/openjobs-api/blob/main/docs/PLUGIN_DEVELOPMENT.md Define sensitive configuration variables like API keys and URLs in the `.env.example` file. Load these variables in your connector using `os.Getenv()`. ```bash # Example for EURES connector ADZUNA_APP_ID=your-app-id-here ADZUNA_APP_KEY=your-app-key-here # Example for Arbetsförmedlingen connector (if needed) ARBETSFORMEDLINGEN_API_KEY=your-api-token-here ``` ```go appID := os.Getenv("ADZUNA_APP_ID") if appID == "" { log.Println("⚠️ Adzuna credentials not configured, using demo data") return fetchDemoJobs() } ``` -------------------------------- ### List Registered Plugins API Endpoint Source: https://github.com/magnusfroste/openjobs-api/blob/main/README.md This bash snippet shows the GET request to list all registered plugins. ```bash GET /plugins # List registered plugins ``` -------------------------------- ### View Sync History API Endpoint Source: https://github.com/magnusfroste/openjobs-api/blob/main/README.md This bash snippet shows the GET request to view synchronization logs. ```bash GET /sync/history # View sync logs ``` -------------------------------- ### Build and Run RemoteOK Connector Source: https://github.com/magnusfroste/openjobs-api/blob/main/connectors/remoteok/README.md Build the Docker image for the RemoteOK connector and run it as a standalone microservice. Ensure the DATABASE_URL environment variable is set. ```bash docker build -f connectors/remoteok/Dockerfile -t plugin-remoteok . docker run -p 8084:8084 -e DATABASE_URL=$DATABASE_URL plugin-remoteok ``` -------------------------------- ### List All Jobs API Endpoint Source: https://github.com/magnusfroste/openjobs-api/blob/main/README.md This bash snippet shows the GET request to list all jobs. It is a public endpoint. ```bash GET /jobs # List all jobs ``` -------------------------------- ### Fetch Jobs Locally Source: https://github.com/magnusfroste/openjobs-api/blob/main/SETUP_GUIDE.md Retrieve a list of jobs from the OpenJobs API by sending a GET request to the /jobs endpoint. ```bash curl http://localhost:8080/jobs ``` -------------------------------- ### Colly Cloudflare Blocked Example Source: https://github.com/magnusfroste/openjobs-api/blob/main/connectors/indeed-chrome/README.md Demonstrates a basic Colly collector attempting to visit a URL, which is expected to be blocked by Cloudflare. ```go // Simple HTTP client c := colly.NewCollector() c.Visit(url) // ❌ Blocked by Cloudflare ``` -------------------------------- ### Error response for job retrieval Source: https://github.com/magnusfroste/openjobs-api/blob/main/API_SPEC.md Example of an error response when the API fails to retrieve jobs. Indicates a server-side issue. ```json { "success": false, "message": "Failed to retrieve jobs" } ``` -------------------------------- ### Docker Build and Run Source: https://github.com/magnusfroste/openjobs-api/blob/main/connectors/offentligajobb/README.md Build a Docker image for the scraper and run it as a container. Map port 8089 and set Supabase environment variables. ```bash docker build -t openjobs-offentligajobb -f connectors/offentligajobb/Dockerfile . docker run -p 8089:8089 \ -e SUPABASE_URL=your_url \ -e SUPABASE_ANON_KEY=your_key \ openjobs-offentligajobb ``` -------------------------------- ### LazyJobs - Files to Keep Source: https://github.com/magnusfroste/openjobs-api/blob/main/CLEANUP_SUMMARY.md Lists essential files and directories to retain for the LazyJobs project, including main documentation, feature-specific guides, AI implementation details, and project structure. ```text README.md - Main documentation AI_MATCHING_IMPLEMENTATION.md - AI feature docs AI_TAILORING_CONSIDERATIONS.md - AI safeguards APPLICATION_ASSISTANT.md - Feature docs TROUBLESHOOTING_APPLICATION_ASSISTANT.md - Debug guide QDRANT_QUICKSTART.md - Semantic search setup ROLLBACK_AI_MATCHING.md - Rollback guide TODO.md - Feature roadmap docs/ - Detailed documentation PROJECT_STRUCTURE.md - Code organization ``` -------------------------------- ### Run Indeed Connector Main Application Source: https://github.com/magnusfroste/openjobs-api/blob/main/INDEED_CONNECTOR_READY.md Executes the main Go program for the Indeed connector. ```bash cd /Users/mafr/Code/OpenJobs go run cmd/plugin-indeed/main.go ``` -------------------------------- ### Test RemoteOK Plugin: Build and Run Source: https://github.com/magnusfroste/openjobs-api/blob/main/docs/architecture/MICROSERVICES_MIGRATION.md Build the RemoteOK plugin executable and run it locally, specifying the port. ```bash # 1. Build go build -o plugin-remoteok ./cmd/plugin-remoteok # 2. Run PORT=8084 ./plugin-remoteok & ``` -------------------------------- ### Easypanel Build Arguments Source: https://github.com/magnusfroste/openjobs-api/blob/main/JOOBLE_SETUP.md Optional build arguments for Easypanel deployment if needed. ```bash SUPABASE_URL=https://supabase.froste.eu SUPABASE_ANON_KEY=your_supabase_key ``` -------------------------------- ### Test Jobs Endpoint Source: https://github.com/magnusfroste/openjobs-api/blob/main/TEST_DATABASE.md Retrieve a list of jobs from the OpenJobs API by sending a GET request to the /jobs endpoint with a limit. ```bash curl http://localhost:8080/jobs?limit=5 ``` -------------------------------- ### Automated Sync Script with ATS Source Source: https://github.com/magnusfroste/openjobs-api/blob/main/SOURCE_GUIDE.md This bash script demonstrates an automated sync from Greenhouse to OpenJobs, setting the 'source' to 'greenhouse-api' and populating relevant 'fields'. ```bash #!/bin/bash # Sync script curl -X POST https://app-openjobs.katsu6.easypanel.host/jobs \ -H "X-API-Key: $OPENJOBS_API_KEY" \ -d '{ "title": "' ``` ```bash ''"$JOB_TITLE"''", "company": "' ``` ```bash ''"$COMPANY_NAME"''", "description": "' ``` ```bash ''"$JOB_DESC"''", "source": "greenhouse-api", "url": "' ``` ```bash ''"$GREENHOUSE_URL"''", "fields": { "ats_system": "greenhouse", "ats_job_id": "' ``` ```bash ''"$GREENHOUSE_ID"''", "synced_at": "' ``` ```bash ''"$(date -u +%Y-%m-%dT%H:%M:%SZ)"''" } }' ``` -------------------------------- ### Test API Health Endpoint Source: https://github.com/magnusfroste/openjobs-api/blob/main/TEST_DATABASE.md Verify the OpenJobs API is running and accessible by sending a GET request to the /health endpoint. ```bash curl http://localhost:8080/health ``` -------------------------------- ### Failed Build Log Example Source: https://github.com/magnusfroste/openjobs-api/blob/main/EASYPANEL_CACHE_FIX.md This log snippet illustrates a failed build due to the Docker cache using an outdated Go version. This is the error pattern the cache bust fix aims to resolve. ```log ❌ FROM golang:1.21-alpine ❌ go: go.mod requires go >= 1.25 ❌ ERROR: failed to build ``` -------------------------------- ### Health Check Endpoint Example Source: https://github.com/magnusfroste/openjobs-api/blob/main/docs/architecture/MICROSERVICES_MIGRATION.md Demonstrates how to perform a health check on a connector microservice using curl, targeting the RemoteOK plugin. ```bash curl http://localhost:8084/health ``` -------------------------------- ### Register for API Key Source: https://github.com/magnusfroste/openjobs-api/blob/main/README.md This bash snippet outlines the steps to register for an API key by visiting the registration page. ```bash # Visit the registration page https://openjobs-web.vercel.app/register # Fill in: - Company name - Email - Website (optional) # ✅ Your API key is generated instantly! ``` -------------------------------- ### Chromedp Cloudflare Bypass Example Source: https://github.com/magnusfroste/openjobs-api/blob/main/connectors/indeed-chrome/README.md Shows how to use chromedp to navigate to a URL with a real Chrome browser, effectively bypassing Cloudflare. ```go // Real Chrome browser ctx := chromedp.NewContext() chromedp.Run(ctx, chromedp.Navigate(url)) // ✅ Bypasses Cloudflare ```