Skip to content

Conversation

kzndotsh
Copy link
Contributor

@kzndotsh kzndotsh commented Jul 28, 2025

Description

This PR initiates the migration of the project's database layer from Prisma to SQLModel, integrating Alembic for future database migrations. The primary motivation is to transition to a more Pythonic and mature database solution.

Key changes include:

  • Dependency Update: Removal of prisma and addition of sqlmodel, sqlalchemy (v2-series), and alembic to pyproject.toml.
  • SQLModel Definitions: Introduction of tux/database/models.py containing all data models (e.g., Guild, Case, AFKModel) rewritten using SQLModel conventions, including the CaseType enum.
  • Database Client Refactor: tux/database/client.py has been re-implemented to utilize an async SQLAlchemy engine and session factory, providing a similar public API for minimal disruption to higher-level code.
  • Base Controller Overhaul: tux/database/controllers/base.py has been rewritten to provide a SQLModel-powered asynchronous CRUD (Create, Read, Update, Delete) layer, maintaining compatibility with the previous Prisma-based controller's API.
  • Partial Controller Migration: AfkController, CaseController, and GuildController have been updated to use the new SQLModel-based models and the refactored BaseController. CaseController's get_next_case_number now uses SQLModel logic for atomic increments.

This PR lays the foundational groundwork for fully deprecating Prisma from the codebase.

Guidelines

  • My code follows the style guidelines of this project (formatted with Ruff)
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation if needed (Partial, full documentation update pending completion of migration)
  • My changes generate no new warnings
  • I have tested this change (Initial compilation and functional checks performed; full test suite validation pending complete migration)
  • Any dependent changes have been merged and published in downstream modules
  • I have added all appropriate labels to this PR

How Has This Been Tested? (if applicable)

The changes have been verified to compile successfully. Initial manual checks confirm the new database client and base controller are functional, and the partially migrated controllers (AfkController, CaseController, GuildController) integrate correctly. Full test suite integration and validation will follow once all remaining controllers are migrated.

Screenshots (if applicable)

N/A

Additional Information

This PR represents the first major phase of the database migration. Remaining work includes:

  • Migrating the rest of the controllers (note.py, reminder.py, snippet.py, guild_config.py, levels.py, starboard.py).
  • Replacing residual Prisma CLI helpers with Alembic commands in tux/cli/database.py.
  • Setting up the Alembic environment and generating the initial database migration scripts.
  • Refactoring existing tests and cogs to align with the new SQLModel models.
  • Updating project documentation and README.md to reflect the new SQLModel and Alembic stack.

Open in WebOpen in CursorOpen Docs

Summary by Sourcery

Migrate the database layer from Prisma to SQLModel/SQLAlchemy, replacing the Prisma client with an async SQLModel-powered repository pattern and integrating Alembic for future migrations.

New Features:

  • Introduce SQLModel-based ORM models and relationships for all entities in tux/database/models.py
  • Implement DatabaseClient to manage an async SQLAlchemy engine, session factory, and context managers for sessions and transactions
  • Create a generic async BaseController offering CRUD, count, upsert, and utility methods over SQLModel models

Enhancements:

  • Refactor existing controllers (CaseController, GuildController, AfkController) to use the new BaseController and SQLModel models, including atomic case number increments
  • Remove Prisma-specific helpers and adapt connect_or_create_relation and other utilities for SQLModel compatibility

Build:

  • Update dependencies: remove prisma and add sqlmodel, sqlalchemy (v2-series), and alembic to pyproject.toml

Copy link
Contributor

sourcery-ai bot commented Jul 28, 2025

Reviewer's Guide

This PR migrates the database layer from Prisma to a SQLModel/SQLAlchemy stack with Alembic support, introducing new SQLModel-based models, refactoring the database client and base controller into async SQLAlchemy patterns, and updating key controllers to leverage the new generic CRUD infrastructure while preserving backward-compatible APIs.

Entity relationship diagram for new SQLModel tables

