The Furniture Store Backend implements a layered MVC (Model-View-Controller) architecture with an additional Service Layer for business logic. This creates clear separation of concerns and makes the codebase maintainable and testable.
from sqlalchemy import funcfrom sqlalchemy.exc import IntegrityErrorfrom app.exceptions import ConflictError, ValidationError, NotFoundErrorfrom app.extensions import dbfrom app.models.color import Colorclass ColorService: """Service for color business operations""" @staticmethod def get_all() -> list[Color]: """Get all active colors""" return Color.query.filter_by(active=True).all() @staticmethod def create(data: dict) -> dict: """Create a new color with validation""" name = data.get("name") # Business validation if not name or not name.strip(): raise ValidationError("El nombre del color es requerido") name = name.strip() # Check for duplicates (case-insensitive) existing = Color.query.filter( func.lower(Color.name) == name.lower() ).first() if existing: raise ConflictError(f"Ya existe un color con el nombre '{name}'") # Create and persist color = Color(name=name) db.session.add(color) try: db.session.commit() except IntegrityError: db.session.rollback() raise ConflictError(f"Ya existe un color con el nombre '{name}'") return color.to_dict() @staticmethod def get_by_id(id_color: int) -> Color: """Get color by ID or raise NotFoundError""" color = Color.query.get(id_color) if not color: raise NotFoundError(f"No se encontró un color con ID {id_color}") return color @staticmethod def update(id_color: int, data: dict) -> dict: """Update existing color""" color = ColorService.get_by_id(id_color) name = data.get("name") if not name or not name.strip(): raise ValidationError("El nombre del color es requerido") name = name.strip() # Check for duplicate names (excluding current color) existing = ( db.session.query(Color.id_color) .filter( func.lower(Color.name) == name.lower(), Color.id_color != id_color ) .first() is not None ) if existing: raise ConflictError(f"Ya existe otro color con el nombre '{name}'") color.name = name try: db.session.commit() except IntegrityError: db.session.rollback() raise ConflictError(f"Ya existe otro color con el nombre '{name}'") return color.to_dict() @staticmethod def delete(id_color: int) -> None: """Soft delete color""" color = ColorService.get_by_id(id_color) color.active = False color.deleted_at = func.current_timestamp() db.session.commit()
The service layer contains all business logic: validation, duplicate checking, error handling, and database transactions.
from flask_wtf import FlaskFormfrom wtforms import StringFieldfrom wtforms.validators import DataRequired, Lengthclass ColorForm(FlaskForm): """Form for creating/editing colors""" name = StringField( "Nombre", validators=[ DataRequired(message="El nombre del color es requerido"), Length(max=50, message="El nombre no puede exceder 50 caracteres"), ], )