{
 "app": "qc26",
 "label": "QC26 — L'élection québécoise 2026, en données",
 "domain": "www.qc26.ca",
 "port": 8200,
 "health_path": "/healthz",
 "dir": "~/apps/qc26",
 "extra_paths": [],
 "sync_excludes": [
  "engine/.venv/",
  "__pycache__/",
  ".pytest_cache/",
  ".ruff_cache/",
  "*.egg-info/",
  ".git/",
  "web/node_modules/",
  "web/.next/",
  "engine/logs/",
  "logs/",
  ".DS_Store",
  "engine/data/qc26.db",
  "engine/data/qc26.db-shm",
  "engine/data/qc26.db-wal",
  "engine/data/archive/",
  "engine/data/cache/"
 ],
 "requires": {
  "runtimes": [
   "pm2",
   "ngrok",
   "node",
   "pnpm",
   "uv",
   "uv-python@3.12"
  ],
  "ram_gb": 4,
  "ports": [
   8200,
   8201
  ]
 },
 "ram_mb_observed": 1200,
 "size_mb": 120,
 "placement": {
  "pin": null,
  "prefer": "M3U96a",
  "avoid": [
   "M3U96b",
   "M1M32"
  ],
  "reason": "Monte Carlo numpy + build Next.js : cœurs et RAM ; uv-py3.12 + pnpm présents ; M3U96b réservé hfmarketdata"
 },
 "processes": [
  {
   "name": "qc26-engine",
   "manager": "pm2",
   "script": "{{HOME}}/apps/qc26/engine/.venv/bin/python",
   "args": [
    "-m",
    "uvicorn",
    "qc26.main:app",
    "--host",
    "127.0.0.1",
    "--port",
    "8201",
    "--no-access-log"
   ],
   "interpreter": null,
   "cwd": "{{HOME}}/apps/qc26/engine",
   "env": {
    "QC26_ENVIRONMENT": "production",
    "QC26_PORT": "8201",
    "QC26_PUBLIC_URL": "https://www.qc26.ca",
    "QC26_ADMIN_TOKEN": "qc26-admin-2026-Kp8vT3nQ7zLw",
    "QC26_FIRECRAWL_API_KEY": "fc-8cc44cb683044aee82e8cbad6505a01a",
    "QC26_ANTHROPIC_API_KEY": "__SET_AT_DEPLOY__",
    "QC26_LLM_MODEL": "claude-opus-5",
    "QC26_N_SIMULATIONS": "20000",
    "PYTHONUNBUFFERED": "1",
    "QC26_SERPER_API_KEY": "__SET_AT_DEPLOY__",
    "QC26_TAVILY_API_KEY": "__SET_AT_DEPLOY__"
   },
   "cron_restart": null,
   "autorestart": true,
   "max_memory_restart": "3G"
  },
  {
   "name": "qc26-web",
   "manager": "pm2",
   "script": "/opt/homebrew/bin/node",
   "args": [
    "node_modules/next/dist/bin/next",
    "start",
    "-p",
    "8200",
    "-H",
    "0.0.0.0"
   ],
   "interpreter": null,
   "cwd": "{{HOME}}/apps/qc26/web",
   "env": {
    "NODE_ENV": "production",
    "QC26_ENGINE_URL": "http://127.0.0.1:8201",
    "NEXT_PUBLIC_SITE_URL": "https://www.qc26.ca",
    "NEXT_TELEMETRY_DISABLED": "1"
   },
   "cron_restart": null,
   "autorestart": true,
   "max_memory_restart": "1500M"
  }
 ],
 "ngrok": {
  "name": "qc26-ngrok",
  "url": "www.qc26.ca",
  "port": 8200
 },
 "launchd": [],
 "env_overrides": {},
 "hooks": {
  "post_sync": [
   "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'",
   "export PATH=\"/opt/homebrew/bin:$PATH\"; cd web && pnpm install --frozen-lockfile --silent && echo '  web deps ok'",
   "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'",
   "mkdir -p engine/data/archive/polls engine/data/archive/documents engine/data/archive/live engine/data/cache engine/logs && echo '  data ok'"
  ],
  "post_start": []
 },
 "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)."
}
