aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/src/meshbay_node/ops/core.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-25 01:30:47 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-25 01:30:47 +0200
commit762233772162a05be67432aa551a430b939250de (patch)
tree311a2f72fef30fec6017313c55ed5beefcf0237e /packages/meshbay-node/src/meshbay_node/ops/core.py
parent320620a18399eb43c4d9056e9fe4c3ffac8fcfd4 (diff)
downloadmeshbay-762233772162a05be67432aa551a430b939250de.tar.gz
refactor(node): split ops.py into the ops package
Each section of ops.py becomes a module of meshbay_node/ops/ (core, node_toml, members, chat, groups, roots, files, settings, apps), cut as text; ops/__init__.py keeps the docstring and re-exports every name, so `ops.<name>` is unchanged for every caller. Logger name unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node/ops/core.py')
-rw-r--r--packages/meshbay-node/src/meshbay_node/ops/core.py57
1 files changed, 57 insertions, 0 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/ops/core.py b/packages/meshbay-node/src/meshbay_node/ops/core.py
new file mode 100644
index 0000000..7c19d78
--- /dev/null
+++ b/packages/meshbay-node/src/meshbay_node/ops/core.py
@@ -0,0 +1,57 @@
+"""What every operation shares: the refusal it raises and the lookups into `state`."""
+
+from __future__ import annotations
+
+from typing import Any
+
+
+class OpError(Exception):
+ """
+ An operation refused, with enough for any adapter to report it.
+
+ `status` is an HTTP code because one adapter needs one; the others ignore it.
+ `extra` carries the "here is what would have worked" payload — a bare "no
+ such group" leaves an operator guessing at a UUID.
+ """
+
+ def __init__(self, message: str, *, status: int = 400,
+ extra: dict[str, Any] | None = None):
+ super().__init__(message)
+ self.message = message
+ self.status = status
+ self.extra = extra or {}
+
+ def as_dict(self) -> dict:
+ return {"error": self.message, **self.extra}
+
+
+# ── Shared lookups ───────────────────────────────────────────────────────────
+
+def _roster(state: dict):
+ roster = state.get("roster")
+ if not roster:
+ raise OpError("Roster not available", status=503)
+ return roster
+
+
+def _hub(state: dict):
+ hub = state.get("hub")
+ if not hub or not hub._session:
+ raise OpError("Hub not connected", status=503)
+ return hub
+
+
+def _group_ctx(state: dict, group_id: str) -> dict:
+ groups_ctx = state.get("groups_ctx", {})
+ if group_id not in groups_ctx:
+ raise OpError("Group not hosted on this node", status=404,
+ extra={"available": [
+ {"id": gid} for gid in groups_ctx]})
+ return groups_ctx[group_id]
+
+
+def _config(state: dict):
+ config = state.get("config")
+ if not config:
+ raise OpError("No config loaded", status=503)
+ return config