aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/db/migrations
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-30 12:37:31 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-30 12:37:31 +0200
commit8a4651e9d223de856ff085b329801998f95db138 (patch)
tree6153ffaf46030613fa9024e85b9890c7fa979154 /packages/meshbay-hub/src/meshbay_hub/db/migrations
parent1684fcb64531eaf2e9bb8567ba4bdcbada6469d8 (diff)
downloadmeshbay-8a4651e9d223de856ff085b329801998f95db138.tar.gz
fix(hub): the admin allow-list grants an account, not a username
Each name in admin_usernames is pinned to the first active account seen holding it (admin_pins), so a name freed by a deletion grants nothing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/db/migrations')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/db/migrations/versions/b2c3d4e5f6a8_admin_pins.py29
1 files changed, 29 insertions, 0 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/db/migrations/versions/b2c3d4e5f6a8_admin_pins.py b/packages/meshbay-hub/src/meshbay_hub/db/migrations/versions/b2c3d4e5f6a8_admin_pins.py
new file mode 100644
index 0000000..57de9b2
--- /dev/null
+++ b/packages/meshbay-hub/src/meshbay_hub/db/migrations/versions/b2c3d4e5f6a8_admin_pins.py
@@ -0,0 +1,29 @@
+"""the admin allow-list grants an account, not whoever holds the name
+
+Revision ID: b2c3d4e5f6a8
+Revises: a1b2c3d4e5f7
+"""
+
+from collections.abc import Sequence
+
+import sqlalchemy as sa
+from alembic import op
+
+revision: str = "b2c3d4e5f6a8"
+down_revision: str | Sequence[str] | None = "a1b2c3d4e5f7"
+branch_labels: str | Sequence[str] | None = None
+depends_on: str | Sequence[str] | None = None
+
+
+def upgrade() -> None:
+ op.create_table(
+ "admin_pins",
+ sa.Column("username", sa.String(64), primary_key=True),
+ sa.Column("user_id", sa.String(36), nullable=False),
+ sa.Column("pinned_at", sa.DateTime(timezone=True), nullable=False,
+ server_default=sa.func.now()),
+ )
+
+
+def downgrade() -> None:
+ op.drop_table("admin_pins")