Skip to content

Fix/alembic migrations#30

Merged
Fl1riX merged 10 commits into
mainfrom
fix/alembic-migrations
Jun 1, 2026
Merged

Fix/alembic migrations#30
Fl1riX merged 10 commits into
mainfrom
fix/alembic-migrations

Conversation

@Fl1riX

@Fl1riX Fl1riX commented May 31, 2026

Copy link
Copy Markdown
Owner

Summary by Sourcery

Добавлено начальное Alembic‑миграции для изменений схемы и усилена безопасность конфигурации.

Новые возможности:

  • Введена Alembic‑миграция v0.0.1, создающая таблицу bans и связанные с ней ограничения и индексы.
  • Добавлено поле‑перечисление user_role в таблицу users и установлена связь magic_tokens с users через внешний ключ.

Улучшения:

  • Введены ограничения NOT NULL для нескольких существующих столбцов, включая appointments.comment, поля в services и users.email.
  • Изменены уникальные индексы и ограничения для users.email, users.phone и users.telegram_id, чтобы использовать уникальность на уровне индексов вместо явных ограничений.
  • Удалён дефолтный секретный ключ разработки из конфигурации, поэтому SECRET_KEY теперь должен задаваться через переменные окружения.

Сборка:

  • Файл конфигурации Alembic удалён из репозитория.
Original summary in English

Summary by Sourcery

Add initial Alembic migration for schema changes and tighten configuration security.

New Features:

  • Introduce Alembic migration v0.0.1 that creates the bans table and related constraints and indexes.
  • Add user_role enum field to users and link magic_tokens to users via a foreign key.

Enhancements:

  • Enforce non-null constraints on several existing columns, including appointments.comment, services fields, and users.email.
  • Adjust users unique indexes and constraints for email, phone, and telegram_id to use indexed uniqueness instead of explicit constraints.
  • Remove the default development secret key from configuration so SECRET_KEY must be provided via environment.

Build:

  • Remove the Alembic configuration file from the repository.

@sourcery-ai

sourcery-ai Bot commented May 31, 2026

Copy link
Copy Markdown
Contributor

Руководство для ревьюера

Удаляет значение по умолчанию для SECRET_KEY из конфигурации и добавляет новую миграцию Alembic, чтобы привести схему базы данных в соответствие с текущими моделями, включая таблицу bans, более строгую обязательность полей (nullability), новые ограничения/индексы и перечисление user_role у пользователей.

Диаграмма связей сущностей для новой таблицы bans и связанных изменений схемы

