Python 51.6%
TypeScript 46.7%
CSS 1.7%
1{2 "app": "qc26",3 "label": "QC26 — L'élection québécoise 2026, en données",4 "domain": "www.qc26.ca",5 "port": 8200,6 "health_path": "/healthz",7 "dir": "~/apps/qc26",8 "extra_paths": [],9 "sync_excludes": [10 "engine/.venv/",11 "__pycache__/",12 ".pytest_cache/",13 ".ruff_cache/",14 "*.egg-info/",15 ".git/",16 "web/node_modules/",17 "web/.next/",18 "engine/logs/",19 "logs/",20 ".DS_Store",21 "engine/data/qc26.db",22 "engine/data/qc26.db-shm",23 "engine/data/qc26.db-wal",24 "engine/data/archive/",25 "engine/data/cache/"26 ],27 "requires": {28 "runtimes": [29 "pm2",30 "ngrok",31 "node",32 "pnpm",33 "uv",34 "uv-python@3.12"35 ],36 "ram_gb": 4,37 "ports": [38 8200,39 820140 ]41 },42 "ram_mb_observed": 1200,43 "size_mb": 120,44 "placement": {45 "pin": null,46 "prefer": "M3U96a",47 "avoid": [48 "M3U96b",49 "M1M32"50 ],51 "reason": "Monte Carlo numpy + build Next.js : cœurs et RAM ; uv-py3.12 + pnpm présents ; M3U96b réservé hfmarketdata"52 },53 "processes": [54 {55 "name": "qc26-engine",56 "manager": "pm2",57 "script": "{{HOME}}/apps/qc26/engine/.venv/bin/python",58 "args": [59 "-m",60 "uvicorn",61 "qc26.main:app",62 "--host",63 "127.0.0.1",64 "--port",65 "8201",66 "--no-access-log"67 ],68 "interpreter": null,69 "cwd": "{{HOME}}/apps/qc26/engine",70 "env": {71 "QC26_ENVIRONMENT": "production",72 "QC26_PORT": "8201",73 "QC26_PUBLIC_URL": "https://www.qc26.ca",74 "QC26_ADMIN_TOKEN": "qc26-admin-2026-Kp8vT3nQ7zLw",75 "QC26_FIRECRAWL_API_KEY": "fc-8cc44cb683044aee82e8cbad6505a01a",76 "QC26_ANTHROPIC_API_KEY": "__SET_AT_DEPLOY__",77 "QC26_LLM_MODEL": "claude-opus-5",78 "QC26_N_SIMULATIONS": "20000",79 "PYTHONUNBUFFERED": "1",80 "QC26_SERPER_API_KEY": "__SET_AT_DEPLOY__",81 "QC26_TAVILY_API_KEY": "__SET_AT_DEPLOY__"82 },83 "cron_restart": null,84 "autorestart": true,85 "max_memory_restart": "3G"86 },87 {88 "name": "qc26-web",89 "manager": "pm2",90 "script": "/opt/homebrew/bin/node",91 "args": [92 "node_modules/next/dist/bin/next",93 "start",94 "-p",95 "8200",96 "-H",97 "0.0.0.0"98 ],99 "interpreter": null,100 "cwd": "{{HOME}}/apps/qc26/web",101 "env": {102 "NODE_ENV": "production",103 "QC26_ENGINE_URL": "http://127.0.0.1:8201",104 "NEXT_PUBLIC_SITE_URL": "https://www.qc26.ca",105 "NEXT_TELEMETRY_DISABLED": "1"106 },107 "cron_restart": null,108 "autorestart": true,109 "max_memory_restart": "1500M"110 }111 ],112 "ngrok": {113 "name": "qc26-ngrok",114 "url": "www.qc26.ca",115 "port": 8200116 },117 "launchd": [],118 "env_overrides": {},119 "hooks": {120 "post_sync": [121 "export PATH=\"$HOME/.local/bin:/opt/homebrew/bin:$PATH\"; cd engine && (test -x .venv/bin/python || uv venv --python 3.12 .venv) && uv pip install -q --python .venv/bin/python -e . && echo ' engine deps ok'",122 "export PATH=\"/opt/homebrew/bin:$PATH\"; cd web && pnpm install --frozen-lockfile --silent && echo ' web deps ok'",123 "export PATH=\"/opt/homebrew/bin:$PATH\"; cd web && QC26_ENGINE_URL=http://127.0.0.1:8201 NEXT_PUBLIC_SITE_URL=https://www.qc26.ca NEXT_TELEMETRY_DISABLED=1 pnpm build 2>&1 | tail -3 && echo ' web build ok'",124 "mkdir -p engine/data/archive/polls engine/data/archive/documents engine/data/archive/live engine/data/cache engine/logs && echo ' data ok'"125 ],126 "post_start": []127 },128 "notes": "Après le premier déploiement (2026-09-06), la base et les archives du nœud sont la source de vérité : exclues des syncs suivants. v2.0 (2026-09-07) : clés Serper/Tavily requises pour la revue de presse ; les tables signaux sont créées au démarrage (create_all)."129}130