erDiagram
    GUILD ||--o{ CASE : has
    GUILD ||--o{ SNIPPET : has
    GUILD ||--o{ NOTE : has
    GUILD ||--o{ REMINDER : has
    GUILD ||--|{ GUILDCONFIG : has
    GUILD ||--o{ AFKMODEL : has
    GUILD ||--|{ STARBOARD : has
    GUILD ||--o{ STARBOARDMESSAGE : has
    GUILD ||--o{ LEVELS : has
    CASE }o--|| GUILD : belongs_to
    SNIPPET }o--|| GUILD : belongs_to
    NOTE }o--|| GUILD : belongs_to
    REMINDER }o--|| GUILD : belongs_to
    GUILDCONFIG }|--|| GUILD : belongs_to
    AFKMODEL }o--|| GUILD : belongs_to
    STARBOARD }|--|| GUILD : belongs_to
    STARBOARDMESSAGE }o--|| GUILD : belongs_to
    LEVELS }o--|| GUILD : belongs_to
    GUILD {
        int guild_id PK
        datetime guild_joined_at
        int case_count
    }
    CASE {
        int case_id PK
        bool case_status
        string case_type
        string case_reason
        int case_moderator_id
        int case_user_id
        int[] case_user_roles
        int case_number
        datetime case_created_at
        datetime case_expires_at
        bool case_tempban_expired
        int guild_id FK
    }
    SNIPPET {
        int snippet_id PK
        string snippet_name
        string snippet_content
        int snippet_user_id
        datetime snippet_created_at
        int guild_id FK
        int uses
        bool locked
        string alias
    }
    NOTE {
        int note_id PK
        string note_content
        datetime note_created_at
        int note_moderator_id
        int note_user_id
        int note_number
        int guild_id FK
    }
    REMINDER {
        int reminder_id PK
        string reminder_content
        datetime reminder_created_at
        datetime reminder_expires_at
        int reminder_channel_id
        int reminder_user_id
        bool reminder_sent
        int guild_id FK
    }
    GUILDCONFIG {
        int guild_id PK, FK
        string prefix
        int mod_log_id
        int audit_log_id
        int join_log_id
        int private_log_id
        int report_log_id
        int dev_log_id
        int jail_channel_id
        int general_channel_id
        int starboard_channel_id
        int perm_level_0_role_id
        int perm_level_1_role_id
        int perm_level_2_role_id
        int perm_level_3_role_id
        int perm_level_4_role_id
        int perm_level_5_role_id
        int perm_level_6_role_id
        int perm_level_7_role_id
        int base_staff_role_id
        int base_member_role_id
        int jail_role_id
        int quarantine_role_id
    }
    AFKMODEL {
        int member_id PK
        string nickname
        string reason
        datetime since
        datetime until
        int guild_id FK
        bool enforced
        bool perm_afk
    }
    STARBOARD {
        int guild_id PK, FK
        int starboard_channel_id
        string starboard_emoji
        int starboard_threshold
    }
    STARBOARDMESSAGE {
        int message_id PK
        string message_content
        datetime message_created_at
        datetime message_expires_at
        int message_channel_id
        int message_user_id
        int message_guild_id FK
        int star_count
        int starboard_message_id
    }
    LEVELS {
        int member_id PK
        int guild_id PK, FK
        float xp
        int level
        bool blacklisted
        datetime last_message
    }
Loading

Class diagram for new SQLModel-based data models

