2.7 KiB
2.7 KiB
VMall Architecture
VMall is a B2B2C marketplace MVP: one Rust API serving three Nuxt 3 frontends, with all HTTP contracts centralized in a shared TypeScript package.
Workspace layout
apps/
api/ Rust (crate vmall-api), port 8080 — the only backend
mall/ Nuxt 3 shopper storefront (PC), port 3000
shop-admin/ Nuxt 3 merchant console, port 3001
admin/ Nuxt 3 platform console, port 3002
packages/
shared/ @vmall/shared — the ONLY API contract (types.ts + api.ts),
en/zh locale packs, Tailwind v4 theme tokens
ui/ @vmall/ui — shared Vue components (VBtn, VCard, VField,
VInput, VTable, VPage, VPanel, VBadge, VAccentSwatch)
openspec/ Spec-driven change management (specs/ = archived truth)
docs/ Architecture, guidelines, code index
Request path
Browser ──► Nuxt (SSR + hydration) ──► $api plugin ──► vmall-api ──► Postgres
│ │
│ └─► Redis (cache/sessions)
└─ mock adapter fallback (mall only)
- Frontends never call
fetchdirectly; they call theApiClientfrom@vmall/shared, provided as$apiby each app'splugins/api.ts. - The mall additionally composes a mock adapter (
apps/mall/mock/api.ts) with per-domain live picks (LIVE_PICKSinapps/mall/plugins/api.ts), so any domain can roll back to deterministic fixtures viaNUXT_PUBLIC_LIVE_DOMAINS. The consoles are always live.
Roles and tenancy
platform_admin (apps/admin), shop_owner/shop_staff (apps/shop-admin,
scoped to their shop via auth.own_shop()), customer (apps/mall). Every
protected route declares its roles; cross-shop access returns 404.
Data rules that shape everything
- Money:
i64minor units + ISO currency code everywhere. No floats. The currency table carries the exponent (JPY=0); display goes throughformatMoney(minor, code, exponent, locale). - User-facing content:
{en, zh}JSONB. - State machines: guarded
UPDATE … WHERE status = …; zero rows → 409. - Concurrent counters: guarded
SET col = col - $q … AND col >= $q; replenish withcol + n, never read-then-write. - Migrations:
apps/api/migrations/, append-only, run on boot.
Where to look next
- Backend conventions →
docs/backend-guidelines.md - Frontend conventions →
docs/frontend-guidelines.md - Run/develop/test →
docs/development.md - Domain deep dives →
docs/domains/ - Find the file for a feature →
docs/code_index/index.md - Normative behavior →
openspec/specs/