Architecture overview
Five standalone Rails applications in one repository (keferboeck/solidus-demos), each a
complete Solidus 4.7 shop with its own database, deployed independently with Kamal to the
shared keferboeck-ltd droplet.
flowchart LR
subgraph Shoppers
V[Browser]
end
subgraph Droplet["keferboeck-ltd ยท 161.35.42.199"]
P[kamal-proxy 80/443]
H1[hampers-web] --- D1[(hampers-db)]
H2[joinery-web] --- D2[(joinery-db)]
H3[marlowfinch-web] --- D3[(marlowfinch-db)]
H4[wagwhisker-web] --- D4[(wagwhisker-db)]
H5[flugschule-web] --- D5[(flugschule-db)]
end
subgraph External
ST[Stripe test mode]
MJ[Mailjet HTTP API]
AN[Anthropic API]
HUB[Portal hub.keferboeck.com]
REP[Replicate FLUX]
end
V --> P
P --> H1 & H2 & H3 & H4 & H5
H1 & H2 & H3 & H4 & H5 --> ST
H1 & H2 & H3 & H4 & H5 --> MJ
H2 & H3 & H4 & H5 -- shop assistants --> AN
H1 & H2 & H3 & H4 & H5 -- "leads via X-Store-Key" --> HUB
REP -. generated imagery, offline pipeline .-> H1
Per-shop stack
Ruby 3.3.9, Rails 8.1, Solidus 4.7, Postgres, Solid Queue, Hotwire, Tailwind, importmap. Bilingual storefronts (EN/DE) with per-currency price lists (a currency switch shows a real price list, never a conversion rate). Stripe runs in test mode with the demo card notice on the payment step. All product imagery is generated (FLUX on Replicate); the photography brief is derived from the catalogue per shop.
Shared platform patterns
- Showcase mode: a floating chip that annotates the shop's special features for prospects.
- Shop assistants: AI product finders grounded in the catalogue; conversations are stored and summarised, with FAQ statistics surfacing in the backend.
- Lead capture: newsletter signups post to the portal's consent ledger with a per-store API key; contacts and consents live in the hub, not the shop.
- Demo resets: nightly demo data reset at 04:15 keeps the shops clean; nightly Postgres backups run at 03:30, before the reset.