Skip to content

Architecture

Conexoos implements MVC (Model-View-Controller) with Flask, with a clear separation between business logic, presentation, and data access.

Project Structure

app/
├── src/
│   ├── blueprints/     # Route definitions and API entry points
│   ├── controllers/    # Business logic and request handling
│   ├── models/         # Data models and database access
│   ├── utils/          # Support utilities
│   ├── config/         # Global configuration
│   └── dto/            # Data Transfer Objects
├── static/
│   ├── css/
│   ├── js/
│   └── img/
├── templates/          # HTML templates
└── __init__.py

Design Patterns

MVC

  • Model: app/src/models/ — entities + database access
  • View: app/templates/ + static resources
  • Controller: app/src/controllers/ — business logic

Blueprint Pattern

Flask blueprints modularise the application into independent components.

Repository Pattern

Abstracts database access — CRUD operations encapsulated inside models.

Factory Pattern

Used for complex instance creation (config, services).

Data Flow

Client → Blueprint → Controller → Model → Database
                   → IOUtils → File System
                   → External Service (Stripe, etc.)
  1. HTTP requests arrive at blueprints (defined routes)
  2. Blueprints call the appropriate controllers
  3. Controllers interact with models
  4. Models query or modify the database
  5. Controllers process results and prepare the response
  6. Views render data for the user

Key Components

Blueprints

Define HTTP entry points and map URLs to controller functions.

@dashboard_api.route('/api/links', methods=['GET'])
@login_required
def get_links():
    links = UserLink.get_links_by_user_id(user_id=current_user.id)
    return jsonify([link.to_json() for link in links])

Controllers

Implement business logic and coordinate component interactions.

def create_subscription_checkout_session():
    plan_id = request.form.get('plan_id')
    if plan_id == 'gratis':
        current_user.subscription_plan = 'gratis'
        db.session.commit()
        return jsonify({'redirect_url': url_for('frontpage.subscriptions', _external=True) + '?success=true'})
    # Stripe payment logic...

Models

Represent domain entities and handle CRUD operations.

class UserLink(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), nullable=False)
    url = db.Column(db.String(500), nullable=False)
    owner_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    order_index = db.Column(db.Integer, nullable=False, default=0)

    def save(self):
        try:
            db.session.add(self)
            db.session.commit()
            return True
        except Exception:
            db.session.rollback()
            return False

IOUtils

Utility class abstracting file operations (profile images, product images).

class IOUtils:
    def save_image(self, form_image, folder='img/products'):
        return self._save_file(form_image, folder, default='default_product.jpg')

API Endpoints

Endpoint Method Description
/api/links GET Get all user links
/api/add/link POST Create new link
/api/edit/link/<id> PUT Update existing link
/api/delete/link/<id> DELETE Delete link
/api/stats GET Get usage statistics
/api/products GET Get user products

Adding a New Feature

  1. Model — create/update in app/src/models/
  2. Controller — add business logic in app/src/controllers/
  3. Blueprint — define routes in app/src/blueprints/
  4. Register — add blueprint in app/routes.py

Security Considerations

  • Always validate input data
  • Use @login_required on protected routes
  • CSRF tokens on all forms and AJAX requests
  • Use try/except with db.session.rollback() on exceptions
  • Never expose sensitive info in API responses