1
03-env.md
hack_23031391_8ff9d8 edited this page 2026-05-23 02:52:34 +00:00

Variables de Entorno

Configuración de .env para desarrollo local y producción.


Backend — .env

Crea basura_backend/.env:

# ========================================
# CONFIGURACIÓN DEL SIMULADOR
# ========================================

# Intervalo de actualización del camión (segundos)
SIM_TICK_SECONDS=10

# Umbral de ETA para notificar proximidad (minutos)
SIM_ETA_ALERT_MINUTES=10

# Multiplicador de velocidad del simulador
# 1.0 = tiempo real
# 2.0 = doble velocidad (útil para demos rápidas)
# 0.5 = mitad de velocidad (útil para debug)
SIM_SPEED_MULTIPLIER=1.0

# ========================================
# BASE DE DATOS
# ========================================

# Ruta del archivo SQLite
DATABASE_PATH=./basura.db

# ========================================
# SERVIDOR
# ========================================

# Host (0.0.0.0 para aceptar conexiones externas)
HOST=0.0.0.0

# Puerto del servidor
PORT=8000

# Hot reload en desarrollo (True/False)
RELOAD=True

# ========================================
# CORS (desarrollo)
# ========================================

# Permitir todos los orígenes en desarrollo
# En producción, especificar dominios exactos
CORS_ORIGINS=*

# ========================================
# JWT (para cuando Persona A integre auth)
# ========================================

# Secret key para firmar tokens JWT
# CAMBIAR EN PRODUCCIÓN a una clave aleatoria fuerte
JWT_SECRET=super-secret-key-change-in-production

# Expiración del token (minutos)
JWT_EXPIRATION_MINUTES=1440  # 24 horas

# ========================================
# LOGGING
# ========================================

# Nivel de log: DEBUG, INFO, WARNING, ERROR
LOG_LEVEL=INFO

Usar las variables en el código

# app/core/config.py
from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    sim_tick_seconds: int = 10
    sim_eta_alert_minutes: int = 10
    sim_speed_multiplier: float = 1.0
    database_path: str = "./basura.db"
    host: str = "0.0.0.0"
    port: int = 8000
    reload: bool = True
    
    class Config:
        env_file = ".env"

settings = Settings()

Frontend — .env (Flutter)

Flutter no soporta .env nativamente, pero hay opciones:

Opción A: Usar flutter_dotenv

1. Instalar:

# pubspec.yaml
dependencies:
  flutter_dotenv: ^5.1.0

2. Crear .env:

# basura_app/.env
API_BASE_URL=http://10.0.2.2:8000
WS_BASE_URL=ws://10.0.2.2:8000
ENVIRONMENT=development

3. Declarar en pubspec:

flutter:
  assets:
    - .env

4. Cargar en main.dart:

import 'package:flutter_dotenv/flutter_dotenv.dart';

Future<void> main() async {
  await dotenv.load(fileName: ".env");
  runApp(ProviderScope(child: MyApp()));
}

5. Usar en el código:

final baseUrl = dotenv.env['API_BASE_URL'] ?? 'http://localhost:8000';

Opción B: Flavors (recomendado para producción)

Permite tener configuraciones separadas para dev, staging, prod.

1. Crear archivos de configuración:

// lib/core/config/environment.dart
enum Environment { dev, staging, prod }

class EnvironmentConfig {
  final String apiBaseUrl;
  final String wsBaseUrl;
  final Environment env;
  
  const EnvironmentConfig({
    required this.apiBaseUrl,
    required this.wsBaseUrl,
    required this.env,
  });
  
  static const dev = EnvironmentConfig(
    apiBaseUrl: 'http://10.0.2.2:8000',
    wsBaseUrl: 'ws://10.0.2.2:8000',
    env: Environment.dev,
  );
  
  static const prod = EnvironmentConfig(
    apiBaseUrl: 'https://api.basura.onlinces.net',
    wsBaseUrl: 'wss://api.basura.onlinces.net',
    env: Environment.prod,
  );
}

2. Crear entry points:

// lib/main_dev.dart
void main() {
  runApp(ProviderScope(
    overrides: [
      envConfigProvider.overrideWithValue(EnvironmentConfig.dev),
    ],
    child: MyApp(),
  ));
}

// lib/main_prod.dart
void main() {
  runApp(ProviderScope(
    overrides: [
      envConfigProvider.overrideWithValue(EnvironmentConfig.prod),
    ],
    child: MyApp(),
  ));
}

3. Correr según entorno:

# Desarrollo
fvm flutter run -t lib/main_dev.dart

# Producción
fvm flutter run -t lib/main_prod.dart --release

Configuraciones específicas por entorno

Desarrollo Local

Backend:

SIM_TICK_SECONDS=5           # Más rápido para debug
SIM_SPEED_MULTIPLIER=2.0     # Doble velocidad
LOG_LEVEL=DEBUG              # Logs detallados

Flutter:

API_BASE_URL=http://10.0.2.2:8000     # Emulador Android
WS_BASE_URL=ws://10.0.2.2:8000

Demo en Hackathon

Backend:

SIM_TICK_SECONDS=10          # Velocidad normal
SIM_ETA_ALERT_MINUTES=5      # Notificar más rápido
SIM_SPEED_MULTIPLIER=1.5     # Un poco más rápido para demo

Flutter:

API_BASE_URL=http://192.168.x.x:8000  # IP de la PC del presentador
WS_BASE_URL=ws://192.168.x.x:8000

Producción (si despliegan después del hackathon)

Backend:

SIM_TICK_SECONDS=10
SIM_ETA_ALERT_MINUTES=10
SIM_SPEED_MULTIPLIER=1.0
DATABASE_PATH=/var/basura/basura.db
HOST=0.0.0.0
PORT=8000
RELOAD=False
CORS_ORIGINS=https://basura.onlinces.net
JWT_SECRET=<generado con secrets.token_urlsafe(32)>
LOG_LEVEL=WARNING

Flutter:

API_BASE_URL=https://api.basura.onlinces.net
WS_BASE_URL=wss://api.basura.onlinces.net

Secretos sensibles — NO commitear

.gitignore debe incluir:

# Backend
basura_backend/.env
basura_backend/*.db
basura_backend/venv/

# Flutter
basura_app/.env
basura_app/.env.*
basura_app/build/
basura_app/.fvm/

# Secretos
*.key
*.pem
*.p12

Provider compartido para configuración (Flutter)

// lib/core/config/env_provider.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'environment.dart';

final envConfigProvider = Provider<EnvironmentConfig>((ref) {
  throw UnimplementedError('EnvConfig debe ser overridden en main.dart');
});

final apiBaseUrlProvider = Provider<String>((ref) {
  return ref.watch(envConfigProvider).apiBaseUrl;
});

final wsBaseUrlProvider = Provider<String>((ref) {
  return ref.watch(envConfigProvider).wsBaseUrl;
});

Testing con diferentes configuraciones

Backend

# Dev rápido
SIM_TICK_SECONDS=1 SIM_SPEED_MULTIPLIER=10.0 uvicorn app.main:app

# Demo lento (explicar paso a paso)
SIM_TICK_SECONDS=30 uvicorn app.main:app

Flutter

# Probar contra backend local
fvm flutter run --dart-define=API_URL=http://10.0.2.2:8000

# Probar contra staging
fvm flutter run --dart-define=API_URL=https://staging.basura.net

Siguiente paso