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 | |
| ```bash | |
| # 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 | |
| ```bash | |
| # 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 | |
| ```bash | |
| 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**: | |
| ```python | |
| 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 | |
| ```python | |
| # 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**: | |
| ```python | |
| 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 | |
| ```python | |
| 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**: | |
| ```python | |
| 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**: | |
| ```python | |
| 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 | |
| ```bash | |
| 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 | |
| 1. `ANALISIS_SOLID.md` - Problemas identificados | |
| 2. `PLAN_REFACTORIZACION.md` - Plan completo | |
| 3. `docs/QUICK_START_REFACTORING.md` - Este archivo | |
| ### Lectura Recomendada | |
| - [Clean Architecture - Robert Martin](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html) | |
| - [SOLID Principles - Python](https://realpython.com/solid-principles-python/) | |
| - [FastAPI Best Practices](https://fastapi.tiangolo.com/tutorial/bigger-applications/) | |
| --- | |
| ## 🚨 Problemas Comunes | |
| ### "ModuleNotFoundError: No module named 'app.infrastructure'" | |
| **Solución**: Agregar `__init__.py` en cada carpeta: | |
| ```bash | |
| 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`: | |
| ```bash | |
| pip install python-dotenv | |
| ``` | |
| ### "Tests no encuentran módulos" | |
| **Solución**: Agregar `__init__.py` en `tests/`: | |
| ```bash | |
| touch tests/__init__.py | |
| touch tests/unit/__init__.py | |
| ``` | |
| --- | |
| ## 💡 Tips de Productividad | |
| ### 1. Usar VSCode Tasks | |
| Crear `.vscode/tasks.json`: | |
| ```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 | |
| ```bash | |
| # 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: | |
| ```json | |
| { | |
| "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: | |
| 1. **Leer**: `PLAN_REFACTORIZACION.md` - Fase 2 | |
| 2. **Implementar**: Modelos de Dominio (TimeSeries, ForecastConfig) | |
| 3. **Commit**: Código con mensaje descriptivo | |
| 4. **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 | |