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