Compare commits

...

6 Commits

Author SHA1 Message Date
c0mrade 5009703676 Merge pull request #2875 from BEDOLAGA-DEV/release-please--branches--main
chore(main): release 3.46.1
2026-04-13 22:09:58 +03:00
github-actions[bot] e88a5989b6 chore(main): release 3.46.1 2026-04-13 19:07:27 +00:00
c0mrade 02747381dc Merge pull request #2874 from BEDOLAGA-DEV/dev
fix: cabinet_refresh_tokens migration + notification_settings jsonb
2026-04-13 22:06:53 +03:00
c0mrade e74fda954c fix: change notification_settings from json to jsonb for DISTINCT compatibility 2026-04-13 21:56:04 +03:00
c0mrade 8587f03f67 fix: add checkfirst guards to cabinet_refresh_tokens migration 2026-04-13 21:47:16 +03:00
c0mrade 4707cdf60c fix: add missing migration for cabinet_refresh_tokens table 2026-04-13 21:43:46 +03:00
7 changed files with 123 additions and 4 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
{
".": "3.46.0"
".": "3.46.1"
}
+10
View File
@@ -1,5 +1,15 @@
# Changelog
## [3.46.1](https://github.com/BEDOLAGA-DEV/remnawave-bedolaga-telegram-bot/compare/v3.46.0...v3.46.1) (2026-04-13)
### Bug Fixes
* add checkfirst guards to cabinet_refresh_tokens migration ([8587f03](https://github.com/BEDOLAGA-DEV/remnawave-bedolaga-telegram-bot/commit/8587f03f67d7a451b07a4d9c450bc4524f4ac0e7))
* add missing migration for cabinet_refresh_tokens table ([4707cdf](https://github.com/BEDOLAGA-DEV/remnawave-bedolaga-telegram-bot/commit/4707cdf60c9d163c1191719b3b1fc4a17ae993d2))
* cabinet_refresh_tokens migration + notification_settings jsonb ([0274738](https://github.com/BEDOLAGA-DEV/remnawave-bedolaga-telegram-bot/commit/02747381dce2b96af7f97b5f41d6acff5d9d8fd3))
* change notification_settings from json to jsonb for DISTINCT compatibility ([e74fda9](https://github.com/BEDOLAGA-DEV/remnawave-bedolaga-telegram-bot/commit/e74fda954ccc63e2ac7a30933d9f9ac26772b25d))
## [3.46.0](https://github.com/BEDOLAGA-DEV/remnawave-bedolaga-telegram-bot/compare/v3.45.2...v3.46.0) (2026-04-13)
+1 -1
View File
@@ -19,7 +19,7 @@ RUN --mount=type=cache,target=/root/.cache/uv \
FROM python:3.13-slim
ARG VERSION="v3.46.0" # x-release-please-version
ARG VERSION="v3.46.1" # x-release-please-version
ARG BUILD_DATE
ARG VCS_REF
+1 -1
View File
@@ -1264,7 +1264,7 @@ class User(Base):
user_promo_groups = relationship('UserPromoGroup', back_populates='user', cascade='all, delete-orphan')
poll_responses = relationship('PollResponse', back_populates='user')
admin_roles_rel = relationship('UserRole', foreign_keys='[UserRole.user_id]', back_populates='user')
notification_settings = Column(JSON, nullable=True, default=dict)
notification_settings = Column(JSONB, nullable=True, default=dict)
last_pinned_message_id = Column(Integer, nullable=True)
# Ограничения пользователя
@@ -0,0 +1,57 @@
"""create cabinet_refresh_tokens table
Revision ID: 0056
Revises: 0055
Create Date: 2026-04-13
"""
from typing import Sequence, Union
import sqlalchemy as sa
from alembic import op
revision: str = '0056'
down_revision: Union[str, None] = '0055'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def _has_table(table: str) -> bool:
conn = op.get_bind()
inspector = sa.inspect(conn)
return table in inspector.get_table_names()
def _has_index(table: str, index_name: str) -> bool:
conn = op.get_bind()
inspector = sa.inspect(conn)
return index_name in [idx['name'] for idx in inspector.get_indexes(table)]
def upgrade() -> None:
if not _has_table('cabinet_refresh_tokens'):
op.create_table(
'cabinet_refresh_tokens',
sa.Column('id', sa.Integer(), primary_key=True, autoincrement=True),
sa.Column('user_id', sa.Integer(), sa.ForeignKey('users.id', ondelete='CASCADE'), nullable=False),
sa.Column('token_hash', sa.String(255), nullable=False),
sa.Column('device_info', sa.String(500), nullable=True),
sa.Column('expires_at', sa.DateTime(timezone=True), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.func.now()),
sa.Column('revoked_at', sa.DateTime(timezone=True), nullable=True),
)
if not _has_index('cabinet_refresh_tokens', 'ix_cabinet_refresh_tokens_id'):
op.create_index('ix_cabinet_refresh_tokens_id', 'cabinet_refresh_tokens', ['id'])
if not _has_index('cabinet_refresh_tokens', 'ix_cabinet_refresh_tokens_token_hash'):
op.create_index('ix_cabinet_refresh_tokens_token_hash', 'cabinet_refresh_tokens', ['token_hash'], unique=True)
if not _has_index('cabinet_refresh_tokens', 'ix_cabinet_refresh_tokens_user'):
op.create_index('ix_cabinet_refresh_tokens_user', 'cabinet_refresh_tokens', ['user_id'])
def downgrade() -> None:
op.drop_index('ix_cabinet_refresh_tokens_user', table_name='cabinet_refresh_tokens')
op.drop_index('ix_cabinet_refresh_tokens_token_hash', table_name='cabinet_refresh_tokens')
op.drop_index('ix_cabinet_refresh_tokens_id', table_name='cabinet_refresh_tokens')
op.drop_table('cabinet_refresh_tokens')
@@ -0,0 +1,52 @@
"""alter notification_settings from json to jsonb
Revision ID: 0057
Revises: 0056
Create Date: 2026-04-13
"""
from typing import Sequence, Union
import sqlalchemy as sa
from alembic import op
revision: str = '0057'
down_revision: Union[str, None] = '0056'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def _get_column_type(table: str, column: str) -> str | None:
conn = op.get_bind()
result = conn.execute(
sa.text(
"SELECT data_type FROM information_schema.columns "
"WHERE table_name = :table AND column_name = :column"
),
{'table': table, 'column': column},
)
row = result.fetchone()
return row[0] if row else None
def upgrade() -> None:
col_type = _get_column_type('users', 'notification_settings')
if col_type and col_type != 'jsonb':
op.execute(
sa.text(
"ALTER TABLE users "
"ALTER COLUMN notification_settings TYPE jsonb "
"USING notification_settings::jsonb"
)
)
def downgrade() -> None:
op.execute(
sa.text(
"ALTER TABLE users "
"ALTER COLUMN notification_settings TYPE json "
"USING notification_settings::json"
)
)
+1 -1
View File
@@ -1,6 +1,6 @@
[project]
name = 'remnawave-bedolaga-telegram-bot'
version = "3.46.0"
version = "3.46.1"
description = 'Telegram bot for RemnaWave VPN service'
readme = 'README.md'
license = { text = 'MIT' }