feat(desktop): implement phase 2 native capabilities
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled

This commit is contained in:
Cheng Zhou
2026-06-30 21:21:55 +08:00
parent 7c721d4e5c
commit 628ff8828b
64 changed files with 3516 additions and 222 deletions
@@ -0,0 +1,74 @@
"""add desktop phase 2 notification and client metadata state
Revision ID: 20260630_02
Revises: 20260630_01
Create Date: 2026-06-30 21:30:00.000000
"""
from typing import Sequence, Union
import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import postgresql
revision: str = "20260630_02"
down_revision: Union[str, None] = "20260630_01"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
op.add_column("security_access_logs", sa.Column("client_type", sa.String(16), nullable=True))
op.add_column("security_access_logs", sa.Column("client_version", sa.String(32), nullable=True))
op.add_column("security_access_logs", sa.Column("client_platform", sa.String(16), nullable=True))
op.add_column("security_access_logs", sa.Column("build_channel", sa.String(16), nullable=True))
op.add_column("security_access_logs", sa.Column("build_commit", sa.String(64), nullable=True))
op.create_index(
"ix_security_log_client_created",
"security_access_logs",
["client_type", "client_version", "created_at"],
)
op.create_table(
"desktop_notification_subscriptions",
sa.Column("user_id", postgresql.UUID(as_uuid=True), nullable=False),
sa.Column("enabled", sa.Boolean(), server_default=sa.false(), nullable=False),
sa.Column("enabled_at", sa.DateTime(timezone=True), nullable=True),
sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
sa.ForeignKeyConstraint(["user_id"], ["users.id"], ondelete="CASCADE"),
sa.PrimaryKeyConstraint("user_id"),
)
op.create_table(
"desktop_notification_deliveries",
sa.Column("id", postgresql.UUID(as_uuid=True), nullable=False),
sa.Column("user_id", postgresql.UUID(as_uuid=True), nullable=False),
sa.Column("distribution_id", postgresql.UUID(as_uuid=True), nullable=False),
sa.Column("claim_token", postgresql.UUID(as_uuid=True), nullable=True),
sa.Column("claimed_at", sa.DateTime(timezone=True), nullable=True),
sa.Column("delivered_at", sa.DateTime(timezone=True), nullable=True),
sa.Column("read_at", sa.DateTime(timezone=True), nullable=True),
sa.ForeignKeyConstraint(["distribution_id"], ["distributions.id"], ondelete="CASCADE"),
sa.ForeignKeyConstraint(["user_id"], ["users.id"], ondelete="CASCADE"),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint(
"user_id",
"distribution_id",
name="uq_desktop_notification_user_distribution",
),
)
op.create_index(
"ix_desktop_notification_claim",
"desktop_notification_deliveries",
["user_id", "delivered_at", "claimed_at"],
)
def downgrade() -> None:
op.drop_index("ix_desktop_notification_claim", table_name="desktop_notification_deliveries")
op.drop_table("desktop_notification_deliveries")
op.drop_table("desktop_notification_subscriptions")
op.drop_index("ix_security_log_client_created", table_name="security_access_logs")
for column in ("build_commit", "build_channel", "client_platform", "client_version", "client_type"):
op.drop_column("security_access_logs", column)