{
  "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"
      },
      "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."
}