Añadir 03-env.md
347
03-env.md.-.md
Normal file
347
03-env.md.-.md
Normal file
@@ -0,0 +1,347 @@
|
||||
# Variables de Entorno
|
||||
|
||||
Configuración de `.env` para desarrollo local y producción.
|
||||
|
||||
---
|
||||
|
||||
## Backend — `.env`
|
||||
|
||||
Crea `basura_backend/.env`:
|
||||
|
||||
```bash
|
||||
# ========================================
|
||||
# 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
|
||||
|
||||
```python
|
||||
# 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:**
|
||||
```yaml
|
||||
# pubspec.yaml
|
||||
dependencies:
|
||||
flutter_dotenv: ^5.1.0
|
||||
```
|
||||
|
||||
**2. Crear `.env`:**
|
||||
```bash
|
||||
# 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:**
|
||||
```yaml
|
||||
flutter:
|
||||
assets:
|
||||
- .env
|
||||
```
|
||||
|
||||
**4. Cargar en main.dart:**
|
||||
```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:**
|
||||
```dart
|
||||
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:**
|
||||
|
||||
```dart
|
||||
// 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:**
|
||||
|
||||
```dart
|
||||
// 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:**
|
||||
```bash
|
||||
# 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:**
|
||||
```bash
|
||||
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:**
|
||||
```bash
|
||||
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:**
|
||||
```bash
|
||||
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:
|
||||
|
||||
```gitignore
|
||||
# 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)
|
||||
|
||||
```dart
|
||||
// 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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
- [Endpoints REST](../api/01-endpoints.md) — usar las URLs configuradas
|
||||
- [WebSocket](../api/02-websocket.md) — conectar con la URL WS
|
||||
- [Troubleshooting](../troubleshooting/01-errores-comunes.md) — solucionar problemas de conexión
|
||||
Reference in New Issue
Block a user