Skip to main content

First Steps

Now that you’ve installed and configured Muebles Roble, let’s run the application and create your first catalog entries. This guide will walk you through starting the server and using the basic features.
Make sure you’ve completed the Installation and Configuration guides before proceeding.

Starting the Application

1

Activate Virtual Environment

First, ensure your virtual environment is activated:
venv\Scripts\activate
You should see (venv) in your terminal prompt.
2

Run the Application

Start the Flask development server using one of these methods:
flask run
You should see output like:
Database connection successful!
 * Serving Flask app 'app'
 * Debug mode: on
 * Running on http://127.0.0.1:5000
 * Press CTRL+C to quit
 * Restarting with stat
 * Debugger is active!
The “Database connection successful!” message confirms your database is configured correctly.
3

Open in Browser

Open your web browser and navigate to:
http://127.0.0.1:5000
or
http://localhost:5000
Keep the terminal window open while using the application. Press Ctrl+C to stop the server.

Understanding the Application URLs

The application is organized into modules with specific URL prefixes:
ModuleBase URLPurpose
Colorshttp://localhost:5000/colors/Manage color catalog
Wood Typeshttp://localhost:5000/wood-types/Manage wood types
Furniture Typeshttp://localhost:5000/furniture-type/Manage furniture categories
Unit of Measureshttp://localhost:5000/unit-of-measures/Manage measurement units
Roleshttp://localhost:5000/roles/Manage user roles
Each module provides these routes:
  • / - List all entries
  • /create - Create a new entry
  • /<id>/edit - Edit an existing entry
  • /<id>/delete - Delete an entry (soft delete)

Creating Your First Color

Let’s start by creating color entries for your furniture finishes.
1

Navigate to Colors

Go to the colors creation page:
http://localhost:5000/colors/create
You’ll see a form with a “Color Name” field.
2

Create Natural Color

Enter “Natural” in the color name field and click “Create Color” (or submit button).If successful, you’ll see a success message:
Color created successfully
The form will be cleared, ready for the next entry.
3

Create More Colors

Add these common furniture colors:
  • White
  • Black
  • Walnut
  • Mahogany
  • Cherry
  • Oak
  • Espresso
For each color, enter the name and submit the form.
4

View Color List

Navigate to the colors list page:
http://localhost:5000/colors/
You’ll see all the colors you’ve created with their:
  • ID
  • Name
  • Active status
  • Created timestamp
  • Action buttons (Edit/Delete)

Behind the Scenes: Color Creation

When you create a color, here’s what happens:
The HTML form sends a POST request to /colors/create:
<form method="POST" action="/colors/create">
    {{ form.hidden_tag() }}  <!-- CSRF token -->
    {{ form.name }}
    <button type="submit">Create</button>
</form>
The route validates the form and calls the service:
# app/catalogs/colors/routes.py
@colors_bp.route("/create", methods=["GET", "POST"])
def create_color():
    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)
The service validates business rules and saves to database:
# app/catalogs/colors/services.py
@staticmethod
def create(data: dict) -> dict:
    name = data.get('name')
    if not name or not name.strip():
        raise ValidationError('Color name is required')
    
    # Check for duplicates
    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()
A new record is created with automatic audit fields:
INSERT INTO colors (name, active, created_at, updated_at) 
VALUES ('Natural', 1, NOW(), NOW());

Creating Wood Types

Next, let’s add the types of wood your furniture shop uses.
1

Navigate to Wood Types

Go to:
http://localhost:5000/wood-types/create
2

Add Common Wood Types

Create these standard wood types:
  • Pine (Pino)
  • Cedar (Cedro)
  • Oak (Encino)
  • Mahogany (Caoba)
  • Maple (Arce)
  • Cherry (Cerezo)
  • Walnut (Nogal)
  • Ash (Fresno)
You can use the Spanish names if your business operates in a Spanish-speaking region.
3

View Wood Types

Navigate to:
http://localhost:5000/wood-types/
You’ll see your complete wood type catalog.

Creating Furniture Types

Define the categories of furniture your shop produces.
1