classDiagram
    class Guild {
        +int guild_id
        +datetime guild_joined_at
        +int case_count
        +List~Case~ cases
        +List~Snippet~ snippets
        +List~Note~ notes
        +List~Reminder~ reminders
        +GuildConfig guild_config
        +List~AFKModel~ afk_records
        +Starboard starboard
        +List~StarboardMessage~ starboard_messages
        +List~Levels~ levels
    }
    class Case {
        +int case_id
        +bool case_status
        +CaseType case_type
        +str case_reason
        +int case_moderator_id
        +int case_user_id
        +List~int~ case_user_roles
        +int case_number
        +datetime case_created_at
        +datetime case_expires_at
        +bool case_tempban_expired
        +int guild_id
        +Guild guild
    }
    class AFKModel {
        +int member_id
        +str nickname
        +str reason
        +datetime since
        +datetime until
        +int guild_id
        +bool enforced
        +bool perm_afk
        +Guild guild
    }
    class GuildConfig {
        +int guild_id
        +str prefix
        +int mod_log_id
        +int audit_log_id
        +int join_log_id
        +int private_log_id
        +int report_log_id
        +int dev_log_id
        +int jail_channel_id
        +int general_channel_id
        +int starboard_channel_id
        +int perm_level_0_role_id
        +int perm_level_1_role_id
        +int perm_level_2_role_id
        +int perm_level_3_role_id
        +int perm_level_4_role_id
        +int perm_level_5_role_id
        +int perm_level_6_role_id
        +int perm_level_7_role_id
        +int base_staff_role_id
        +int base_member_role_id
        +int jail_role_id
        +int quarantine_role_id
        +Guild guild
    }
    class Levels {
        +int member_id
        +int guild_id
        +float xp
        +int level
        +bool blacklisted
        +datetime last_message
        +Guild guild
    }
    class Note {
        +int note_id
        +str note_content
        +datetime note_created_at
        +int note_moderator_id
        +int note_user_id
        +int note_number
        +int guild_id
        +Guild guild
    }
    class Reminder {
        +int reminder_id
        +str reminder_content
        +datetime reminder_created_at
        +datetime reminder_expires_at
        +int reminder_channel_id
        +int reminder_user_id
        +bool reminder_sent
        +int guild_id
        +Guild guild
    }
    class Snippet {
        +int snippet_id
        +str snippet_name
        +str snippet_content
        +int snippet_user_id
        +datetime snippet_created_at
        +int guild_id
        +int uses
        +bool locked
        +str alias
        +Guild guild
    }
    class Starboard {
        +int guild_id
        +int starboard_channel_id
        +str starboard_emoji
        +int starboard_threshold
        +Guild guild
    }
    class StarboardMessage {
        +int message_id
        +str message_content
        +datetime message_created_at
        +datetime message_expires_at
        +int message_channel_id
        +int message_user_id
        +int message_guild_id
        +int star_count
        +int starboard_message_id
        +Guild guild
    }
    Guild "1" --o "*" Case : cases
    Guild "1" --o "*" Snippet : snippets
    Guild "1" --o "*" Note : notes
    Guild "1" --o "*" Reminder : reminders
    Guild "1" --o "1" GuildConfig : guild_config
    Guild "1" --o "*" AFKModel : afk_records
    Guild "1" --o "1" Starboard : starboard
    Guild "1" --o "*" StarboardMessage : starboard_messages
    Guild "1" --o "*" Levels : levels
    Case "*" --o "1" Guild : guild
    AFKModel "*" --o "1" Guild : guild
    GuildConfig "1" --o "1" Guild : guild
    Levels "*" --o "1" Guild : guild
    Note "*" --o "1" Guild : guild
    Reminder "*" --o "1" Guild : guild
    Snippet "*" --o "1" Guild : guild
    Starboard "1" --o "1" Guild : guild
    StarboardMessage "*" --o "1" Guild : guild
    class CaseType {
        <<enum>>
        BAN
        UNBAN
        HACKBAN
        TEMPBAN
        KICK
        SNIPPETBAN
        TIMEOUT
        UNTIMEOUT
        WARN
        JAIL
        UNJAIL
        SNIPPETUNBAN
        UNTEMPBAN
        POLLBAN
        POLLUNBAN
    }
Loading

Class diagram for refactored BaseController and DatabaseClient

classDiagram
    class BaseController~ModelT~ {
        -Type model
        -str model_name
        -Type table
        +find_one(where, include, ...)
        +find_unique(where, include, ...)
        +find_many(where, order, take, skip, ...)
        +count(where)
        +create(data)
        +update(where, data)
        +delete(where)
        +upsert(where, create, update)
        +safe_get_attr(obj, attr, default)
        +connect_or_create_relation(id_field, model_id, ...)
    }
    class DatabaseClient {
        -AsyncEngine _engine
        -async_sessionmaker _session_factory
        +is_connected
        +connect(database_url, echo)
        +disconnect()
        +session()
        +transaction()
    }
    BaseController~ModelT~ <|-- AfkController
    BaseController~ModelT~ <|-- CaseController
    BaseController~ModelT~ <|-- GuildController
    note for BaseController~ModelT~ "Now generic over SQLModel types"
    note for DatabaseClient "Now wraps SQLAlchemy async engine/session"
    AfkController : +get_afk_member(member_id, guild_id)
    CaseController : +get_next_case_number(guild_id)
    CaseController : +insert_case(...)
    GuildController : +get_guild_by_id(guild_id)
    GuildController : +get_or_create_guild(guild_id)
    GuildController : +insert_guild_by_id(guild_id)
    DatabaseClient : +db (singleton instance)
    class AfkController
    class CaseController
    class GuildController
Loading

File-Level Changes

