notification catalogue: GET /api/notify/mapping
the piece that makes a new notification kind a server change rather than an app store release. a push carries a code and integers; this is what the code means, synced to the device instead of compiled into it. deliberately the same shape as affordances rather than a second mechanism: a `notifications/` directory of yaml in the plugin repository, copied to capabilities/notifications/<publisher>/<appName>/ on install, removed on uninstall. publish.ts mirrors affordances/publish.ts closely enough to diff. the namespace is DERIVED from where the file lands, never from what it declares — same rule as mountPrefix. a plugin writing `officer/core:test` as a key gets `<publisher>/<plugin>:officer/core:test` and the real core entry is untouched. that is the security property of the whole scheme and it is pinned by test. version is a content hash, not a counter. a counter needs somewhere to live and is then wrong after a restore, a rollback, or two servers built from the same install; a hash needs no storage and is right in all three. so the client compares mv !== version, and both docs now say so — i had written "higher". core entries ship in code rather than on disk, because capabilities/ is installed rather than committed and `test` has to exist on a machine that has installed nothing — it is what first light is proved with. read from disk per request, not memoised: installing a plugin has to change the answer without a restart, or it presents as "the new plugin's notifications don't work", which is the hardest kind of bug to place. verified live: 401 through the platform, plugin catalogue appearing and disappearing with no restart, version returning to its prior value when the plugin is removed. 10 catalogue tests, 100% coverage of catalogue.ts.
This commit is contained in:
@@ -130,18 +130,27 @@ An entry says how to render and where to go:
|
||||
| `route` | the deep link, with `{id}` interpolated |
|
||||
| `thread` | grouping key, so like-notifications collapse rather than stack |
|
||||
|
||||
**Plugins declare their own**, on the affordances pattern (`src/servers/affordances/publish.ts`): a
|
||||
directory in the plugin repository, copied to a platform-managed store on install, removed on uninstall,
|
||||
namespaced `<publisher>/<appName>/`. That mechanism already exists and is understood; a second one for
|
||||
**Plugins declare their own**, on the affordances pattern (`src/servers/notifications/publish.ts`, which
|
||||
deliberately mirrors `affordances/publish.ts`): a `notifications/` directory of YAML in the plugin
|
||||
repository, copied to `capabilities/notifications/<publisher>/<appName>/` on install and removed on
|
||||
uninstall.
|
||||
|
||||
The namespace is **derived from where the file lands, never from what it declares** — the same rule as
|
||||
`mountPrefix`. A plugin therefore cannot claim `officer/core:` or another publisher's codes by writing
|
||||
them into its own catalogue; it would have to install itself somewhere it cannot. This is pinned by test. That mechanism already exists and is understood; a second one for
|
||||
notifications would drift from it. The platform aggregates every installed plugin's catalogue plus its own
|
||||
into the response above, and `version` increments whenever that aggregate changes.
|
||||
|
||||
### Staying in sync, and the fallback
|
||||
|
||||
Every push carries `mv`, the mapping version it was rendered against. The app compares it to its cached
|
||||
version and **resyncs in the background when it is behind** — so the mapping normally catches up before an
|
||||
version and **resyncs in the background when they differ** — so the mapping normally catches up before an
|
||||
unknown code can arrive.
|
||||
|
||||
`version` is a **content hash, not a counter**, so the test is `mv !== version` rather than `mv > version`.
|
||||
A counter would need somewhere to live and would then be wrong after a restore, a rollback, or two servers
|
||||
built from the same install; a hash needs no storage and is right in all three.
|
||||
|
||||
When a push still outruns the sync, the fallback renders:
|
||||
|
||||
> **Unknown notification**
|
||||
|
||||
Reference in New Issue
Block a user