Navigate to Furniture Types

Go to:
http://localhost:5000/furniture-type/create
2

Add Furniture Categories

Create these common furniture types:
  • Tables (Mesas)
  • Chairs (Sillas)
  • Closets (Closets)
  • Desks (Escritorios)
  • Shelves (Estantes)
  • Cabinets (Gabinetes)
  • Bookcases (Libreros)
  • Nightstands (Burós)
  • Dressers (Cómodas)
3

View Furniture Types

Navigate to:
http://localhost:5000/furniture-type/

Creating Units of Measure

Add the measurement units used for tracking materials and products.
1

Navigate to Units

Go to:
http://localhost:5000/unit-of-measures/create
2

Add Measurement Units

Create these units:
  • Kilogram (kg) - For wood weight
  • Square Meter (m²) - For wood surface area
  • Linear Meter (m) - For wood length
  • Piece (pza) - For individual items
  • Liter (L) - For finishes and glues
  • Gallon (gal) - For paint and varnish

Editing Catalog Entries

You can edit any catalog entry:
1

Navigate to List

Go to any catalog list page (e.g., /colors/)
2

Click Edit

Click the “Edit” button next to the entry you want to modify
3

Update and Save

The form will be pre-populated with the current value. Make your changes and submit.Example URL: http://localhost:5000/colors/1/edit

Edit Flow

Here’s what happens during an edit:
# app/catalogs/colors/routes.py
@colors_bp.route("/<int:id_color>/edit", methods=["GET", "POST"])
def edit_color(id_color: int):
    try:
        color = ColorService.get_by_id(id_color)
    except NotFoundError as e:
        flash(e.message, "error")
        return redirect(url_for("colors.list_colors"))
    
    form = ColorForm()
    
    if form.validate_on_submit():
        data = {"name": form.name.data}
        try:
            ColorService.update(id_color, data)
            flash("Color updated successfully", "success")
            return redirect(url_for("colors.list_colors"))
        except (ConflictError, ValidationError) as e:
            flash(e.message, "error")
    
    elif request.method == "GET":
        # Pre-populate form on GET requests
        form.name.data = color.name
    
    return render_template("colors/edit.html", form=form, color=color)
The system uses the PRG (Post-Redirect-Get) pattern to prevent duplicate submissions if the user refreshes the page.

Deleting Catalog Entries

The system uses soft deletion to preserve data:
1

Navigate to List

Go to any catalog list page
2

Click Delete

Click the “Delete” button next to the entry
3

Confirm Deletion

The entry will be marked as inactive (active = False) and the deletion timestamp will be recorded.The entry disappears from the active list but remains in the database.

Soft Delete Implementation

# app/catalogs/colors/routes.py
@colors_bp.route("/<int:id_color>/delete", methods=["POST"])
def delete_color(id_color: int):
    try:
        ColorService.delete(id_color)
        flash("Color deleted successfully", "success")
    except NotFoundError as e:
        flash(e.message, "error")
    
    return redirect(url_for("colors.list_colors"))
Deletion is a POST request for security. You cannot delete by simply visiting a URL.

Understanding Flash Messages

The application uses Flask’s flash messaging system for user feedback:

Success Messages

✓ Color created successfully
✓ Wood type updated successfully

Error Messages

✗ Color 'White' already exists
✗ Color with ID 999 not found
✗ Color name is required
Flash messages appear at the top of the page and are cleared after being displayed once.

Validating Data Entry

Try these scenarios to see validation in action:

Duplicate Detection

1

Create a Color

Create a color named “White”
2

Try to Create Again

Try creating another color named “White”
3

See Error

You’ll see: Color 'White' already exists

Required Fields

1

Leave Field Empty

Go to create form and submit without entering a name
2

See Validation

You’ll see: This field is required or Color name is required

Length Validation

1

Enter Single Character

Try entering just “A” as a color name
2

See Error

You’ll see: Name must be 2-50 characters

Viewing the Database

You can verify your data was saved to MySQL:
mysql -u your_username -p
USE muebles_roble_db;

