1{2 "app": "findata",3 "label": "FinData OS — private financial data lakehouse (findata.spboucher.ai)",4 "domain": "findata.spboucher.ai",5 "port": 8600,6 "health_path": "/api/v1/health",7 "dir": "~/apps/findata",8 "extra_paths": [],9 "sync_excludes": [10 ".git/",11 ".DS_Store",12 ".venv/",13 "apps/web/node_modules/",14 "apps/web/.next/",15 "apps/web/out/",16 "data/",17 "logs/",18 "backups/",19 ".env",20 "__pycache__/",21 ".pytest_cache/",22 ".ruff_cache/",23 "tests/_tmp/"24 ],25 "requires": {26 "runtimes": [27 "uv",28 "node",29 "pnpm",30 "pm2",31 "postgresql@17"32 ],33 "ram_gb": 6,34 "disk_gb": 1500,35 "ports": [36 860037 ]38 },39 "ram_mb_observed": 900,40 "size_mb": 20,41 "placement": {42 "pin": "M3U96a",43 "prefer": "M3U96a",44 "avoid": [45 "M1M32"46 ],47 "reason": "Storage node chosen in docs/DISCOVERY.md: 1 TB Apple NVMe (508 GB free, SMART verified, 5 GB/s), 32 cores / 96 GB for DuckDB, Postgres 17 + Redis already local, wg1 10.67.0.10. Lake at ~/findata-lake (outside the app dir)."48 },49 "processes": [50 {51 "name": "findata-api",52 "manager": "pm2",53 "script": "{{HOME}}/apps/findata/.venv/bin/python",54 "args": [55 "-m",56 "uvicorn",57 "findata_api.main:app",58 "--host",59 "0.0.0.0",60 "--port",61 "8600",62 "--workers",63 "1"64 ],65 "interpreter": null,66 "cwd": "{{HOME}}/apps/findata",67 "env": {68 "FINDATA_ROOT": "{{HOME}}/apps/findata",69 "PATH": "/opt/homebrew/opt/postgresql@17/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin"70 },71 "cron_restart": null,72 "autorestart": true,73 "max_memory_restart": "6G"74 },75 {76 "name": "findata-worker",77 "manager": "pm2",78 "script": "{{HOME}}/apps/findata/.venv/bin/python",79 "args": [80 "-m",81 "findata_ingest.cli",82 "worker"83 ],84 "interpreter": null,85 "cwd": "{{HOME}}/apps/findata",86 "env": {87 "FINDATA_ROOT": "{{HOME}}/apps/findata",88 "PATH": "/opt/homebrew/opt/postgresql@17/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin"89 },90 "cron_restart": null,91 "autorestart": true,92 "max_memory_restart": "24G"93 },94 {95 "name": "findata-bulk-1",96 "manager": "pm2",97 "script": "{{HOME}}/apps/findata/.venv/bin/python",98 "args": [99 "-m",100 "findata_ingest.cli",101 "worker",102 "--role",103 "bulk"104 ],105 "interpreter": null,106 "cwd": "{{HOME}}/apps/findata",107 "env": {108 "FINDATA_ROOT": "{{HOME}}/apps/findata",109 "PATH": "/opt/homebrew/opt/postgresql@17/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin"110 },111 "cron_restart": null,112 "autorestart": true,113 "max_memory_restart": "12G"114 },115 {116 "name": "findata-bulk-2",117 "manager": "pm2",118 "script": "{{HOME}}/apps/findata/.venv/bin/python",119 "args": [120 "-m",121 "findata_ingest.cli",122 "worker",123 "--role",124 "bulk"125 ],126 "interpreter": null,127 "cwd": "{{HOME}}/apps/findata",128 "env": {129 "FINDATA_ROOT": "{{HOME}}/apps/findata",130 "PATH": "/opt/homebrew/opt/postgresql@17/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin"131 },132 "cron_restart": null,133 "autorestart": true,134 "max_memory_restart": "12G"135 },136 {137 "name": "findata-bulk-3",138 "manager": "pm2",139 "script": "{{HOME}}/apps/findata/.venv/bin/python",140 "args": [141 "-m",142 "findata_ingest.cli",143 "worker",144 "--role",145 "bulk"146 ],147 "interpreter": null,148 "cwd": "{{HOME}}/apps/findata",149 "env": {150 "FINDATA_ROOT": "{{HOME}}/apps/findata",151 "PATH": "/opt/homebrew/opt/postgresql@17/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin"152 },153 "cron_restart": null,154 "autorestart": true,155 "max_memory_restart": "12G"156 },157 {158 "name": "findata-bulk-4",159 "manager": "pm2",160 "script": "{{HOME}}/apps/findata/.venv/bin/python",161 "args": [162 "-m",163 "findata_ingest.cli",164 "worker",165 "--role",166 "bulk"167 ],168 "interpreter": null,169 "cwd": "{{HOME}}/apps/findata",170 "env": {171 "FINDATA_ROOT": "{{HOME}}/apps/findata",172 "PATH": "/opt/homebrew/opt/postgresql@17/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin"173 },174 "cron_restart": null,175 "autorestart": true,176 "max_memory_restart": "12G"177 }178 ],179 "ngrok": null,180 "launchd": [],181 "env_overrides": {},182 "hooks": {183 "post_sync": [184 "test -f .env || { echo 'ERREUR: .env absent (secrets) — copier ~/Desktop/Cluster/secrets/findata/.env'; exit 1; }; chmod 600 .env",185 "export PATH=\"/opt/homebrew/bin:$HOME/.local/bin:$PATH\"; uv sync --frozen 2>&1 | tail -1 && echo ' python deps ok'",186 "export PATH=\"/opt/homebrew/bin:$PATH\"; cd apps/web && pnpm install --frozen-lockfile --silent && pnpm build 2>&1 | tail -2 && echo ' web build ok'",187 "export PATH=\"/opt/homebrew/opt/postgresql@17/bin:/opt/homebrew/bin:$PATH\"; set -a; . ./.env; set +a; .venv/bin/python -m findata_ingest.cli migrate && echo ' migrations ok'",188 "mkdir -p ~/findata-lake logs && chmod 700 ~/findata-lake && echo ' lake dir ok'"189 ],190 "post_start": []191 },192 "ka_repo": false,193 "tunnel": {194 "domain": "findata.spboucher.ai",195 "gateway": "BHS64",196 "note": "DNS GoDaddy A findata.spboucher.ai → 51.161.112.61 vérifié le 2026-11-01 avant déploiement ; route Caddy posée par mld deploy ; findata-api écoute 0.0.0.0:8600 avec garde de provenance (loopback, wg1 10.67.0.0/16, LAN) ; Caddy → wg1 10.67.0.10:8600"197 },198 "notes": "Monorepo uv (Python 3.13) : services/api (FastAPI :8600, sert aussi la console Next.js statique apps/web/out), services/ingest (worker unique = verrou d'écriture du lac + ordonnanceur), lac Parquet ~/findata-lake, Postgres 17 local (DB findata, rôle findata). Secrets uniquement dans ~/apps/findata/.env (600) ; copie ~/Desktop/Cluster/secrets/findata/.env. Sauvegarde quotidienne 04:00 ET → M4M64a:~/backups/findata (rsync + pg_dump zstd). CLI : .venv/bin/findata status|discover|ingest … | 2026-11-01 soir : lac froid FINDATA_LAKE_COLD=/Volumes/ssd/findata (SSD externe 4 To, marqueur .findata-cold-root) pour les archives brutes et les datasets non « hot » ; 4 workers bulk (findata-bulk-1..4) pour backfill/options/fundamentals en parallèle ; téléchargement complet FirstRate lancé via `findata ingest backfill-all`."199}200