Model classes use PascalCase, table names use plural snake_case:
app/models/color.py
class Color(db.Model): """ Model for color catalog. Attributes: id_color: Unique identifier name: Color name active: Active/inactive status """ __tablename__ = 'colors' # Plural, snake_case id_color = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50), nullable=False) active = db.Column(db.Boolean, default=True) created_at = db.Column(db.TIMESTAMP, server_default=func.current_timestamp())
"""Routes/Controllers for the colors module."""from flask import flash, redirect, render_template, url_forfrom . import colors_bpfrom .forms import ColorFormfrom .services import ColorServicefrom app.exceptions import ConflictError@colors_bp.route('/create', methods=['GET', 'POST'])def create_color(): """ Display form and create a new color. GET: Render the creation form. POST: Validate form, create color, and redirect. Returns: GET - HTML: Page with the creation form POST - Redirect: Redirects with flash message """ form = ColorForm() if form.validate_on_submit(): data = {'name': form.name.data} try: ColorService.create(data) flash('Color created successfully', 'success') return redirect(url_for('colors.create_color')) except ConflictError as e: flash(e.message, 'error') return render_template('colors/create.html', form=form)
"""Business logic services for colors."""from app.models.color import Colorfrom app.extensions import dbfrom app.exceptions import ConflictError, ValidationErrorclass ColorService: """Service for color-related business operations.""" @staticmethod def create(data: dict) -> dict: """ Create a new color. Args: data: Dictionary with color data Returns: dict: Serialized created color Raises: ValidationError: If name is empty ConflictError: If color already exists """ name = data.get('name') if not name or not name.strip(): raise ValidationError('Color name is required') existing = Color.query.filter_by(name=name.strip()).first() if existing: raise ConflictError(f"Color '{name}' already exists") color = Color(name=name.strip()) db.session.add(color) db.session.commit() return color.to_dict()
from typing import Optionaldef create_color(name: str, hex_code: Optional[str] = None) -> dict: """ Create a new color in the catalog. Args: name: Color name (required) hex_code: Hexadecimal color code (optional) Returns: dict: Serialized created color Raises: ValidationError: If name is empty ConflictError: If color already exists Example: >>> create_color("Red", "#FF0000") {'id': 1, 'name': 'Red', 'hex_code': '#FF0000'} """ pass