Project Structure¶
Top-Level Layout¶
vectis/
├── backend/ # Python FastAPI application
│ ├── vectis/
│ │ ├── core/ # App factory, config, middleware, strategy, events, database
│ │ ├── modules/ # 53 domain modules (see below)
│ │ ├── extensions/ # Namespace anchor only (`__init__.py`) — extensions live in the sibling repo (see below)
│ │ ├── cli_ext.py # `vectis ext lint` CLI — lints extension packages (e.g. the dev-linked enterprise-extensions checkout)
│ │ ├── events/ # Redpanda producer/consumer, JSON Schema registry
│ │ └── worker.py # Temporal worker entry point
│ ├── vectis_sdk/ # Frozen import surface for extensions
│ ├── vectis_testkit/ # Test helpers for extension authors (linted by `make check`)
│ ├── alembic/ # Core database migrations (extensions ship their own chains)
│ ├── extensions.lock # Install-set source of truth — `make lock-extensions`
│ ├── scripts/ # Gate + tooling scripts (see below)
│ ├── Dockerfile / Dockerfile.prod # Dev + multi-stage production images
│ └── tests/ # pytest test suite (~2,260 tests)
├── admin/ # SvelteKit admin dashboard
│ └── src/
│ ├── lib/ # Components, help JSON, Houdini ops ($lib/houdini/), houdiniClient.ts
│ └── routes/ # ~40 admin routes (incl. refund-approvals, workflow-faults, affiliates, packaging)
├── storefront/ # SvelteKit B2B/B2C storefront
│ └── src/
│ ├── lib/ # Components, i18n, format, Houdini ops ($lib/houdini/), houdiniClient.ts
│ └── routes/ # Product pages, cart, checkout, account, affiliates portal
├── infra/ # grafana dashboards, prometheus config, deployment scripts
├── migrator/ # WooCommerce → Vectis data migration CLI
├── docs/ # Internal runbooks: constitution, conventions, REDPANDA_TOPICS, DR_RUNBOOK, DEPLOYMENT_DIGITALOCEAN, CUSTOMER_ONBOARDING_PILOT, CACHING, EXTENSION_GUIDE
├── scripts/ # test.sh, verify_setup.sh (gate scripts live in backend/scripts/: check_resolver_redefs.py, check_no_core_extension_imports.py, check_extension_imports.py + extension_import_allowlist.json, check_core_migrations_ext_tables.py, check_model_drift.py, export_extensions_lock.py, sync_admin_extensions.py, backup_postgres.sh, verify_backup_restore.py)
├── docker-compose.yml # Full development environment (incl. Prometheus + Grafana); mounts ../enterprise-extensions
├── docker-compose.prod.yml
└── Makefile # `make check` runs the full local gate (~25s)
../enterprise-extensions/ # Sibling repo — all 48 ext_* packages (see Extensions below)
Note
The core repo is extension-agnostic in-tree: backend/vectis/extensions/ holds only the namespace anchor. All extensions live in the separate vectiscommerce/enterprise-extensions repo, which dev setups clone as a sibling directory — docker-compose.yml bind-mounts ../enterprise-extensions read-only into the API container and dev-links it via VECTIS_DEV_EXTENSIONS=/enterprise-extensions.
Note
The public documentation site (this site) lives in a separate repo — vectiscommerce/vectis-commerce-docs — and deploys to Cloudflare Pages at docs.vectisb2b.com. Keep code and docs in lockstep via PRs across both repos.
Backend Module Structure¶
Every core module follows this layout:
vectis/modules/{name}/
├── __init__.py
├── models.py # SQLAlchemy ORM models
├── services.py # Business logic (service layer)
├── resolvers.py # Strawberry GraphQL resolvers
├── strategies.py # ABC strategy interfaces (if applicable)
└── workflows.py # Temporal workflows (if applicable)
Core Modules (53)¶
| Module | Description |
|---|---|
auth |
Login, JWT, sessions, BFF, RBAC, channel resolution |
account |
Account, Location, Employee, Address, CustomerGroup |
activity |
Activity feed across entities |
ai |
LLM provider integrations (chat, descriptions, assistants) |
api_key |
API key issuance, scoping, and rotation |
approval |
Registration rules, document upload |
audit |
Immutable append-only log |
banner |
Site-wide banners / announcements |
cart |
Per-location carts, snapshots, pessimistic locking, coupons |
catalog_policy |
Catalog visibility + purchase policy rules |
cms |
Pages (JSONB blocks), navigation, media |
compliance |
Regulatory checks (tobacco, age-restricted goods) |
customer_referral |
Customer-to-customer referral rewards |
fee |
Configurable surcharges and fees |
fraud |
Fraud holds, signals from risk extensions |
fulfillment |
Multi-box shipments, multi-carrier, by_box + by_order modes |
geo |
Geographic data model (country/region/county/city), IP geolocation |
gift_card |
Virtual + physical, partial redemption |
inventory |
Warehouses, stock levels, FIFO allocation |
lead |
Sales lead capture + sync |
lists |
B2B saved order lists |
loyalty |
Points program, tiers, rewards |
marketing |
Campaigns, email marketing integrations |
net_terms |
Invoices, aging, credit holds |
notification |
Templates, delivery log |
observability |
Metrics, readiness probes, health surfacing |
order |
Configurable state machine, custom order numbers, dual-currency |
payment |
Gateway strategies, eligibility, transactions, lifecycle (auth/capture/void/refund) |
platform |
Cross-cutting platform settings |
pricing |
8-level hierarchy, customer price lists, category overrides, volume tiers, multi-currency, exchange rates |
privacy |
Data-privacy requests + consent tracking |
product |
Product, Variant, Category, Brand |
promotion |
Discount engine, BOGO, stacking, cart indexer |
quote |
Quote lifecycle |
rate_limit |
Request rate limiting + throttle policies |
recurring |
Subscription/recurring orders |
registration |
B2B registration flow + document requirements |
reporting |
Saved + scheduled reports |
restriction |
Product/customer purchase restrictions |
review |
Product reviews + moderation |
rma |
Line-level return approval, state machine |
sales |
Rep assignment, commissions |
search |
Meilisearch (admin) + Typesense (storefront) indexing, SSR search |
seo |
SEO metadata, sitemaps, redirects |
store_credit |
Financial ledger, overdraft protection |
tags |
Universal tagging system |
tax |
Stage-sorted multi-strategy engine (sales tier 100, excise tier 200) |
tax_filing |
Tax filing exports + jurisdiction reporting |
tracking |
Shipment tracking integrations |
product_label |
Predicate-driven product labels with batch evaluation |
refund_approval |
Refund approval inbox + durable Temporal execution |
affiliate |
Affiliate program with multi-factor fraud guard |
wishlist |
Customer wishlists |
(Packaging + MMOQ live as columns + helpers inside the product and cart modules — no standalone packaging module. Workflow faults are an event domain, not a module — the schema is at events/schemas/workflow/fault_v1.json and faults persist to a workflow_faults table.)
Core Infrastructure (vectis/core/)¶
| File | Purpose |
|---|---|
app.py |
FastAPI application factory, lifespan, GraphQL router |
config.py |
Pydantic settings (env-based infrastructure config) |
database.py |
SQLAlchemy engine, session factory, Base, MoneyColumn |
middleware.py |
Channel resolution, auth, locale, currency context |
context.py |
RequestContext dataclass threaded through every request |
strategy.py |
StrategyResolver with channel-scoped extension filtering |
events/ |
In-process EventBus + Redpanda producer/consumer |
graphql.py |
Root Query and Mutation composing all module resolvers |
extension.py |
ExtensionRegistry, ExtensionProtocol/VectisExtension, ExtensionManifest, ChannelExtension model, canonical-id enforcement |
registration_ledger.py |
Per-extension registration ownership + auto-unregister |
ext_migrations.py |
Per-extension Alembic runner — re-exported as vectis_sdk.migrations |
permission_sync.py |
Boot-time additive permission upsert from manifests |
security.py |
JWT creation/validation, password hashing |
deps.py |
Dependency injection helpers (get_session context manager) |
Extensions¶
Extensions are installed Python packages discovered via pyproject.toml entry points (keyed by the bare canonical id — shopify, not ext_shopify). None live in the core repo: all 48 first-party extensions are maintained in the sibling vectiscommerce/enterprise-extensions repository (proprietary, commercial — see Architecture) and are discovered either as installed wheels or, in dev, via the VECTIS_DEV_EXTENSIONS dev-link described above. Extensions import vectis_sdk.* only. The current set spans several categories:
| Category | Extensions |
|---|---|
| Payment | ext_authorize_net, ext_nmi (gift cards, ACH, and manual payment are core payment methods, not extensions) |
| Shipping / carriers | ext_ups, ext_usps_priority_mail, ext_ontrac, ext_priority1, ext_goshippo, ext_shipstation, ext_shipstation_address, ext_package_protection, ext_local_delivery_routes, ext_openship |
| Tax / compliance | ext_excise_engine, ext_taxjar, ext_agechecker |
| Fraud / risk | ext_signifyd, ext_riskified, ext_radar, ext_ipqs, ext_maxmind |
| Storage | ext_rustfs (default local-dev store), ext_minio, ext_s3, ext_digitalocean_spaces, ext_dropbox |
| Email / messaging | ext_elastic_email, ext_ses, ext_sns, ext_twilio, ext_omnisend |
| Address / maps | ext_smarty, ext_google_maps |
| Tracking / delivery | ext_aftership |
| Import / data migration | ext_shopify, ext_woocommerce |
| Search | ext_algolia (pluggable search) |
| AI providers | ext_chatgpt, ext_claude, ext_grok, ext_mcp_catalog |
| Support | ext_jai_chat (promoted from core module, 2026-05) |
| Auth / e-sign | ext_keycloak, ext_docusign, ext_hellosign |
| Marketing / affiliates | ext_awin, ext_payout_csv, ext_customer_label |
| CRM / ERP | ext_odoo_leads (Odoo lead sync) |
See the enterprise-extensions repo (or backend/extensions.lock in the core repo) for the authoritative list.
Admin Routes¶
| Route | Page |
|---|---|
/ |
Dashboard |
/orders, /orders/[id] |
Orders list and detail (with inventory-risk filter, external handoff state) |
/products, /products/[id], /products/new, /products/labels, /products/labels/[id], /products/labels/new |
Product management + label CRUD |
/accounts, /accounts/[id], /accounts/create, /accounts/b2c |
B2B account + B2C customer management (old /customers* paths 301-redirect) |
/pricing |
Price lists |
/promotions |
Discount rules |
/inventory |
Stock levels |
/shipping |
Shipping zones and methods |
/tax |
Tax rates and strategies |
/cms |
CMS pages |
/settings, /settings/packaging, /settings/compliance, … |
Channel and system settings (~36 entries) |
/carts, /carts/new, /quotes, /recurring-orders |
Cart/quote/subscription management |
/claims, /returns, /fraud, /pending-changes |
Customer service workflows |
/refund-approvals |
Refund approval inbox |
/workflow-faults |
Workflow fault inbox |
/gift-cards, /store-credit, /store-credit/overdraft-drafts |
Financial instruments |
/affiliates/approvals, /affiliates/payouts, /affiliates/rules |
Affiliate program |
/lists, /lists/[id] |
B2B saved order lists |
/marketing, /registrations, /reports |
Marketing + admin ops |
/brands, /categories, /collections, /attributes, /traits, /tags, /quicklinks |
Catalog support |
/excise-calculator |
Tax tooling |
/extensions/<slug>/* |
Extension-contributed routes mirrored from each extension's admin_pages/ |
Channel context travels via the X-Channel-Slug header, not a URL prefix. Routes are flat. Full list: see admin/src/routes/.