Under the hood
The architecture, the integrations, and the isolation model. For buyers who want the engineering detail before they commit.
Architecture
Two layers behind one front door
Each tenant runs a containerized stack with an edge proxy as the single entry point and the application services behind it on an internal network. Data lives in named volumes on fast local storage — never bind-mounted onto network shares.
Public / LAN → edge (nginx) ← the front door
│ internal bridge network
┌─────────────────────┼──────────────────────┐
│ WordPress + WooCommerce (storefront) │
│ Ops services (RFQ, inventory, fulfilment…) │
│ MariaDB 11.4 · Redis 7 (data + cache) │
└─────────────────────────────────────────────┘
- Edge: nginx, the only exposed surface; routes to storefront and ops services.
- Apps: WordPress + WooCommerce (PHP 8.3), plus Python ops services (FastAPI).
- Data: MariaDB 11.4 and Redis 7, per tenant, on local NVMe-backed volumes.
- Deploy: Docker Compose projects, reproducible per tenant, fronted by Cloudflare at the hosting step.
Engineering depth
What it’s actually made of
The platform is proven, not theoretical — it runs a real multi-channel store with a catalog in the tens of thousands of SKUs. The specifics below are the engine, stripped of any single seller’s vertical.
Services
Python FastAPI services with Jinja2 templating power the pick station and admin panels; PHP 8.3 runs WooCommerce. Quote and packing-slip PDFs render via WeasyPrint from versioned HTML templates.
Inventory & sync
A poller runs on a 5-minute cadence, FIFO-reserves stock under MySQL advisory locks (no double-reservation across concurrent runs), and pushes quantity to WooCommerce + eBay with retry. GTIN-14/EAN-13 are normalized to UPC-A against a cached, disk-persisted lookup so scanners never block.
Fulfillment & labels
Multi-piece shipments make one carrier call → N tracking numbers + N labels. Labels print as native ZPL to a thermal printer via CUPS; packing slips print alongside. Serials are captured per lot at pack time.
Accounting
Orders consume lots oldest-first and write a full FIFO COGS audit trail (lot, date, unit cost, run totals) into double-entry books, with gateway-fee splits and purchase-order orders routed to accounts receivable.
Quoting
Quotes carry immutable version snapshots, a customer-facing revision counter, and validity windows. Pricing falls through in-stock → supplier landed cost (markup, freshness-checked) → marketplace comps. Sender domains are scored for reputation.
Dashboard & jobs
A live dashboard streams an event log over server-sent events and runs 20-plus collectors in parallel with short-TTL caching. A small cron fleet drives sync, tracking sweeps, alerts, review requests, and a daily summary.
Data model: roughly 15+ core tables — inventory lots and serials, quotes and line items, pick queue, shipments and packages, supplier invoices and costs, COGS history, and the event log — per tenant.
Integrations
The integration registry
Every external service the platform can talk to, what it powers, and whether each customer needs their own credential. Roughly twelve are mandatory for a fully-loaded store; a quoting MVP needs six.
Core commerce (mandatory)
| Service | Powers | Per-tenant? |
|---|---|---|
| WooCommerce REST | Products, orders, customers, stock — the system of record | Yes |
| WordPress app password | Admin REST, cache flush, option reads, index rebuild | Yes |
| Host SSH | CLI, DB queries, deploys, feed upload | Yes |
| MariaDB | The ops database — inventory, quotes, shipments, ledger | Yes |
| Payment gateway | Checkout + gateway-fee accounting splits | Yes |
| Transactional SMTP | Order / ship / delivered / review email | Yes |
Channels, carriers & accounting
| Service | Powers | Per-tenant? |
|---|---|---|
| eBay Sell + Trading | Listings, inventory sync, fulfillment, buyer-tracking pull | If on eBay |
| UPS | Rating, labels (ZPL), multi-piece, inbound + outbound tracking | If shipping |
| USPS / FedEx / DHL | Tracking and rating | Per carrier |
| Tracking aggregator | Optional one-key coverage (EasyPost/AfterShip) | Optional |
| Double-entry book (GnuCash) | FIFO COGS posting, reconciliation target | If accounting |
| Tax (TaxJar / native) | Sales-tax rates for quotes and orders | Yes |
Growth, content & intelligence
| Service | Powers | Per-tenant? |
|---|---|---|
| Gmail / Workspace | RFQ intake, quote delivery, outbox, alerts | Yes |
| Search Console / Indexing API | SEO queries, audits, fast (de)indexing | Optional |
| Bing Webmaster / IndexNow | Index coverage + instant submission | Optional |
| Google Ads / Microsoft Ads | Campaign management + report ingest | Optional |
| Merchant Center feed | Shopping product feed | Optional |
| Cloudflare + R2 | Edge/WAF/DNS + document and backup storage | Recommended |
| Anthropic (Claude) | Description generation, invoice + RFQ parsing | Shared, metered |
Configuration
The tenant-config boundary
The product core is generic. Everything that differs between customers lives in a per-tenant config file validated against a schema — identity and branding, credentials (as vault references, never raw values), and the swappable sector sources.
- Per-tenant: credentials, branding, domains, module flags.
- Shared platform: the metered AI key, proxy pool, orchestration host.
- Sector-specific: supplier-catalog, competitor, and datasheet sources — swapped per vertical. The mechanism is core; the source is config.
Security & isolation
Built to keep tenants apart
- Own instance and own database per tenant.
- Secrets resolved at deploy time from a per-tenant vault.
- Config files are safe to commit — they hold references, not secrets.
- Internal services never exposed directly; only the edge is reachable.
- Automated backups and continuous monitoring.
Want a deeper architecture walkthrough?
We’ll walk your engineers through the stack, the data model, and the isolation guarantees.
Request a technical call