Entorno Reproducible con Flox — LeadFlow AI

SaaS B2B de cualificación automática de leads · Stack Python + Node + PostgreSQL + Redis + IA

Flox 1.3 Nix • 150k+ pkgs Python 3.11 • Node 20 • PG 16 macOS ARM/Intel • Linux x86/ARM
📄

.flox/env/manifest.toml — Manifiesto completo

.flox/env/manifest.toml TOML • Flox Environment Definition
# =============================================================
# LeadFlow AI — Entorno de desarrollo reproducible con Flox
# Commit: git add .flox/ && git commit -m "feat: flox env"
# Onboarding: git clone <repo> && cd leadflow && flox activate --start-services
# =============================================================

[install]
# ── Python Stack ─────────────────────────────────────────────
python.pkg-path    = "python311"
python.pkg-group   = "python-stack"
uv.pkg-path        = "uv"
uv.pkg-group       = "python-stack"

# ── Backend de IA / ML ────────────────────────────────────────
# (Paquetes Python instalados via uv en el hook, no aqui)

# ── Node.js (dashboard Next.js) ───────────────────────────────
nodejs.pkg-path    = "nodejs"
nodejs.version     = "^20.0"

# ── Bases de datos ────────────────────────────────────────────
postgresql.pkg-path = "postgresql_16"
redis.pkg-path      = "redis"

# ── Utilidades de desarrollo ──────────────────────────────────
jq.pkg-path         = "jq"
curl.pkg-path       = "curl"
httpie.pkg-path     = "httpie"
git.pkg-path        = "git"
ripgrep.pkg-path    = "ripgrep"

# ── Especificos de Linux ──────────────────────────────────────
valgrind.pkg-path   = "valgrind"
valgrind.systems    = ["x86_64-linux", "aarch64-linux"]

# ── Especificos de macOS ──────────────────────────────────────
coreutils.pkg-path  = "coreutils"
coreutils.systems   = ["x86_64-darwin", "aarch64-darwin"]

[vars]
# ── Rutas de cache (portables, usan variables de Flox) ────────
UV_CACHE_DIR       = "$FLOX_ENV_CACHE/uv-cache"
PIP_CACHE_DIR      = "$FLOX_ENV_CACHE/pip-cache"
GOPATH             = "$FLOX_ENV_CACHE/go"

# ── Base de datos ─────────────────────────────────────────────
DATABASE_URL       = "postgres://leadflow:leadflow@localhost:5432/leadflow_dev"
REDIS_URL          = "redis://localhost:6379"
PGDATA             = "$FLOX_ENV_CACHE/pgdata"
PGHOST             = "$FLOX_ENV_CACHE"

# ── Aplicacion ────────────────────────────────────────────────
ML_MODEL_PATH      = "$FLOX_ENV_PROJECT/models"
LOG_LEVEL          = "DEBUG"
PYTHONDONTWRITEBYTECODE = "1"

# ── Secretos: NUNCA hardcodear, referenciar del entorno ───────
OPENAI_API_KEY     = "${OPENAI_API_KEY:-}"   # export antes de flox activate
DATABASE_PASSWORD  = "${DATABASE_PASSWORD:-leadflow}"

[hook]
# Ejecutado en cada activacion (no-interactivo, debe ser rapido e idempotente)
on-activate = """
  # ── 1. Inicializar PostgreSQL si no existe ─────────────────
  if [ ! -d "$FLOX_ENV_CACHE/pgdata" ]; then
    echo "[flox] Inicializando PostgreSQL en $FLOX_ENV_CACHE/pgdata..."
    initdb -D "$FLOX_ENV_CACHE/pgdata" \\
      --no-locale --encoding=UTF8 \\
      --username=leadflow 2>/dev/null
    echo "host all all 127.0.0.1/32 trust" \\
      >> "$FLOX_ENV_CACHE/pgdata/pg_hba.conf"
    echo "[flox] PostgreSQL inicializado."
  fi

  # ── 2. Virtualenv Python con uv ───────────────────────────
  venv="$FLOX_ENV_CACHE/venv"
  if [ ! -d "$venv" ]; then
    echo "[flox] Creando virtualenv Python 3.11..."
    uv venv "$venv" --python python3 --quiet
  fi
  if [ -f "$venv/bin/activate" ]; then
    source "$venv/bin/activate"
  fi

  # ── 3. Instalar dependencias Python (una sola vez) ────────
  stamp="$FLOX_ENV_CACHE/.py_deps_ok"
  req="$FLOX_ENV_PROJECT/requirements.txt"
  if [ -f "$req" ] && [ ! -f "$stamp" ]; then
    echo "[flox] Instalando dependencias Python..."
    uv pip install --python "$venv/bin/python" -r "$req" --quiet
    touch "$stamp"
    echo "[flox] Dependencias Python instaladas."
  fi

  # ── 4. Instalar dependencias Node.js (una sola vez) ───────
  if [ -f "$FLOX_ENV_PROJECT/package.json" ] && \\
     [ ! -d "$FLOX_ENV_PROJECT/node_modules" ]; then
    echo "[flox] Instalando dependencias npm..."
    cd "$FLOX_ENV_PROJECT" && npm install --silent
    echo "[flox] node_modules listo."
  fi
"""