-- View all colors
SELECT * FROM colors;

-- View active colors only
SELECT * FROM colors WHERE active = 1;

-- View with formatting
SELECT 
    id_color,
    name,
    active,
    created_at,
    updated_at
FROM colors
ORDER BY created_at DESC;
You should see all the audit fields populated:
+----------+---------+--------+---------------------+---------------------+
| id_color | name    | active | created_at          | updated_at          |
+----------+---------+--------+---------------------+---------------------+
|        1 | Natural |      1 | 2024-03-15 10:30:00 | 2024-03-15 10:30:00 |
|        2 | White   |      1 | 2024-03-15 10:31:00 | 2024-03-15 10:31:00 |
|        3 | Black   |      1 | 2024-03-15 10:32:00 | 2024-03-15 10:32:00 |
+----------+---------+--------+---------------------+---------------------+

Testing CSRF Protection

Try submitting a form without the CSRF token:
For educational purposes only. Never disable CSRF protection in production.
  1. Open browser developer tools (F12)
  2. Go to /colors/create
  3. In the console, try:
    fetch('/colors/create', {
        method: 'POST',
        body: 'name=Test',
        headers: {'Content-Type': 'application/x-www-form-urlencoded'}
    })
    
  4. The request will be rejected with a CSRF error
This demonstrates that all forms are protected against CSRF attacks.

Development Tips

Auto-Reload

Flask’s debug mode automatically reloads when you change code:
  1. Edit a file (e.g., routes.py)
  2. Save the file
  3. The server automatically restarts
  4. Refresh your browser to see changes
You don’t need to manually restart the server during development.

Debug Mode Features

With FLASK_ENV=development, you get:
  • Detailed error pages - Stack traces in the browser
  • Auto-reload - Automatic server restart on code changes
  • Debug toolbar - (if installed) Request/response inspection

Viewing Logs

The terminal where you ran flask run shows:
Database connection successful!
127.0.0.1 - - [15/Mar/2024 10:30:00] "GET /colors/create HTTP/1.1" 200 -
127.0.0.1 - - [15/Mar/2024 10:30:15] "POST /colors/create HTTP/1.1" 302 -
127.0.0.1 - - [15/Mar/2024 10:30:15] "GET /colors/create HTTP/1.1" 200 -
This shows:
  • Timestamp
  • HTTP method and path
  • Response status code (200 = success, 302 = redirect)

Common Issues

Error: Address already in useSolution: Either:
  • Stop the existing server (find and kill the process)
  • Use a different port: flask run --port 5001
Error: Database connection failed: Access deniedSolution:
  • Verify your .env file has correct credentials
  • Check MySQL is running: mysql -u root -p
  • Review the Configuration Guide
Error: 404 Not FoundSolution:
  • Verify the URL is correct (check for typos)
  • Ensure you’re using the right prefix (/colors/, not /color/)
  • Check that the blueprint is registered in app/__init__.py
Problem: Clicking submit does nothingSolution:
  • Check browser console for JavaScript errors
  • Verify the form has method="POST"
  • Ensure {{ form.hidden_tag() }} is present (CSRF token)

Next Steps

Now that you understand the basics:

Key Features

Explore advanced features like audit trails and soft deletes

Architecture

Understand the layered MVC architecture in depth

Deploy to Production

Deploy the application to a production server

Quick Reference

Common URLs

http://localhost:5000/colors/
http://localhost:5000/colors/create
http://localhost:5000/wood-types/
http://localhost:5000/furniture-type/
http://localhost:5000/unit-of-measures/
http://localhost:5000/roles/

Common Commands

# Start server
flask run
python run.py

# Database migrations
flask db migrate -m "Description"
flask db upgrade
flask db downgrade

# Check routes
flask routes

# Stop server
Ctrl+C

File Locations

config.py          # Configuration
.env               # Environment variables
run.py             # Entry point
app/__init__.py    # App factory
app/models/        # Database models
app/catalogs/      # Business modules
app/templates/     # HTML templates
Bookmark this page for quick reference while developing!

Build docs developers (and LLMs) love