Modules & Apps
Chapter 2: How sparQ organizes code into modules.
In the previous chapter, you learned that sparQ is built on modules. Now let's understand exactly what modules are, where they live, and how they work together.
What is a Module?
A sparQ module is NOT a Python module. When we say "module" in sparQ, we mean a self-contained feature unit—a folder with a specific structure. This is different from Python's concept of a module (any .py file).
A module is a self-contained piece of functionality with its own models, controllers, views, and translations. Your Hello sparQ app from the tutorial? That's a module.
Every module follows the same structure:
This consistent structure means once you understand one module, you understand them all.
Module Types
sparQ has two types of modules, determined by where they live:
| Type | Location | Purpose |
|---|---|---|
| Base Modules | modules/base/ |
Core sparQ functionality (Sales, Billing, Team, etc.) |
| Apps | data/modules/apps/ |
Your custom applications and marketplace installs |
The folder determines the type. Put your code in data/modules/apps/ and sparQ automatically treats it as an app.
Base Modules vs Apps
The key difference is how they appear in the UI:
Base Modules
- Part of the main sparQ experience
- Show up in the left sidebar navigation
- Examples: Dashboard, Sales, Service, Billing
Apps
- Launched from the Launch Pad
- Can be pinned to the main navigation for quick access
- Can have their own sidebar navigation
- Examples: Notes, Weather, your custom apps
Users can pin frequently-used apps to the main navigation, making them as accessible as base modules.
Where Your Apps Live
When you run the SDK scaffolding command:
cd sdk
make app name=myapp
It creates your app in:
data/modules/apps/myapp/
This location is important because:
- Persists across updates - Your code won't be overwritten when sparQ updates
- Auto-discovered - sparQ finds and loads it automatically
- Portable - You can zip it up and share it on the marketplace
The Directory Structure Explained
Let's look at each part of a module:
__manifest__.py
The identity card of your app. Contains name, version, mappid, and configuration:
# __manifest__.py
manifest = {
# Required fields
"name": "MyApp", # Display name (PascalCase)
"version": "1.0", # Semantic version
"mappid": "x7k2m9", # Marketplace app ID (auto-generated)
"main_route": "/myapp", # URL slug (used in /m/{mappid}/{main_route})
"type": "App", # "App" (visible) or "System" (hidden)
"depends": ["core"], # Module dependencies
# Display fields
"icon_class": "fa-solid fa-cube", # FontAwesome icon class
"color": "#7c3aed", # Theme color (purple)
"description": "What my app does",
"long_description": "Detailed description of the app's features.",
}
module.py
Contains lifecycle hooks that run when sparQ starts:
# module.py
def init_app(app):
"""Called when Flask app initializes."""
pass
def init_database(db):
"""Called after database tables are created."""
# Good place to seed initial data
pass
controllers/
Flask blueprints that handle HTTP requests. Each file typically handles one area:
# controllers/main.py
from flask import Blueprint, render_template
bp = Blueprint('main', __name__, url_prefix='/myapp')
@bp.route('/')
def index():
return render_template('myapp/desktop/index.html')
models/
SQLAlchemy models for your database tables:
# models/item.py
from system.db import db
class Item(db.Model):
__tablename__ = 'myapp_items'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100))
views/
Contains templates and static assets. Templates go in a namespaced subfolder with desktop/ and mobile/ variants:
<!-- views/templates/myapp/desktop/index.html -->
{% extends "core/desktop/base.html" %}
{% block content %}
<h1>Welcome to My App</h1>
{% endblock %}
CSS files go in views/assets/css/:
/* views/assets/css/myapp.css */
.myapp-app .content-card {
/* Your custom styles */
}
lang/
JSON files with translations for each language:
// lang/en.json
{
"welcome": "Welcome to My App",
"save": "Save",
"cancel": "Cancel"
}
App Navigation
Apps can define their own sidebar navigation using nav_sections in the manifest:
# __manifest__.py
{
'name': 'Helpdesk',
'nav_sections': [
{
'title': 'Tickets',
'icon': 'ticket',
'items': [
{'route': 'helpdesk.tickets.list', 'label': 'All Tickets'},
{'route': 'helpdesk.tickets.unassigned', 'label': 'Unassigned'}
]
}
]
}
This creates a custom left sidebar when users are in your app.
Module Loading Order
When sparQ starts, modules load in this order:
- Core - The foundation (authentication, base templates)
- Dashboard - Business dashboard (Home)
- Team - Employee management
- All other base modules - Alphabetically
- Apps - From
data/modules/apps/, alphabetically
This order matters if your app depends on another module being loaded first.
Key Takeaways
- Everything in sparQ is a module with a consistent structure
- The folder location determines if it's a base module or app
- Your apps go in
data/modules/apps/ - Use
cd sdk && make app name=myappto scaffold a new app - Each module has manifest (with mappid), controllers, models, views, and lang files
- Templates go in
views/templates/appname/desktop/ - Apps can define their own navigation