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/b4d82e1c77a9_notification_groups_and_mute.py41
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/db/models.py8
2 files changed, 49 insertions, 0 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/db/migrations/versions/b4d82e1c77a9_notification_groups_and_mute.py b/packages/meshbay-hub/src/meshbay_hub/db/migrations/versions/b4d82e1c77a9_notification_groups_and_mute.py
new file mode 100644
index 0000000..d66a932
--- /dev/null
+++ b/packages/meshbay-hub/src/meshbay_hub/db/migrations/versions/b4d82e1c77a9_notification_groups_and_mute.py
@@ -0,0 +1,41 @@
+"""notification_groups_and_mute
+
+Two columns, both so notifications behave the way people expect.
+
+`notifications.group_id` lets chat keep one row per group and move its date,
+instead of one row per message — a busy conversation should be one line saying
+when it last spoke.
+
+`group_members.muted` moves a setting that existed only in the browser's
+localStorage, where nothing ever read it: turning notifications off for a group
+did nothing at all. Muting now happens where the notification is created, so it
+is not created.
+
+Revision ID: b4d82e1c77a9
+Revises: a7c31f9e40b2
+Create Date: 2026-08-14
+
+"""
+from typing import Sequence, Union
+
+import sqlalchemy as sa
+from alembic import op
+
+revision: str = 'b4d82e1c77a9'
+down_revision: Union[str, Sequence[str], None] = 'a7c31f9e40b2'
+branch_labels: Union[str, Sequence[str], None] = None
+depends_on: Union[str, Sequence[str], None] = None
+
+
+def upgrade() -> None:
+ op.add_column('notifications',
+ sa.Column('group_id', sa.String(36), sa.ForeignKey('groups.id'),
+ nullable=True))
+ op.add_column('group_members',
+ sa.Column('muted', sa.Boolean(), nullable=False,
+ server_default=sa.false()))
+
+
+def downgrade() -> None:
+ op.drop_column('group_members', 'muted')
+ op.drop_column('notifications', 'group_id')
diff --git a/packages/meshbay-hub/src/meshbay_hub/db/models.py b/packages/meshbay-hub/src/meshbay_hub/db/models.py
index a75217b..f749204 100644
--- a/packages/meshbay-hub/src/meshbay_hub/db/models.py
+++ b/packages/meshbay-hub/src/meshbay_hub/db/models.py
@@ -103,6 +103,10 @@ class GroupMember(Base):
group_id: Mapped[str] = mapped_column(ForeignKey("groups.id"), primary_key=True)
user_id: Mapped[str] = mapped_column(ForeignKey("users.id"), primary_key=True)
+ # Set here rather than in the browser: a notification nobody wants should not
+ # be created at all. It used to be a checkbox in localStorage that nothing
+ # read, so muting a group did nothing whatsoever.
+ muted: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
joined_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=_now)
group: Mapped["Group"] = relationship(back_populates="members")
@@ -184,6 +188,10 @@ class Notification(Base):
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
user_id: Mapped[str] = mapped_column(ForeignKey("users.id"), nullable=False)
kind: Mapped[str] = mapped_column(String(32), nullable=False)
+ # Which group this is about, when it is about one. Chat keeps a single row per
+ # group and moves its date, so a busy conversation is one line that says when
+ # it last spoke — not forty lines saying it spoke.
+ group_id: Mapped[str | None] = mapped_column(ForeignKey("groups.id"))
title: Mapped[str] = mapped_column(String(256), nullable=False)
detail: Mapped[str | None] = mapped_column(String(512))
link: Mapped[str | None] = mapped_column(String(256))