Spaces:
Build error
Build error
🚀 Quick Start - Refactorización SOLID
Para: Desarrollador que inicia la refactorización
Tiempo estimado: 15 minutos de setup inicial
Objetivo: Entender y comenzar la refactorización
📖 Contexto Rápido
Estado Actual (v2.1.1)
- 1 archivo Python monolítico (680 líneas)
- 1 archivo JavaScript monolítico (1,105 líneas)
- 0% cobertura de tests
- 25% cumplimiento SOLID
Estado Objetivo (v3.0.0)
- 20+ archivos Python modulares (<150 líneas c/u)
- 6+ archivos JavaScript modulares
- 70% cobertura de tests
- 85% cumplimiento SOLID
🎯 Principios Clave
SOLID en 1 Minuto
S - Single Responsibility → 1 clase = 1 trabajo
O - Open/Closed → Extender sin modificar
L - Liskov Substitution → Interfaces intercambiables
I - Interface Segregation → Interfaces pequeñas
D - Dependency Inversion → Depender de abstracciones
Arquitectura en Capas
┌─────────────────┐
│ API Layer │ ← Endpoints (FastAPI)
├─────────────────┤
│ Domain Layer │ ← Lógica de negocio
├─────────────────┤
│ Infrastructure │ ← Implementaciones (Chronos, DB)
└─────────────────┘
🛠️ Setup Inicial
1. Preparar Entorno
# Navegar al proyecto
cd /var/home/joss/Proyectos/chronos2-server
# Crear branch de refactorización
git checkout -b refactor/solid-architecture
# Backup del código actual
cp app/main.py app/main_v2.1.1_backup.py
cp static/taskpane/taskpane.js static/taskpane/taskpane_v2.1.1_backup.js
# Instalar dependencias de desarrollo
pip install pytest pytest-cov black flake8 mypy
2. Crear Estructura de Carpetas
# Backend
mkdir -p app/{api/{routes,middleware},domain/{models,services,interfaces},infrastructure/{ml,config},schemas/{requests,responses},utils}
# Frontend
mkdir -p static/taskpane/js/{services,excel,ui,features,config}
# Tests
mkdir -p tests/{unit,integration,fixtures}
# Docs
mkdir -p docs
3. Verificar Estructura
tree -L 3 app/
Output esperado:
app/
├── api/
│ ├── routes/
│ └── middleware/
├── domain/
│ ├── models/
│ ├── services/
│ └── interfaces/
├── infrastructure/
│ ├── ml/
│ └── config/
├── schemas/
│ ├── requests/
│ └── responses/
└── utils/
📝 Primera Tarea: Settings Centralizados
¿Por qué empezar aquí?
- Fácil de implementar
- Sin dependencias
- Base para todo lo demás
Código a Crear
app/infrastructure/config/settings.py:
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
# API
api_title: str = "Chronos-2 Forecasting API"
api_version: str = "3.0.0"
# Model
model_id: str = "amazon/chronos-2"
device_map: str = "cpu"
# CORS
cors_origins: list = ["*"]
class Config:
env_file = ".env"
settings = Settings()
Test Rápido
# En Python REPL
from app.infrastructure.config.settings import settings
print(settings.api_title) # "Chronos-2 Forecasting API"
print(settings.model_id) # "amazon/chronos-2"
📝 Segunda Tarea: Logger Centralizado
app/utils/logger.py:
import logging
def setup_logger(name: str) -> logging.Logger:
logger = logging.getLogger(name)
logger.setLevel(logging.INFO)
if not logger.handlers:
handler = logging.StreamHandler()
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
Uso
from app.utils.logger import setup_logger
logger = setup_logger(__name__)
logger.info("Test message")
logger.error("Error message")
📝 Tercera Tarea: Primera Interface
app/domain/interfaces/forecast_model.py:
from abc import ABC, abstractmethod
from typing import List, Dict, Any
import pandas as pd
class IForecastModel(ABC):
"""Interface para modelos de forecasting"""
@abstractmethod
def predict(
self,
context_df: pd.DataFrame,
prediction_length: int,
quantile_levels: List[float],
**kwargs
) -> pd.DataFrame:
pass
@abstractmethod
def get_model_info(self) -> Dict[str, Any]:
pass
¿Por qué una interface?
- Abstracción: No depender de implementación específica
- Testeable: Fácil de mockear
- Extensible: Agregar modelos (Prophet, ARIMA) sin cambiar código
🧪 Primer Test
tests/unit/test_settings.py:
import pytest
from app.infrastructure.config.settings import Settings
def test_settings_defaults():
settings = Settings()
assert settings.api_title == "Chronos-2 Forecasting API"
assert settings.api_version == "3.0.0"
assert settings.model_id == "amazon/chronos-2"
def test_settings_from_env(monkeypatch):
monkeypatch.setenv("MODEL_ID", "amazon/chronos-t5-small")
settings = Settings()
assert settings.model_id == "amazon/chronos-t5-small"
Correr Test
pytest tests/unit/test_settings.py -v
Output esperado:
tests/unit/test_settings.py::test_settings_defaults PASSED
tests/unit/test_settings.py::test_settings_from_env PASSED
🎯 Checklist de Hoy (2-3 horas)
- Setup entorno (git branch, dependencias)
- Crear estructura de carpetas
- Implementar Settings
- Implementar Logger
- Crear primera Interface (IForecastModel)
- Escribir primeros tests
- Commit: "chore: setup SOLID architecture foundation"
📚 Recursos de Referencia
Documentación del Proyecto
ANALISIS_SOLID.md- Problemas identificadosPLAN_REFACTORIZACION.md- Plan completodocs/QUICK_START_REFACTORING.md- Este archivo
Lectura Recomendada
🚨 Problemas Comunes
"ModuleNotFoundError: No module named 'app.infrastructure'"
Solución: Agregar __init__.py en cada carpeta:
touch app/__init__.py
touch app/infrastructure/__init__.py
touch app/infrastructure/config/__init__.py
# etc...
"Settings no carga .env"
Solución: Instalar python-dotenv:
pip install python-dotenv
"Tests no encuentran módulos"
Solución: Agregar __init__.py en tests/:
touch tests/__init__.py
touch tests/unit/__init__.py
💡 Tips de Productividad
1. Usar VSCode Tasks
Crear .vscode/tasks.json:
{
"version": "2.0.0",
"tasks": [
{
"label": "Run Tests",
"type": "shell",
"command": "pytest tests/ -v",
"group": "test"
},
{
"label": "Type Check",
"type": "shell",
"command": "mypy app/",
"group": "test"
}
]
}
2. Pre-commit Hooks
# Instalar pre-commit
pip install pre-commit
# Crear .pre-commit-config.yaml
cat > .pre-commit-config.yaml << EOF
repos:
- repo: https://github.com/psf/black
rev: 23.12.1
hooks:
- id: black
- repo: https://github.com/pycqa/flake8
rev: 7.0.0
hooks:
- id: flake8
EOF
# Instalar hooks
pre-commit install
3. Snippets para Interfaces
VSCode snippet para crear interfaces rápidamente:
{
"Python Interface": {
"prefix": "interface",
"body": [
"from abc import ABC, abstractmethod",
"",
"class I${1:Name}(ABC):",
" \"\"\"${2:Description}\"\"\"",
" ",
" @abstractmethod",
" def ${3:method}(self, ${4:params}):",
" pass"
]
}
}
📞 Siguiente Paso
Una vez completado el checklist de hoy:
- Leer:
PLAN_REFACTORIZACION.md- Fase 2 - Implementar: Modelos de Dominio (TimeSeries, ForecastConfig)
- Commit: Código con mensaje descriptivo
- Review: Auto-review del código antes de continuar
🎉 ¡Felicitaciones!
Has completado el setup inicial. Ahora tienes:
- ✅ Estructura de carpetas organizada
- ✅ Configuración centralizada
- ✅ Logger consistente
- ✅ Primera interface (abstracción)
- ✅ Primeros tests
Tiempo invertido: 2-3 horas
Progreso: ~5% de la refactorización
Próxima sesión: Modelos de Dominio (4-5 horas)
Actualizado: 2025-11-09
Versión: 1.0
Autor: Claude AI