feat(finlab): dashboard web (graphiques/portefeuille/actions) + fix seed NFS

Ajoute une interface graphique à finlab, en plus de la console Claude Code (les
deux cohabitent sur finance.lab.local) :

- dashboard/ : backend FastAPI (sans LLM/clé) exposant les données finlab en JSON
  (/api/portfolio, /api/scan, /api/ohlc, /api/plan, /api/alerts) + front statique
  (lightweight-charts) : graphiques chandeliers MM50/200 + volume, portefeuille
  (P&L/poids/secteurs), watchlists thématiques scannées, alertes, plan de trade R:R
- Découplage code/data : finlab lit ses configs depuis FINLAB_HOME si défini
  (workspace persistant) ; repli sur le dossier du package en dév local
- Image double usage (un build, deux conteneurs) : code → /opt/app, seed minimal
  (configs + persona + MCP) → workspace
- Fix seed NFS (cause racine du workspace vide) : WORKDIR n'est plus sur le volume
  (le runtime le créait en root sur NFS) ; seed déplacé dans un initContainer
  robuste (recrée le dossier s'il est non-inscriptible)
- Deployment : initContainer seed + 2 conteneurs (console ttyd -b /console, dashboard
  uvicorn) ; Service 2 ports ; IngressRoute 2 routes (/console + dashboard), basicAuth

Validé en local (podman) : seed OK, dashboard /api/portfolio → 16k€/10 positions
via FINLAB_HOME, endpoints ohlc/scan/plan/alerts OK, ttyd/claude/finlab présents.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
alkatrazz 2026-06-30 00:54:11 +02:00
parent 607e5e6c0a
commit a2b39a084b
19 changed files with 700 additions and 149 deletions

View file

@ -1,13 +1,11 @@
# funk-finlab — console Claude Code web, spécialisée finance.
#
# Une vraie session Claude Code (sur l'ABONNEMENT de l'utilisateur, login persisté sur le
# PVC) servie dans un terminal web (ttyd), dans un workspace où vit la boîte à outils finlab
# (exposée en MCP). C'est l'esprit OpenAlice, mais c'est Claude Code + le toolkit maison —
# aucune facturation API, aucun broker, lecture/analyse uniquement.
# funk-finlab — image double usage (un seul build, deux conteneurs en déploiement) :
# • CONSOLE : session Claude Code dans un terminal web (ttyd), abonnement persisté.
# • DASHBOARD : interface web (graphiques marché / portefeuille / watchlists / actions).
# Les deux partagent le workspace persistant (PVC) où vivent les CONFIGS éditables (portefeuille,
# watchlists, alertes) ; le CODE finlab vit dans l'image (/opt/app) et se met à jour avec elle.
FROM python:3.12-slim-bookworm
# Node (pour le CLI claude-code) + git + tini (PID 1 propre). ttyd n'est PAS dans les dépôts
# Debian bookworm → on récupère le binaire statique (musl) depuis les releases GitHub (pin).
# Node (CLI claude-code) + git + tini. ttyd n'est pas packagé sur bookworm → binaire statique.
ARG TTYD_VERSION=1.7.7
RUN apt-get update && apt-get install -y --no-install-recommends \
curl ca-certificates git tini procps \
@ -21,35 +19,39 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
&& npm cache clean --force \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
# Dépendances Python de finlab dans un venv dédié (séparé du workspace, donc non altérable
# depuis la session). finlab lui-même est importé depuis le workspace (PYTHONPATH au runtime).
# Dépendances Python (venv dédié, hors du workspace).
COPY requirements.txt /opt/finlab/requirements.txt
RUN python -m venv /opt/venv \
&& /opt/venv/bin/pip install --no-cache-dir -r /opt/finlab/requirements.txt
# « Seed » du workspace : copié dans le PVC au premier boot (sans écraser les edits ensuite).
# Contient le code finlab, les configs (portefeuille/watchlists/alertes), la persona Claude
# (CLAUDE.md), le branchement MCP finlab et les réglages d'autorisation.
COPY finlab/ /opt/seed/finlab/
COPY webapp/ /opt/seed/webapp/
# CODE applicatif (mis à jour avec l'image) : package finlab + backend dashboard + webapp (option).
COPY finlab/ /opt/app/finlab/
COPY dashboard/ /opt/app/dashboard/
COPY webapp/ /opt/app/webapp/
# « Seed » du workspace : UNIQUEMENT ce que l'utilisateur édite/possède (pas de code).
# Configs finlab + persona Claude + branchement MCP + autorisations. Copié dans le PVC au
# 1er boot par l'initContainer (cp -rn no-clobber → edits préservés ensuite).
COPY portfolio.yaml watchlists.yaml alerts.yaml /opt/seed/
COPY workspace/CLAUDE.md /opt/seed/CLAUDE.md
COPY workspace/.mcp.json /opt/seed/.mcp.json
COPY workspace/.claude/ /opt/seed/.claude/
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
COPY entrypoint-seed.sh entrypoint-console.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/entrypoint-seed.sh /usr/local/bin/entrypoint-console.sh
# uid non-root (PodSecurity « restricted » du namespace ai). HOME et workspace vivent sur le
# PVC monté en /home/finlab : ainsi ~/.claude (login abonnement) ET le workspace persistent.
# uid non-root (PodSecurity « restricted »). HOME = PVC (login abonnement + workspace).
# WORKDIR reste sur /opt/app (PAS sur le volume) : sinon le runtime crée le dossier du workspace
# en root sur le NFS avant le process → seed cassé (bug corrigé). Le seed/console font le cd.
RUN useradd -m -u 1000 -s /bin/bash finlab
ENV HOME=/home/finlab \
WORKSPACE=/home/finlab/workspace \
FINLAB_HOME=/home/finlab/workspace \
PATH=/opt/venv/bin:/usr/local/bin:/usr/bin:/bin \
PYTHONPATH=/home/finlab/workspace \
PYTHONPATH=/opt/app \
PYTHONUNBUFFERED=1 \
TZ=Europe/Paris
USER 1000
WORKDIR /home/finlab/workspace
EXPOSE 7681
ENTRYPOINT ["tini", "--", "/usr/local/bin/entrypoint.sh"]
WORKDIR /opt/app
# Pas d'ENTRYPOINT unique : le Deployment fixe la commande par conteneur
# (entrypoint-seed.sh en initContainer, entrypoint-console.sh + uvicorn en conteneurs).