erDiagram
    users {
        int id
        enum user_role
        string email
        string phone
        string telegram_id
    }

    bans {
        int id
        string reason
        int user_id
        int banned_by
        int revoked_by
        datetime banned_at
        datetime expires_at
        datetime revoked_at
    }

    magic_tokens {
        int id
        int user_id
    }

    users ||--o{ bans : has_bans
    users ||--o{ bans : bans_banned_by
    users ||--o{ bans : bans_revoked_by
    users ||--o{ magic_tokens : has_magic_tokens
Loading

Изменения на уровне файлов

Change Details Files
Прекратить использование жестко заданного значения SECRET_KEY по умолчанию в конфигурации.
  • Изменить загрузку SECRET_KEY так, чтобы он требовался из переменных окружения без резервного значения по умолчанию
src/config.py
Ввести миграцию Alembic v0.0.1 для создания таблицы bans и приведения существующих таблиц в соответствие с текущими определениями моделей.
  • Создать таблицу bans с ограничениями, внешними ключами на users и индексами, включая условный уникальный индекс для активных блокировок
  • Ужесточить nullability для appointments.comment, services.description, services.address и users.email, сделав их обязательными
  • Добавить столбец внешнего ключа user_id в magic_tokens, ссылающийся на users
  • Добавить столбец перечисления user_role в users с ограничением NOT NULL
  • Пересоздать индексы и ограничения уникальности для users.email, users.phone и users.telegram_id, чтобы обеспечить уникальность через индексы вместо именованных ограничений
  • Предоставить соответствующую логику отката (downgrade) для полного возврата изменений схемы
alembic/versions/4972fe91500d_v0_0_1.py

Подсказки и команды

Взаимодействие с Sourcery

  • Запустить новое ревью: Оставьте комментарий @sourcery-ai review в pull request.
  • Продолжить обсуждение: Отвечайте напрямую на комментарии ревью от Sourcery.
  • Создать задачу GitHub из комментария ревью: Попросите Sourcery создать
    задачу из комментария ревью, ответив на него. Можно также ответить на
    комментарий ревью с @sourcery-ai issue, чтобы создать задачу на его основе.
  • Сгенерировать заголовок pull request: Напишите @sourcery-ai в любом месте
    заголовка pull request, чтобы сгенерировать заголовок в любой момент.
    Также можно оставить комментарий @sourcery-ai title в pull request, чтобы
    (пере)сгенерировать заголовок в любой момент.
  • Сгенерировать краткое описание pull request: Напишите @sourcery-ai summary
    в любом месте тела pull request, чтобы сгенерировать краткое описание PR
    именно там, где вы хотите. Также можно оставить комментарий
    @sourcery-ai summary в pull request, чтобы (пере)сгенерировать краткое
    описание в любой момент.
  • Сгенерировать руководство для ревьюера: Оставьте комментарий
    @sourcery-ai guide в pull request, чтобы (пере)сгенерировать руководство
    для ревьюера в любой момент.
  • Отметить все комментарии Sourcery как решенные: Оставьте комментарий
    @sourcery-ai resolve в pull request, чтобы отметить все комментарии
    Sourcery как решенные. Полезно, если вы уже разобрались со всеми комментариями
    и больше не хотите их видеть.
  • Отклонить все ревью Sourcery: Оставьте комментарий @sourcery-ai dismiss
    в pull request, чтобы отклонить все существующие ревью Sourcery. Особенно
    полезно, если вы хотите начать с нуля с новым ревью — не забудьте оставить
    комментарий @sourcery-ai review, чтобы запустить новое ревью!

Настройка работы

Зайдите в свою панель управления, чтобы:

  • Включать или отключать функции ревью, такие как автогенерируемое краткое
    описание pull request, руководство для ревьюера и другие.
  • Изменить язык ревью.
  • Добавлять, удалять или редактировать пользовательские инструкции для ревью.
  • Настроить другие параметры ревью.

Получение помощи

Original review guide in English

Reviewer's Guide

Removes default SECRET_KEY from configuration and introduces a new Alembic migration to align the database schema with the current models, including a bans table, stricter field nullability, new constraints/indexes, and a user_role enum on users.

Entity relationship diagram for new bans table and related schema changes

erDiagram
    users {
        int id
        enum user_role
        string email
        string phone
        string telegram_id
    }

    bans {
        int id
        string reason
        int user_id
        int banned_by
        int revoked_by
        datetime banned_at
        datetime expires_at
        datetime revoked_at
    }

    magic_tokens {
        int id
        int user_id
    }

    users ||--o{ bans : has_bans
    users ||--o{ bans : bans_banned_by
    users ||--o{ bans : bans_revoked_by
    users ||--o{ magic_tokens : has_magic_tokens
Loading

File-Level Changes

Change Details Files
Stop using a hardcoded default SECRET_KEY in configuration.
  • Change SECRET_KEY loading to require it from environment variables without a fallback default value
src/config.py
Introduce Alembic migration v0.0.1 to create bans table and align existing tables with current model definitions.
  • Create bans table with constraints, foreign keys to users, and indexes including a conditional unique index for active bans
  • Tighten nullability on appointments.comment, services.description, services.address, and users.email to make them required
  • Add user_id foreign key column to magic_tokens referencing users
  • Add user_role enum column on users with non-null constraint
  • Rebuild indexes and uniqueness constraints on users.email, users.phone, and users.telegram_id to enforce uniqueness via indexes rather than named constraints
  • Provide corresponding downgrade logic to fully revert schema changes
alembic/versions/4972fe91500d_v0_0_1.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Привет — я нашёл 3 проблемы и оставил несколько общих замечаний:

  • Удаление значения по умолчанию для SECRET_KEY теперь приведёт к жёсткому падению, если переменная окружения отсутствует; подумайте о том, чтобы либо валидировать и выбрасывать понятную ошибку при старте, либо держать отдельное явное dev-only значение по умолчанию/конфиг, чтобы избежать непонятных ошибок.
  • Новый столбец Enum user_role добавлен с nullable=False без значения по умолчанию на стороне сервера, что может привести к ошибкам на существующих строках при миграции; рассмотрите вариант либо сделать его nullable на время перехода, либо задать явное значение по умолчанию (например, 'user') и выполнить backfill.
  • В этом PR удаляется alembic.ini — если Alembic всё ещё используется, убедитесь, что удаление этого файла намеренное и что конфигурация доступна в другом месте (например, через переменные окружения или другой путь к конфигу).
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Removing the default `SECRET_KEY` will now hard-fail if the env var is missing; consider either validating and raising a clear error on startup or keeping a separate explicit dev-only default/config to avoid confusing failures.
- The new `user_role` Enum column is added as `nullable=False` without a server default, which may fail on existing rows during migration; consider either making it nullable for the transition or setting an explicit default (e.g. 'user') and backfilling.
- `alembic.ini` is being deleted in this PR—if Alembic is still in use, double-check that this file removal is intentional and that configuration is available elsewhere (e.g., via env or another config path).

## Individual Comments

### Comment 1
<location path="src/config.py" line_range="11" />
<code_context>
 DATABASE_URL = os.getenv("DATABASE_URL")

-SECRET_KEY = os.getenv("SECRET_KEY", "development-secret-key-i-love_coding")
+SECRET_KEY = os.getenv("SECRET_KEY")
 ALGORITHM = os.getenv("ALGORITHM", "HS256")
 ACCESS_TOKEN_EXPIRE_MINUTES = int(os.getenv("ACCESS_TOKEN_EXPIRE_MINUTES", 30))
</code_context>
<issue_to_address>
**issue (bug_risk):** Consider failing fast or providing a clear error path when SECRET_KEY is missing from the environment.

With the default removed, `SECRET_KEY` becomes `None` if the env var is missing, which can cause unclear runtime failures. Please add an explicit startup check (or use a helper for required env vars) to fail fast when `SECRET_KEY` is not set.
</issue_to_address>

### Comment 2
<location path="alembic/versions/4972fe91500d_v0_0_1.py" line_range="56" />
<code_context>
+    op.alter_column('services', 'address',
+               existing_type=sa.VARCHAR(length=100),
+               nullable=False)
+    op.add_column('users', sa.Column('user_role', sa.Enum('user', 'admin', 'moderator'), nullable=False))
+    op.alter_column('users', 'email',
+               existing_type=sa.VARCHAR(length=50),
</code_context>
<issue_to_address>
**issue (bug_risk):** Adding a non-nullable column without a default will break on existing rows.

On a populated `users` table this migration will fail, since existing rows have no value for `user_role` and the column is added as `nullable=False` with no `server_default`. Please either (a) add it as nullable with a default, backfill existing rows (e.g. `'user'`), then make it non-nullable, or (b) add it with a `server_default` that you later drop.
</issue_to_address>

### Comment 3
<location path="alembic/versions/4972fe91500d_v0_0_1.py" line_range="92" />
<code_context>
+    op.alter_column('services', 'description',
+               existing_type=sa.VARCHAR(length=2000),
+               nullable=True)
+    op.drop_constraint(None, 'magic_tokens', type_='foreignkey')
+    op.drop_column('magic_tokens', 'user_id')
+    op.alter_column('appointments', 'comment',
</code_context>
<issue_to_address>
**issue (bug_risk):** Dropping a foreign key with a `None` name may fail; the constraint name should match the one created in `upgrade`.

In `upgrade`, this FK from `magic_tokens.user_id` to `users.id` is created without a name, so the database generates one. `op.drop_constraint` needs that real name; passing `None` will likely fail when the migration runs. Define an explicit constraint name in `create_foreign_key` and reuse it here (optionally via `op.f(...)` to honor naming conventions).
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Помогите мне стать полезнее! Пожалуйста, нажимайте 👍 или 👎 на каждом комментарии — я использую этот фидбек, чтобы улучшать обзоры.
Original comment in English

Hey - I've found 3 issues, and left some high level feedback:

  • Removing the default SECRET_KEY will now hard-fail if the env var is missing; consider either validating and raising a clear error on startup or keeping a separate explicit dev-only default/config to avoid confusing failures.
  • The new user_role Enum column is added as nullable=False without a server default, which may fail on existing rows during migration; consider either making it nullable for the transition or setting an explicit default (e.g. 'user') and backfilling.
  • alembic.ini is being deleted in this PR—if Alembic is still in use, double-check that this file removal is intentional and that configuration is available elsewhere (e.g., via env or another config path).
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Removing the default `SECRET_KEY` will now hard-fail if the env var is missing; consider either validating and raising a clear error on startup or keeping a separate explicit dev-only default/config to avoid confusing failures.
- The new `user_role` Enum column is added as `nullable=False` without a server default, which may fail on existing rows during migration; consider either making it nullable for the transition or setting an explicit default (e.g. 'user') and backfilling.
- `alembic.ini` is being deleted in this PR—if Alembic is still in use, double-check that this file removal is intentional and that configuration is available elsewhere (e.g., via env or another config path).

## Individual Comments

### Comment 1
<location path="src/config.py" line_range="11" />
<code_context>
 DATABASE_URL = os.getenv("DATABASE_URL")

-SECRET_KEY = os.getenv("SECRET_KEY", "development-secret-key-i-love_coding")
+SECRET_KEY = os.getenv("SECRET_KEY")
 ALGORITHM = os.getenv("ALGORITHM", "HS256")
 ACCESS_TOKEN_EXPIRE_MINUTES = int(os.getenv("ACCESS_TOKEN_EXPIRE_MINUTES", 30))
</code_context>
<issue_to_address>
**issue (bug_risk):** Consider failing fast or providing a clear error path when SECRET_KEY is missing from the environment.

With the default removed, `SECRET_KEY` becomes `None` if the env var is missing, which can cause unclear runtime failures. Please add an explicit startup check (or use a helper for required env vars) to fail fast when `SECRET_KEY` is not set.
</issue_to_address>

### Comment 2
<location path="alembic/versions/4972fe91500d_v0_0_1.py" line_range="56" />
<code_context>
+    op.alter_column('services', 'address',
+               existing_type=sa.VARCHAR(length=100),
+               nullable=False)
+    op.add_column('users', sa.Column('user_role', sa.Enum('user', 'admin', 'moderator'), nullable=False))
+    op.alter_column('users', 'email',
+               existing_type=sa.VARCHAR(length=50),
</code_context>
<issue_to_address>
**issue (bug_risk):** Adding a non-nullable column without a default will break on existing rows.

On a populated `users` table this migration will fail, since existing rows have no value for `user_role` and the column is added as `nullable=False` with no `server_default`. Please either (a) add it as nullable with a default, backfill existing rows (e.g. `'user'`), then make it non-nullable, or (b) add it with a `server_default` that you later drop.
</issue_to_address>

### Comment 3
<location path="alembic/versions/4972fe91500d_v0_0_1.py" line_range="92" />
<code_context>
+    op.alter_column('services', 'description',
+               existing_type=sa.VARCHAR(length=2000),
+               nullable=True)
+    op.drop_constraint(None, 'magic_tokens', type_='foreignkey')
+    op.drop_column('magic_tokens', 'user_id')
+    op.alter_column('appointments', 'comment',
</code_context>
<issue_to_address>
**issue (bug_risk):** Dropping a foreign key with a `None` name may fail; the constraint name should match the one created in `upgrade`.

In `upgrade`, this FK from `magic_tokens.user_id` to `users.id` is created without a name, so the database generates one. `op.drop_constraint` needs that real name; passing `None` will likely fail when the migration runs. Define an explicit constraint name in `create_foreign_key` and reuse it here (optionally via `op.f(...)` to honor naming conventions).
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/config.py Outdated
Comment thread alembic/versions/4972fe91500d_v0_0_1.py
Comment thread alembic/versions/4972fe91500d_v0_0_1.py
@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 26742049364

Coverage decreased (-0.2%) to 30.2%

Details

  • Coverage decreased (-0.2%) from the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • 10 coverage regressions across 2 files.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

10 previously-covered lines in 2 files lost coverage.

File Lines Losing Coverage Coverage
config.py 5 70.59%
infrastructure/db/database.py 5 50.0%

Coverage Stats

Coverage Status
Relevant Lines: 1202
Covered Lines: 363
Line Coverage: 30.2%
Coverage Strength: 0.6 hits per line

💛 - Coveralls

1 similar comment
@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 26742049364

Coverage decreased (-0.2%) to 30.2%

Details

  • Coverage decreased (-0.2%) from the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • 10 coverage regressions across 2 files.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

10 previously-covered lines in 2 files lost coverage.

File Lines Losing Coverage Coverage
config.py 5 70.59%
infrastructure/db/database.py 5 50.0%

Coverage Stats

Coverage Status
Relevant Lines: 1202
Covered Lines: 363
Line Coverage: 30.2%
Coverage Strength: 0.6 hits per line

💛 - Coveralls

@coveralls

coveralls commented Jun 1, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 26742351520

Coverage decreased (-0.2%) to 30.167%

Details

  • Coverage decreased (-0.2%) from the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • 9 coverage regressions across 2 files.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

9 previously-covered lines in 2 files lost coverage.

File Lines Losing Coverage Coverage
config.py 5 70.59%
infrastructure/db/database.py 4 50.0%

Coverage Stats

Coverage Status
Relevant Lines: 1200
Covered Lines: 362
Line Coverage: 30.17%
Coverage Strength: 0.6 hits per line

💛 - Coveralls

@Fl1riX Fl1riX merged commit cdf9ded into main Jun 1, 2026
4 checks passed
@Fl1riX Fl1riX deleted the fix/alembic-migrations branch June 1, 2026 10:58
Fl1riX added a commit that referenced this pull request Jun 2, 2026
* fix: Delete alembic.ini

* chore: add alembic.ini into .gitignore

* chore: update alembic scheme

* fix: Remove the backup key from config.py

* fix: Fix the SECRET_KEY test environment variable

* fix(auth): Fixing a missing SECRET_KEY error in .env

* fix(tests): Fix E401 [*] Multiple imports on one line

* feat(config): Add a check for the absence of DATABSE_URL in .env

* Add a database engine to lifespan's fastapi

* refactor: Move session factory to lifespan

---------

Co-authored-by: Squ1reX <maksimhripinkov658@gmail.com>
Fl1riX added a commit that referenced this pull request Jun 2, 2026
* delete cloudflared.deb"

* feat(models): Start implementing the role system, add a ban table, and fix date fields by adding the timezone=True property to store time zone information. Fix and add missing relationships

* chore(.gitignore): remove tracking of different caches

* refactor(tg_link): rename MagicTokens to MagicToken

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(bot): send login-link URL on start when telegram is not linked

Co-authored-by: Cursor <cursoragent@cursor.com>

* test(auth): add JWT unit tests

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(models): Improve the readability of field checks in the bans table

* feat(models): Add validation of the revoked_at field at the database level

* feat(models): Add checks for the expires_at and revoked_at fields, and also fix the issue of multiple bans for one user simultaneously, while preserving the ban history.

* refactor(models): Rename MagicTokens to MagicToken across the codebase for consistency

* fix(modedls): Add foreigkey to the appointments table relationship

* Fix/backround clear magic tokens (#17)

* delete cloudflared.deb"

* feat(models): Start implementing the role system, add a ban table, and fix date fields by adding the timezone=True property to store time zone information. Fix and add missing relationships

* chore(.gitignore): remove tracking of different caches

* refactor(tg_link): rename MagicTokens to MagicToken

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(bot): send login-link URL on start when telegram is not linked

Co-authored-by: Cursor <cursoragent@cursor.com>

* test(auth): add JWT unit tests

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(models): Improve the readability of field checks in the bans table

* feat(models): Add validation of the revoked_at field at the database level

* feat(models): Add checks for the expires_at and revoked_at fields, and also fix the issue of multiple bans for one user simultaneously, while preserving the ban history.

* refactor(models): Rename MagicTokens to MagicToken across the codebase for consistency

* fix(modedls): Add foreigkey to the appointments table relationship

* fix(tasks): Fix database issues with the background task for clearing magic tokens

---------

Co-authored-by: Squ1reX <maksimhripinkov658@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(ci): Add Docker image building and pushing to the ghcr registry (#18)

* feat(ci): Add Docker image building and pushing to the ghcr registry

* feat(docker-compose): Add watchtower to query the registry and download dcoker images from there.

* feat(ci): Add a commit hash tag to Docker images

* chore: remove old SSH deploy workflow (#19)

* Fix/put things in order (#20)

* fix: Remove the get_db file from infrastructure and remove logging of all SQL queries to reduce the IO load.

* chore(jwt): Remove dprecated definition of the current time

* fix(compose): Fix port forwarding to localhost only (#21)

Co-authored-by: Squ1reX <maksimhripinkov658@gmail.com>

* fix(compose): Fix the error of accessing the database outside the local network (#22)

Co-authored-by: Squ1reX <maksimhripinkov658@gmail.com>

* Revert "fix(compose): Fix the error of accessing the database outside the local network (#22)" (#23)

This reverts commit 73920aa.

* Fix/magic link bot auth (#24)

* fix(auth): Fix a vulnerability in the process of linking a Telegram bot to an account by adding X-Bot-Secret to the header

* chore(auth): Improve logging of the create_telegram_magic_link function

* fix(auth): Fix X-Bot-Secret authentication. Eliminates timig attack.

* chore(requirements): update requrements.txt list

* fix(bot): Add sending of the X-Bot-Secret header from the Telegram bot

* fix(config): Remove os.environ, which causes an error in tests

* Update comment src/presentation/api/v1/auth/tg_link.py

Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>

* docs(services): Fix logging and doc string errors

---------

Co-authored-by: Squ1reX <maksimhripinkov658@gmail.com>
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>

* Feature/docker security improvements (#25)

* feat(docker): Isolate services by separating docker networks

* feat(docker): Add a system user app. Remove buffering and .pyc, __pycache__ files.

* feat(docker): Remove root privileges. Add cap_drop to disable root privileges. Enable write access to the /tmp folder.

* feat(logger): Remove logging to a file

* feat(docker): Write a user creation command in the api container and transfer the user change to the bot container

* docs: Correct syntax errors

---------

Co-authored-by: Squ1reX <maksimhripinkov658@gmail.com>

* fix: Add && to the docker image build command (#27)

Co-authored-by: Squ1reX <maksimhripinkov658@gmail.com>

* Feature/heartbit endpoint (#28)

* feat: Add a health endpoint to check if the API is online

* feat(docker): Add cleaning of outdated Docker images

* fix: Change your HealthCheck internet connection to avoid being blocked by RateLimiting

---------

Co-authored-by: Squ1reX <maksimhripinkov658@gmail.com>

* feat: Bring the architecture to a clean archeticture. In the structur… (#29)

* feat: Bring the architecture to a clean archeticture. In the structure, repeat the project structure for easier navigation. Separate the models into different files.

* fix(models): Fix circular import

* fix(models): Fix circular import

* fix(models): correct error texts in models

---------

Co-authored-by: Squ1reX <maksimhripinkov658@gmail.com>

* Fix/alembic migrations (#30)

* fix: Delete alembic.ini

* chore: add alembic.ini into .gitignore

* chore: update alembic scheme

* fix: Remove the backup key from config.py

* fix: Fix the SECRET_KEY test environment variable

* fix(auth): Fixing a missing SECRET_KEY error in .env

* fix(tests): Fix E401 [*] Multiple imports on one line

* feat(config): Add a check for the absence of DATABSE_URL in .env

* Add a database engine to lifespan's fastapi

* refactor: Move session factory to lifespan

---------

Co-authored-by: Squ1reX <maksimhripinkov658@gmail.com>

* fix(migrations): Add alembic.ini file (#31)

Co-authored-by: Squ1reX <maksimhripinkov658@gmail.com>

* refactor: refactor: simplify ban uniqueness constraint and database session handling

* feat(tasks): add background task for revoking expired bans

---------

Co-authored-by: Squ1reX <maksimhripinkov658@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
Fl1riX added a commit that referenced this pull request Jun 2, 2026
* delete cloudflared.deb"

* feat(models): Start implementing the role system, add a ban table, and fix date fields by adding the timezone=True property to store time zone information. Fix and add missing relationships

* chore(.gitignore): remove tracking of different caches

* refactor(tg_link): rename MagicTokens to MagicToken

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(bot): send login-link URL on start when telegram is not linked

Co-authored-by: Cursor <cursoragent@cursor.com>

* test(auth): add JWT unit tests

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(models): Improve the readability of field checks in the bans table

* feat(models): Add validation of the revoked_at field at the database level

* feat(models): Add checks for the expires_at and revoked_at fields, and also fix the issue of multiple bans for one user simultaneously, while preserving the ban history.

* refactor(models): Rename MagicTokens to MagicToken across the codebase for consistency

* fix(modedls): Add foreigkey to the appointments table relationship

* Fix/backround clear magic tokens (#17)

* delete cloudflared.deb"

* feat(models): Start implementing the role system, add a ban table, and fix date fields by adding the timezone=True property to store time zone information. Fix and add missing relationships

* chore(.gitignore): remove tracking of different caches

* refactor(tg_link): rename MagicTokens to MagicToken

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(bot): send login-link URL on start when telegram is not linked

Co-authored-by: Cursor <cursoragent@cursor.com>

* test(auth): add JWT unit tests

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(models): Improve the readability of field checks in the bans table

* feat(models): Add validation of the revoked_at field at the database level

* feat(models): Add checks for the expires_at and revoked_at fields, and also fix the issue of multiple bans for one user simultaneously, while preserving the ban history.

* refactor(models): Rename MagicTokens to MagicToken across the codebase for consistency

* fix(modedls): Add foreigkey to the appointments table relationship

* fix(tasks): Fix database issues with the background task for clearing magic tokens

---------

Co-authored-by: Squ1reX <maksimhripinkov658@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(ci): Add Docker image building and pushing to the ghcr registry (#18)

* feat(ci): Add Docker image building and pushing to the ghcr registry

* feat(docker-compose): Add watchtower to query the registry and download dcoker images from there.

* feat(ci): Add a commit hash tag to Docker images

* chore: remove old SSH deploy workflow (#19)

* Fix/put things in order (#20)

* fix: Remove the get_db file from infrastructure and remove logging of all SQL queries to reduce the IO load.

* chore(jwt): Remove dprecated definition of the current time

* fix(compose): Fix port forwarding to localhost only (#21)

Co-authored-by: Squ1reX <maksimhripinkov658@gmail.com>

* fix(compose): Fix the error of accessing the database outside the local network (#22)

Co-authored-by: Squ1reX <maksimhripinkov658@gmail.com>

* Revert "fix(compose): Fix the error of accessing the database outside the local network (#22)" (#23)

This reverts commit 73920aa.

* Fix/magic link bot auth (#24)

* fix(auth): Fix a vulnerability in the process of linking a Telegram bot to an account by adding X-Bot-Secret to the header

* chore(auth): Improve logging of the create_telegram_magic_link function

* fix(auth): Fix X-Bot-Secret authentication. Eliminates timig attack.

* chore(requirements): update requrements.txt list

* fix(bot): Add sending of the X-Bot-Secret header from the Telegram bot

* fix(config): Remove os.environ, which causes an error in tests

* Update comment src/presentation/api/v1/auth/tg_link.py

Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>

* docs(services): Fix logging and doc string errors

---------

Co-authored-by: Squ1reX <maksimhripinkov658@gmail.com>
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>

* Feature/docker security improvements (#25)

* feat(docker): Isolate services by separating docker networks

* feat(docker): Add a system user app. Remove buffering and .pyc, __pycache__ files.

* feat(docker): Remove root privileges. Add cap_drop to disable root privileges. Enable write access to the /tmp folder.

* feat(logger): Remove logging to a file

* feat(docker): Write a user creation command in the api container and transfer the user change to the bot container

* docs: Correct syntax errors

---------

Co-authored-by: Squ1reX <maksimhripinkov658@gmail.com>

* fix: Add && to the docker image build command (#27)

Co-authored-by: Squ1reX <maksimhripinkov658@gmail.com>

* Feature/heartbit endpoint (#28)

* feat: Add a health endpoint to check if the API is online

* feat(docker): Add cleaning of outdated Docker images

* fix: Change your HealthCheck internet connection to avoid being blocked by RateLimiting

---------

Co-authored-by: Squ1reX <maksimhripinkov658@gmail.com>

* feat: Bring the architecture to a clean archeticture. In the structur… (#29)

* feat: Bring the architecture to a clean archeticture. In the structure, repeat the project structure for easier navigation. Separate the models into different files.

* fix(models): Fix circular import

* fix(models): Fix circular import

* fix(models): correct error texts in models

---------

Co-authored-by: Squ1reX <maksimhripinkov658@gmail.com>

* Fix/alembic migrations (#30)

* fix: Delete alembic.ini

* chore: add alembic.ini into .gitignore

* chore: update alembic scheme

* fix: Remove the backup key from config.py

* fix: Fix the SECRET_KEY test environment variable

* fix(auth): Fixing a missing SECRET_KEY error in .env

* fix(tests): Fix E401 [*] Multiple imports on one line

* feat(config): Add a check for the absence of DATABSE_URL in .env

* Add a database engine to lifespan's fastapi

* refactor: Move session factory to lifespan

---------

Co-authored-by: Squ1reX <maksimhripinkov658@gmail.com>

* fix(migrations): Add alembic.ini file (#31)

Co-authored-by: Squ1reX <maksimhripinkov658@gmail.com>

* refactor: refactor: simplify ban uniqueness constraint and database session handling

* feat(tasks): add background task for revoking expired bans

* chore(migrations): Upate migration scheme

* chore: update alembic scheme

---------

Co-authored-by: Squ1reX <maksimhripinkov658@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants