diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-10 17:49:58 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-10 17:49:58 +0200 |
| commit | 07ff8b4f6143039fcc74b8cf7c423282bce093c1 (patch) | |
| tree | 89e095aeef9f5ad0bcbe7b3e6cfdc67d36bcbba8 /packages/meshbay-node/src/meshbay_node/ops.py | |
| parent | 1e6f3861a1570029897a30b42121836fd03565c1 (diff) | |
| download | meshbay-07ff8b4f6143039fcc74b8cf7c423282bce093c1.tar.gz | |
refactor(mnp)!: one operation for an app's folders, not one per app
`video_root`, `audio_root` and `photo_roots` are gone — the messages, the
signed operations, the handlers, the `ops` wrappers, the three scalars on the
handshake ack, and the client's handlers for their acks. `app_directories`
does the same thing for every application, keyed by the app's own registry
name, and it is what the SPA has been sending.
The three were the same instruction three times, differing only in the key they
wrote and whether they carried a string or a list. That shape is what made
adding an application mean adding a message type, an op, a handler and a widget;
it also meant three validation paths, and the older ones validated nothing —
a typo was stored and then quietly matched no entry, an app showing an empty tab
with no way to tell "misconfigured" from "no files yet".
**What stays, and why.** `Roster.LEGACY_DIR_KEYS` still reads `video_root` and
friends out of `group_settings`: that is a key on an operator's disk, not on the
wire, and a node upgraded into this must find its own configuration. The Search
page still reads its own older cache keys, for the same reason — the cache
outlives a deploy. `CTX_ALIASES` keeps only `chat`, which is the one app whose
second name something still reads.
The two per-app policy test files go with the messages. What only they held —
the real challenge/response path from message to database, which no other test
exercises — is retargeted at `app_directories` in
`test_app_directories_signed.py`, and the handler's own refusals (unknown app,
malformed `directories`, nobody to authorize it) join `test_app_directories.py`.
Node and common suites 1368 passed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AsoWC3GmhNdwVFomW3QjH3
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node/ops.py')
| -rw-r--r-- | packages/meshbay-node/src/meshbay_node/ops.py | 32 |
1 files changed, 5 insertions, 27 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/ops.py b/packages/meshbay-node/src/meshbay_node/ops.py index 5b8e22d..4d3422d 100644 --- a/packages/meshbay-node/src/meshbay_node/ops.py +++ b/packages/meshbay-node/src/meshbay_node/ops.py @@ -1641,9 +1641,8 @@ async def set_app_directories(state: dict, group_id: str, app_key: str, One function for every app, keyed by the app's own name: adding an application is a registry entry and a settings component, not another - near-identical op here. It replaces `set_video_root`, `set_audio_root` and - `set_photo_roots`, which differed only in the key they wrote and whether - they took a string or a list. + near-identical op here — one per app differing only in the key it wrote + and whether it took a string or a list. Empty means nothing configured, which every app reads as "show nothing until an operator has chosen" — never "the whole group index". Pointing an @@ -1661,9 +1660,9 @@ async def set_app_directories(state: dict, group_id: str, app_key: str, await roster.set_app_directories(group_id, app_key, clean, set_by=state.get("node_user_id", "")) ctx[f"{app_key}_directories"] = clean - # The scalar the handshake ack still publishes for MNP 1.0 clients is - # derived, and has to be re-derived here: leaving it behind would make the - # ack disagree with the list within a single run, and only until a restart + # An app whose directories are also published under a second name (chat's + # single destination) has that name re-derived here: leaving it behind + # would make the two disagree within a single run, and only until a restart # — the shape of bug that reads as "it works after a restart". from meshbay_node.roster import Roster alias = Roster.ctx_alias(app_key, clean) @@ -1696,27 +1695,6 @@ async def set_app_directory(state: dict, group_id: str, app_key: str, return {**result, "path": dirs[0] if dirs else ""} -# The per-app wrappers MNP still names. They exist so an MNP 1.0 client's -# `video_root` / `audio_root` / `photo_roots` messages keep working; nothing -# new should be added here — a new app calls the generic pair above. - -async def set_video_root(state: dict, group_id: str, path: str) -> dict: - result = await set_app_directory(state, group_id, "video", path) - return {"path": result["path"], "group_id": group_id} - - -async def set_audio_root(state: dict, group_id: str, path: str) -> dict: - # "music", not "audio": the app's registry key is what identifies it - # everywhere, and `audio_root` is only the name the setting used to have. - result = await set_app_directory(state, group_id, "music", path) - return {"path": result["path"], "group_id": group_id} - - -async def set_photo_roots(state: dict, group_id: str, roots: list[str]) -> dict: - result = await set_app_directories(state, group_id, "photo", roots) - return {"roots": result["directories"], "group_id": group_id} - - # ── Chat ───────────────────────────────────────────────────────────────────── async def set_chat_directory(state: dict, group_id: str, path: str) -> dict: |