Synaplan
开源 AI 软件平台,面向企业:自托管 AI 代理,符合 GDPR 的聊天机器人小部件,RAG 知识库,WhatsApp 与 Outlook AI,MCP,多模型路由。支持 Docker、Kubernetes 或在 Germ 托管。
AI 翻译
Open-source, compliance-first remote job platform for the EU market.
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗OpenJobsEU is an open-source, compliance-first project focused on aggregating legally accessible, EU-wide remote job offers.
The project is backend-first and infrastructure-oriented. It leverages a modern Serverless stack on Google Cloud to provide a zero-maintenance, zero-compute public feed, while the FastAPI runtime itself stays private behind Cloud Run IAM.
feed.json is refreshed by the runtime maintenance pipeline, while frontend/index.html, frontend/style.css, and frontend/feed.js are published separately by CI after a successful production deploy. Both are served from Google Cloud Storage/CDN, and runtime endpoints such as /jobs, /companies, and /jobs/stats/compliance-7d remain private Cloud Run interfaces in production rather than public internet APIs.APP_RUNTIME=local), the system falls back to dummy placeholders to ensure low friction.GROUPING SETS for real-time audit aggregations.dev and prod now run in DB_MODE=standard against Aiven PostgreSQL via DATABASE_URL.Detailed documentation detailing the design decisions and data flows is located in the docs/ directory:
Note: OpenJobsEU does not engage in scraping closed/protected platforms, nor does it automate applications.
ci.yml runs the full pytest suite for pull requests targeting main and develop. This is the required status check that should block merges until green.pre-commit.yml continues to validate pre-commit hooks and Commitizen commit-message compliance on pull requests.terraform-plan.yml runs terraform validate and terraform plan on pull requests that touch infra/**.dev_flow.yml deploys after pushes to develop (typically after merge), and prod_flow.yml handles release/deploy steps after pushes to main. Neither workflow runs on pull requests.ci.yml/pre-commit.yml. The deploy workflows run only after the merge commit lands on develop or main.sync_main_to_develop.yml keeps develop aligned with release changes merged to main, and protect_develop.yml recreates develop if the branch is deleted.main and develop so the required status check includes CI / pytest before merge.feed.jsonapp/workers/frontend_exporter.py executed from the private backend pipeline.feed.json.Cache-Control: public, max-age=300.prod_flow.yml, only after the production deploy job finishes successfully.scripts/publish_frontend_assets.py, which reuses run_frontend_export(..., sync_assets=True) from app/workers/frontend_exporter.py.frontend/index.html, frontend/style.css, frontend/feed.js.frontend/index.html is published by CI/CD and remains the release-controlled entrypoint.frontend/style.css and frontend/feed.js are also published by CI/CD, not by the runtime worker.?v=<release tag or commit SHA> into the index.html references to style.css and feed.js, which provides simple cache busting for frontend changes without coupling asset deploys to feed.json refreshes.feed.json, while asset publication can use a separate deploy credential.The repository now assumes OIDC-based federation between GitHub Actions and Google Cloud instead of long-lived JSON keys.
token.actions.githubusercontent.com.dev-openjobseu and openjobseu).aergaroth/openjobseu.dev trust accepts only:
push / workflow_dispatch runs from refs/heads/developpull_request runs whose base_ref is developprod trust accepts only:
push / workflow_dispatch runs from refs/heads/mainpull_request runs whose base_ref is maingithub-deploy (dev/prod): builds and pushes the container image, runs terraform apply, and therefore needs Artifact Registry write access, Terraform state bucket object access, Cloud Run/Scheduler/Tasks admin, Secret Manager admin, project IAM admin, plus iam.serviceAccountUser on the runtime and scheduler identities.github-terraform-plan (dev/prod): used only by PR plans; it gets read-only access to the Terraform state bucket and project metadata (roles/viewer + roles/secretmanager.viewer).github-assets-publish (prod): used only after a successful production deploy to publish frontend/index.html, frontend/style.css, and frontend/feed.js; it only receives roles/storage.objectAdmin on the public bucket.feed.json).terraform applyCreate/update GitHub repository variables (not secrets) with the Terraform outputs from each environment:
GCP_WIF_PROVIDER_DEVGCP_SERVICE_ACCOUNT_DEVGCP_SERVICE_ACCOUNT_TERRAFORM_PLAN_DEVGCP_WIF_PROVIDER_PRODGCP_SERVICE_ACCOUNT_PRODGCP_SERVICE_ACCOUNT_TERRAFORM_PLAN_PRODGCP_SERVICE_ACCOUNT_ASSETS_PRODThe remaining application secrets (DEV_GOOGLE_CLIENT_SECRET, PROD_GOOGLE_API_KEY, etc.) stay in GitHub Secrets because they are application data, not cloud authentication material.
terraform apply in infra/gcp/dev and infra/gcp/prod to create the workload identity pools/providers, service accounts, and IAM bindings.terraform-plan.yml, dev_flow.yml, and prod_flow.yml once to confirm OIDC authentication works end to end.GCP_SA_KEY_DEV and GCP_SA_KEY_PROD.Most tests expect PostgreSQL. CI starts postgres:16 and uses:
DB_MODE=standardDATABASE_URL=postgresql+psycopg://postgres:postgres@localhost:5432/testdbNote: The test suite explicitly blocks external HTTP requests to prevent accidental hangs or timeouts. Fast DELETE sweeps are used over TRUNCATE CASCADE for near-instant teardowns.
Local pattern:
# start postgres
docker run --rm --name openjobspg -e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=testdb -p 5432:5432 -d postgres:16
make check still runs compile and pre-commit --all-files, but when the
local PostgreSQL test database is unavailable it now marks the pytest hook as
Skipped instead of letting it appear as Passed after a fully skipped test
session.