[profile]
# Funciones disponibles en el shell interactivo del desarrollador
common = """
  # ── Comandos de desarrollo ─────────────────────────────────
  api()      { uvicorn app.main:app --reload --host 0.0.0.0 --port 8000; }
  worker()   { python -m app.worker; }
  web()      { cd "$FLOX_ENV_PROJECT" && npm run dev; }
  migrate()  { alembic upgrade head; }
  seed()     { python scripts/seed_db.py; }

  # ── Base de datos ──────────────────────────────────────────
  psql-dev() { psql -h "$FLOX_ENV_CACHE" -U leadflow -d leadflow_dev; }
  db-reset() {
    echo "Eliminando y recreando DB leadflow_dev..."
    dropdb  -h "$FLOX_ENV_CACHE" -U leadflow leadflow_dev --if-exists
    createdb -h "$FLOX_ENV_CACHE" -U leadflow leadflow_dev
    migrate
    seed
  }

  # ── Tests ──────────────────────────────────────────────────
  tests()    { pytest tests/ -v --tb=short "$@"; }
  test-cov() { pytest tests/ --cov=app --cov-report=html; }

  # ── Utilidades ─────────────────────────────────────────────
  env-check() {
    echo "DATABASE_URL : $DATABASE_URL"
    echo "REDIS_URL    : $REDIS_URL"
    echo "ML_MODEL_PATH: $ML_MODEL_PATH"
    echo "Python       : $(python --version)"
    echo "Node         : $(node --version)"
    echo "psql         : $(psql --version)"
  }
"""

[services]
# Arrancados con: flox activate --start-services
postgres.command = "postgres -D $FLOX_ENV_CACHE/pgdata -k $FLOX_ENV_CACHE -p 5432"
redis.command    = "redis-server --port 6379 --daemonize no --loglevel warning"

[options]
systems = [
  "x86_64-linux",
  "aarch64-linux",
  "x86_64-darwin",
  "aarch64-darwin"
]
📦

Paquetes instalados

🐍
python311 + uv
pkg-group: python-stack (resuelven juntos)
3.11.x
🟢
nodejs
Dashboard Next.js 14 + TypeScript
^20.0
🐘
postgresql_16
Base de datos principal + embeddings
16.x
redis
Colas de scoring IA + caché
7.x
🔧
jq • curl • httpie
Debugging de APIs y scripts de datos
latest
🔍
ripgrep • git
Búsqueda y control de versiones
latest
🖥

Compatibilidad de plataformas

macOS
ARM64
macOS
Intel
🐧
Linux
x86_64
🐧
Linux
ARM64
1 manifiesto. Funciona idéntico en los 5 ordenadores del equipo y en GitHub Actions — sin contenedores, sin sudo, sin "en mi máquina funciona".

Servicios locales

PostgreSQL 16 :5432
Redis 7 :6379
$ flox activate --start-services
Los dos servicios arrancan con un solo comando. Sin Docker, sin docker-compose.
🔑

Variables de entorno — patrón seguro

DATABASE_URL
postgres://leadflow:leadflow@localhost:5432/leadflow_dev
REDIS_URL
redis://localhost:6379
ML_MODEL_PATH
$FLOX_ENV_PROJECT/models  (portabl, nunca ruta absoluta)
UV_CACHE_DIR
$FLOX_ENV_CACHE/uv-cache  (persistente entre activaciones)
OPENAI_API_KEY
${OPENAI_API_KEY:-}  — secreto referenciado, NO guardado en el manifiesto
🚀

Onboarding en 10 minutos — dev nuevo a primer commit

1
Instalar Flox (una sola vez por máquina)
$ curl -sSf https://install.flox.dev | sh
macOS: también disponible via Homebrew — brew install flox
2
Clonar el repo
$ git clone git@github.com:leadflow-ai/api.git && cd api
El directorio .flox/ ya viene en el repo con el manifiesto
3
Exportar secretos (una sola vez)
$ export OPENAI_API_KEY="sk-..."
Agregar al ~/.zshrc o ~/.bashrc para persistencia
4
Activar entorno y arrancar servicios
$ flox activate --start-services
Flox descarga paquetes, crea virtualenv, instala deps Python y npm, inicia PostgreSQL y Redis automáticamente
5
Levantar el stack completo
$ api     # FastAPI en :8000     $ web   # Next.js en :3000
Los alias api(), web(), migrate(), tests() están disponibles en el shell activado
Tiempo total de onboarding: ~8 minutos (descarga de paquetes Nix incluida). Sin leer wikis, sin resolver conflictos de versiones, sin sudo.
🤖

Workflow para agentes IA (Claude Code) — sin sudo, sin sandbox

agent-workflow.sh — Claude Code añade herramientas sin privilegios
# El agente necesita una herramienta nueva → la añade al proyecto sin sudo
flox search pgvector                    # 1. Verificar que existe en Nix
flox install pgvector                   # 2. Instalar en el entorno del proyecto

# O editar el manifiesto directamente para control total
tmp="$(mktemp)"
flox list -c > "$tmp"                   # 3. Exportar manifiesto actual
# Claude edita $tmp añadiendo pgvector al [install] ...
flox edit -f "$tmp"                     # 4. Aplicar cambios

# Ejecutar comandos con la herramienta nueva disponible
flox activate -- psql -U leadflow -c "CREATE EXTENSION pgvector;"

# Commitear el entorno actualizado → todos los devs reciben el cambio
git add .flox/ && git commit -m "feat: add pgvector for semantic lead search"