Tech Stack
No framework roulette. Each layer was chosen for what B2B and B2C commerce both demand at scale — performance, async I/O, type safety, and real extensibility.
Backend framework
Async from the ground up. Native Pydantic validation on every request. Auto-generated OpenAPI docs in dev. FastAPI handles thousands of concurrent connections without breaking a sweat — critical when your storefront, admin panel, and integrations are all hitting the same API.
Why not Django/Flask: synchronous by default. Retrofitting async onto a sync framework is duct tape.
API layer
Type-safe Python-first GraphQL. The schema is composed from domain modules — each module registers its own queries and mutations. Storefronts fetch exactly the data they need in one round trip. No over-fetching, no REST endpoint sprawl.
Why not REST: commerce frontends need flexible data shapes. A product page with pricing tiers, inventory per warehouse, and account-specific visibility is one query, not five — whether it's a wholesale portal or a retail storefront.
Transactional data
The database that doesn't surprise you at 3am. ACID transactions, JSONB for flexible metadata, row-level security, and partitioning for large catalogs. SQLAlchemy 2.0 async with Alembic migrations — the ORM that gets out of the way.
Why not MongoDB: commerce pricing is relational. Five pricing tiers referencing accounts, locations, and customer groups is a JOIN problem, not a document problem.
Admin & Storefront
Both the admin panel and the buyer-facing storefronts are SvelteKit apps. Server-side rendering for SEO, BFF pattern with httpOnly cookies for security, Svelte 5 reactivity, Paraglide JS for type-safe i18n, LayerChart for visual dashboards, TanStack Virtual for 1000+ row tables. Tailwind CSS 4.
Why not Next.js/React: smaller bundles, less boilerplate, faster renders. Paraglide's compile-time i18n means zero runtime overhead for translations.
Durable workflows
Order approval chains, recurring order scheduling, and multi-step fulfillment flows that survive crashes, restarts, and deployments. Workflows are code, not YAML — version them, test them, debug them like any other module.
All workflows and background tasks unified under Temporal — durable business processes and scheduled jobs through a single system with full visibility.
Event streaming
Kafka-compatible but without the JVM tax. When an order is placed, inventory, notifications, fulfillment, and analytics all react in parallel through event topics. Decoupled modules, no cascading failures, full replay capability.
Why not RabbitMQ: topic-based fan-out, persistent log, replay from any offset. Event sourcing needs a log, not a queue.
Cache & sessions
Pricing resolution is one of the most expensive operations in commerce — five tiers with volume breaks, evaluated per line item. Redis caches resolved prices so the second request for the same account + product is sub-millisecond. Also backs BFF sessions.
Dual search engines
Typesense powers storefront product search with scoped API keys for catalog visibility. Meilisearch handles admin search. Both are typo-tolerant, faceted, and sub-50ms. No Elasticsearch cluster to babysit.
Why dual: storefront search needs scoped keys per buyer. Admin search needs full access. Different security models, different engines.
Architecture
38 domain modules behind a single GraphQL endpoint. Clean service boundaries internally, zero microservice overhead externally.
Strawberry GraphQL with async resolvers. Type-safe schema composed from 38 domain modules. One endpoint, full B2B and B2C surface area.
PostgreSQL 16 for transactional data. Redis for session cache and pricing resolution. Typesense + Meilisearch for search. MinIO (S3-compatible) for file and media storage.
Redpanda (Kafka-compatible) for event streaming via a dedicated consumer process. Temporal worker for durable workflows like approvals and recurring orders. In-process event bus for module communication.
Routes requests to the correct channel · Applies pricing, visibility, and checkout rules per channel
FastAPI + Strawberry · 36 domain modules · Strategy pattern
Modules
Every module is self-contained with its own models, services, resolvers, and events. Clean boundaries enforced by convention — no cross-module SQL.
Extensible
Vectis uses Python entry points for a true plugin architecture. Add custom tax providers, carrier integrations, compliance checks, or entirely new modules without touching core code. Extensions are scoped per storefront — your B2B store can run tobacco compliance while your B2C store doesn't.
Per-Storefront Extensions
Extensions activate per storefront. Different storefronts get different capabilities — no global on/off switches.
Strategy Registration
Register pricing, tax, and shipping strategies via entry points. The core discovers them at boot.
Event Hooks
Subscribe to domain events (order.placed, account.created) to trigger custom workflows.
41 Bundled Extensions
Payment, shipping, AI providers, fraud scoring, e-signatures, address validation, file storage, marketing, age verification, SSO, package protection — all ship out of the box.
# 41 extensions — payment, shipping, AI, fraud, address, storage, and more
# Payment
authorize_net nmi ach manual_payment
# Shipping
ups fedex usps usps_flatrate goshippo
shipstation ontrac priority1 aftership
# Address validation
smarty shipstation_address google_maps
# AI
anthropic claude openai chatgpt grok
# Fraud & compliance
signifyd riskified ipqs radar
agechecker
# Storage
s3 minio digitalocean_spaces dropbox
# E-signatures
docusign hellosign
# Marketing & messaging
omnisend elastic_email ses sns twilio
# Auth, geo, tax, commerce
keycloak maxmind exciseiq gift_cards package_protection
Open-source frameworks and hosted SaaS giants — great for B2C. Here's where they stop.
| Capability | Open-source / hosted SaaS | Vectis |
|---|---|---|
| Multi-location accounts | Not in data model | Core |
| Tiered B2B pricing | Plugin / manual | 5-level, cached |
| Net terms & invoicing | Build it yourself | Core |
| Approval workflows | Not available | Temporal-powered |
| Swap pricing / tax / shipping logic | Fork the core | Strategy pattern |
| Catalog visibility per account | Plugin | Core |
| Event-driven architecture | Hooks / basic events | Redpanda + EventBus |
| Durable business workflows | Not available | Temporal |
| B2B + B2C from one engine | Pick one | Channels |
| Multi-strategy tax (sales + excise) | Single provider | resolve_all pipeline |
| ISO geographic data (seeded) | String fields | FK-based, ISO 3166 |
| IP geolocation + address validation | Extension / paid only | Core (MaxMind free) |
| Fraud scoring (IP distance, VPN detection) | Not available | Async via Temporal |
| 3D bin packing engine | Not available | Built-in + fallback |
| Auth/capture + auto void/refund | Basic charge only | Full lifecycle |
| RBAC + 2FA + social login | Basic roles | Granular + TOTP + OAuth |
| Age verification | Not available | AgeChecker.net |
| AI content editing | Not available | Claude, ChatGPT, OpenAI |
| B2B registration + e-signatures | Not available | Form builder + DocuSign |
| Pluggable file storage | Local only | S3, MinIO, DO Spaces |
| Composable promotions engine | Coupon codes only | 25+ conditions · 8 actions |
| Volume-tiered B2B discounts | Not available | Native rule type |
| Stacking policy + mutually-exclusive rules | Manual / none | Built-in |
| Boxing-first shipping model | Duplicate box configs per carrier | Define once, assign to providers |
| Bundled extensions | 3-5 | 41 and growing |