Change Details Files
Dependency stack updated to SQLModel/SQLAlchemy/Alembic
  • Removed the prisma dependency
  • Added sqlmodel, sqlalchemy (v2.x), and alembic dependencies
  • Updated pyproject.toml accordingly
pyproject.toml
Introduced SQLModel-based data model definitions
  • Created a centralized models.py with SQLModel table definitions
  • Defined CaseType enum to mirror old Prisma enum values
  • Established relationships with SQLModel’s Relationship field
tux/database/models.py
Refactored database client from Prisma to SQLAlchemy async engine
  • Replaced Prisma client with AsyncEngine and async_sessionmaker
  • Implemented connect/disconnect and auto-create table logic
  • Added session and transaction context managers with commit/rollback
tux/database/client.py
Rewrote BaseController to a generic async CRUD repository
  • Removed Prisma-specific helpers and type imports
  • Added generic _execute_query with Sentry spans
  • Implemented find_one, find_many, count, create, update, delete, upsert methods
  • Retained backward-compatible shims (safe_get_attr, connect_or_create_relation)
tux/database/controllers/base.py
Updated controllers to use new BaseController and SQLModel
  • Switched AfkController, CaseController, GuildController to inherit BaseController[Model]
  • Replaced Prisma imports and types with SQLModel equivalents
  • Reimplemented CaseController.get_next_case_number using atomic SQLModel logic
tux/database/controllers/afk.py
tux/database/controllers/case.py
tux/database/controllers/guild.py

Possibly linked issues

  • [FEATURE] Tortoise Migration #843: The PR fully implements the database migration from Prisma to SQLModel, including model refactoring, client, and controller rewrites, and dependency updates, directly addressing the issue's objectives.

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

Copy link
Contributor

github-actions bot commented Jul 28, 2025

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 4 package(s) with unknown licenses.
See the Details below.

License Issues

poetry.lock

PackageVersionLicenseIssue Type
regex2025.7.31NullUnknown License
jaraco-functools4.2.1NullUnknown License
aiohttp3.12.15NullUnknown License
pymdown-extensions10.16.1NullUnknown License

OpenSSF Scorecard

