⚡ VBWD
A sales platform for the digital world — SaaS subscriptions, CMS, shop, booking and a token economy on one self-hosted backend, two Vue front-ends and one plugin contract.
A Kotlin + Jetpack Compose port of the iOS app
Android is a faithful iOS port that
preserves the exact public contracts — the
Plugin interface, the PlatformSdk facade,
event names, manifest shape and route/permission semantics — so an
iOS or web plugin author maps across 1:1. Built with
Kotlin, Jetpack Compose and
Hilt; compileSdk 36,
minSdk 26, JDK 17.
:app — hostSingle-activity @HiltAndroidApp;
MainActivity → AppRoot, the composition root
(di/CoreModule.kt), and the
plugins.json + vbwd_config.json assets.
:core — the SDKNetworking (OkHttp + kotlinx.serialization),
domain + session, the plugin system, and the shared Compose
screens. Published as com.vbwd:vbwd-android-core.
:plugins:* — featuresDepend on :core only — a
CI-enforced dependencyBoundaryCheck fails the build
on any undeclared edge (the core-agnosticism rule).
The same seams, in Kotlin
A plugin implements the Plugin interface; all hooks
are suspend and all but install default to
no-ops. The host loads the manifest, registers the compiled-in
plugins, installs the enabled ones in topological dependency order
and activates them — every failure isolated to its plugin:
interface Plugin {
val metadata: PluginMetadata // name, SemanticVersion, dependencies
suspend fun install(sdk: PlatformSdk) // register into the app
suspend fun activate() {}
suspend fun deactivate() {}
suspend fun uninstall() {}
}
install receives the PlatformSdk facade
— and nothing else — exposing
addRoute, addMenuItem,
addComponent (Dashboard* /
Profile* by prefix), createStore,
addTranslations, addPaymentAction,
addCheckoutSource, plus the injected
api, events and cart.
Adding a plugin = a new :plugins:<name> module +
an entry in provideAvailablePlugins and
plugins.json.
Config asset, encrypted token store
Configuration lives in
app/src/main/assets/vbwd_config.json. Set
api_base_url to your instance — use
http://10.0.2.2:5000/api/v1 to reach the host's
localhost from the emulator, or
https://vbwd.cc/api/v1 for the live demo. Login
POST /auth/login yields a bearer token persisted with
EncryptedSharedPreferences (the
Keychain analogue); requests go through a single
ApiClient (OkHttp) port that injects the token and maps
a 401 to a sign-out event.
Login to LLM bot, all in Compose
Once authenticated, AppShellView renders a top bar,
a navigation drawer (Dashboard, Profile, Settings + every plugin's
menu items) and the routed content. Material 3 theming flows
from a ThemeManager; plugins register their own
AppThemes.










Captured from the live Android
build talking to vbwd.cc. The
iOS app renders the same screens.
What's in the build
meinchatMulti-room chat: SSE message streaming, image attachments, peer-to-peer token transfers, bot meta-content (choices/menu/cart cards).
meinchat-plusSecure-messaging extension (crypto protocol); declares a dependency on meinchat.
cmsConfig-driven “Posts” browser over the host CMS embed — page/post/video/PDF through one WebView.
subscriptionTarif-plan + add-on browser, subscription overview, dashboard widget, a subscription checkout source.
token-paymentToken-balance payment method — quote + charge, registers the “token” payment action.
stripeStripe checkout-session payment method with a WebView redirect section.
invoiceInvoice-info payment method — registers the “invoice” action + info section.
tarotTarot reading feature; draw/reading routes, independent of commerce.
exampleReference plugin exercising every PlatformSdk seam — the canonical new-plugin template.
One Gradle task
- Point
api_base_urlinapp/src/main/assets/vbwd_config.jsonat your backend. - Build & install to a device/emulator:
./gradlew :app:installDebug(app idcom.vbwd.app). - The quality gate —
./gradlew check dependencyBoundaryCheck— is what CI runs (ktlint + detekt + unit + boundary).
Same contract, different runtime: see the iOS guide for the SwiftUI original, or the plugin system for how a feature lights up across web, iOS and Android at once.