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.)
- HTTP requests arrive at blueprints (defined routes)
- Blueprints call the appropriate controllers
- Controllers interact with models
- Models query or modify the database
- Controllers process results and prepare the response
- 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¶
- Model — create/update in
app/src/models/ - Controller — add business logic in
app/src/controllers/ - Blueprint — define routes in
app/src/blueprints/ - Register — add blueprint in
app/routes.py
Security Considerations¶
- Always validate input data
- Use
@login_requiredon 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