Scorecard details
PackageVersionScoreDetails
pip/aiohttp 3.12.15 🟢 6.8
Details
CheckScoreReason
Code-Review🟢 5Found 4/8 approved changesets -- score normalized to 5
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Maintained🟢 1030 commit(s) and 23 issue activity found in the last 90 days -- score normalized to 10
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Binary-Artifacts🟢 10no binaries found in the repo
License🟢 9license file detected
Vulnerabilities🟢 100 existing vulnerabilities detected
Fuzzing🟢 10project is fuzzed
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration
Security-Policy🟢 10security policy file detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Packaging🟢 10packaging workflow detected
SAST🟢 8SAST tool detected but not run on all commits
Signed-Releases⚠️ 0Project has not signed or included provenance with any releases.
pip/aiosignal 1.4.0 🟢 6.1
Details
CheckScoreReason
Code-Review⚠️ 1Found 1/8 approved changesets -- score normalized to 1
Maintained🟢 1030 commit(s) and 6 issue activity found in the last 90 days -- score normalized to 10
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Binary-Artifacts🟢 10no binaries found in the repo
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Pinned-Dependencies⚠️ 2dependency not pinned by hash detected -- score normalized to 2
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Vulnerabilities🟢 100 existing vulnerabilities detected
Signed-Releases⚠️ 0Project has not signed or included provenance with any releases.
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration
Security-Policy🟢 10security policy file detected
Packaging🟢 10packaging workflow detected
SAST🟢 10SAST tool is run on all commits
pip/alembic 1.16.4 🟢 6.3
Details
CheckScoreReason
Security-Policy🟢 10security policy file detected
Code-Review⚠️ 0Found 1/30 approved changesets -- score normalized to 0
Packaging⚠️ -1packaging workflow not detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Maintained🟢 1030 commit(s) and 22 issue activity found in the last 90 days -- score normalized to 10
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions🟢 10GitHub workflow tokens follow principle of least privilege
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
License🟢 10license file detected
Fuzzing⚠️ 0project is not fuzzed
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration
Vulnerabilities🟢 82 existing vulnerabilities detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
pip/backrefs 5.9 🟢 5.3
Details
CheckScoreReason
Code-Review⚠️ 0Found 0/29 approved changesets -- score normalized to 0
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Binary-Artifacts🟢 10no binaries found in the repo
Maintained🟢 56 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 5
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Security-Policy🟢 10security policy file detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
License🟢 10license file detected
Fuzzing⚠️ 0project is not fuzzed
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Vulnerabilities🟢 100 existing vulnerabilities detected
Signed-Releases⚠️ -1no releases found
Packaging🟢 10packaging workflow detected
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
pip/certifi 2025.7.14 🟢 6.6
Details
CheckScoreReason
Code-Review⚠️ 2Found 1/4 approved changesets -- score normalized to 2
Maintained🟢 109 commit(s) and 4 issue activity found in the last 90 days -- score normalized to 10
Pinned-Dependencies🟢 5dependency not pinned by hash detected -- score normalized to 5
Binary-Artifacts🟢 10no binaries found in the repo
Security-Policy🟢 10security policy file detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions🟢 10GitHub workflow tokens follow principle of least privilege
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
Vulnerabilities🟢 100 existing vulnerabilities detected
License🟢 9license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Packaging🟢 10packaging workflow detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
pip/coverage 7.10.1 🟢 8.5
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 24 issue activity found in the last 90 days -- score normalized to 10
Security-Policy🟢 10security policy file detected
Code-Review⚠️ 0Found 1/29 approved changesets -- score normalized to 0
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Binary-Artifacts🟢 10no binaries found in the repo
License🟢 10license file detected
Vulnerabilities🟢 100 existing vulnerabilities detected
Token-Permissions🟢 10GitHub workflow tokens follow principle of least privilege
CII-Best-Practices🟢 5badge detected: Passing
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration
Signed-Releases⚠️ -1no releases found
Pinned-Dependencies🟢 5dependency not pinned by hash detected -- score normalized to 5
Fuzzing🟢 10project is fuzzed
Packaging🟢 10packaging workflow detected
SAST🟢 10SAST tool is run on all commits
pip/cryptography 45.0.5 🟢 8.4
Details
CheckScoreReason
Code-Review🟢 10all changesets reviewed
Maintained🟢 1030 commit(s) and 12 issue activity found in the last 90 days -- score normalized to 10
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Security-Policy🟢 10security policy file detected
License🟢 9license file detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration
Signed-Releases⚠️ -1no releases found
Token-Permissions🟢 9detected GitHub workflow tokens with excessive permissions
Packaging🟢 10packaging workflow detected
Fuzzing🟢 10project is fuzzed
Binary-Artifacts🟢 10no binaries found in the repo
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
Vulnerabilities🟢 82 existing vulnerabilities detected
Pinned-Dependencies🟢 5dependency not pinned by hash detected -- score normalized to 5
pip/distlib 0.4.0 UnknownUnknown
pip/gitpython 3.1.45 🟢 8.3
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 10 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 5Found 5/9 approved changesets -- score normalized to 5
Packaging⚠️ -1packaging workflow not detected
Security-Policy🟢 10security policy file detected
Binary-Artifacts🟢 10no binaries found in the repo
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions🟢 9detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
License🟢 10license file detected
Fuzzing🟢 10project is fuzzed
Vulnerabilities🟢 100 existing vulnerabilities detected
Signed-Releases⚠️ -1no releases found
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration
SAST🟢 10SAST tool is run on all commits
pip/greenlet 3.2.3 🟢 4.8
Details
CheckScoreReason
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Code-Review⚠️ 0Found 2/22 approved changesets -- score normalized to 0
Maintained🟢 1017 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Binary-Artifacts🟢 10no binaries found in the repo
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Security-Policy⚠️ 0security policy file not detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 9license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
Packaging🟢 10packaging workflow detected
SAST🟢 10SAST tool is run on all commits
Vulnerabilities🟢 55 existing vulnerabilities detected
pip/griffe 1.9.0 🟢 4.7
Details
CheckScoreReason
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Code-Review🟢 3Found 9/30 approved changesets -- score normalized to 3
Packaging⚠️ -1packaging workflow not detected
Maintained🟢 1017 commit(s) and 4 issue activity found in the last 90 days -- score normalized to 10
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Binary-Artifacts🟢 10no binaries found in the repo
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Security-Policy⚠️ 0security policy file not detected
License🟢 10license file detected
Vulnerabilities🟢 100 existing vulnerabilities detected
Fuzzing⚠️ 0project is not fuzzed
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
pip/hishel 0.1.3 UnknownUnknown
pip/jaraco-functools 4.2.1 🟢 5.6
Details
CheckScoreReason
Code-Review⚠️ 0Found 1/28 approved changesets -- score normalized to 0
Binary-Artifacts🟢 10no binaries found in the repo
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Security-Policy🟢 10security policy file detected
Maintained🟢 1013 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 10
Token-Permissions🟢 10GitHub workflow tokens follow principle of least privilege
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Packaging⚠️ -1packaging workflow not detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License⚠️ 0license file not detected
Vulnerabilities🟢 100 existing vulnerabilities detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
pip/mako 1.3.10 🟢 4.2
Details
CheckScoreReason
Maintained⚠️ 10 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 1
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Packaging⚠️ -1packaging workflow not detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Code-Review⚠️ 0Found 0/30 approved changesets -- score normalized to 0
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
License🟢 10license file detected
SAST⚠️ 0no SAST tool detected
Security-Policy⚠️ 0security policy file not detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Binary-Artifacts🟢 10no binaries found in the repo
Vulnerabilities🟢 100 existing vulnerabilities detected
Fuzzing🟢 10project is fuzzed
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
pip/multidict 6.6.3 🟢 6.2
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 13 issue activity found in the last 90 days -- score normalized to 10
Code-Review⚠️ 1Found 5/26 approved changesets -- score normalized to 1
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Binary-Artifacts🟢 10no binaries found in the repo
Vulnerabilities🟢 100 existing vulnerabilities detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
License🟢 9license file detected
Fuzzing🟢 10project is fuzzed
Security-Policy🟢 10security policy file detected
Packaging🟢 10packaging workflow detected
SAST🟢 10SAST tool is run on all commits
Branch-Protection🟢 3branch protection is not maximal on development and all release branches
Signed-Releases⚠️ 0Project has not signed or included provenance with any releases.
pip/pbs-installer 2025.7.23 UnknownUnknown
pip/pymdown-extensions 10.16.1 🟢 4.8
Details
CheckScoreReason
Code-Review⚠️ 0Found 2/30 approved changesets -- score normalized to 0
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Maintained🟢 1022 commit(s) and 5 issue activity found in the last 90 days -- score normalized to 10
Security-Policy🟢 10security policy file detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Binary-Artifacts🟢 10no binaries found in the repo
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Fuzzing⚠️ 0project is not fuzzed
License🟢 9license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration
Packaging🟢 10packaging workflow detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
Vulnerabilities⚠️ 010 existing vulnerabilities detected
pip/regex 2025.7.31 UnknownUnknown
pip/sentry-sdk 2.34.0 🟢 5.2
Details
CheckScoreReason
Code-Review🟢 7Found 22/30 approved changesets -- score normalized to 7
Maintained🟢 1030 commit(s) and 21 issue activity found in the last 90 days -- score normalized to 10
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Binary-Artifacts🟢 10no binaries found in the repo
License🟢 10license file detected
Packaging⚠️ -1packaging workflow not detected
Fuzzing⚠️ 0project is not fuzzed
Signed-Releases⚠️ 0Project has not signed or included provenance with any releases.
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Security-Policy🟢 10security policy file detected
Branch-Protection🟢 4branch protection is not maximal on development and all release branches
Vulnerabilities⚠️ 041 existing vulnerabilities detected
SAST🟢 9SAST tool detected but not run on all commits
pip/sqlalchemy 2.0.42 🟢 5.8
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 22 issue activity found in the last 90 days -- score normalized to 10
Code-Review⚠️ 2Found 6/30 approved changesets -- score normalized to 2
Packaging⚠️ -1packaging workflow not detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Security-Policy🟢 10security policy file detected
License🟢 10license file detected
Vulnerabilities🟢 100 existing vulnerabilities detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Binary-Artifacts🟢 10no binaries found in the repo
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration
Signed-Releases⚠️ 0Project has not signed or included provenance with any releases.
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Fuzzing🟢 10project is fuzzed
pip/sqlmodel 0.0.16 UnknownUnknown
pip/types-aiofiles 24.1.0.20250708 🟢 5.2
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 25 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 10all changesets reviewed
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
License🟢 9license file detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Fuzzing⚠️ 0project is not fuzzed
Packaging⚠️ -1packaging workflow not detected
Signed-Releases⚠️ -1no releases found
Branch-Protection🟢 3branch protection is not maximal on development and all release branches
Security-Policy🟢 10security policy file detected
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Vulnerabilities⚠️ 012 existing vulnerabilities detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
pip/types-dateparser 1.2.2.20250627 🟢 5.2
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 25 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 10all changesets reviewed
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
License🟢 9license file detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Fuzzing⚠️ 0project is not fuzzed
Packaging⚠️ -1packaging workflow not detected
Signed-Releases⚠️ -1no releases found
Branch-Protection🟢 3branch protection is not maximal on development and all release branches
Security-Policy🟢 10security policy file detected
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Vulnerabilities⚠️ 012 existing vulnerabilities detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
pip/types-python-dateutil 2.9.0.20250708 🟢 5.2
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 25 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 10all changesets reviewed
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
License🟢 9license file detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Fuzzing⚠️ 0project is not fuzzed
Packaging⚠️ -1packaging workflow not detected
Signed-Releases⚠️ -1no releases found
Branch-Protection🟢 3branch protection is not maximal on development and all release branches
Security-Policy🟢 10security policy file detected
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Vulnerabilities⚠️ 012 existing vulnerabilities detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
pip/typing-extensions 4.14.1 🟢 6.6
Details
CheckScoreReason
Maintained🟢 1017 commit(s) and 12 issue activity found in the last 90 days -- score normalized to 10
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Packaging⚠️ -1packaging workflow not detected
Code-Review🟢 8Found 26/30 approved changesets -- score normalized to 8
Token-Permissions🟢 10GitHub workflow tokens follow principle of least privilege
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Fuzzing⚠️ 0project is not fuzzed
License🟢 9license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration
Security-Policy🟢 10security policy file detected
Vulnerabilities🟢 37 existing vulnerabilities detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
pip/virtualenv 20.32.0 🟢 5.6
Details
CheckScoreReason
Code-Review🟢 4Found 7/15 approved changesets -- score normalized to 4
Maintained🟢 1030 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Security-Policy🟢 10security policy file detected
Binary-Artifacts🟢 5binaries present in source code
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
License🟢 10license file detected
Vulnerabilities🟢 100 existing vulnerabilities detected
Signed-Releases⚠️ -1no releases found
Fuzzing⚠️ 0project is not fuzzed
Branch-Protection🟢 4branch protection is not maximal on development and all release branches
Packaging🟢 10packaging workflow detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
pip/xattr 1.2.0 🟢 4.5
Details
CheckScoreReason
Maintained⚠️ 23 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 2
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Code-Review⚠️ 1Found 2/12 approved changesets -- score normalized to 1
Binary-Artifacts🟢 10no binaries found in the repo
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Security-Policy⚠️ 0security policy file not detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 9license file detected
Vulnerabilities🟢 100 existing vulnerabilities detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration
Packaging🟢 10packaging workflow detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
pip/alembic ^ 1.13.1 🟢 6.3
Details
CheckScoreReason
Security-Policy🟢 10security policy file detected
Code-Review⚠️ 0Found 1/30 approved changesets -- score normalized to 0
Packaging⚠️ -1packaging workflow not detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Maintained🟢 1030 commit(s) and 22 issue activity found in the last 90 days -- score normalized to 10
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions🟢 10GitHub workflow tokens follow principle of least privilege
Binary-Artifacts🟢 10no binaries found in the repo
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
License🟢 10license file detected
Fuzzing⚠️ 0project is not fuzzed
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration
Vulnerabilities🟢 82 existing vulnerabilities detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
pip/pydantic ^ 2.11.7 🟢 7.4
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 14 issue activity found in the last 90 days -- score normalized to 10
Code-Review🟢 10all changesets reviewed
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
License🟢 10license file detected
Vulnerabilities🟢 100 existing vulnerabilities detected
Binary-Artifacts🟢 10no binaries found in the repo
Signed-Releases⚠️ -1no releases found
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Fuzzing🟢 10project is fuzzed
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Security-Policy🟢 10security policy file detected
Packaging🟢 10packaging workflow detected
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
pip/sqlalchemy ^ 2.0.30 🟢 5.8
Details
CheckScoreReason
Maintained🟢 1030 commit(s) and 22 issue activity found in the last 90 days -- score normalized to 10
Code-Review⚠️ 2Found 6/30 approved changesets -- score normalized to 2
Packaging⚠️ -1packaging workflow not detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Security-Policy🟢 10security policy file detected
License🟢 10license file detected
Vulnerabilities🟢 100 existing vulnerabilities detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Binary-Artifacts🟢 10no binaries found in the repo
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration
Signed-Releases⚠️ 0Project has not signed or included provenance with any releases.
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Fuzzing🟢 10project is fuzzed
pip/sqlmodel ^ 0.0.16 UnknownUnknown

