Six projects, one repository, one CI pipeline. The structa.cloud monorepo holds Django sites, an Astro frontend, a desktop POS, and the libraries that bind them.
Shared everything
Configs, assets, and component templates live once under projects/. Sites pick from them instead of copying. A fix in django-fusion propagates to every site in one commit.
The cost
Monorepos trade isolation for consistency. We pay it down with a strict Makefile dispatcher and per-site tests, so a change to shared code is validated against every consumer before it lands.
For a small team shipping products that share a stack, the trade is worth it.
Formints: the SQLite schema shared across editions
Every Formints edition starts from the same local schema. Community uses it directly, Standard adds a sync layer, and Pro turns it into a cloud master. Here is the core of it:
CREATE TABLE sales (
id INTEGER PRIMARY KEY AUTOINCREMENT,
terminal_id TEXT NOT NULL,
total_cents INTEGER NOT NULL,
payment_method TEXT NOT NULL,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE TABLE sale_items (
id INTEGER PRIMARY KEY AUTOINCREMENT,
sale_id INTEGER NOT NULL REFERENCES sales(id),
product_id TEXT NOT NULL,
quantity INTEGER NOT NULL,
unit_cents INTEGER NOT NULL
);
The Rust model that maps to this schema via Diesel ORM:
#[derive(Queryable, Insertable, Serialize)]
#[diesel(table_name = crate::db::schema::sales)]
pub struct Sale {
pub id: i32,
pub terminal_id: String,
pub total_cents: i32,
pub payment_method: String,
pub created_at: String,
}
The Tauri command that generates an invoice — reusable across Standard and Pro:
#[tauri::command]
pub fn generate_invoice(sale_id: i32, state: State) -> Result {
let conn = &mut state.pool.get().map_err(|e| e.to_string())?;
let sale: Sale = sales::table.find(sale_id).first(conn).map_err(|e| e.to_string())?;
let items: Vec = sale_items::table
.filter(sale_items::sale_id.eq(sale_id)).load(conn).map_err(|e| e.to_string())?;
render_invoice_pdf(&sale, &items)
}
One codebase, four editions — the schema and commands stay the same, and each edition gates features on top of them.
Comments
Sign in to join the conversation.
Commenting as