aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/db
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/db')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/db/migrations/versions/3dc91cd4ea52_group_hosted_at.py37
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/db/models.py5
2 files changed, 42 insertions, 0 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/db/migrations/versions/3dc91cd4ea52_group_hosted_at.py b/packages/meshbay-hub/src/meshbay_hub/db/migrations/versions/3dc91cd4ea52_group_hosted_at.py
new file mode 100644
index 0000000..57aa9a7
--- /dev/null
+++ b/packages/meshbay-hub/src/meshbay_hub/db/migrations/versions/3dc91cd4ea52_group_hosted_at.py
@@ -0,0 +1,37 @@
+"""group hosted_at
+
+Records the first time a node announced that it hosts a group. Groups without
+it are shown to their owner only, and `meshbay-hub prune-groups` collects the
+ones that never got a node.
+
+Backfilled to created_at for every existing group: they predate the rule, and
+starting the clock on them retroactively would delete live groups on the first
+run of the reaper.
+
+Revision ID: 3dc91cd4ea52
+Revises: d1f47a90c3b2
+Create Date: 2026-08-16 03:20:00.575130
+
+"""
+from typing import Sequence, Union
+
+from alembic import op
+import sqlalchemy as sa
+
+
+# revision identifiers, used by Alembic.
+revision: str = '3dc91cd4ea52'
+down_revision: Union[str, Sequence[str], None] = 'd1f47a90c3b2'
+branch_labels: Union[str, Sequence[str], None] = None
+depends_on: Union[str, Sequence[str], None] = None
+
+
+def upgrade() -> None:
+ op.add_column("groups",
+ sa.Column("hosted_at", sa.DateTime(timezone=True), nullable=True))
+ # Existing groups are grandfathered in rather than left to expire.
+ op.execute("UPDATE groups SET hosted_at = created_at WHERE hosted_at IS NULL")
+
+
+def downgrade() -> None:
+ op.drop_column("groups", "hosted_at")
diff --git a/packages/meshbay-hub/src/meshbay_hub/db/models.py b/packages/meshbay-hub/src/meshbay_hub/db/models.py
index 7d5a3e3..a220a64 100644
--- a/packages/meshbay-hub/src/meshbay_hub/db/models.py
+++ b/packages/meshbay-hub/src/meshbay_hub/db/models.py
@@ -99,6 +99,11 @@ class Group(Base):
description: Mapped[str | None] = mapped_column(String(512))
status: Mapped[str] = mapped_column(String(16), default="active") # active|suspended|revoked
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_now)
+ # First time a node registered on /v1/nodes/ws announcing that it hosts this
+ # group. Until then the group has no files, no key and nobody to serve it, so
+ # it is shown to its owner only and is what `prune-groups` collects. Set once
+ # and never cleared: a node going offline does not un-host a group.
+ hosted_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
members: Mapped[list["GroupMember"]] = relationship(back_populates="group")