Architecture

Chapter 1: Understanding how sparQ works under the hood.

Now that you've built your first app, let's step back and understand how sparQ is structured. This knowledge will help you make better decisions as you build more complex applications.

Design Philosophy

sparQ is built on a foundation that prioritizes modularity and extensibility. The goal is a system that can grow and scale over time while remaining simple, intuitive, and efficient.

Everything in sparQ—including the core system itself—is a module. This means:

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).

Architectural Principles

Seven key pillars guide sparQ's architecture:

Principle What It Means
Modular Structure Every component functions as an independent module with its own models, views, and controllers
Dynamic Loading Only essential modules are required; additional features load on demand
Lightweight Database SQLite as the primary data store for simplicity and portability
ORM Layer SQLAlchemy handles all database interactions with clean Python code
Server-Side Rendering Jinja2 templates with HTMX for dynamic updates without JavaScript complexity
Containerized Deployment Docker-based deployment for consistent environments
Internationalization JSON-based translation system enables global functionality

The Big Picture

sparQ is a modular business platform built on Flask. Think of it as a foundation that handles all the common stuff—authentication, database, email, payments—so you can focus on building your specific business logic.

Image: High-level architecture diagram showing Flask at the core with modules around it

Here's what makes up a sparQ installation:

+-------------------------------------------------------------+
|                      Flask Application                      |
|                         (app.py)                            |
+-------------------------------------------------------------+
|                                                             |
|  +-----------+  +-----------+  +---------------------+      |
|  |  Module   |  | Database  |  |        i18n         |      |
|  |  Loader   |  |(SQLAlchemy)|  |   (JSON files)     |      |
|  | (pluggy)  |  |  SQLite   |  |                     |      |
|  +-----+-----+  +-----------+  +---------------------+      |
|        |                                                    |
|        v                                                    |
|  +-----------------------------------------------------+    |
|  |                    Modules                          |    |
|  |  +-------+ +-------+ +-------+ +-------+            |    |
|  |  | Core  | | Team  | |Dashbrd| | Apps  |            |    |
|  |  +-------+ +-------+ +-------+ +-------+            |    |
|  +-----------------------------------------------------+    |
|                                                             |
+-------------------------------------------------------------+

Required Modules

Three modules are essential for sparQ to run:

Module Purpose
Core Authentication, user administration, base templates, and foundational services
Dashboard (Home) Business dashboard, pipeline view, and central landing page after login
Team Employee management with roles, departments, and organizational structure

Everything else—Sales, Billing, Service, and your custom apps—is optional and loads only when needed.

Technology Stack

sparQ uses a carefully chosen set of technologies:

Layer Technology Why
Web Framework Flask Lightweight, flexible, extensive ecosystem
Database SQLite Zero configuration, portable, surprisingly powerful
ORM SQLAlchemy Python's most mature database toolkit
Templates Jinja2 Fast, secure, Flask's native templating
Interactivity HTMX + Alpine.js Dynamic UIs without JavaScript complexity
Styling Bootstrap 5 Responsive, well-documented, customizable
Plugin System Pluggy Python's standard for extensibility (used by pytest)
AI Integration OpenAI / Anthropic LLM-powered assistant with tool calling

System Services

sparQ provides a set of system services that any module can use. These live in the system/ directory:

Service What It Does Example Use
db Database connection and ORM from system.db import db
auth Authentication decorators @login_required
email Send emails EmailService.send()
pdf Generate PDF documents PDFService.generate()
i18n Translations _('Hello')
payments Stripe integration PaymentService.charge()
background Background task processing BackgroundTask.run()
marketplace Install/manage apps MarketplaceService.install()
ai AI tools and LLM integration from system.ai import Tool

You'll use these services throughout your apps. For example, to require login on a route:

from system.auth import login_required

@bp.route('/dashboard')
@login_required
def dashboard():
    return render_template('my_app/dashboard.html')

Request Lifecycle

When a user clicks something in your app, here's what happens:

1. Request arrives at Flask
       ↓
2. URL routing matches a controller
       ↓
3. Auth middleware checks permissions
       ↓
4. Your controller runs
       ↓
5. Controller calls models/services
       ↓
6. Template renders HTML
       ↓
7. Response sent to browser

Let's trace a real example. When a user visits /hello/ from your Hello sparQ app:

  1. Flask sees the URL matches @bp.route('/') in your main.py controller
  2. Your index() function runs
  3. It calls render_template('hello/desktop/index.html')
  4. Jinja2 processes the template
  5. HTML is sent back to the browser

The Frontend Stack

sparQ uses a server-rendered approach rather than a Single Page Application (SPA). This means:

This stack is simpler than React/Vue and perfect for business applications where SEO matters and you don't need complex client-side state.

Image: Diagram showing Jinja2, HTMX, Alpine.js, and Bootstrap working together

Database Layer

sparQ uses SQLite as its primary database and SQLAlchemy as its ORM (Object-Relational Mapper). This lets you work with Python objects instead of writing raw SQL:

# Instead of: SELECT * FROM tasks WHERE user_id = 1
tasks = Task.query.filter_by(user_id=1).all()

# Instead of: INSERT INTO tasks (title, user_id) VALUES ('Buy milk', 1)
task = Task(title='Buy milk', user_id=1)
db.session.add(task)
db.session.commit()

SQLite might seem simple, but it's incredibly capable. It handles millions of records, supports concurrent reads, and requires zero configuration. For most business applications, it's more than enough.

The SDK

The sdk/ folder contains developer tooling for building apps:

# Create a new app with auto-generated mappid
cd sdk
make app name=myapp

# Package for marketplace
make release name=myapp

The SDK handles scaffolding, generates unique marketplace IDs (mappid), and packages apps for distribution.

The Module System

Everything in sparQ is a module. There are three types:

Type Location Purpose
Base Modules modules/base/ Core functionality shipped with sparQ
Apps data/modules/apps/ Your custom applications
Plugins data/addons/ Extensions that enhance other modules

When sparQ starts, it automatically discovers and loads modules in this order:

  1. Core - Authentication, base templates
  2. Dashboard - Business dashboard (Home)
  3. Team - Employee management
  4. Other base modules - Alphabetically
  5. Your apps - Alphabetically

Modules can define dependencies on other modules, ensuring they load in the correct order.

We'll dive deeper into modules in the next chapter.

Key Takeaways