Scanned Files

  • poetry.lock
  • pyproject.toml

Copy link

cloudflare-workers-and-pages bot commented Jul 28, 2025

Deploying tux with  Cloudflare Pages  Cloudflare Pages

Latest commit: 03a0cb6
Status: ✅  Deploy successful!
Preview URL: https://49692e84.tux-afh.pages.dev
Branch Preview URL: https://cursor-migrate-database-from.tux-afh.pages.dev

View logs

Copy link

codecov bot commented Jul 28, 2025

Codecov Report

❌ Patch coverage is 37.89731% with 254 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (main@b82903c). Learn more about missing BASE report.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
tux/database/controllers/base.py 0.00% 97 Missing ⚠️
tux/database/client.py 30.61% 34 Missing ⚠️
tux/database/controllers/guild_config.py 0.00% 31 Missing ⚠️
tux/database/controllers/snippet.py 0.00% 22 Missing ⚠️
tux/cli/database.py 0.00% 21 Missing ⚠️
tux/database/controllers/case.py 0.00% 11 Missing ⚠️
tux/database/controllers/guild.py 0.00% 3 Missing ⚠️
tux/database/controllers/starboard.py 0.00% 3 Missing ⚠️
tux/cogs/moderation/cases.py 0.00% 2 Missing ⚠️
tux/database/controllers/afk.py 0.00% 2 Missing ⚠️
... and 25 more
Additional details and impacted files
@@           Coverage Diff           @@
##             main     #982   +/-   ##
=======================================
  Coverage        ?   10.78%           
