Skip to main content

Application surfaces vs platform backbone

Tier: Public
Status: Decision-of-record 2026-05-28 (terminology + layering; no new RFC)
Audience: core team, module authors, self-hosting operators, anyone asking "where does backend live?" or "do we need admin vs storefront?"
Builds on: PLATFORM-ARCHITECTURE.md §1.1, §2, §4.0–§4.2; REPOSITORY-STRUCTURE.md §2; RFC-0001 §8 (Decision F); ROADMAP.md standing principles

Disclaimer. Clarifies vocabulary and audience boundaries already committed elsewhere. Does not allocate a new canonical module, does not introduce @umbraculum/core as a package, and does not change the one-shell / one-AI-context principle.


1. Summary​

QuestionShort answer
What is the platform backbone?Horizontal platform services (auth, workspace, billing, AI, rendering, i18n, navigation primitives) + services/api as the single API monolith + @umbraculum/module-sdk as the module registration contract.
What is a backend in this repo?Usually services/api (layer 2). Sometimes the whole horizontal platform. Rarely "Drupal admin" — that phrase overloads operator UI with API service.
Drupal-style admin vs customer frontend?Not the model for PIM / WMS / MRP / CRP / CRM or for brewery today. Operator modules share one workspace-member shell. Shopper-facing surfaces (if any) are separate apps.
How do you "configure" a public operational product?Install canonical modules + vertical configuration + workspace entitlements — not by theming a second backend inside apps/web.
Is @umbraculum/core the backbone?No. That npm name is reserved and unused. The backbone SDK is @umbraculum/module-sdk plus horizontal packages (§5).

2. Four layers (not "backend vs frontend")​

