docs: kiosk replaces the marketplace, and the shape it takes
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
# Kiosk — the store, and what it replaces
|
||||
|
||||
Decided in conversation on 2026-08-18. Direction, not a work order: none of it is built, and the parts that
|
||||
touch third parties are months out. Recorded so the shape is not re-argued.
|
||||
|
||||
The commercial reasoning is `BUSINESS-MODEL.md` in the `officer-oas` repository; this file is the technical
|
||||
half.
|
||||
|
||||
---
|
||||
|
||||
## One brand, two halves
|
||||
|
||||
**Kiosk** is what a person sees. `kiosk.officer.dev` is the public hub: a searchable catalogue of
|
||||
everything in the Officer ecosystem — plugins, apps, the plugins that have companion apps, the apps that
|
||||
have plugins. **Nothing happens there.** It stores metadata and exposes an API, so a platform can embed it.
|
||||
|
||||
Underneath, two separate plugins with separate repositories:
|
||||
|
||||
| | ships to | holds | is |
|
||||
| ------------------- | -------------------------- | ------------------------------------------------- | ------------------- |
|
||||
| the **storefront** | every instance | no database, no sidecar | free infrastructure |
|
||||
| the **apps engine** | whoever distributes builds | 4 tables, a sidecar, artefacts, Apple credentials | the paid product |
|
||||
|
||||
They are split on that last column rather than on any technical boundary. Bundled, every server would carry
|
||||
app-distribution machinery it will never run, and the commercial half would live inside the plugin that can
|
||||
never be uninstalled. That is the wrong seam.
|
||||
|
||||
**Brand is not `appName`.** `label` is what a person reads; `appName` is the directory name and the route.
|
||||
Both can be "Kiosk" to a human while being distinct identifiers underneath — the same way `email`'s label is
|
||||
"Email".
|
||||
|
||||
---
|
||||
|
||||
## `/marketplace` goes away
|
||||
|
||||
Replaced by `/kiosk`, and the screen moves out of the platform into the storefront plugin, which mounts
|
||||
exactly the way every other plugin does.
|
||||
|
||||
**The install machinery does NOT move.** `src/servers/plugins/` — discover, mount, install, schema,
|
||||
ecosystem — is how any plugin gets mounted, including Kiosk itself, so it cannot live inside one. It is
|
||||
already API-shaped (`/api/plugins`: what is on this machine, what is installed, and the four verbs that
|
||||
change it), which is what makes this a UI move rather than a refactor.
|
||||
|
||||
So: **the platform keeps the mechanism, the plugin owns the shop window.**
|
||||
|
||||
Because a first-party plugin mounts at `/<appName>` (`mountPrefix`, verified), the storefront must be
|
||||
`appName: 'kiosk'`. That settles the identifier by way of the route.
|
||||
|
||||
## The storefront is a privileged plugin
|
||||
|
||||
Not a normal one, and the differences are deliberate:
|
||||
|
||||
- **installed on every instance**, as a setup step rather than a marketplace action — you cannot install the
|
||||
installer with the installer;
|
||||
- **not listed** among installed plugins;
|
||||
- **no uninstall UI**;
|
||||
- **and removing it must not brick the server.** A user can always stop or delete the PM2 service by hand,
|
||||
so the platform has to survive the storefront being absent. The install verbs are the platform's and stay
|
||||
reachable without it; that is what makes this true rather than hoped.
|
||||
|
||||
## Two calls to action, one catalogue
|
||||
|
||||
The hub is a discovery surface for people who do not have a server yet — someone browses it and asks their
|
||||
admin for something. That is a funnel, and it means the two halves end differently:
|
||||
|
||||
- **a plugin can be installed** — by an admin, on a server, now;
|
||||
- **an app cannot be installed from the hub at all.** It needs a server running the apps plugin, an account,
|
||||
a registered device, and somebody paying Apple.
|
||||
|
||||
Same catalogue, two endings. Worth designing the entry shape around, rather than discovering it when the
|
||||
Install button does nothing for half the listings.
|
||||
|
||||
**The pairing is declared data, not inference.** "Plugins that have apps" cannot be derived from names that
|
||||
happen to match; a manifest field declares the companion. It is the smallest piece of work here and the
|
||||
whole browsing experience hangs off it. Safe to put in the public catalogue — names, not artefacts.
|
||||
|
||||
---
|
||||
|
||||
## Open
|
||||
|
||||
- **What the apps plugin is called.** It cannot be `kiosk`, since the storefront takes that with the route.
|
||||
`kiosk-apps` is legible and obviously paired; `builds` describes what it manages. Currently sitting at
|
||||
`plugins/kiosk` (and `gitea.officer.dev/plugins/kiosk`) from the night it was started — **that name is
|
||||
wrong and pending a decision**, which is cheap now and expensive after either ships.
|
||||
- **Whether `marketplace.officer.dev` becomes `kiosk.officer.dev`.** Precedent says rename the screen and
|
||||
leave the machine endpoint alone: every installed server has the current URL baked in as its default, so a
|
||||
rename drops them to the bundled catalogue until they update.
|
||||
- Everything about third parties — review, pinning, confining a plugin's sidecar. See `TODO.md`,
|
||||
"Plugin ecosystem — before it opens to third parties". Months away and not a prerequisite for the rename.
|
||||
Reference in New Issue
Block a user