Architecture
Control plane, modules, services, and how they fit together.
Layers
1. Control plane: the Backpack console (repo: site-editor, live at sites.backpackops.com). Next.js on Vercel. Owns navigation, auth, the sites/CMS tooling, and light integrations into everything else (status, counts, deep links). It never absorbs a full product.
2. Client websites. Static exports (ported from Webflow) in one GitHub repo per site, hosted free on Vercel, one Vercel project per site. Content is structured data inside each repo (see CMS). The porter automates cloning, repo creation, Vercel setup, and analytics registration.
3. Service platforms. Complete open-source products running as their own deployments, never bundled into the console:
| Module | Platform | Model |
|---|---|---|
| Inbox | iese (our Chatwoot fork, repo mrcoven94/iese) | one deployment, per-client inboxes |
| Email campaigns | Listmonk | one instance per large client |
| Transactional email | Openship mail server (trial) or SES | fleet-shared, per-client domains |
| Social | Postiz, self-hosted | one instance, per-client workspaces |
| Money | QuickBooks Online (SaaS) | integration only, never self-hosted |
| Analytics | Umami, self-hosted at analytics.backpackops.com | fleet-shared, one website entry per site |
The console’s module pages (Inbox, Social, Money, Tasks) light up when their URL env var is set (INBOX_URL, SOCIAL_URL, MONEY_URL, TASKS_URL). Until then they show setup instructions. See Modules.
4. Substrates. Where things physically run:
- Vercel: all static client sites and the console. Free tier covers static sites entirely.
- Railway: existing services (iese). Managed, reliable, roughly $20/mo.
- Hostinger VPS + Openship (trial): the mail server (needs open port 25 and PTR records, which PaaS providers block) and new per-client service spin-ups. See the Openship decision.
Every capability is multi-tenant per client (ADR 11): platform-native tenants where strong, instance-per-client where not.
Substrates are interchangeable plumbing. The console reaches services by URL and API, so moving a service between substrates changes nothing above it.
Repo layout
All repos will live in the backpackops GitHub org (migration pending, currently under mrcoven94):
console(today: site-editor). The control plane.porter(today: site-porter). GitHub Actions pipeline that ports a site end to end.iese. The Chatwoot fork.- One private repo per client site (e.g. naacp-snohomish-site).
backpack-docs. This documentation.
Separate repos are deliberate: sub-agents work one platform each without tripping over the rest, and the orchestration layer (console + porter + playbooks here) ties them together.
Data flows worth knowing
- Site edit (human or AI): console writes to the site repo via GitHub API. Vercel auto-deploys from the repo. Production changes in about a minute.
- AI page edits: staged on a
preview/*branch, Vercel builds a public preview URL, publishing merges to main. CMS item operations skip branches; draft status on the item itself controls visibility instead. - Analytics: every page carries the Umami script. The console resolves a site’s Umami entry by reading the data-website-id off the live page, which works before DNS cutovers.
- Provisioning (future): a services registry maps client to instances to URLs, and provisioning a Listmonk or inbox for a client becomes the same gesture as porting a site.