LayerRoleExamples in tree
Platform backboneCross-cutting services every module consumes (RFC-0001 §8.2); single source of truth for tenancy and AI contextservices/api, @umbraculum/contracts, @umbraculum/module-sdk, @umbraculum/ui, @umbraculum/navigation, @umbraculum/rendering, …
Canonical modulesPeer operational domains (flat SAP-style decomposition, not nested under "manufacturing")automation, pim (shipped); mrp, crp (alpha read-only shipped); wms, crm (open doors)
Vertical configurationSeed data, prompts, vertical UI — consumes canonicals, does not replace thembrewery (reference tier-6 configuration) — web slice under apps/web/app/[locale]/(brewery)/ (β layout complete for recipes, 2026-06)
Application surfacesDeployable UIs or sites for a specific audienceapps/web + apps/native (operators); Ubuntu Touch via Click Morph webapp wrapper over apps/web (ubuntu-touch-shell-strategy.md); umbraculum-brochure (public orientation); future storefront = separate apps/*

Repository layers vs product layers. REPOSITORY-STRUCTURE.md names layer 1 Applications (apps/*) and layer 2 Services (services/*). That is spatial (where code lives), not Drupal's merchant/customer split. Both web and native are operator applications talking to the same API.


3. Terminology glossary​

Use these terms in reviews and plans to avoid talking past each other. For onboarding terms (vertical, canonical, brewery reference vertical, module taxonomy): GLOSSARY.md.

TermMeaningDo not confuse with
API serviceHTTP monolith: routes, Prisma, jobsOperator UI, "admin theme"
Horizontal platformAuth, workspace, billing, AI orchestrator, rendering, notifications boundary, …A single package named core
Workspace web UIFederated web shell (apps/web) workspace members use dailyStorefront, brochure site; not “all native binaries”
Workspace-member appPrimarily workspace web UI — one web shell, one AI workspace context (ROADMAP)B2C shopper app; not one mega-native shell
Native purpose-built binaryOne Expo store app at apps/native/<app-code>/ (brew-day, future floor/scanner apps)@umbraculum/native-shell package; apps/web
Native app compositionWhich module native slices a binary registers at build time (registerNativeModule subset)Installation profile listing every server module in one app
Module registrationBoot-time declaration via registerModule() / registerWebModule() / registerNativeModule()Runtime shared layout registration (partially deferred — see §5)
Public surface (marketing)Static orientation HTMLOperational "public API"
Storefront / commerce (future)Separate deployable; read-only consumer of PIM/CRM master dataPIM admin UI

4. Drupal-style vs ERP-style​

4.1 Drupal-style (usually not this project)​

  • Merchant configures catalog in admin backend
  • Customer shops on themed frontend
  • Two audiences, often two apps, shared CMS core

4.2 Umbraculum-style (committed)​

  • Workspace members (planners, brewers, warehouse staff, admins) use one web shell (apps/web) with federated module routes — the ecosystem can grow large on web (Odoo-class operator UI is in scope on this surface)
  • Native ships many purpose-built binaries (apps/native/<app-code>/), each composed from a subset of module native slices — not one native deployable that mirrors every web route (RFC-0011 Decision C; installation-profile.md § Web vs native)
  • Canonical modules are operator systems (Akeneo / SAP / Odoo class admin), not storefronts
  • AI consultant requires workspace-scope context on web + API — multiple native task apps do not split that context; a single mega-native shell is not required and is not the target shape

Standing principle (ROADMAP.md) — read web vs native:

One audience per app. Workspace-member modules share one web shell. Shopper-facing surfaces (if any) are separate apps. Native uses separate store binaries where mobile form factor is intrinsic (offline, scanning, floor input) — see apps/native/README.md.

4.3 Where Drupal does apply — the optional edge​

SurfaceAudienceIn repo today
PIM product adminWorkspace member(pim)/ routes in apps/web
Channel feed / CSV exportDownstream systemPIM + RFC-0007 rendering
Shopper storefrontAnonymous / customerNot in repo; explicitly separate app if pursued
Marketing siteEvaluator / contributorumbraculum-brochure (static; not operational)

PIM boundary (canonical-pim-module-surface.md §3.2): master product data is canonical; storefront projections belong to a sibling commerce module, not inside PIM.


5. Module SDK vs @umbraculum/core vs shell composition​

5.1 Yes — the "core SDK" already exists​

In governance and npm terms, the module registration spine is shipped:

PackageTierRole
@umbraculum/module-sdk2 (MIT)registerModule(), registerWebModule(), registerNativeModule(), reserved codes, ValidatedSchema<T>, document-template types
@umbraculum/ai-tool-sdk2 (MIT)AI tool contract types
@umbraculum/i18n-keys2 (MIT)Module nav / message-key conventions

Third-party modules pin these — they are the public "how you plug into the platform" contract (MODULES.md §3.3, RFC-0001 tier 2).

The SDK is contract + boot-time registry, not the API implementation:

ConcernOwner
Fastify routes, Prisma, orchestrator, billing webhooksservices/api
Registration shape, collision detection, nav metadata types@umbraculum/module-sdk
Tamagui primitives, route IDs, useT, api-clientOther horizontal packages

5.2 What @umbraculum/core is not​

During the @brewery/* → @umbraculum/* scope migration, @brewery/core (brewing math) was renamed to @umbraculum/brewery-core — deliberately not @umbraculum/core — so "core" does not read as "everything shared" (brewery-scope-migration-plan.md §1.3).

There is no @umbraculum/core package today. The name remains reserved; creating it as a grab-bag of shared code would recreate the trap the migration avoided.

Some runtime shell concerns are partially extracted:

These are operator-shell composition problems. Reasonable future homes (pick one when the debt hurts — no commitment now):

  1. Stay in apps/web / apps/native until a second shell consumer exists
  2. Extract shared shell helpers to a new horizontal package (e.g. @umbraculum/shell — name illustrative only)
  3. Extend @umbraculum/navigation with registry-aware composition helpers

They should not become a second API, duplicate module-sdk, or hold domain logic. @umbraculum/module-sdk remains the registration contract; any future shell package would consume it, same as apps/web does.


6. Worked examples​

6.1 Brewery workspace (today)​

PieceClassification
Recipe editor, brew-day flowsVertical configuration UI in workspace web UI
/auth/*, workspace switcherHorizontal platform
services/api recipe routesAPI service (brewery-vertical routes today; β-layout under modules/brewery/)
Brochure at umbraculum.devLayer 4 marketing — not operational backend
Hypothetical beer shopLayer 4 separate app — would consume PIM/CRM APIs, not live inside (brewery)/

Brewery operators are the users of apps/web / apps/native. There is no in-repo B2C storefront; native exists for offline brew-day (form factor), not for shoppers.

6.2 PIM-only workspace (future)​

A cosmetics company using only pim + platform horizontal services:

  • Operators use (pim)/products, (pim)/categories, … in the same shell as any other installed module
  • No WMS/MRP required for a minimal deployment
  • Shopify storefront (if built) = separate app reading channel feeds / APIs — not "PIM frontend theme"

6.3 Configuring a hosted product​

To offer "Umbraculum hosted for breweries" or "hosted PIM":

  1. Enable modules + vertical seed (brewery configuration or PIM-only)
  2. Set workspace billing tier and (future) per-module add-ons
  3. Assign workspace members and roles
  4. Optionally operate a separate marketing or commerce app — not by forking the workspace web UI into "admin" vs "store"

7. Cross-references​