46 lines
1.4 KiB
Python
46 lines
1.4 KiB
Python
"""saved_chats.share_token: the anonymous share link (phase 51)
|
|
|
|
Revision ID: 0009
|
|
Revises: 0008
|
|
Create Date: 2026-08-29
|
|
|
|
Phase 51 (share-a-chat-by-link, owner-locked 2026-08-29): a saved chat
|
|
can be turned into a public link — ``/shared/<token>`` — that anyone
|
|
with the URL can read anonymously (no admin session); unsharing sets
|
|
the token back to NULL and revokes the link.
|
|
|
|
* ``saved_chats.share_token`` — ``UUID`` (a 128-bit ``uuid4``), NULL =
|
|
not shared. One column, no new table (A10 extension unchanged —
|
|
sharing reuses the already-stored row).
|
|
* ``ix_saved_chats_share_token`` — UNIQUE index on the column. A unique
|
|
index on a NULLable column: Postgres treats NULLs as distinct, so any
|
|
number of unshared chats coexist while two identical non-NULL tokens
|
|
can never exist (the ``git_sources.path`` house precedent, phase 38).
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import sqlalchemy as sa
|
|
from sqlalchemy.dialects import postgresql
|
|
|
|
from alembic import op
|
|
|
|
revision = "0009"
|
|
down_revision = "0008"
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.add_column(
|
|
"saved_chats",
|
|
sa.Column("share_token", postgresql.UUID(as_uuid=True), nullable=True),
|
|
)
|
|
op.create_index(
|
|
"ix_saved_chats_share_token", "saved_chats", ["share_token"], unique=True
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.drop_index("ix_saved_chats_share_token", table_name="saved_chats")
|
|
op.drop_column("saved_chats", "share_token")
|