=======================================
  Files           ?      124           
  Lines           ?    10530           
  Branches        ?     1281           
=======================================
  Hits            ?     1136           
  Misses          ?     9289           
  Partials        ?      105           
Flag Coverage Δ *Carryforward flag
database 0.32% <0.00%> (?) Carriedforward from 5f6d1bf
integration 7.10% <37.89%> (?)
unit 7.54% <37.89%> (?)

*This pull request uses carry forward flags. Click here to find out more.

Components Coverage Δ
Core Bot Infrastructure 16.45% <ø> (?)
Database Layer 0.00% <0.00%> (?)
Bot Commands & Features 0.00% <0.00%> (?)
Event & Error Handling ∅ <ø> (?)
Utilities & Helpers ∅ <ø> (?)
User Interface Components 0.00% <ø> (?)
CLI Interface ∅ <ø> (?)
External Service Wrappers ∅ <ø> (?)

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

cursoragent and others added 13 commits July 28, 2025 16:52
Move `from __future__ import annotations` to the top of files to
ensure future compatibility. Reorganize imports in `cases.py` and
`snippet.py` for better readability and maintainability. Remove
redundant inline imports in `snippet.py` to streamline the code.

style: replace en dashes with hyphens for consistency

Replace en dashes with hyphens in comments and docstrings to maintain
consistency across the codebase. This change improves readability and
ensures uniformity in documentation style.

These changes enhance code readability, maintainability, and ensure
future compatibility by organizing imports and standardizing comment
styles.
refactor(core.py): update log message for clarity on database usage

refactor(client.py): improve comments and add type ignores for SQLAlchemy methods

refactor(base.py): enhance comments for clarity and maintain API consistency

refactor(case.py, guild_config.py): update comments and remove Prisma-specific notes

refactor(snippet.py): add type ignores for SQLAlchemy methods

refactor(models.py): simplify imports and update comments for consistency

The addition of Pydantic is necessary for data validation and parsing, which enhances the robustness of the application. The refactoring across various files aims to improve code readability and maintainability by updating comments, removing outdated references to Prisma, and ensuring type consistency with SQLAlchemy methods. These changes help in maintaining a clean codebase and facilitate easier future updates.
@electron271 electron271 changed the title Migrate database from prisma to sqlmodel refactor!: Migrate database from prisma to sqlmodel Jul 31, 2025
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