Skip to content

service.py

This file centralizes core application services for managing users, posts, categories, tags, and comments. It orchestrates data operations and business logic for a content management system, ensuring data integrity and user interactions.

Scope

  • Manages user authentication, creation, and profile updates, including password hashing and email verification.

  • Orchestrates content creation, retrieval, updating, and soft deletion for posts, categories, and tags.

  • Facilitates comment management, including creation, retrieval, updates, soft deletion, and approval processes.

  • Ensures data integrity by applying soft deletion policies and generating unique slugs for content entities.

  • Provides search and filtering capabilities for posts based on various criteria like category, tag, and keywords.

File diagram - "service.py" /app/services/service.pyFile diagram - "service.py"  GlobalImportsSessionand_or_UserPostCommentCategoryTagUserCreatePostCreatePostUpdateCommentCreateCommentUpdateCategoryCreateTagCreatehash_passwordverify_passwordgenerate_slugloggerdatetime/app/services/service.pyUserServiceCategoryServiceTagServicePostServiceCommentServiceUserServicecreate_user()get_user_by_email()get_user_by_username()get_user_by_id()authenticate_user()update_password()verify_user_email()CategoryServicecreate_category()get_category_by_id()get_all_categories()delete_category()TagServicecreate_tag()get_tag_by_id()get_all_tags()delete_tag()PostServicecreate_post()get_post_by_id()get_post_by_slug()get_all_posts()search_posts()get_user_posts()update_post()delete_post()increment_view_count()CommentServicecreate_comment()get_comment_by_id()get_post_comments()update_comment()delete_comment()approve_comment()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
File diagram - "service.py" /app/services/service.pyFile diagram - "service.py"  GlobalImportsSessionand_or_UserPostCommentCategoryTagUserCreatePostCreatePostUpdateCommentCreateCommentUpdateCategoryCreateTagCreatehash_passwordverify_passwordgenerate_slugloggerdatetime/app/services/service.pyUserServiceCategoryServiceTagServicePostServiceCommentServiceUserServicecreate_user()get_user_by_email()get_user_by_username()get_user_by_id()authenticate_user()update_password()verify_user_email()CategoryServicecreate_category()get_category_by_id()get_all_categories()delete_category()TagServicecreate_tag()get_tag_by_id()get_all_tags()delete_tag()PostServicecreate_post()get_post_by_id()get_post_by_slug()get_all_posts()search_posts()get_user_posts()update_post()delete_post()increment_view_count()CommentServicecreate_comment()get_comment_by_id()get_post_comments()update_comment()delete_comment()approve_comment()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Imports

  • Session from sqlalchemy.orm

    Imports the Session class from SQLAlchemy ORM, providing a transactional scope for database operations within service methods.

  • and_, or_ from sqlalchemy

    Imports and_ and or_ operators from SQLAlchemy, enabling complex conditional filtering in database queries for entity retrieval.

  • User, Post, Comment, Category, Tag from app.models.models

    Imports SQLAlchemy ORM models representing core domain entities, facilitating object-relational mapping and database interaction for all services.

  • UserCreate, PostCreate, PostUpdate, CommentCreate, CommentUpdate, CategoryCreate, TagCreate from app.schemas.schemas

    Imports Pydantic schemas for data validation and serialization of incoming request payloads and outgoing responses, ensuring data consistency and type safety.

  • hash_password, verify_password from app.core.security

    Imports utility functions for securely hashing and verifying user passwords, crucial for authentication and maintaining user account security.

  • generate_slug from app.utils.helpers

    Imports a helper function to create URL-friendly slugs from strings, ensuring unique and readable identifiers for posts, categories, and tags.

  • logger from app.core.logging

    Imports the application's centralized logger, enabling structured logging of events, errors, and operational information across all service operations.

  • datetime from datetime

    Imports the datetime module for handling date and time operations, primarily used for timestamping entity creation, updates, and soft deletions.

Classes

UserService

Provides static utility methods for managing user-related operations within the application. Handles user creation, retrieval, authentication, password updates, and email verification. Integrates with database sessions and user models to ensure data consistency and security.

Class diagram - "UserService" /app/services/service.pyClass diagram - "UserService"  UserServicecreate_user()get_user_by_email()get_user_by_username()get_user_by_id()authenticate_user()update_password()verify_user_email()create_userdb_userUser()hash_password()db.add()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()get_user_by_emaildb.query.filter.first()db.query.filter()db.query()and_()get_user_by_usernamedb.query.filter.first()db.query.filter()db.query()and_()get_user_by_iddb.query.filter.first()db.query.filter()db.query()and_()authenticate_useruserverify_password()UserService.get_user_by_email()update_passworduserhashed_passwordupdated_bydate_updatedhash_password()datetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()UserService.get_user_by_id()verify_user_emailuseris_verifiedupdated_bydate_updateddatetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()UserService.get_user_by_id()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Class diagram - "UserService" /app/services/service.pyClass diagram - "UserService"  UserServicecreate_user()get_user_by_email()get_user_by_username()get_user_by_id()authenticate_user()update_password()verify_user_email()create_userdb_userUser()hash_password()db.add()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()get_user_by_emaildb.query.filter.first()db.query.filter()db.query()and_()get_user_by_usernamedb.query.filter.first()db.query.filter()db.query()and_()get_user_by_iddb.query.filter.first()db.query.filter()db.query()and_()authenticate_useruserverify_password()UserService.get_user_by_email()update_passworduserhashed_passwordupdated_bydate_updatedhash_password()datetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()UserService.get_user_by_id()verify_user_emailuseris_verifiedupdated_bydate_updateddatetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()UserService.get_user_by_id()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Methods

authenticate_user

public

Authenticates a user by verifying their email and password against stored credentials. This method is crucial for secure access control and user session management throughout the application. It returns the `User` object upon successful validation.
=== " "

Activity Diagram - "authenticate_user" /app/services/service.pyActivity Diagram - "authenticate_user"  Inputs: db, email, passwordCalls UserService.get_user_by_emailRetrieve user by emailuser not found?yesnoreturn NoneCalls verify_password with provided password and user'shashed passwordVerify passwordpassword does not match?yesnoreturn Nonereturn Authenticated user object   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "authenticate_user" /app/services/service.pyActivity Diagram - "authenticate_user"  Inputs: db, email, passwordCalls UserService.get_user_by_emailRetrieve user by emailuser not found?yesnoreturn NoneCalls verify_password with provided password and user'shashed passwordVerify passwordpassword does not match?yesnoreturn Nonereturn Authenticated user object   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "authenticate_user" /app/services/service.pyMethod diagram - "authenticate_user"  authenticate_useruserverify_password()UserService.get_user_by_email()get_user_by_emaildb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "authenticate_user" /app/services/service.pyMethod diagram - "authenticate_user"  authenticate_useruserverify_password()UserService.get_user_by_email()get_user_by_emaildb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "authenticate_user" Sequence Diagram - "authenticate_user"  authenticate_userUserServiceDatabaseSessionPasswordVerifierCallerauthenticate_userUserServiceDatabaseSessionPasswordVerifierCallerCallerauthenticate_userauthenticate_userUserServiceUserServiceDatabaseSessionDatabaseSessionPasswordVerifierPasswordVerifierauthenticate_userUserServiceDatabaseSessionPasswordVerifierUser Authentication Flowauthenticate_user(db, email, password)Attempt to retrieve user by emailget_user_by_email(db, email)query_user_by_email(email)user_recorduserUser not found, authentication failsalt[user is None]None[user exists]verify_password(password, user.hashed_password)is_password_validPassword mismatch, authentication failsalt[is_password_valid is False]None[is_password_valid is True]user/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "authenticate_user" Sequence Diagram - "authenticate_user"  authenticate_userUserServiceDatabaseSessionPasswordVerifierCallerauthenticate_userUserServiceDatabaseSessionPasswordVerifierCallerCallerauthenticate_userauthenticate_userUserServiceUserServiceDatabaseSessionDatabaseSessionPasswordVerifierPasswordVerifierauthenticate_userUserServiceDatabaseSessionPasswordVerifierUser Authentication Flowauthenticate_user(db, email, password)Attempt to retrieve user by emailget_user_by_email(db, email)query_user_by_email(email)user_recorduserUser not found, authentication failsalt[user is None]None[user exists]verify_password(password, user.hashed_password)is_password_validPassword mismatch, authentication failsalt[is_password_valid is False]None[is_password_valid is True]user/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def authenticate_user(db: Session, email: str, password: str) -> User:

Input Parameters

  • db (Session)

    The SQLAlchemy database session object used for database operations. Provides the necessary connection to query user data from the database. Ensures transactional integrity and proper resource management during authentication attempts.

  • email (str)

    The user's email address provided for authentication. This string is used to retrieve the corresponding user record from the database. It must exactly match a registered user's email for successful lookup.

  • password (str)

    The plain-text password provided by the user for authentication. This string is securely verified against the stored hashed password. It is never stored directly, only used for comparison.

Output / Return Values

  • authenticated_user (User)

    The User object representing the authenticated user if credentials are valid. Returns None if authentication fails due to incorrect email or password. This object contains all user details for subsequent application operations.

Logic / Execution Flow

  • Retrieve a user record from the database using the provided email by calling UserService.get_user_by_email(db, email).
  • Check if the user object was not found or if the provided password does not match the user.hashed_password using verify_password:
    • If no user is found or the password verification fails:
      • Return None, indicating authentication was unsuccessful.
  • If a user is found and the password verification succeeds:
    • Return the user object, indicating successful authentication.

Usage Tips

  • Always call this method within a secure context, such as an API endpoint protected by HTTPS. Ensure email and password are handled securely to prevent interception. Avoid logging sensitive credentials directly.

Additional Notes

  • This method relies on UserService.get_user_by_email and verify_password for its core functionality. Ensure these dependencies are correctly configured and robust. verify_password handles the secure comparison of hashed passwords.

create_user

public

Creates a new user record in the database by hashing the provided password and persisting user details. This method ensures data integrity and logs creation events, returning the newly created `User` object for further application use.
=== " "

Activity Diagram - "create_user" /app/services/service.pyActivity Diagram - "create_user"  Inputs: db, user_createTry Block: Attempt User CreationInstantiate User object with hashed passwordAdd user to DB sessionCommit transactionRefresh user objectLog user creation successSet operation_successful = trueSet result_user = db_userNo exception occurredCapture exceptionSet operation_successful = falseSet caught_exception = eyesexception occurs during try block?noCatch Block: Handle Exceptionoperation_successful is false?yesnoRollback transactionLog error details from caught_exceptionSet re_raise_exception = trueNo exception to catchSet re_raise_exception = falseFinally Block: CleanupNo explicit finally block in codere_raise_exception is true?yesnoRe-raise caught_exceptionThis path should not be reached if no exception wasre-raised and operation was not successfulreturn result_useryesoperation_successful is true?no   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "create_user" /app/services/service.pyActivity Diagram - "create_user"  Inputs: db, user_createTry Block: Attempt User CreationInstantiate User object with hashed passwordAdd user to DB sessionCommit transactionRefresh user objectLog user creation successSet operation_successful = trueSet result_user = db_userNo exception occurredCapture exceptionSet operation_successful = falseSet caught_exception = eyesexception occurs during try block?noCatch Block: Handle Exceptionoperation_successful is false?yesnoRollback transactionLog error details from caught_exceptionSet re_raise_exception = trueNo exception to catchSet re_raise_exception = falseFinally Block: CleanupNo explicit finally block in codere_raise_exception is true?yesnoRe-raise caught_exceptionThis path should not be reached if no exception wasre-raised and operation was not successfulreturn result_useryesoperation_successful is true?no   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "create_user" /app/services/service.pyMethod diagram - "create_user"  create_userdb_userUser()hash_password()db.add()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "create_user" /app/services/service.pyMethod diagram - "create_user"  create_userdb_userUser()hash_password()db.add()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "create_user" Sequence Diagram - "create_user"  create_userSessionSessionSessionSessionhash_passwordLoggerLoggerCallercreate_userSessionUser Modelhash_passwordLoggerCallerCallercreate_usercreate_userSessionSessionUser ModelUser Modelhash_passwordhash_passwordLoggerLoggercreate_userSessionSessionSessionSessionhash_passwordLoggerLoggerUser Creation Flowcreate_user(db, user_create)Try Blocknew User()Instantiate User object with provided datahash_password(user_create.password)hashed_passwordSet User object attributesAssign email, username, full_name, hashed_password, bio,profile_image_urladd(db_user)commit()refresh(db_user)info(f"User created: {db_user.email}")db_user[Exception as e]rollback()error(f"Error creating user: {str(e)}")raise Exception/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "create_user" Sequence Diagram - "create_user"  create_userSessionSessionSessionSessionhash_passwordLoggerLoggerCallercreate_userSessionUser Modelhash_passwordLoggerCallerCallercreate_usercreate_userSessionSessionUser ModelUser Modelhash_passwordhash_passwordLoggerLoggercreate_userSessionSessionSessionSessionhash_passwordLoggerLoggerUser Creation Flowcreate_user(db, user_create)Try Blocknew User()Instantiate User object with provided datahash_password(user_create.password)hashed_passwordSet User object attributesAssign email, username, full_name, hashed_password, bio,profile_image_urladd(db_user)commit()refresh(db_user)info(f"User created: {db_user.email}")db_user[Exception as e]rollback()error(f"Error creating user: {str(e)}")raise Exception/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def create_user(db: Session, user_create: UserCreate) -> User:

Input Parameters

  • db (Session)

    The SQLAlchemy database session object used for interacting with the database. This session manages transactions and persistence operations for the new user record creation process.

  • user_create (UserCreate)

    A Pydantic schema object containing the new user's details, including email, username, full_name, password, bio, and profile_image_url. This object provides validated input for user creation.

Output / Return Values

  • db_user (User)

    The newly created User object, retrieved from the database after successful commit. This object includes all persisted attributes, such as the id and hashed_password, ready for subsequent operations.

Exceptions

  • Exception

    Raised if any error occurs during the user creation process, such as database connection issues or constraint violations. The transaction is rolled back, and the original exception is re-raised.

Logic / Execution Flow

  • Begin a try block to handle potential exceptions during user creation.
  • Create a new User instance named db_user:
    • Assign user_create.email to db_user.email.
    • Assign user_create.username to db_user.username.
    • Assign user_create.full_name to db_user.full_name.
    • Hash user_create.password using hash_password() and assign the result to db_user.hashed_password.
    • Assign user_create.bio to db_user.bio.
    • Assign user_create.profile_image_url to db_user.profile_image_url.
  • Add the newly created db_user object to the database session db.
  • Commit the transaction to persist the db_user record to the database.
  • Refresh the db_user object from the database to ensure it contains any generated fields, like id.
  • Log an informational message indicating successful user creation, including the user's email.
  • Return the db_user object.
  • If an Exception occurs during the try block:
    • Roll back the database session db to discard any uncommitted changes.
    • Log an error message detailing the exception that occurred during user creation.
    • Re-raise the caught Exception to propagate the error to the caller.

Usage Tips

  • Ensure UserCreate schema includes robust validation for all fields, especially email and password, before calling this method. This prevents invalid data from reaching the database and causing errors.

Additional Notes

  • The hash_password() function is critical for security; ensure it uses a strong, up-to-date hashing algorithm. Never store plain-text passwords, always hash them before database persistence.

get_user_by_email

public

This method retrieves a `User` object from the database using their email address. It ensures the user is not marked as deleted, providing a safe way to fetch active user records. Essential for authentication flows and user profile management.
=== " "

Activity Diagram - "get_user_by_email" /app/services/service.pyActivity Diagram - "get_user_by_email"  Inputs: db, emailInitiate query for User modelApply filter for matching email and non-deleted statusExecute query and retrieve first matching userreturn User object or None   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "get_user_by_email" /app/services/service.pyActivity Diagram - "get_user_by_email"  Inputs: db, emailInitiate query for User modelApply filter for matching email and non-deleted statusExecute query and retrieve first matching userreturn User object or None   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "get_user_by_email" /app/services/service.pyMethod diagram - "get_user_by_email"  get_user_by_emaildb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "get_user_by_email" /app/services/service.pyMethod diagram - "get_user_by_email"  get_user_by_emaildb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "get_user_by_email" Sequence Diagram - "get_user_by_email"  get_user_by_emailDatabaseSessionCallerget_user_by_emailDatabaseSessionUserTableCallerCallerget_user_by_emailget_user_by_emailDatabaseSessionDatabaseSessionUserTableUserTableget_user_by_emailDatabaseSessionFunction Callget_user_by_email(db, email)Query Construction and Executionquery(UserTable)Initiates a query targeting the User modelfilter(User.email == email, User.deleted_at == None)Applies filtering conditions to the User tablefirst()Executes the query and retrieves the first matching recordUser object or NoneFunction ReturnUser object or None/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "get_user_by_email" Sequence Diagram - "get_user_by_email"  get_user_by_emailDatabaseSessionCallerget_user_by_emailDatabaseSessionUserTableCallerCallerget_user_by_emailget_user_by_emailDatabaseSessionDatabaseSessionUserTableUserTableget_user_by_emailDatabaseSessionFunction Callget_user_by_email(db, email)Query Construction and Executionquery(UserTable)Initiates a query targeting the User modelfilter(User.email == email, User.deleted_at == None)Applies filtering conditions to the User tablefirst()Executes the query and retrieves the first matching recordUser object or NoneFunction ReturnUser object or None/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def get_user_by_email(db: Session, email: str) -> User:

Input Parameters

  • db (Session)

    The SQLAlchemy Session object used to interact with the database. This session manages the connection and transactions for querying user data. It is crucial for executing database operations effectively.

  • email (str)

    The email address string of the user to be retrieved. This parameter is used to uniquely identify the user record within the database. It must be a valid email format for successful lookup.

Output / Return Values

  • user_record (User)

    Returns a User object if a matching user is found in the database. If no user matches the provided email or if the user is marked as deleted, it returns None. This object represents the active user.

Logic / Execution Flow

  • Initiate a database query on the User model using the provided db session.
  • Apply a filter condition to select users where User.email matches the input email.
  • Add another filter condition to ensure User.deleted_at is None, meaning the user is not soft-deleted.
  • Execute the query and retrieve the first matching User record found.
  • Return the retrieved User object, or None if no active user matches the criteria.

Usage Tips

  • Always use this method when fetching user details by email to ensure only active, non-deleted accounts are retrieved. This prevents accidental access or operations on logically deleted user data within the application.

  • Integrate this method into authentication services or user lookup functionalities where a unique email identifies the user. It provides a consistent and secure way to access user records efficiently.

Additional Notes

  • The method implicitly returns None if no user matches the criteria, including if the user exists but deleted_at is not None. Handle this None return explicitly in calling code to avoid AttributeError.

  • This method performs a case-sensitive email comparison by default, depending on database collation settings. If case-insensitivity is required, consider normalising email input to lowercase before calling this function.

get_user_by_id

public

This method retrieves a single user record from the database using their unique identifier. It ensures only active, non-deleted users are returned. This function is crucial for fetching specific user profiles for various application operations.
=== " "

Activity Diagram - "get_user_by_id" /app/services/service.pyActivity Diagram - "get_user_by_id"  Inputs: db, user_idConstruct query for User modelApply filter conditions: User ID matches and User is notsoft-deletedExecute query and retrieve first matching userreturn User object or None   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "get_user_by_id" /app/services/service.pyActivity Diagram - "get_user_by_id"  Inputs: db, user_idConstruct query for User modelApply filter conditions: User ID matches and User is notsoft-deletedExecute query and retrieve first matching userreturn User object or None   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "get_user_by_id" /app/services/service.pyMethod diagram - "get_user_by_id"  get_user_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "get_user_by_id" /app/services/service.pyMethod diagram - "get_user_by_id"  get_user_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "get_user_by_id" Sequence Diagram - "get_user_by_id"  get_user_by_idSession .db.SQLAlchemy .and_.DatabaseCallerget_user_by_idSession .db.User .Model.SQLAlchemy .and_.DatabaseCallerCallerget_user_by_idget_user_by_idSession (db)Session (db)User (Model)User (Model)SQLAlchemy (and_)SQLAlchemy (and_)DatabaseDatabaseget_user_by_idSession .db.SQLAlchemy .and_.DatabaseFunction Callget_user_by_id(db, user_id)Query Constructionquery(User)Initiates a query for the User modelAccess 'id' attributeRetrieves the 'id' column for comparisonAccess 'deleted_at' attributeRetrieves the 'deleted_at' column for comparisonand_(User.id == user_id, User.deleted_at == None)Combines the conditions (id matches, not deleted)Combined conditionfilter(combined_condition)Applies the combined condition to the queryfirst()Executes the query and retrieves the first matching recordDatabase InteractionSELECT * FROM users WHERE id = :user_id AND deleted_atIS NULL LIMIT 1User Record / NoneUser Object / NoneFunction ReturnUser Object / None/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "get_user_by_id" Sequence Diagram - "get_user_by_id"  get_user_by_idSession .db.SQLAlchemy .and_.DatabaseCallerget_user_by_idSession .db.User .Model.SQLAlchemy .and_.DatabaseCallerCallerget_user_by_idget_user_by_idSession (db)Session (db)User (Model)User (Model)SQLAlchemy (and_)SQLAlchemy (and_)DatabaseDatabaseget_user_by_idSession .db.SQLAlchemy .and_.DatabaseFunction Callget_user_by_id(db, user_id)Query Constructionquery(User)Initiates a query for the User modelAccess 'id' attributeRetrieves the 'id' column for comparisonAccess 'deleted_at' attributeRetrieves the 'deleted_at' column for comparisonand_(User.id == user_id, User.deleted_at == None)Combines the conditions (id matches, not deleted)Combined conditionfilter(combined_condition)Applies the combined condition to the queryfirst()Executes the query and retrieves the first matching recordDatabase InteractionSELECT * FROM users WHERE id = :user_id AND deleted_atIS NULL LIMIT 1User Record / NoneUser Object / NoneFunction ReturnUser Object / None/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def get_user_by_id(db: Session, user_id: int) -> User:

Input Parameters

  • db (Session)

    The db parameter represents the SQLAlchemy database session for executing queries. It provides the necessary connection and transaction context to interact with the underlying database. This session is essential for data retrieval operations.

  • user_id (int)

    The user_id parameter is an integer representing the unique identifier of the user to retrieve. This ID is used to precisely locate the desired user record within the database. It ensures accurate and specific user data fetching.

Output / Return Values

  • user (User)

    This method returns a User object if a matching, non-deleted user is found in the database. If no such user exists, it returns None. This output is vital for subsequent operations requiring user data.

Logic / Execution Flow

  • Query the database for a User object using the provided db session.
  • Apply a filter to select User records where the User.id matches the provided user_id.
  • Additionally, apply a filter to ensure that the User.deleted_at field is None, effectively excluding soft-deleted users.
  • Retrieve the first matching User record found after applying both filters.

Usage Tips

  • Always ensure the user_id provided is valid and corresponds to an existing user. Handle cases where None is returned gracefully to prevent downstream errors in your application logic.

  • Integrate this method into user profile views or administrative panels where specific user data retrieval is required. Prioritize error handling for None returns to maintain application stability.

Additional Notes

  • This method implicitly filters out soft-deleted users by checking deleted_at == None. If you need to retrieve deleted users, a separate method or modified query would be necessary.

  • The query uses first() which efficiently retrieves only one record, optimising database load. For scenarios requiring multiple users, consider using all() with different filtering criteria.

get_user_by_username

public

This method retrieves a single user record from the database using their unique username. It ensures only active users, not marked as deleted, are returned. This function is crucial for authentication, user profile retrieval, and various user-centric operations within the application.
=== " "

Activity Diagram - "get_user_by_username" /app/services/service.pyActivity Diagram - "get_user_by_username"  Inputs: db, usernameQuery User tableFilter by username and deleted_at is NoneRetrieve the first matching userreturn User object or None   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "get_user_by_username" /app/services/service.pyActivity Diagram - "get_user_by_username"  Inputs: db, usernameQuery User tableFilter by username and deleted_at is NoneRetrieve the first matching userreturn User object or None   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "get_user_by_username" /app/services/service.pyMethod diagram - "get_user_by_username"  get_user_by_usernamedb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "get_user_by_username" /app/services/service.pyMethod diagram - "get_user_by_username"  get_user_by_usernamedb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "get_user_by_username" Sequence Diagram - "get_user_by_username"  get_user_by_usernameDatabaseSessionCallerget_user_by_usernameDatabaseSessionUserORMCallerCallerget_user_by_usernameget_user_by_usernameDatabaseSessionDatabaseSessionUserORMUserORMget_user_by_usernameDatabaseSessionFunction Callget_user_by_username(db, username)Database Interactionquery(User)Initiates a query builder for the User modelreference User model for filteringUses User.username and User.deleted_at for conditionsapply filter (username == username AND deleted_at ISNULL)Constructs the WHERE clause using SQLAlchemy's and_fetch first matching resultExecutes the query and retrieves the first record or NoneUser object or NoneFunction ReturnUser object or None/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "get_user_by_username" Sequence Diagram - "get_user_by_username"  get_user_by_usernameDatabaseSessionCallerget_user_by_usernameDatabaseSessionUserORMCallerCallerget_user_by_usernameget_user_by_usernameDatabaseSessionDatabaseSessionUserORMUserORMget_user_by_usernameDatabaseSessionFunction Callget_user_by_username(db, username)Database Interactionquery(User)Initiates a query builder for the User modelreference User model for filteringUses User.username and User.deleted_at for conditionsapply filter (username == username AND deleted_at ISNULL)Constructs the WHERE clause using SQLAlchemy's and_fetch first matching resultExecutes the query and retrieves the first record or NoneUser object or NoneFunction ReturnUser object or None/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def get_user_by_username(db: Session, username: str) -> User:

Input Parameters

  • db (Session)

    The SQLAlchemy session object for database interaction. Provides the necessary connection and transaction management to query the User table effectively. Essential for executing database operations within the application.

  • username (str)

    The string representing the unique username of the user to retrieve. This parameter is used to filter the User table, ensuring the correct user is identified for subsequent operations.

Output / Return Values

  • user_object (User)

    An instance of the User model if a matching user is found. Returns None if no user matches the provided criteria, indicating the user does not exist or is deleted.

Logic / Execution Flow

  • Query the User model using the provided SQLAlchemy database session db.
  • Apply a filter to the query using and_ to combine two conditions.
  • The first condition checks if the User.username attribute matches the input username.
  • The second condition checks if the User.deleted_at attribute is None, ensuring only non-deleted users are considered.
  • Execute the query and retrieve the first matching User object found in the database.

Usage Tips

  • Always ensure the username provided is properly sanitised and validated before calling this method. This prevents potential SQL injection vulnerabilities and ensures data integrity during database queries.

  • Handle the None return value explicitly in your calling code. If None is returned, the user does not exist or is deleted, requiring appropriate error handling or user feedback.

Additional Notes

  • This method implicitly assumes User.username is unique and indexed for optimal performance. Consider adding an index to the username column if not already present to speed up lookups.

  • The deleted_at check is crucial for soft-deletion strategies, preventing retrieval of logically deleted users. Ensure consistent application of this filter across all user retrieval methods.

update_password

public

This method securely updates a user's password by hashing the new password and persisting changes. It ensures data integrity through database transactions. Essential for user account management and security, it integrates with authentication systems to maintain user credentials.
=== " "

400. PlantUML 1.2026.1[From string (line 601) ] @startuml<style>root {--common-background: #f1f1f1;--note-background: #FEFFDD;...... ( skipping 575 lines )...:Hash new password;:Update user's hashed password;:Set updated_by field;:Set date_updated field;:Commit database transaction;:Log password update success;if (exception thrown during these operations?) then (yes):Capture exception;:Set exception_occurred = true;else (no):Set exception_occurred = false;endif} group "Catch Block: Handle Exception" {if (exception_occurred is true?) then (yes):Rollback database transaction;:Log error details;:Re-raise exception;stop note right: Abnormal termination due to re-raised exceptionSyntax Error? (Assumed diagram type: activity)
400. PlantUML 1.2026.1[From string (line 665) ] @startuml<style>root {FontName SansSerif  HyperLinkUnderlineThickness 1...... ( skipping 638 lines )...:Hash new password;:Update user's hashed password;:Set updated_by field;:Set date_updated field;:Commit database transaction;:Log password update success;if (exception thrown during these operations?) then (yes):Capture exception;:Set exception_occurred = true;else (no):Set exception_occurred = false;endif} group "Catch Block: Handle Exception" {if (exception_occurred is true?) then (yes):Rollback database transaction;:Log error details;:Re-raise exception;stop note right: Abnormal termination due to re-raised exceptionSyntax Error? (Assumed diagram type: activity)

Method diagram - "update_password" /app/services/service.pyMethod diagram - "update_password"  update_passworduserhashed_passwordupdated_bydate_updatedhash_password()datetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()UserService.get_user_by_id()get_user_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "update_password" /app/services/service.pyMethod diagram - "update_password"  update_passworduserhashed_passwordupdated_bydate_updatedhash_password()datetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()UserService.get_user_by_id()get_user_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "update_password" Sequence Diagram - "update_password"  UserServiceUserServiceSessionSessionSessionLoggerLoggerCallerUserServiceSessionLoggerCallerCallerUserServiceUserServiceSessionSessionLoggerLoggerUserServiceUserServiceSessionSessionSessionLoggerLoggerPassword Update Processupdate_password(db, user_id, new_password)Try Blockget_user_by_id(db, user_id)Internal call to retrieve user by ID.query_user_by_id(user_id)user_object_or_Noneuser_object_or_Nonealt[user is not found]False[user is found]hash_password(new_password)Hashes the new password using an internal utility.update user.hashed_passwordupdate user.updated_byupdate user.date_updatedcommit()commit_successinfo("Password updated for user")log_ackTruebreak[Exception as e]rollback()rollback_ackerror("Error updating password")log_ackraise Exception(e)/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "update_password" Sequence Diagram - "update_password"  UserServiceUserServiceSessionSessionSessionLoggerLoggerCallerUserServiceSessionLoggerCallerCallerUserServiceUserServiceSessionSessionLoggerLoggerUserServiceUserServiceSessionSessionSessionLoggerLoggerPassword Update Processupdate_password(db, user_id, new_password)Try Blockget_user_by_id(db, user_id)Internal call to retrieve user by ID.query_user_by_id(user_id)user_object_or_Noneuser_object_or_Nonealt[user is not found]False[user is found]hash_password(new_password)Hashes the new password using an internal utility.update user.hashed_passwordupdate user.updated_byupdate user.date_updatedcommit()commit_successinfo("Password updated for user")log_ackTruebreak[Exception as e]rollback()rollback_ackerror("Error updating password")log_ackraise Exception(e)/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def update_password(db: Session, user_id: int, new_password: str) -> bool:

Input Parameters

  • db (Session)

    The db parameter represents the SQLAlchemy session for database operations. It provides the necessary connection to interact with the database, enabling user retrieval, password updates, and transaction management for data persistence.

  • user_id (int)

    This integer user_id uniquely identifies the target user whose password needs updating. It ensures the correct user record is fetched and modified, preventing unintended password changes for other accounts within the system.

  • new_password (str)

    The new_password string contains the plain-text password provided by the user. This value is securely hashed before storage, ensuring sensitive data protection and compliance with security best practices for credential management.

Output / Return Values

  • password_updated (bool)

    This boolean indicates whether the password update operation was successful. True signifies a successful update and commit, while False means the user was not found, preventing further processing and indicating failure.

Exceptions

  • Exception

    Raised for any unexpected errors occurring during the password update process. This generic exception ensures that all unhandled issues are caught, the database transaction is rolled back, and the error is propagated for further handling.

Logic / Execution Flow

  • Begin a try block to handle potential exceptions during the password update process.
  • Retrieve the User object from the database using the provided user_id via UserService.get_user_by_id().
  • Check if a user object was successfully retrieved from the database.
    • If user is None (user not found):
      • Return False immediately, indicating that the password update could not proceed.
  • If user is found:
    • Hash the new_password using the hash_password() utility function.
    • Assign the newly hashed password to the user.hashed_password attribute.
    • Set the user.updated_by attribute to the user_id of the user performing the update.
    • Update the user.date_updated attribute with the current UTC timestamp.
    • Commit the transaction to the database, persisting all changes to the user record.
    • Log an informational message indicating successful password update for the user's email.
    • Return True, signifying that the password update operation completed successfully.
  • Catch any Exception that occurs within the try block:
    • Rollback the database transaction to undo any partial changes made before the error.
    • Log an error message detailing the exception that occurred during the password update.
    • Re-raise the caught Exception, propagating the error to the calling function for handling.

Usage Tips

  • Always ensure user_id corresponds to an existing user before calling this method. Validating user existence beforehand prevents unnecessary database operations and ensures a smoother, more efficient password update flow.

  • Implement strong password policies and validation at the application layer before passing new_password to this method. This enhances security by enforcing complexity requirements, protecting against weak or easily guessable passwords.

Additional Notes

  • This method relies on datetime.utcnow() for timestamping updates. Ensure system clocks are synchronized and consider timezone implications if datetime.now() with timezone awareness is preferred for consistency.

  • The hash_password() function is crucial for security. Verify its implementation uses a robust, modern hashing algorithm (e.g., bcrypt, Argon2) with appropriate salt generation to protect against brute-force attacks.

verify_user_email

public

This method verifies a user's email by updating their verification status in the database. It ensures the user exists before marking them as verified. This function is crucial for user account activation workflows.
=== " "

Activity Diagram - "verify_user_email" /app/services/service.pyActivity Diagram - "verify_user_email"  Inputs: db, user_idInitialize exception_occurred = falseInitialize verification_result = nullTry Block: Attempt Email VerificationRetrieve user by IDIf any operation in the Try Block fails, 'exception_occurred' is implicitly set to true and execution bypasses the normal return path.user not found?yesnoSet verification_result = FalseSet user.is_verified to TrueSet user.updated_by to user_idSet user.date_updated to current UTC timeCommit changes to databaseLog email verification successSet verification_result = TrueNo exception occurred, proceed with normal returnsexception_occurred is true?yesnoCatch Block: Handle ExceptionRollback database transactionLog error detailsRe-raise exceptionverification_result is True?yesnoreturn Truereturn False   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "verify_user_email" /app/services/service.pyActivity Diagram - "verify_user_email"  Inputs: db, user_idInitialize exception_occurred = falseInitialize verification_result = nullTry Block: Attempt Email VerificationRetrieve user by IDIf any operation in the Try Block fails, 'exception_occurred' is implicitly set to true and execution bypasses the normal return path.user not found?yesnoSet verification_result = FalseSet user.is_verified to TrueSet user.updated_by to user_idSet user.date_updated to current UTC timeCommit changes to databaseLog email verification successSet verification_result = TrueNo exception occurred, proceed with normal returnsexception_occurred is true?yesnoCatch Block: Handle ExceptionRollback database transactionLog error detailsRe-raise exceptionverification_result is True?yesnoreturn Truereturn False   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "verify_user_email" /app/services/service.pyMethod diagram - "verify_user_email"  verify_user_emailuseris_verifiedupdated_bydate_updateddatetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()UserService.get_user_by_id()get_user_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "verify_user_email" /app/services/service.pyMethod diagram - "verify_user_email"  verify_user_emailuseris_verifiedupdated_bydate_updateddatetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()UserService.get_user_by_id()get_user_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "verify_user_email" Sequence Diagram - "verify_user_email"  verify_user_emailUserServiceDatabaseSessionDatabaseSessionLoggerLoggerCallerverify_user_emailUserServiceDatabaseSessionLoggerCallerCallerverify_user_emailverify_user_emailUserServiceUserServiceDatabaseSessionDatabaseSessionLoggerLoggerverify_user_emailUserServiceDatabaseSessionDatabaseSessionLoggerLoggerFunction Callverify_user_email(db, user_id)Try BlockAn error occurred during verificationget_user_by_id(db, user_id)userUser not foundalt[user is None]False[user exists]Set user.is_verified = TrueSet user.updated_by = user_idSet user.date_updated = datetime.utcnow()commit()commit_successinfo(f"Email verified for user: {user.email}")log_acknowledgedTrueException Handlingbreak[Exception as e]rollback()rollback_successerror(f"Error verifying email: {str(e)}")log_acknowledgedraise Exception/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "verify_user_email" Sequence Diagram - "verify_user_email"  verify_user_emailUserServiceDatabaseSessionDatabaseSessionLoggerLoggerCallerverify_user_emailUserServiceDatabaseSessionLoggerCallerCallerverify_user_emailverify_user_emailUserServiceUserServiceDatabaseSessionDatabaseSessionLoggerLoggerverify_user_emailUserServiceDatabaseSessionDatabaseSessionLoggerLoggerFunction Callverify_user_email(db, user_id)Try BlockAn error occurred during verificationget_user_by_id(db, user_id)userUser not foundalt[user is None]False[user exists]Set user.is_verified = TrueSet user.updated_by = user_idSet user.date_updated = datetime.utcnow()commit()commit_successinfo(f"Email verified for user: {user.email}")log_acknowledgedTrueException Handlingbreak[Exception as e]rollback()rollback_successerror(f"Error verifying email: {str(e)}")log_acknowledgedraise Exception/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def verify_user_email(db: Session, user_id: int) -> bool:

Input Parameters

  • db (Session)

    The Session object provides a transactional scope for database operations. It manages the lifecycle of database connections and ensures data consistency. This parameter is essential for interacting with the database.

  • user_id (int)

    The unique integer identifier for the user whose email needs verification. This user_id is used to retrieve the specific user record from the database. It ensures the correct user account is targeted for status update.

Output / Return Values

  • verification_status (bool)

    Returns True if the user's email was successfully verified and updated in the database. Returns False if the specified user_id does not correspond to an existing user. This indicates operation success or failure.

Exceptions

  • Exception

    Raised for any unexpected error occurring during the email verification process. This generic exception ensures that all unhandled issues are caught, the database transaction is rolled back, and the error is logged for debugging.

Logic / Execution Flow

  • Begin a try block to handle potential exceptions during the verification process.
  • Retrieve the User object from the database using UserService.get_user_by_id(db, user_id).
  • Check if the user object returned from the database query is None.
  • If user is None (meaning no user was found with the given user_id):
    • Return False to indicate that the verification failed because the user does not exist.
  • If a user object is found:
    • Set the user.is_verified attribute to True.
    • Set the user.updated_by attribute to the provided user_id.
    • Set the user.date_updated attribute to the current UTC time using datetime.utcnow().
    • Commit the changes to the database session using db.commit().
    • Log an informational message using logger.info() indicating successful email verification for the user's email.
    • Return True to indicate successful email verification.
  • If any Exception occurs during the try block execution:
    • Enter the except Exception as e block.
    • Rollback any pending database changes using db.rollback() to maintain data integrity.
    • Log an error message using logger.error() detailing the exception that occurred during email verification.
    • Re-raise the caught Exception to propagate the error further up the call stack.

Usage Tips

  • Integrate this method into your user registration and email confirmation workflows. Call verify_user_email() immediately after a user clicks their unique verification link to activate their account securely and reliably.

  • Ensure the user_id passed to this method is securely obtained and validated to prevent unauthorized verification attempts. Always verify user identity before invoking this critical status-changing operation for security.

Additional Notes

  • The method relies on UserService.get_user_by_id to retrieve user data. Performance of this lookup directly impacts verification speed. Consider caching strategies for frequently accessed user data to optimize this process.

  • This method updates updated_by and date_updated fields, providing an audit trail for verification. Ensure datetime.utcnow() is consistently used across your application for timestamping to avoid timezone issues.

CategoryService

The `CategoryService` class provides static methods for managing `Category` entities within the application's data store. It encapsulates CRUD operations like creation, retrieval, and soft deletion, ensuring data integrity and consistent access patterns for category-related business logic.

Class diagram - "CategoryService" /app/services/service.pyClass diagram - "CategoryService"  CategoryServicecreate_category()get_category_by_id()get_all_categories()delete_category()create_categorydb_categoryCategory()generate_slug()db.add()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()get_category_by_iddb.query.filter.first()db.query.filter()db.query()and_()get_all_categoriesdb.query.filter.offset.limit.all()db.query.filter.offset.limit()db.query.filter.offset()db.query.filter()db.query()delete_categorycategorydeleted_atupdated_bydatetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()CategoryService.get_category_by_id()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Class diagram - "CategoryService" /app/services/service.pyClass diagram - "CategoryService"  CategoryServicecreate_category()get_category_by_id()get_all_categories()delete_category()create_categorydb_categoryCategory()generate_slug()db.add()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()get_category_by_iddb.query.filter.first()db.query.filter()db.query()and_()get_all_categoriesdb.query.filter.offset.limit.all()db.query.filter.offset.limit()db.query.filter.offset()db.query.filter()db.query()delete_categorycategorydeleted_atupdated_bydatetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()CategoryService.get_category_by_id()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Destructor

def __del__(self):

This class does not define an explicit destructor method. Therefore, no specific cleanup or finalisation logic is executed when instances of CategoryService are garbage collected by the Python runtime environment.

Methods

create_category

public

This method creates a new category entry in the database using provided data. It ensures data integrity by rolling back transactions on error. This function is crucial for managing content organization within the application.
=== " "

Activity Diagram - "create_category" /app/services/service.pyActivity Diagram - "create_category"  Inputs: db, category_create, user_idTry Block: Attempt Category CreationCreate Category objectGenerate slug from category nameAssign name, slug, description, added_by, updated_byAdd category to DB sessionCommit transaction to databaseexception thrown during commit?yesnoSet exception_occurred = trueSet exception_occurred = falseRefresh category object from DBLog category creation successNormal function exitreturn Created Category ObjectNo exception, catch block skippedCatch Block: Handle ExceptionRollback database transactionLog error detailsAbnormal function exitRe-raise exceptionyesexception_occurred is true?noFinally Block: CleanupNo explicit finally block in code   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "create_category" /app/services/service.pyActivity Diagram - "create_category"  Inputs: db, category_create, user_idTry Block: Attempt Category CreationCreate Category objectGenerate slug from category nameAssign name, slug, description, added_by, updated_byAdd category to DB sessionCommit transaction to databaseexception thrown during commit?yesnoSet exception_occurred = trueSet exception_occurred = falseRefresh category object from DBLog category creation successNormal function exitreturn Created Category ObjectNo exception, catch block skippedCatch Block: Handle ExceptionRollback database transactionLog error detailsAbnormal function exitRe-raise exceptionyesexception_occurred is true?noFinally Block: CleanupNo explicit finally block in code   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "create_category" /app/services/service.pyMethod diagram - "create_category"  create_categorydb_categoryCategory()generate_slug()db.add()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "create_category" /app/services/service.pyMethod diagram - "create_category"  create_categorydb_categoryCategory()generate_slug()db.add()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "create_category" Sequence Diagram - "create_category"  create_categoryDatabaseSessionDatabaseSessionDatabaseSessionDatabaseSessionLoggerLoggerCallercreate_categoryDatabaseSessionLoggerCallerCallercreate_categorycreate_categoryDatabaseSessionDatabaseSessionLoggerLoggercreate_categoryDatabaseSessionDatabaseSessionDatabaseSessionDatabaseSessionLoggerLoggerMethod Callcreate_category(db, category_create, user_id)Try BlockConstruct Category object (name, slug, description,added_by, updated_by)generate_slug(category_create.slug)Generates a URL-friendly string from the category slug.add(db_category)commit()refresh(db_category)info(f"Category created: {db_category.name}")db_categorybreak[Exception]rollback()error(f"Error creating category: {str(e)}")raise Exception(e)/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "create_category" Sequence Diagram - "create_category"  create_categoryDatabaseSessionDatabaseSessionDatabaseSessionDatabaseSessionLoggerLoggerCallercreate_categoryDatabaseSessionLoggerCallerCallercreate_categorycreate_categoryDatabaseSessionDatabaseSessionLoggerLoggercreate_categoryDatabaseSessionDatabaseSessionDatabaseSessionDatabaseSessionLoggerLoggerMethod Callcreate_category(db, category_create, user_id)Try BlockConstruct Category object (name, slug, description,added_by, updated_by)generate_slug(category_create.slug)Generates a URL-friendly string from the category slug.add(db_category)commit()refresh(db_category)info(f"Category created: {db_category.name}")db_categorybreak[Exception]rollback()error(f"Error creating category: {str(e)}")raise Exception(e)/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def create_category(db: Session, category_create: CategoryCreate, user_id: int) -> Category:

Input Parameters

  • db (Session)

    The SQLAlchemy database session object used for interacting with the database. It facilitates adding, committing, and refreshing the new category instance. This session manages transaction scope and persistence.

  • category_create (CategoryCreate)

    A Pydantic schema object containing the data for the new category. This includes name, slug, and description fields. It ensures structured and validated input for category creation operations.

  • user_id (int)

    The integer ID of the user performing the category creation. This ID is used to populate the added_by and updated_by fields for auditing purposes. It tracks who initiated the record.

Output / Return Values

  • db_category (Category)

    The newly created and persisted Category object from the database. This object includes all fields, including database-generated IDs and timestamps. It represents the successfully added category record.

Exceptions

  • Exception

    Raised if any unexpected error occurs during the category creation process. This includes database errors or issues with data processing. The transaction is rolled back before re-raising.

Logic / Execution Flow

  • Begin a try block to handle potential exceptions during category creation.
  • Instantiate a new Category object with data from category_create and user_id:
    • Set name from category_create.name.
    • Generate slug using generate_slug function with category_create.slug.
    • Set description from category_create.description.
    • Set added_by to user_id.
    • Set updated_by to user_id.
  • Add the newly created db_category object to the database session.
  • Commit the transaction to persist the new category in the database.
  • Refresh the db_category object to load any database-generated fields (e.g., id).
  • Log an informational message indicating successful category creation with the category's name.
  • Return the db_category object.
  • If an Exception occurs during the try block:
    • Enter the except block, catching the Exception as e.
    • Roll back the database session to undo any uncommitted changes.
    • Log an error message detailing the failure to create the category, including the exception string.
    • Re-raise the caught Exception to propagate the error further.

Usage Tips

  • Always ensure category_create data is pre-validated before calling this method to prevent common errors. Utilize generate_slug for consistent, SEO-friendly URLs, enhancing content discoverability and user experience effectively.

  • Wrap calls to this method within a larger transaction if multiple related database operations are involved. This ensures atomicity, preventing partial updates and maintaining data consistency across complex workflows.

Additional Notes

  • The generate_slug function is crucial for creating URL-friendly identifiers, but ensure its logic handles edge cases like duplicate slugs. Consider adding unique constraint handling for slug at the database level.

  • The rollback_and_raise error strategy ensures data integrity by undoing changes on failure. However, calling code must handle the re-raised Exception appropriately, potentially translating it into a user-friendly error response.

delete_category

public

This method logically deletes a `Category` record by setting its `deleted_at` timestamp. It ensures data integrity by updating the `updated_by` field. This function is crucial for maintaining soft-deletion policies across the application.
=== " "

Activity Diagram - "delete_category" /app/services/service.pyActivity Diagram - "delete_category"  Inputs: db, category_id, user_idInitialize return_value = NoneInitialize exception_raised = falseTry Block: Attempt Category DeletionCall CategoryService.get_category_by_id(db, category_id)category is None?yesnoSet return_value = FalseSet category.deleted_at = datetime.utcnow()Set category.updated_by = user_idCommit changes to database (db.commit())Log category deletion success (logger.info)Set return_value = TrueCatch Block: Handle ExceptionNo exception occurred, proceed to finallySet exception_raised = trueRollback database transaction (db.rollback())Log error deleting category (logger.error)yesexception occurred during try block?noFinally Block: Implicit CleanupThis block represents the implicit finally behavior in Python. It executes regardless of try/except outcome.exception_raised is true?yesnoRe-raise the caught exception (raise)Should not be reached if all paths handledreturn_value is True?yesnoreturn Truereturn Falseyesreturn_value is not None?no   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "delete_category" /app/services/service.pyActivity Diagram - "delete_category"  Inputs: db, category_id, user_idInitialize return_value = NoneInitialize exception_raised = falseTry Block: Attempt Category DeletionCall CategoryService.get_category_by_id(db, category_id)category is None?yesnoSet return_value = FalseSet category.deleted_at = datetime.utcnow()Set category.updated_by = user_idCommit changes to database (db.commit())Log category deletion success (logger.info)Set return_value = TrueCatch Block: Handle ExceptionNo exception occurred, proceed to finallySet exception_raised = trueRollback database transaction (db.rollback())Log error deleting category (logger.error)yesexception occurred during try block?noFinally Block: Implicit CleanupThis block represents the implicit finally behavior in Python. It executes regardless of try/except outcome.exception_raised is true?yesnoRe-raise the caught exception (raise)Should not be reached if all paths handledreturn_value is True?yesnoreturn Truereturn Falseyesreturn_value is not None?no   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "delete_category" /app/services/service.pyMethod diagram - "delete_category"  delete_categorycategorydeleted_atupdated_bydatetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()CategoryService.get_category_by_id()get_category_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "delete_category" /app/services/service.pyMethod diagram - "delete_category"  delete_categorycategorydeleted_atupdated_bydatetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()CategoryService.get_category_by_id()get_category_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "delete_category" Sequence Diagram - "delete_category"  CategoryServiceCategoryServiceDatabaseSessionDatabaseSessionDatabaseSessionLoggerLoggerCallerCategoryServiceDatabaseSessionLoggerCallerCallerCategoryServiceCategoryServiceDatabaseSessionDatabaseSessionLoggerLoggerCategoryServiceCategoryServiceDatabaseSessionDatabaseSessionDatabaseSessionLoggerLoggerMethod Call: delete_categorydelete_category(db_session, category_id, user_id)Try BlockHandles any Exception during deletionget_category_by_id(db_session, category_id)Calls static method within CategoryServicequery_category_by_id(category_id)category_objectcategory_objectIf category not foundalt[category is None]False[category found]Set category.deleted_at = datetime.utcnow()Set category.updated_by = user_idcommit()commit_successinfo("Category deleted")Truebreak[Exception occurred]rollback()rollback_completeerror("Error deleting category")raise Exception/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "delete_category" Sequence Diagram - "delete_category"  CategoryServiceCategoryServiceDatabaseSessionDatabaseSessionDatabaseSessionLoggerLoggerCallerCategoryServiceDatabaseSessionLoggerCallerCallerCategoryServiceCategoryServiceDatabaseSessionDatabaseSessionLoggerLoggerCategoryServiceCategoryServiceDatabaseSessionDatabaseSessionDatabaseSessionLoggerLoggerMethod Call: delete_categorydelete_category(db_session, category_id, user_id)Try BlockHandles any Exception during deletionget_category_by_id(db_session, category_id)Calls static method within CategoryServicequery_category_by_id(category_id)category_objectcategory_objectIf category not foundalt[category is None]False[category found]Set category.deleted_at = datetime.utcnow()Set category.updated_by = user_idcommit()commit_successinfo("Category deleted")Truebreak[Exception occurred]rollback()rollback_completeerror("Error deleting category")raise Exception/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def delete_category(db: Session, category_id: int, user_id: int) -> bool:

Input Parameters

  • db (Session)

    Provides the database session for interacting with the persistence layer. It enables querying, updating, and committing changes to Category records. Essential for transactional operations.

  • category_id (int)

    Unique identifier for the Category to be logically deleted. This ID is used to retrieve the specific category record from the database for modification. Essential for targeting the correct record.

  • user_id (int)

    Identifier of the user performing the deletion. This ID is recorded in the updated_by field, providing an audit trail for category modifications. Crucial for tracking administrative actions.

Output / Return Values

  • deletion_status (bool)

    Indicates whether the category was successfully marked as deleted. Returns True upon successful logical deletion and False if the category was not found. Essential for caller to confirm operation status.

Exceptions

  • Exception

    Raised if any unexpected error occurs during the deletion process. This ensures that database transactions are rolled back, preventing partial updates and maintaining data consistency. Crucial for system stability.

Logic / Execution Flow

  • Begin a try block to handle potential exceptions during the category deletion process.
  • Call CategoryService.get_category_by_id(db, category_id) to retrieve the Category object from the database using the provided category_id.
  • Check if the category object was found (i.e., if not category).
  • If category is None (not found):
    • Return False, indicating that the category could not be deleted because it does not exist.
  • If category is found:
    • Set the category.deleted_at field to the current UTC datetime using datetime.utcnow().
    • Set the category.updated_by field to the provided user_id.
    • Commit the database transaction using db.commit() to persist the changes.
    • Log an informational message indicating the successful deletion of the category, including its name.
    • Return True, indicating that the category was successfully logically deleted.
  • If any Exception occurs during the try block:
    • Enter the except Exception as e: block.
    • Roll back the database transaction using db.rollback() to undo any uncommitted changes.
    • Log an error message detailing the exception that occurred during the category deletion.
    • Re-raise the caught Exception to propagate the error further up the call stack.

Usage Tips

  • Always ensure the category_id and user_id are valid before calling this method. Invalid IDs can lead to unnecessary database lookups or incorrect audit trails. Validate inputs carefully.

  • Implement proper authorization checks before invoking this deletion method. Only users with appropriate permissions should be allowed to logically delete categories from the system. Secure access is paramount.

Additional Notes

  • This method performs a soft deletion, marking the record as deleted rather than removing it permanently. This preserves historical data and allows for potential recovery if needed. Consider data retention policies.

  • The datetime.utcnow() function is used for consistency across different time zones. Ensure all timestamp operations within the application use UTC for reliable data management and accurate historical tracking.

get_all_categories

public

Retrieves all active `Category` objects from the database, applying pagination. This method supports fetching categories that have not been soft-deleted. It is crucial for displaying available content classifications across the application.
=== " "

Activity Diagram - "get_all_categories" /app/services/service.pyActivity Diagram - "get_all_categories"  Inputs: db, skip, limitInitialize query for Category objectsApply filter for non-deleted categoriesApply offset for paginationApply limit for paginationExecute query and fetch all resultsreturn List of Category objects   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "get_all_categories" /app/services/service.pyActivity Diagram - "get_all_categories"  Inputs: db, skip, limitInitialize query for Category objectsApply filter for non-deleted categoriesApply offset for paginationApply limit for paginationExecute query and fetch all resultsreturn List of Category objects   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "get_all_categories" /app/services/service.pyMethod diagram - "get_all_categories"  get_all_categoriesdb.query.filter.offset.limit.all()db.query.filter.offset.limit()db.query.filter.offset()db.query.filter()db.query()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "get_all_categories" /app/services/service.pyMethod diagram - "get_all_categories"  get_all_categoriesdb.query.filter.offset.limit.all()db.query.filter.offset.limit()db.query.filter.offset()db.query.filter()db.query()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "get_all_categories" Sequence Diagram - "get_all_categories"  get_all_categoriesDatabaseSessionCallerget_all_categoriesDatabaseSessionCallerCallerget_all_categoriesget_all_categoriesDatabaseSessionDatabaseSessionget_all_categoriesDatabaseSessionFunction Callget_all_categories(db, skip, limit)Database Queryquery(Category)filter(Category.deleted_at == None)offset(skip)limit(limit)execute query and fetch all()list_of_categoriesFunction Returnlist_of_categories/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "get_all_categories" Sequence Diagram - "get_all_categories"  get_all_categoriesDatabaseSessionCallerget_all_categoriesDatabaseSessionCallerCallerget_all_categoriesget_all_categoriesDatabaseSessionDatabaseSessionget_all_categoriesDatabaseSessionFunction Callget_all_categories(db, skip, limit)Database Queryquery(Category)filter(Category.deleted_at == None)offset(skip)limit(limit)execute query and fetch all()list_of_categoriesFunction Returnlist_of_categories/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def get_all_categories(db: Session, skip: int = 0, limit: int = 100):

Input Parameters

  • db (Session)

    The SQLAlchemy database session object used for executing queries. Provides the necessary connection and transaction context to interact with the underlying database. Essential for data retrieval operations within the application's ORM layer.

  • skip (int)

    An integer representing the number of records to skip for pagination. This parameter allows fetching results starting from a specific offset, enabling efficient data retrieval in large datasets. Defaults to 0 for the first page.

  • limit (int)

    An integer specifying the maximum number of Category records to return. This parameter controls the size of the result set, preventing excessive data transfer and improving performance. Defaults to 100 for reasonable batch sizes.

Output / Return Values

  • categories (List[Category])

    A list of Category model instances representing active categories found in the database. Each object contains category-specific data. This collection is used for displaying, filtering, or further processing category information.

Logic / Execution Flow

  • Initiate a database query for the Category model.
  • Filter the Category objects where the deleted_at attribute is None, ensuring only active categories are retrieved.
  • Apply an offset to the query results based on the skip parameter value.
  • Apply a limit to the number of results returned based on the limit parameter value.
  • Execute the query and retrieve all matching Category objects as a list.

Usage Tips

  • Always use skip and limit parameters when fetching large datasets to prevent performance issues. Implement robust pagination logic in your frontend or API consumers to leverage these parameters effectively.

  • Consider caching frequently accessed category lists to reduce database load and improve response times. This method provides the base data, but caching layers can significantly enhance application scalability.

Additional Notes

  • This method explicitly filters out soft-deleted categories by checking deleted_at for None. If deleted categories are ever needed, a separate method or an additional parameter would be required.

  • The Category model is assumed to have a deleted_at field for soft deletion. Ensure this field is properly indexed in the database for optimal query performance, especially with large category tables.

get_category_by_id

public

This method retrieves a specific `Category` object from the database using its unique identifier. It ensures only active, non-deleted categories are returned. This function is crucial for fetching category details for display or further processing.
=== " "

Activity Diagram - "get_category_by_id" /app/services/service.pyActivity Diagram - "get_category_by_id"  Inputs: db, category_idQuery Category tableFilter by Category IDFilter by deleted_at is NoneRetrieve first matching categoryreturn Category object or None   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "get_category_by_id" /app/services/service.pyActivity Diagram - "get_category_by_id"  Inputs: db, category_idQuery Category tableFilter by Category IDFilter by deleted_at is NoneRetrieve first matching categoryreturn Category object or None   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "get_category_by_id" /app/services/service.pyMethod diagram - "get_category_by_id"  get_category_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "get_category_by_id" /app/services/service.pyMethod diagram - "get_category_by_id"  get_category_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "get_category_by_id" Sequence Diagram - "get_category_by_id"  get_category_by_idDatabaseSessionCallerget_category_by_idDatabaseSessionCallerCallerget_category_by_idget_category_by_idDatabaseSessionDatabaseSessionget_category_by_idDatabaseSessionFunction Callget_category_by_id(db, category_id)Database Queryquery(Category)Initiates a query for the Category modelfilter(Category.id == category_id, Category.deleted_at ==None)Applies filters for ID and non-deleted statusCategory_object_or_NoneFunction ReturnCategory_object_or_None/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "get_category_by_id" Sequence Diagram - "get_category_by_id"  get_category_by_idDatabaseSessionCallerget_category_by_idDatabaseSessionCallerCallerget_category_by_idget_category_by_idDatabaseSessionDatabaseSessionget_category_by_idDatabaseSessionFunction Callget_category_by_id(db, category_id)Database Queryquery(Category)Initiates a query for the Category modelfilter(Category.id == category_id, Category.deleted_at ==None)Applies filters for ID and non-deleted statusCategory_object_or_NoneFunction ReturnCategory_object_or_None/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def get_category_by_id(db: Session, category_id: int) -> Category:

Input Parameters

  • db (Session)

    The SQLAlchemy database session object used to execute queries. Provides the necessary connection and transaction context for interacting with the underlying database. Essential for data retrieval operations.

  • category_id (int)

    The unique integer identifier of the category to be retrieved. This id is used to precisely locate the desired category record within the database. Ensures accurate and specific data fetching.

Output / Return Values

  • category (Category)

    Returns the Category object matching the provided category_id if found and not deleted. If no such category exists, None is returned. Represents the requested category's data.

Logic / Execution Flow

  • Execute a database query to select Category objects.
  • Filter the Category objects where Category.id matches the provided category_id.
  • Further filter the results to include only categories where Category.deleted_at is None, indicating an active category.
  • Retrieve the first matching Category object from the filtered results.

Usage Tips

  • Always check the return value for None after calling this method, as it indicates a category was not found or is soft-deleted. Handle None gracefully to prevent AttributeError exceptions.

  • Utilise this method when you need to display category-specific content or validate relationships. It provides a direct and efficient way to access category data by its primary key.

Additional Notes

  • This method performs a soft-delete check by filtering deleted_at == None. If hard-deleted categories are ever needed, a different query or method would be required.

  • The first() method is used, which is efficient for retrieving a single record. For scenarios requiring multiple categories, consider using all() with appropriate filtering or pagination for better performance.

TagService

This class provides static methods for managing `Tag` entities within a database. It handles creation, retrieval, and soft deletion of tags, ensuring data integrity and logging operations. It integrates with a database session and `TagCreate` DTO.

Class diagram - "TagService" /app/services/service.pyClass diagram - "TagService"  TagServicecreate_tag()get_tag_by_id()get_all_tags()delete_tag()create_tagdb_tagTag()generate_slug()db.add()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()get_tag_by_iddb.query.filter.first()db.query.filter()db.query()and_()get_all_tagsdb.query.filter.offset.limit.all()db.query.filter.offset.limit()db.query.filter.offset()db.query.filter()db.query()delete_tagtagdeleted_atupdated_bydatetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()TagService.get_tag_by_id()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Class diagram - "TagService" /app/services/service.pyClass diagram - "TagService"  TagServicecreate_tag()get_tag_by_id()get_all_tags()delete_tag()create_tagdb_tagTag()generate_slug()db.add()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()get_tag_by_iddb.query.filter.first()db.query.filter()db.query()and_()get_all_tagsdb.query.filter.offset.limit.all()db.query.filter.offset.limit()db.query.filter.offset()db.query.filter()db.query()delete_tagtagdeleted_atupdated_bydatetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()TagService.get_tag_by_id()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Methods

create_tag

public

Creates a new `Tag` entry in the database with provided details. It generates a slug, assigns creation/update user, then persists the tag. This method ensures data integrity and proper logging for new tag entities.
=== " "

Activity Diagram - "create_tag" /app/services/service.pyActivity Diagram - "create_tag"  Inputs: db, tag_create, user_idTry Block: Attempt Tag CreationGenerate slug from tag_create.slugInstantiate Tag object with name, generated slug, added_by,updated_byAdd new Tag object to database sessionCommit database sessionRefresh Tag object from databaseLog successful tag creationreturn created Tag objectCatch Block: Handle ExceptionThis block is entered if an exception occurs in the Try BlockRollback database sessionLog error creating tagRe-raise caught exception   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "create_tag" /app/services/service.pyActivity Diagram - "create_tag"  Inputs: db, tag_create, user_idTry Block: Attempt Tag CreationGenerate slug from tag_create.slugInstantiate Tag object with name, generated slug, added_by,updated_byAdd new Tag object to database sessionCommit database sessionRefresh Tag object from databaseLog successful tag creationreturn created Tag objectCatch Block: Handle ExceptionThis block is entered if an exception occurs in the Try BlockRollback database sessionLog error creating tagRe-raise caught exception   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "create_tag" /app/services/service.pyMethod diagram - "create_tag"  create_tagdb_tagTag()generate_slug()db.add()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "create_tag" /app/services/service.pyMethod diagram - "create_tag"  create_tagdb_tagTag()generate_slug()db.add()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "create_tag" Sequence Diagram - "create_tag"  create_tagSessionSessionLoggerLoggerSlugGeneratorCallercreate_tagSessionTag ModelLoggerSlugGeneratorCallerCallercreate_tagcreate_tagSessionSessionTag ModelTag ModelLoggerLoggerSlugGeneratorSlugGeneratorcreate_tagSessionSessionLoggerLoggerSlugGeneratorFunction Callcreate_tag(db, tag_create, user_id)Try Blockgenerate_slug(tag_create.slug)generated_slugnew(name=tag_create.name, slug=generated_slug,added_by=user_id, updated_by=user_id)db_tagadd(db_tag)commit()refresh(db_tag)refreshed_db_taginfo(f"Tag created: {db_tag.name}")db_tagbreak[Exception as e]rollback()error(f"Error creating tag: {str(e)}")raise Exception/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "create_tag" Sequence Diagram - "create_tag"  create_tagSessionSessionLoggerLoggerSlugGeneratorCallercreate_tagSessionTag ModelLoggerSlugGeneratorCallerCallercreate_tagcreate_tagSessionSessionTag ModelTag ModelLoggerLoggerSlugGeneratorSlugGeneratorcreate_tagSessionSessionLoggerLoggerSlugGeneratorFunction Callcreate_tag(db, tag_create, user_id)Try Blockgenerate_slug(tag_create.slug)generated_slugnew(name=tag_create.name, slug=generated_slug,added_by=user_id, updated_by=user_id)db_tagadd(db_tag)commit()refresh(db_tag)refreshed_db_taginfo(f"Tag created: {db_tag.name}")db_tagbreak[Exception as e]rollback()error(f"Error creating tag: {str(e)}")raise Exception/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def create_tag(db: Session, tag_create: TagCreate, user_id: int) -> Tag:

Input Parameters

  • db (Session)

    The SQLAlchemy database session object used for database operations. This session manages the transaction and persistence of the new Tag entity within the application's data store.

  • tag_create (TagCreate)

    A Pydantic model containing the data for the new tag, including name and slug. This object provides the necessary attributes to construct the Tag database model instance for creation.

  • user_id (int)

    The integer ID of the user initiating the tag creation. This ID is recorded as added_by and updated_by to track authorship and modification history for the new Tag entry.

Output / Return Values

  • db_tag (Tag)

    The newly created and persisted Tag database model instance. This object includes all attributes, including any database-generated IDs, after successful commit. It represents the complete, stored tag.

Exceptions

  • Exception

    Raised for any unexpected errors occurring during the tag creation process. This generic exception ensures that database transactions are rolled back, preventing partial or corrupted data entries.

Logic / Execution Flow

  • Begin a try block to handle potential exceptions during tag creation.
  • Instantiate a Tag object:
    • Set name attribute from tag_create.name.
    • Generate slug using generate_slug function with tag_create.slug.
    • Set added_by attribute to user_id.
    • Set updated_by attribute to user_id.
  • Add the newly created db_tag object to the database session.
  • Commit the transaction to persist the db_tag in the database.
  • Refresh the db_tag object to load any database-generated attributes, such as its ID.
  • Log an informational message indicating successful tag creation, including the tag's name.
  • Return the db_tag object.
  • If any Exception occurs during the try block:
    • Enter the except block catching a generic Exception.
    • Rollback the database session to undo any uncommitted changes.
    • Log an error message detailing the failure to create the tag, including the exception string.
    • Re-raise the caught Exception to propagate the error further up the call stack.

Usage Tips

  • Ensure tag_create data is pre-validated before calling this method to prevent database constraint errors. Proper validation reduces unexpected exceptions and maintains data quality within the system effectively.

  • Always handle the re-raised Exception in the calling context to provide appropriate user feedback or retry mechanisms. This ensures robust error management and graceful degradation of application functionality.

Additional Notes

  • The generate_slug function is crucial for creating SEO-friendly and unique identifiers for tags. Its behavior regarding duplicate slugs or special characters should be well-understood for consistent tag management.

  • The db.rollback() ensures atomicity; if any part of the transaction fails, no partial data is committed. This is vital for maintaining database consistency, especially in concurrent environments.

delete_tag

public

This method logically deletes a specific tag by setting its `deleted_at` timestamp. It marks records as inactive, ensuring data integrity without permanent removal. This supports audit trails and potential recovery of deleted tags.
=== " "

Activity Diagram - "delete_tag" /app/services/service.pyActivity Diagram - "delete_tag"  Inputs: db, tag_id, user_idTry Block: Attempt Tag DeletionRetrieve tag by ID using TagServicetag not found?yesnoreturn FalseSet tag deleted_at timestamp to current UTCSet tag updated_by user IDCommit database transactionLog tag deletion successreturn TrueCatch Block: Handle ExceptionThis block is executed if any exception occurs during the operations in the Try Block.Rollback database transactionLog error detailsRe-raise caught exception   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "delete_tag" /app/services/service.pyActivity Diagram - "delete_tag"  Inputs: db, tag_id, user_idTry Block: Attempt Tag DeletionRetrieve tag by ID using TagServicetag not found?yesnoreturn FalseSet tag deleted_at timestamp to current UTCSet tag updated_by user IDCommit database transactionLog tag deletion successreturn TrueCatch Block: Handle ExceptionThis block is executed if any exception occurs during the operations in the Try Block.Rollback database transactionLog error detailsRe-raise caught exception   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "delete_tag" /app/services/service.pyMethod diagram - "delete_tag"  delete_tagtagdeleted_atupdated_bydatetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()TagService.get_tag_by_id()get_tag_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "delete_tag" /app/services/service.pyMethod diagram - "delete_tag"  delete_tagtagdeleted_atupdated_bydatetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()TagService.get_tag_by_id()get_tag_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

400. PlantUML 1.2026.1[From string (line 625) ] @startuml<style>root {--common-background: #f1f1f1;--note-background: #FEFFDD;...... ( skipping 599 lines )...deactivate logger    func --> caller: Truedeactivate funcendend group Exception Blockbreak Exception as efunc -> db: rollback()activate dbdb --> func: rollback_completedeactivate db    func -> logger: error(f"Error deleting tag: {str(e)}")activate loggerdeactivate logger    deactivate funcfunc -[#red]> [*]: raise ExceptionSyntax Error? (Assumed diagram type: sequence)
400. PlantUML 1.2026.1[From string (line 689) ] @startuml<style>root {FontName SansSerif  HyperLinkUnderlineThickness 1...... ( skipping 662 lines )...deactivate logger    func --> caller: Truedeactivate funcendend group Exception Blockbreak Exception as efunc -> db: rollback()activate dbdb --> func: rollback_completedeactivate db    func -> logger: error(f"Error deleting tag: {str(e)}")activate loggerdeactivate logger    deactivate funcfunc -[#red]> [*]: raise ExceptionSyntax Error? (Assumed diagram type: sequence)

Syntax

def delete_tag(db: Session, tag_id: int, user_id: int) -> bool:

Input Parameters

  • db (Session)

    This Session object provides the database connection and transaction management. It facilitates querying, updating, and committing changes to the underlying data store, ensuring data consistency and persistence for all database operations.

  • tag_id (int)

    The unique integer identifier for the tag intended for deletion. This tag_id is crucial for locating the specific Tag record within the database to apply the logical deletion flag effectively.

  • user_id (int)

    The unique integer identifier of the user performing the deletion. This user_id is recorded in the updated_by field, providing an audit trail of who initiated the logical deletion action.

Output / Return Values

  • deletion_status (bool)

    A boolean value indicating the success or failure of the tag deletion operation. Returns True if the tag was successfully marked as deleted, False if the tag was not found in the system.

Exceptions

  • Exception

    Raised for any unexpected errors during the tag deletion process. This generic exception ensures all unhandled issues are caught, logged, and re-raised, preventing silent failures and maintaining application stability.

Logic / Execution Flow

  • Begin a try block to handle potential exceptions during the tag deletion process.
  • Retrieve the Tag object from the database using TagService.get_tag_by_id() with the provided db session and tag_id.
  • Check if the tag object was found (i.e., tag is not None):
    • If tag is None (the tag was not found in the database):
      • Return False to indicate that the tag could not be deleted because it does not exist.
  • If the tag object exists:
    • Set the deleted_at attribute of the tag object to the current UTC timestamp using datetime.utcnow().
    • Set the updated_by attribute of the tag object to the provided user_id.
    • Commit the pending changes to the database using db.commit(), persisting the logical deletion.
    • Log an informational message indicating the successful deletion of the tag, including its name.
    • Return True to signify that the tag was successfully logically deleted.
  • If any Exception occurs during the try block:
    • Enter the except block, catching the Exception as e.
    • Rollback any pending database changes using db.rollback() to ensure data consistency.
    • Log an error message detailing the failure to delete the tag, including the exception string.
    • Re-raise the caught Exception to propagate the error further up the call stack.

Usage Tips

  • Always verify tag_id and user_id before calling this method to prevent unnecessary database lookups. Implement robust error handling in calling code to manage re-raised exceptions gracefully and inform users promptly.

Additional Notes

  • This method performs a logical deletion by updating a timestamp, not a physical removal from the database. This allows for data recovery and maintains historical integrity, but requires filtering logically deleted records in all queries.

get_all_tags

public

Retrieves a paginated list of all active `Tag` objects from the database. This method is crucial for displaying available tags across the application, supporting content categorization and discovery features effectively.
=== " "

Activity Diagram - "get_all_tags" /app/services/service.pyActivity Diagram - "get_all_tags"  Inputs: db, skip, limitQuery database for Tag objectsFilter tags where deleted_at is NULLApply offset for paginationApply limit for paginationRetrieve all matching Tag objectsreturn List of Tag objects   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "get_all_tags" /app/services/service.pyActivity Diagram - "get_all_tags"  Inputs: db, skip, limitQuery database for Tag objectsFilter tags where deleted_at is NULLApply offset for paginationApply limit for paginationRetrieve all matching Tag objectsreturn List of Tag objects   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "get_all_tags" /app/services/service.pyMethod diagram - "get_all_tags"  get_all_tagsdb.query.filter.offset.limit.all()db.query.filter.offset.limit()db.query.filter.offset()db.query.filter()db.query()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "get_all_tags" /app/services/service.pyMethod diagram - "get_all_tags"  get_all_tagsdb.query.filter.offset.limit.all()db.query.filter.offset.limit()db.query.filter.offset()db.query.filter()db.query()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "get_all_tags" Sequence Diagram - "get_all_tags"  get_all_tagsDatabaseSessionCallerget_all_tagsDatabaseSessionCallerCallerget_all_tagsget_all_tagsDatabaseSessionDatabaseSessionget_all_tagsDatabaseSessionFunction Callget_all_tags(db, skip, limit)Database Interactionquery(Tag)Initiates a query for the Tag modelfilter(Tag.deleted_at == None)Filters out soft-deleted tagsoffset(skip)Applies an offset for paginationlimit(limit)Applies a limit for paginationall()Executes the query and fetches all resultslist_of_tagsFunction Returnlist_of_tags/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "get_all_tags" Sequence Diagram - "get_all_tags"  get_all_tagsDatabaseSessionCallerget_all_tagsDatabaseSessionCallerCallerget_all_tagsget_all_tagsDatabaseSessionDatabaseSessionget_all_tagsDatabaseSessionFunction Callget_all_tags(db, skip, limit)Database Interactionquery(Tag)Initiates a query for the Tag modelfilter(Tag.deleted_at == None)Filters out soft-deleted tagsoffset(skip)Applies an offset for paginationlimit(limit)Applies a limit for paginationall()Executes the query and fetches all resultslist_of_tagsFunction Returnlist_of_tags/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def get_all_tags(db: Session, skip: int = 0, limit: int = 100):

Input Parameters

  • db (Session)

    The SQLAlchemy database session object used for executing queries. This session provides the necessary connection and transaction management to interact with the underlying database effectively.

  • skip (int)

    The number of Tag records to skip from the beginning of the query result. This parameter facilitates pagination, allowing retrieval of subsequent data pages efficiently for display purposes.

  • limit (int)

    The maximum number of Tag records to retrieve in a single query. This parameter controls the size of the result set, enabling efficient data fetching for paginated displays or batch processing.

Output / Return Values

  • tags (List[Tag])

    A list of Tag objects that are not marked as deleted. Each Tag object represents an active category or keyword, suitable for display or further processing within the application.

Logic / Execution Flow

  • Query the database for Tag objects using the provided db session.
  • Filter the Tag objects to include only those where the deleted_at field is None, ensuring only active tags are considered.
  • Apply an offset to the filtered query results based on the skip parameter, skipping a specified number of records.
  • Apply a limit to the offset results based on the limit parameter, restricting the number of records returned.
  • Execute the constructed query and retrieve all matching Tag objects as a list.

Usage Tips

  • Always use appropriate skip and limit values to prevent fetching excessive data, which can impact performance. Implement client-side pagination controls to leverage these parameters effectively.

Additional Notes

  • This method implicitly assumes Tag objects with a deleted_at timestamp are soft-deleted. Ensure consistent application of this soft-delete pattern across all tag management operations for data integrity.

get_tag_by_id

public

Retrieves a specific `Tag` object from the database using its unique identifier. This method ensures only active, non-deleted tags are returned. It is crucial for fetching tag details for display or association within the application.
=== " "

Activity Diagram - "get_tag_by_id" /app/services/service.pyActivity Diagram - "get_tag_by_id"  Inputs: db, tag_idQuery Tag model in databaseFilter by Tag.id == tag_idFilter by Tag.deleted_at is NoneRetrieve the first matching tagreturn Tag object or None   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "get_tag_by_id" /app/services/service.pyActivity Diagram - "get_tag_by_id"  Inputs: db, tag_idQuery Tag model in databaseFilter by Tag.id == tag_idFilter by Tag.deleted_at is NoneRetrieve the first matching tagreturn Tag object or None   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "get_tag_by_id" /app/services/service.pyMethod diagram - "get_tag_by_id"  get_tag_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "get_tag_by_id" /app/services/service.pyMethod diagram - "get_tag_by_id"  get_tag_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "get_tag_by_id" Sequence Diagram - "get_tag_by_id"  get_tag_by_idDatabase SessionCallerget_tag_by_idDatabase SessionCallerCallerget_tag_by_idget_tag_by_idDatabase SessionDatabase Sessionget_tag_by_idDatabase SessionRetrieve Tag by IDget_tag_by_id(db, tag_id)Initiates retrieval of a Tag object by its ID.query(Tag)Prepares a query for the Tag model.filter(Tag.id == tag_id, Tag.deleted_at == None)Applies conditions to find a specific Tag that is not deleted.first()Executes the query and retrieves the first matching Tag.Tag_object_or_NoneReturns the found Tag object or None if not found.Tag_object_or_NoneReturns the result to the original caller./app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "get_tag_by_id" Sequence Diagram - "get_tag_by_id"  get_tag_by_idDatabase SessionCallerget_tag_by_idDatabase SessionCallerCallerget_tag_by_idget_tag_by_idDatabase SessionDatabase Sessionget_tag_by_idDatabase SessionRetrieve Tag by IDget_tag_by_id(db, tag_id)Initiates retrieval of a Tag object by its ID.query(Tag)Prepares a query for the Tag model.filter(Tag.id == tag_id, Tag.deleted_at == None)Applies conditions to find a specific Tag that is not deleted.first()Executes the query and retrieves the first matching Tag.Tag_object_or_NoneReturns the found Tag object or None if not found.Tag_object_or_NoneReturns the result to the original caller./app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def get_tag_by_id(db: Session, tag_id: int) -> Tag:

Input Parameters

  • db (Session)

    The SQLAlchemy Session object used to interact with the database. Provides the necessary connection and transaction context for executing queries. Essential for data retrieval operations within the application's data layer.

  • tag_id (int)

    The unique integer identifier of the Tag to be retrieved. This id parameter is used to precisely locate the desired tag record in the database. Ensures accurate and specific data fetching.

Output / Return Values

  • tag_object (Tag)

    Returns the Tag object matching the provided tag_id if found and not deleted. If no such tag exists or it is marked as deleted, None is returned. Represents the requested tag's data.

Logic / Execution Flow

  • Initiate a database query on the Tag model using the provided db session.
  • Apply a filter to select Tag records where the id column matches the tag_id parameter.
  • Further apply a filter to ensure that the deleted_at column of the Tag record is None, indicating it is not soft-deleted.
  • Execute the query and retrieve the first matching Tag object found, or None if no such record exists.

Usage Tips

  • Always check the return value for None after calling get_tag_by_id() to handle cases where the tag does not exist or is soft-deleted. This prevents AttributeError when accessing tag properties.

  • Utilize this method when you need to fetch a single, specific tag by its identifier for operations like displaying tag details or associating it with other entities.

Additional Notes

  • This method performs a soft-delete check, meaning it will not return tags that have a value in their deleted_at field. This ensures data consistency and integrity across the application.

  • The first() method efficiently retrieves only one record, optimising database performance for single-item lookups. Consider using all() if multiple tags matching criteria were expected, though not applicable here.

PostService

PostService provides comprehensive static methods for managing blog posts within the application. It handles creation, retrieval, updating, and soft deletion of `Post` entities, ensuring data integrity and efficient database interactions for content management operations.

Class diagram - "PostService" /app/services/service.pyClass diagram - "PostService"  PostServicecreate_post()get_post_by_id()get_post_by_slug()get_all_posts()search_posts()get_user_posts()update_post()delete_post()increment_view_count()create_postdb_posttagsPost()generate_slug()db.query.filter.all()db.query.filter()db.query()Tag.id.in_()db.add()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()get_post_by_iddb.query.filter.first()db.query.filter()db.query()and_()get_post_by_slugdb.query.filter.first()db.query.filter()db.query()and_()get_all_postsquerydb.query.filter()db.query()query.filter()query.join.filter()query.join()query.order_by.offset.limit.all()query.order_by.offset.limit()query.order_by.offset()query.order_by()Post.date_added.desc()search_postsdb.query.filter.order_by.offset.limit.all()db.query.filter.order_by.offset.limit()db.query.filter.order_by.offset()db.query.filter.order_by()db.query.filter()db.query()and_()or_()Post.title.ilike()Post.content.ilike()Post.excerpt.ilike()Post.date_added.desc()get_user_postsdb.query.filter.order_by.offset.limit.all()db.query.filter.order_by.offset.limit()db.query.filter.order_by.offset()db.query.filter.order_by()db.query.filter()db.query()and_()Post.date_added.desc()update_postdb_posttitleslugcontentexcerptcategory_idis_publishedfeatured_image_urltagsupdated_bydate_updatedgenerate_slug()db.query.filter.all()db.query.filter()db.query()Tag.id.in_()datetime.utcnow()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()PostService.get_post_by_id()delete_postdb_postdeleted_atupdated_bydatetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()PostService.get_post_by_id()increment_view_countdb_postdb.commit()logger.error()str()PostService.get_post_by_id()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Class diagram - "PostService" /app/services/service.pyClass diagram - "PostService"  PostServicecreate_post()get_post_by_id()get_post_by_slug()get_all_posts()search_posts()get_user_posts()update_post()delete_post()increment_view_count()create_postdb_posttagsPost()generate_slug()db.query.filter.all()db.query.filter()db.query()Tag.id.in_()db.add()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()get_post_by_iddb.query.filter.first()db.query.filter()db.query()and_()get_post_by_slugdb.query.filter.first()db.query.filter()db.query()and_()get_all_postsquerydb.query.filter()db.query()query.filter()query.join.filter()query.join()query.order_by.offset.limit.all()query.order_by.offset.limit()query.order_by.offset()query.order_by()Post.date_added.desc()search_postsdb.query.filter.order_by.offset.limit.all()db.query.filter.order_by.offset.limit()db.query.filter.order_by.offset()db.query.filter.order_by()db.query.filter()db.query()and_()or_()Post.title.ilike()Post.content.ilike()Post.excerpt.ilike()Post.date_added.desc()get_user_postsdb.query.filter.order_by.offset.limit.all()db.query.filter.order_by.offset.limit()db.query.filter.order_by.offset()db.query.filter.order_by()db.query.filter()db.query()and_()Post.date_added.desc()update_postdb_posttitleslugcontentexcerptcategory_idis_publishedfeatured_image_urltagsupdated_bydate_updatedgenerate_slug()db.query.filter.all()db.query.filter()db.query()Tag.id.in_()datetime.utcnow()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()PostService.get_post_by_id()delete_postdb_postdeleted_atupdated_bydatetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()PostService.get_post_by_id()increment_view_countdb_postdb.commit()logger.error()str()PostService.get_post_by_id()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Methods

create_post

public

This method creates a new `Post` entry in the database, associating it with a specific user and optional tags. It handles data persistence, slug generation, and error logging for robust content management operations within the application.
=== " "

Activity Diagram - "create_post" /app/services/service.pyActivity Diagram - "create_post"  Inputs: db, post_create, user_idTry Block: Create and Save PostCreate new Post objectGenerate slug from post_create.slugAssign title, content, excerpt, category_id, is_published,featured_image_urlSet author_id, added_by, updated_by to user_idNo tag IDs provided, skip tag assignmentQuery Tag objects by IDsAssign retrieved tags to db_postyespost_create has tag_ids?noAdd db_post to database sessionCommit changes to databaseRefresh db_post from databaseLog post creation successreturn Created Post objectCatch Block: Handle ExceptionAn exception occurred during post creationRollback database transactionLog error detailsRe-raise the caught exceptionFinally Block: No explicit finally in codeNo explicit finally block defined in the code   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "create_post" /app/services/service.pyActivity Diagram - "create_post"  Inputs: db, post_create, user_idTry Block: Create and Save PostCreate new Post objectGenerate slug from post_create.slugAssign title, content, excerpt, category_id, is_published,featured_image_urlSet author_id, added_by, updated_by to user_idNo tag IDs provided, skip tag assignmentQuery Tag objects by IDsAssign retrieved tags to db_postyespost_create has tag_ids?noAdd db_post to database sessionCommit changes to databaseRefresh db_post from databaseLog post creation successreturn Created Post objectCatch Block: Handle ExceptionAn exception occurred during post creationRollback database transactionLog error detailsRe-raise the caught exceptionFinally Block: No explicit finally in codeNo explicit finally block defined in the code   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "create_post" /app/services/service.pyMethod diagram - "create_post"  create_postdb_posttagsPost()generate_slug()db.query.filter.all()db.query.filter()db.query()Tag.id.in_()db.add()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "create_post" /app/services/service.pyMethod diagram - "create_post"  create_postdb_posttagsPost()generate_slug()db.query.filter.all()db.query.filter()db.query()Tag.id.in_()db.add()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "create_post" Sequence Diagram - "create_post"  create_postDatabaseSessionDatabaseSessionDatabaseSessionDatabaseSessionDatabaseSessionSlugGeneratorLoggerLoggerCallercreate_postDatabaseSessionPostModelTagModelSlugGeneratorLoggerCallerCallercreate_postcreate_postDatabaseSessionDatabaseSessionPostModelPostModelTagModelTagModelSlugGeneratorSlugGeneratorLoggerLoggercreate_postDatabaseSessionDatabaseSessionDatabaseSessionDatabaseSessionDatabaseSessionSlugGeneratorLoggerLoggerMethod Callcreate_post(db, post_create, user_id)Try BlockPost Object Instantiationgenerate_slug(post_create.slug)generated_slugnew Post(title, generated_slug, content, ...)Instantiate Post object with provided data and generatedslugOptional Tag Assignmentalt[post_create.tag_ids is not empty]query(TagModel).filter(TagModel.id.in_(post_create.tag_ids)).all()filter by IDsmatching_tagstags_listassign tags to db_postDatabase Persistenceadd(db_post)post_added_to_sessioncommit()transaction_committedrefresh(db_post)refreshed_post_dataSuccess Logginginfo(f"Post created: {db_post.title}")log_recordedReturn Valuedb_postException Handlingbreak[Exception as e]rollback()rollback_completeerror(f"Error creating post: {str(e)}")error_loggedre-raise exception/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "create_post" Sequence Diagram - "create_post"  create_postDatabaseSessionDatabaseSessionDatabaseSessionDatabaseSessionDatabaseSessionSlugGeneratorLoggerLoggerCallercreate_postDatabaseSessionPostModelTagModelSlugGeneratorLoggerCallerCallercreate_postcreate_postDatabaseSessionDatabaseSessionPostModelPostModelTagModelTagModelSlugGeneratorSlugGeneratorLoggerLoggercreate_postDatabaseSessionDatabaseSessionDatabaseSessionDatabaseSessionDatabaseSessionSlugGeneratorLoggerLoggerMethod Callcreate_post(db, post_create, user_id)Try BlockPost Object Instantiationgenerate_slug(post_create.slug)generated_slugnew Post(title, generated_slug, content, ...)Instantiate Post object with provided data and generatedslugOptional Tag Assignmentalt[post_create.tag_ids is not empty]query(TagModel).filter(TagModel.id.in_(post_create.tag_ids)).all()filter by IDsmatching_tagstags_listassign tags to db_postDatabase Persistenceadd(db_post)post_added_to_sessioncommit()transaction_committedrefresh(db_post)refreshed_post_dataSuccess Logginginfo(f"Post created: {db_post.title}")log_recordedReturn Valuedb_postException Handlingbreak[Exception as e]rollback()rollback_completeerror(f"Error creating post: {str(e)}")error_loggedre-raise exception/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def create_post(db: Session, post_create: PostCreate, user_id: int) -> Post:

Input Parameters

  • db (Session)

    The SQLAlchemy database session instance used for all database operations. This session manages the transaction, allowing for adding, committing, and rolling back changes to ensure data integrity during post creation.

  • post_create (PostCreate)

    A Pydantic schema object containing the data for the new post, including title, content, category_id, and optional tag_ids. This object ensures structured and validated input for post creation.

  • user_id (int)

    The integer ID of the user who is authoring and adding this post. This user_id is used to establish the author_id and added_by/updated_by relationships for the new Post object.

Output / Return Values

  • db_post (Post)

    The newly created and persisted Post object, including its generated id and all associated data. This object represents the complete and saved post record from the database after successful creation.

Exceptions

  • Exception

    Raised for any unhandled error occurring during the post creation process, including database transaction failures or issues with tag association. The transaction is rolled back to maintain data consistency.

Logic / Execution Flow

  • Begin a try block to handle potential exceptions during the post creation process.
  • Instantiate a new Post object, db_post, populating its fields from the post_create data and the provided user_id.
  • Generate a URL-friendly slug from post_create.slug using the generate_slug() helper function for the new post.
  • Assign the user_id to the author_id, added_by, and updated_by fields of the newly created db_post.
  • Check if the post_create.tag_ids list is provided and contains any tag identifiers.
    • If tag_ids are present:
      • Query the database for Tag objects whose ids match those in post_create.tag_ids.
      • Assign the retrieved Tag objects to the tags relationship of the db_post object.
  • Add the newly constructed db_post object to the SQLAlchemy database session.
  • Commit the current transaction to persist the db_post and its associated tags to the database.
  • Refresh the db_post object to load any database-generated attributes, such as its primary key id.
  • Log an informational message using logger.info indicating the successful creation of the post, including its title.
  • Return the fully populated and refreshed db_post object, representing the newly created database record.
  • If any Exception occurs during the try block execution:
    • Enter the except block to handle the encountered error.
    • Rollback the database session to discard any uncommitted changes and maintain data integrity.
    • Log an error message using logger.error detailing the exception that occurred during post creation.
    • Re-raise the caught Exception to propagate the error further up the call stack for higher-level handling.

Usage Tips

  • Ensure post_create data is thoroughly validated before calling this method to prevent database integrity issues. Pre-validation reduces unexpected errors and improves data quality for all new Post entries.

  • Always handle the re-raised Exception in the calling context to provide appropriate user feedback or retry mechanisms. This ensures robust error management and graceful degradation for post creation failures.

Additional Notes

  • The generate_slug() function is crucial for SEO-friendly URLs, ensuring unique and readable identifiers for each post. Its proper functioning is vital for content discoverability and user experience.

  • The db.rollback() call within the exception block is essential for transactional integrity, preventing partial data writes. This guarantees that either the entire post creation succeeds or completely fails.

delete_post

public

This method logically deletes a specific post by setting its `deleted_at` timestamp. It ensures data integrity by marking the post as deleted rather than physically removing it. This approach supports audit trails and potential recovery mechanisms effectively.
=== " "

Activity Diagram - "delete_post" /app/services/service.pyActivity Diagram - "delete_post"  Inputs: db, post_id, user_idInitialize _function_returned = falseInitialize _return_value = nullTry Block: Attempt Post DeletionCall PostService.get_post_by_id(db, post_id)If an exception occurs, control transfers to the catch block.db_post is None?yesnoSet _return_value = FalseSet _function_returned = trueSet db_post.deleted_at = datetime.utcnow()Set db_post.updated_by = user_idCall db.commit()Log info: "Post deleted: {db_post.title}"Set _return_value = TrueSet _function_returned = truereturn _return_valueyes_function_returned is true?noCatch Block: Handle ExceptionExecuted if an exception occurred in the try block.Call db.rollback()Log error: "Error deleting post: {str(e)}"Raise exceptionFinally Block: No Explicit FinallyThis final 'stop' is technically unreachable in this code flow.   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "delete_post" /app/services/service.pyActivity Diagram - "delete_post"  Inputs: db, post_id, user_idInitialize _function_returned = falseInitialize _return_value = nullTry Block: Attempt Post DeletionCall PostService.get_post_by_id(db, post_id)If an exception occurs, control transfers to the catch block.db_post is None?yesnoSet _return_value = FalseSet _function_returned = trueSet db_post.deleted_at = datetime.utcnow()Set db_post.updated_by = user_idCall db.commit()Log info: "Post deleted: {db_post.title}"Set _return_value = TrueSet _function_returned = truereturn _return_valueyes_function_returned is true?noCatch Block: Handle ExceptionExecuted if an exception occurred in the try block.Call db.rollback()Log error: "Error deleting post: {str(e)}"Raise exceptionFinally Block: No Explicit FinallyThis final 'stop' is technically unreachable in this code flow.   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "delete_post" /app/services/service.pyMethod diagram - "delete_post"  delete_postdb_postdeleted_atupdated_bydatetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()PostService.get_post_by_id()get_post_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "delete_post" /app/services/service.pyMethod diagram - "delete_post"  delete_postdb_postdeleted_atupdated_bydatetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()PostService.get_post_by_id()get_post_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "delete_post" Sequence Diagram - "delete_post"  PostServicePostServiceDatabaseSessionDatabaseSessionDatabaseSessionLoggerLoggerCallerPostServiceDatabaseSessionLoggerCallerCallerPostServicePostServiceDatabaseSessionDatabaseSessionLoggerLoggerPostServicePostServiceDatabaseSessionDatabaseSessionDatabaseSessionLoggerLoggerMethod Calldelete_post(db, post_id, user_id)Try Blockget_post_by_id(db, post_id)query_post_by_id(post_id)post_recorddb_post_objectdb_post is Nonealt[Post not found]False[Post found]update db_post.deleted_at with current UTC timeupdate db_post.updated_by with user_idcommit()commit_successinfo(f"Post deleted: {db_post.title}")log_ackTruebreak[Exception as e]rollback()rollback_successerror(f"Error deleting post: {str(e)}")log_ackraise Exception/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "delete_post" Sequence Diagram - "delete_post"  PostServicePostServiceDatabaseSessionDatabaseSessionDatabaseSessionLoggerLoggerCallerPostServiceDatabaseSessionLoggerCallerCallerPostServicePostServiceDatabaseSessionDatabaseSessionLoggerLoggerPostServicePostServiceDatabaseSessionDatabaseSessionDatabaseSessionLoggerLoggerMethod Calldelete_post(db, post_id, user_id)Try Blockget_post_by_id(db, post_id)query_post_by_id(post_id)post_recorddb_post_objectdb_post is Nonealt[Post not found]False[Post found]update db_post.deleted_at with current UTC timeupdate db_post.updated_by with user_idcommit()commit_successinfo(f"Post deleted: {db_post.title}")log_ackTruebreak[Exception as e]rollback()rollback_successerror(f"Error deleting post: {str(e)}")log_ackraise Exception/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def delete_post(db: Session, post_id: int, user_id: int) -> bool:

Input Parameters

  • db (Session)

    The SQLAlchemy database session object used for database operations. It provides the connection and transaction management for interacting with the database. This session is crucial for fetching and updating the Post record.

  • post_id (int)

    The unique identifier of the post to be logically deleted. This integer value precisely targets the specific Post entry within the database for modification. It ensures the correct post is processed.

  • user_id (int)

    The unique identifier of the user performing the deletion. This user_id is recorded in the updated_by field, providing an audit trail of who initiated the logical deletion. It tracks accountability.

Output / Return Values

  • deletion_status (bool)

    A boolean indicating whether the post was successfully marked as deleted. Returns True if the post was found and updated, False if the post was not found. This status informs the caller of the operation's outcome.

Exceptions

  • Exception

    Raised if any unexpected error occurs during the post deletion process. This generic exception ensures that all unhandled issues are caught, the database transaction is rolled back, and the error is propagated.

Logic / Execution Flow

  • Begin a try block to handle potential exceptions during the deletion process.
  • Attempt to retrieve the Post object from the database using PostService.get_post_by_id with the provided db session and post_id.
  • Check if db_post (the retrieved post) is None:
    • If db_post is None (post not found):
      • Return False to indicate that the post could not be deleted because it does not exist.
  • If db_post is found:
    • Set the deleted_at attribute of db_post to the current UTC datetime using datetime.utcnow().
    • Set the updated_by attribute of db_post to the provided user_id.
    • Commit the changes to the database session db to persist the logical deletion.
    • Log an informational message indicating successful post deletion, including the post's title.
    • Return True to indicate that the post was successfully marked as deleted.
  • If any Exception occurs during the try block:
    • Enter the except block, catching the Exception as e.
    • Rollback the database session db to undo any uncommitted changes.
    • Log an error message indicating the failure to delete the post, including the exception string.
    • Re-raise the caught Exception to propagate the error further up the call stack.

Usage Tips

  • Always verify the post_id and user_id before calling this method to prevent unnecessary database lookups. Implement robust authorization checks to ensure only authorized users can initiate post deletions.

Additional Notes

  • This method performs a soft delete, preserving the post record for auditing or potential restoration. Consider implementing a separate hard delete mechanism for permanent data removal, if required by data retention policies.

get_all_posts

public

This method retrieves a paginated list of `Post` objects from the database. It allows filtering by category, tag, and publication status. This function is crucial for displaying blog posts on various pages, supporting content categorisation and user browsing experiences effectively.
=== " "

Activity Diagram - "get_all_posts" /app/services/service.pyActivity Diagram - "get_all_posts"  Inputs: db, skip, limit, category_id, tag_id, published_onlyInitialize query with all posts not deletedSkip published filterAdd filter for published postsyespublished_only is true?noSkip category filterAdd filter by category IDyescategory_id is provided?noSkip tag filterJoin with tags and filter by tag IDyestag_id is provided?noOrder results by date added descendingApply offset and limit for paginationExecute query and fetch all resultsreturn List of Post objects   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "get_all_posts" /app/services/service.pyActivity Diagram - "get_all_posts"  Inputs: db, skip, limit, category_id, tag_id, published_onlyInitialize query with all posts not deletedSkip published filterAdd filter for published postsyespublished_only is true?noSkip category filterAdd filter by category IDyescategory_id is provided?noSkip tag filterJoin with tags and filter by tag IDyestag_id is provided?noOrder results by date added descendingApply offset and limit for paginationExecute query and fetch all resultsreturn List of Post objects   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "get_all_posts" /app/services/service.pyMethod diagram - "get_all_posts"  get_all_postsquerydb.query.filter()db.query()query.filter()query.join.filter()query.join()query.order_by.offset.limit.all()query.order_by.offset.limit()query.order_by.offset()query.order_by()Post.date_added.desc()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "get_all_posts" /app/services/service.pyMethod diagram - "get_all_posts"  get_all_postsquerydb.query.filter()db.query()query.filter()query.join.filter()query.join()query.order_by.offset.limit.all()query.order_by.offset.limit()query.order_by.offset()query.order_by()Post.date_added.desc()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "get_all_posts" Sequence Diagram - "get_all_posts"  get_all_postsDatabaseSessionDatabaseSessionCallerget_all_postsDatabaseSessionCallerCallerget_all_postsget_all_postsDatabaseSessionDatabaseSessionget_all_postsDatabaseSessionDatabaseSessionMethod Callget_all_posts(db, skip, limit, category_id, tag_id,published_only)Query Initializationquery(Post)Initializes ORM query builder with Post modelquery_objectApply filter: Post.deleted_at == NoneExcludes soft-deleted posts from resultsConditional Filteringalt[published_only is True]Apply filter: Post.is_published == TrueFilters for posts explicitly marked as publishedalt[category_id is not None]Apply filter: Post.category_id == category_idFilters posts by a specific category IDalt[tag_id is not None]Apply join(Post.tags)Apply filter: Tag.id == tag_idJoins with Tag model and filters by a specific tag IDQuery Ordering and PaginationApply order_by(Post.date_added.desc())Apply offset(skip)Apply limit(limit)Query Executionexecute_query.all()Executes the constructed query against the databaselist_of_postsMethod Returnlist_of_posts/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "get_all_posts" Sequence Diagram - "get_all_posts"  get_all_postsDatabaseSessionDatabaseSessionCallerget_all_postsDatabaseSessionCallerCallerget_all_postsget_all_postsDatabaseSessionDatabaseSessionget_all_postsDatabaseSessionDatabaseSessionMethod Callget_all_posts(db, skip, limit, category_id, tag_id,published_only)Query Initializationquery(Post)Initializes ORM query builder with Post modelquery_objectApply filter: Post.deleted_at == NoneExcludes soft-deleted posts from resultsConditional Filteringalt[published_only is True]Apply filter: Post.is_published == TrueFilters for posts explicitly marked as publishedalt[category_id is not None]Apply filter: Post.category_id == category_idFilters posts by a specific category IDalt[tag_id is not None]Apply join(Post.tags)Apply filter: Tag.id == tag_idJoins with Tag model and filters by a specific tag IDQuery Ordering and PaginationApply order_by(Post.date_added.desc())Apply offset(skip)Apply limit(limit)Query Executionexecute_query.all()Executes the constructed query against the databaselist_of_postsMethod Returnlist_of_posts/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def get_all_posts(db: Session, skip: int = 0, limit: int = 10, category_id: int = None, tag_id: int = None, published_only: bool = True):

Input Parameters

  • db (Session)

    The SQLAlchemy database Session instance used for executing queries. This session manages the database connection and transaction state, ensuring data consistency and proper resource handling for all operations.

  • skip (int)

    The number of records to skip from the beginning of the query result set. This parameter facilitates pagination, allowing retrieval of subsequent data pages efficiently. Defaulting to 0 ensures the first page is returned.

  • limit (int)

    The maximum number of Post records to return in a single query. This parameter controls the size of each paginated result set, preventing excessive data transfer and improving application performance. Defaulting to 10 provides a reasonable page size.

  • category_id (int)

    An optional integer ID to filter posts belonging to a specific category. When provided, only posts associated with this category_id will be included in the results, enabling category-specific content display.

  • tag_id (int)

    An optional integer ID to filter posts associated with a particular tag. If supplied, the query will join with the Tag model to include only posts linked to this tag_id, supporting tag-based content filtering.

  • published_only (bool)

    A boolean flag indicating whether to retrieve only published posts. When True, only posts marked as is_published will be returned, ensuring only public content is displayed by default.

Output / Return Values

  • posts (List[Post])

    A list of Post objects matching the specified filtering and pagination criteria. Each Post object represents a blog entry with its associated data, ready for display or further processing within the application.

Logic / Execution Flow

  • Initialize a database query for Post objects using the provided db session.
  • Filter the initial query to include only posts where Post.deleted_at is None, ensuring only active posts are considered.
  • Check if published_only is True:
    • If True, further filter the query to include only posts where Post.is_published is True.
  • Check if category_id is provided (not None):
    • If category_id exists, filter the query to include posts where Post.category_id matches the provided category_id.
  • Check if tag_id is provided (not None):
    • If tag_id exists, perform an inner join with Post.tags and filter to include posts where Tag.id matches the provided tag_id.
  • Order the filtered query results by Post.date_added in descending order, ensuring the most recent posts appear first.
  • Apply pagination by offsetting the results by skip records.
  • Limit the number of returned results to limit records.
  • Execute the constructed query and retrieve all matching Post objects as a list.

Usage Tips

  • Utilise skip and limit parameters for efficient pagination when displaying large numbers of posts. This prevents loading all records into memory, significantly improving performance and user experience for content browsing.

  • Combine category_id and tag_id filters to create highly specific content views. This allows users to narrow down their search results effectively, enhancing content discoverability and relevance within the application.

Additional Notes

  • The published_only filter defaults to True, meaning unpublished posts are excluded unless explicitly set to False. Remember to adjust this parameter when retrieving posts for administrative or draft viewing purposes.

  • Filtering by tag_id involves a database join operation, which might have performance implications for very large datasets. Consider optimising database indexes on Post.tags and Tag.id for improved query speed.

get_post_by_id

public

Retrieves a single `Post` object from the database using its unique identifier. This method ensures only active, non-deleted posts are returned. It is crucial for fetching specific post details for display or further processing.
=== " "

Activity Diagram - "get_post_by_id" /app/services/service.pyActivity Diagram - "get_post_by_id"  Inputs: db, post_idConstruct database query for Post modelApply filter: Post ID matches provided post_idApply filter: Post is not deleted (deleted_at is NULL)Execute query and retrieve the first matching postreturn Found Post object or None   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "get_post_by_id" /app/services/service.pyActivity Diagram - "get_post_by_id"  Inputs: db, post_idConstruct database query for Post modelApply filter: Post ID matches provided post_idApply filter: Post is not deleted (deleted_at is NULL)Execute query and retrieve the first matching postreturn Found Post object or None   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "get_post_by_id" /app/services/service.pyMethod diagram - "get_post_by_id"  get_post_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "get_post_by_id" /app/services/service.pyMethod diagram - "get_post_by_id"  get_post_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "get_post_by_id" Sequence Diagram - "get_post_by_id"  get_post_by_idDatabase SessionCallerget_post_by_idDatabase SessionCallerCallerget_post_by_idget_post_by_idDatabase SessionDatabase Sessionget_post_by_idDatabase SessionFunction Callget_post_by_id(db, post_id)Database Query Construction and Executionquery(Post)Initiates a query for Post objectsfilter(Post.id == post_id, Post.deleted_at == None)Applies filtering conditions to the queryfirst()Executes the constructed query and retrieves the firstmatching resultPost object or NoneFunction ReturnPost object or None/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "get_post_by_id" Sequence Diagram - "get_post_by_id"  get_post_by_idDatabase SessionCallerget_post_by_idDatabase SessionCallerCallerget_post_by_idget_post_by_idDatabase SessionDatabase Sessionget_post_by_idDatabase SessionFunction Callget_post_by_id(db, post_id)Database Query Construction and Executionquery(Post)Initiates a query for Post objectsfilter(Post.id == post_id, Post.deleted_at == None)Applies filtering conditions to the queryfirst()Executes the constructed query and retrieves the firstmatching resultPost object or NoneFunction ReturnPost object or None/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def get_post_by_id(db: Session, post_id: int) -> Post:

Input Parameters

  • db (Session)

    The SQLAlchemy database session object used to interact with the database. This session facilitates querying and retrieving Post entities, ensuring proper transaction management and connection handling for data operations.

  • post_id (int)

    The unique integer identifier of the Post to be retrieved from the database. This id is essential for precisely locating the desired post record, ensuring accurate and efficient data fetching.

Output / Return Values

  • post (Post)

    The Post object matching the provided post_id and not marked as deleted. Returns None if no such post is found in the database. This object contains all relevant post data.

Logic / Execution Flow

  • Initiate a database query targeting the Post model.
  • Apply a filter to select Post records where the Post.id column matches the provided post_id.
  • Further apply a filter to ensure the Post.deleted_at column is None, indicating the post is not soft-deleted.
  • Execute the query and retrieve the first matching Post object found, or None if no such post exists.

Usage Tips

  • Always ensure the post_id provided is valid and corresponds to an existing post. This method implicitly handles soft-deleted posts, returning None for them, so check the return value carefully.

  • Integrate this method into API endpoints or service layers requiring specific post data. It provides a robust way to fetch individual posts while respecting deletion status, simplifying data retrieval logic significantly.

Additional Notes

  • This method performs a combined filter on id and deleted_at for efficiency. For performance-critical applications, consider adding an index on deleted_at if not already present, alongside the primary key.

  • The Post object returned is an ORM instance. Accessing its attributes might trigger lazy loading of relationships, potentially leading to N+1 query issues if not handled with joinedload or selectinload in broader contexts.

get_post_by_slug

public

Retrieves a single `Post` object from the database using its unique slug. This method ensures only non-deleted posts are returned, facilitating content display and management across the application's public interfaces.
=== " "

Activity Diagram - "get_post_by_slug" /app/services/service.pyActivity Diagram - "get_post_by_slug"  Inputs: db, slugQuery Post modelFilter by slug and where deleted_at is NoneRetrieve the first matching Postreturn Found Post object or None   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "get_post_by_slug" /app/services/service.pyActivity Diagram - "get_post_by_slug"  Inputs: db, slugQuery Post modelFilter by slug and where deleted_at is NoneRetrieve the first matching Postreturn Found Post object or None   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "get_post_by_slug" /app/services/service.pyMethod diagram - "get_post_by_slug"  get_post_by_slugdb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "get_post_by_slug" /app/services/service.pyMethod diagram - "get_post_by_slug"  get_post_by_slugdb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "get_post_by_slug" Sequence Diagram - "get_post_by_slug"  get_post_by_slugDatabaseSessionCallerget_post_by_slugDatabaseSessionCallerCallerget_post_by_slugget_post_by_slugDatabaseSessionDatabaseSessionget_post_by_slugDatabaseSessionMethod Callget_post_by_slug(db, slug)Database Queryquery(Post)Initiates a query for the Post modelfilter(Post.slug == slug AND Post.deleted_at == None)Applies conditions: slug matches and deleted_at is Nonefirst()Executes the query and fetches the first matching recordPost object | NoneReturn ResultPost object | None/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "get_post_by_slug" Sequence Diagram - "get_post_by_slug"  get_post_by_slugDatabaseSessionCallerget_post_by_slugDatabaseSessionCallerCallerget_post_by_slugget_post_by_slugDatabaseSessionDatabaseSessionget_post_by_slugDatabaseSessionMethod Callget_post_by_slug(db, slug)Database Queryquery(Post)Initiates a query for the Post modelfilter(Post.slug == slug AND Post.deleted_at == None)Applies conditions: slug matches and deleted_at is Nonefirst()Executes the query and fetches the first matching recordPost object | NoneReturn ResultPost object | None/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def get_post_by_slug(db: Session, slug: str) -> Post:

Input Parameters

  • db (Session)

    The SQLAlchemy database session instance used for executing queries. This session provides the necessary connection and transaction management to interact with the underlying database effectively.

  • slug (str)

    The unique string identifier for the Post to be retrieved. This slug is typically a URL-friendly version of the post's title, ensuring direct access to specific content.

Output / Return Values

  • post (Post)

    The Post object matching the provided slug and not marked as deleted. Returns None if no such post is found, indicating the content is unavailable or does not exist.

Logic / Execution Flow

  • Query the database for Post objects.
  • Filter the Post objects by two conditions:
    • The slug attribute of the Post must match the provided slug parameter.
    • The deleted_at attribute of the Post must be None, ensuring only active posts are considered.
  • Retrieve the first Post object that satisfies both filtering conditions.
  • Return the found Post object, or None if no matching post exists.

Usage Tips

  • Always ensure slug values are unique and properly indexed in your database for optimal query performance. This method relies on slug for efficient retrieval, making indexing crucial for large datasets.

Additional Notes

  • This method implicitly handles soft-deleted posts by filtering deleted_at == None. If you need to retrieve deleted posts, a separate method or modified query would be necessary to bypass this specific condition.

get_user_posts

public

Retrieves a paginated list of posts authored by a specific user, excluding soft-deleted entries. This method efficiently queries the database, filtering by author ID and active status, then orders results for consistent display across the application.
=== " "

Activity Diagram - "get_user_posts" /app/services/service.pyActivity Diagram - "get_user_posts"  Inputs: db, user_id, skip, limitInitialize database query for Post modelApply filter for author_id matching user_idApply filter for deleted_at being NULLOrder results by date_added in descending orderApply offset for paginationApply limit for paginationExecute query and fetch all resultsreturn List of posts   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "get_user_posts" /app/services/service.pyActivity Diagram - "get_user_posts"  Inputs: db, user_id, skip, limitInitialize database query for Post modelApply filter for author_id matching user_idApply filter for deleted_at being NULLOrder results by date_added in descending orderApply offset for paginationApply limit for paginationExecute query and fetch all resultsreturn List of posts   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "get_user_posts" /app/services/service.pyMethod diagram - "get_user_posts"  get_user_postsdb.query.filter.order_by.offset.limit.all()db.query.filter.order_by.offset.limit()db.query.filter.order_by.offset()db.query.filter.order_by()db.query.filter()db.query()and_()Post.date_added.desc()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "get_user_posts" /app/services/service.pyMethod diagram - "get_user_posts"  get_user_postsdb.query.filter.order_by.offset.limit.all()db.query.filter.order_by.offset.limit()db.query.filter.order_by.offset()db.query.filter.order_by()db.query.filter()db.query()and_()Post.date_added.desc()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "get_user_posts" Sequence Diagram - "get_user_posts"  get_user_postsDatabaseSessionCallerget_user_postsDatabaseSessionCallerCallerget_user_postsget_user_postsDatabaseSessionDatabaseSessionget_user_postsDatabaseSessionFunction Callget_user_posts(db, user_id, skip, limit)Database Query Construction and Executionquery(Post)Initiates query for Post modelfilter(Post.author_id == user_id, Post.deleted_at == None)Filters posts by author_id and non-deleted statusorder_by(Post.date_added.desc())Orders results by date_added in descending orderoffset(skip)Applies pagination offsetlimit(limit)Applies pagination limitall()Executes the constructed query and fetches all resultslist of Post objectsFunction Returnlist of Post objects/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "get_user_posts" Sequence Diagram - "get_user_posts"  get_user_postsDatabaseSessionCallerget_user_postsDatabaseSessionCallerCallerget_user_postsget_user_postsDatabaseSessionDatabaseSessionget_user_postsDatabaseSessionFunction Callget_user_posts(db, user_id, skip, limit)Database Query Construction and Executionquery(Post)Initiates query for Post modelfilter(Post.author_id == user_id, Post.deleted_at == None)Filters posts by author_id and non-deleted statusorder_by(Post.date_added.desc())Orders results by date_added in descending orderoffset(skip)Applies pagination offsetlimit(limit)Applies pagination limitall()Executes the constructed query and fetches all resultslist of Post objectsFunction Returnlist of Post objects/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def get_user_posts(db: Session, user_id: int, skip: int = 0, limit: int = 10):

Input Parameters

  • db (Session)

    The SQLAlchemy Session object used for database interaction. This session manages the connection and transactions, enabling efficient querying and retrieval of Post entities from the underlying data store.

  • user_id (int)

    The unique integer identifier of the user whose posts are to be retrieved. This user_id is crucial for filtering posts, ensuring only relevant content associated with the specified author is returned.

  • skip (int)

    The number of initial posts to skip for pagination purposes. This integer parameter allows fetching results starting from a specific offset, commonly used in conjunction with limit for paginated data display.

  • limit (int)

    The maximum number of posts to return in the result set. This integer parameter controls the size of the fetched data chunk, essential for efficient pagination and preventing excessively large query results.

Output / Return Values

  • posts_list (list[Post])

    A list of Post objects matching the criteria, ordered by date_added descending. Each Post object represents an active entry authored by the specified user, ready for display or further processing.

Logic / Execution Flow

  • Query the database for Post entities.
  • Filter the Post entities where Post.author_id matches the provided user_id.
  • Further filter the Post entities to include only those where Post.deleted_at is None, ensuring only active posts are retrieved.
  • Order the filtered Post entities by Post.date_added in descending order.
  • Apply an offset of skip to the ordered results for pagination.
  • Limit the number of results to limit for pagination.
  • Execute the query and retrieve all matching Post objects as a list.
  • Return the list of Post objects.

Usage Tips

  • Utilize skip and limit parameters to implement efficient pagination for user post listings. This prevents loading excessive data, improving application performance and user experience, especially for users with many posts.

  • Ensure user_id corresponds to an existing user to avoid empty results. While this method does not validate user_id existence, upstream validation is recommended for robust data retrieval operations.

Additional Notes

  • The Post.deleted_at == None condition effectively implements soft deletion, ensuring logically deleted posts are excluded from results without permanent data removal. This preserves historical data while maintaining clean active listings.

  • This method assumes Post objects have author_id and date_added fields, and a deleted_at field for soft deletion. Ensure your Post model adheres to this structure for correct query execution.

increment_view_count

public

Increments the view count for a specified post in the database. This method ensures that post engagement metrics are accurately updated. It is crucial for tracking content popularity and user interest effectively.
=== " "

Activity Diagram - "increment_view_count" /app/services/service.pyActivity Diagram - "increment_view_count"  Inputs: db, post_idTry Block: Attempt to Increment View CountCall PostService.get_post_by_idexception thrown during retrieval or update?yesnoCapture exceptionSet exception_occurred = truePost not found, no update performeddb_post is not None?yesnoIncrement db_post.view_countCall db.commit()Set exception_occurred = falseSet exception_occurred = falseCatch Block: Handle ExceptionNo exception was caught by the try blockLog error messageyesexception_occurred is true?noFinally Block: No Explicit CleanupNo explicit finally block in the code   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "increment_view_count" /app/services/service.pyActivity Diagram - "increment_view_count"  Inputs: db, post_idTry Block: Attempt to Increment View CountCall PostService.get_post_by_idexception thrown during retrieval or update?yesnoCapture exceptionSet exception_occurred = truePost not found, no update performeddb_post is not None?yesnoIncrement db_post.view_countCall db.commit()Set exception_occurred = falseSet exception_occurred = falseCatch Block: Handle ExceptionNo exception was caught by the try blockLog error messageyesexception_occurred is true?noFinally Block: No Explicit CleanupNo explicit finally block in the code   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "increment_view_count" /app/services/service.pyMethod diagram - "increment_view_count"  increment_view_countdb_postdb.commit()logger.error()str()PostService.get_post_by_id()get_post_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "increment_view_count" /app/services/service.pyMethod diagram - "increment_view_count"  increment_view_countdb_postdb.commit()logger.error()str()PostService.get_post_by_id()get_post_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "increment_view_count" Sequence Diagram - "increment_view_count"  increment_view_countPostServiceSessionSessionCallerincrement_view_countPostServiceSessionLoggerCallerCallerincrement_view_countincrement_view_countPostServicePostServiceSessionSessionLoggerLoggerincrement_view_countPostServiceSessionSessionMethod Callincrement_view_count(db, post_id)Try BlockLog the error if an exception occurs during the processget_post_by_id(db, post_id)PostService queries the database for the postquery_post_by_id(post_id)db_post_recorddb_postIncrement the view count of the retrieved post objectalt[db_post is not None]increment db_post.view_countCommit the changes to the databasecommit()commit_successbreak[Exception as e]error("Error incrementing view count: " + str(e))return/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "increment_view_count" Sequence Diagram - "increment_view_count"  increment_view_countPostServiceSessionSessionCallerincrement_view_countPostServiceSessionLoggerCallerCallerincrement_view_countincrement_view_countPostServicePostServiceSessionSessionLoggerLoggerincrement_view_countPostServiceSessionSessionMethod Callincrement_view_count(db, post_id)Try BlockLog the error if an exception occurs during the processget_post_by_id(db, post_id)PostService queries the database for the postquery_post_by_id(post_id)db_post_recorddb_postIncrement the view count of the retrieved post objectalt[db_post is not None]increment db_post.view_countCommit the changes to the databasecommit()commit_successbreak[Exception as e]error("Error incrementing view count: " + str(e))return/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def increment_view_count(db: Session, post_id: int):

Input Parameters

  • db (Session)

    The SQLAlchemy database session object used for database operations. This session manages transactions and interactions with the underlying database. It is essential for data persistence and retrieval.

  • post_id (int)

    The unique identifier of the post whose view count needs to be incremented. This integer value precisely targets the specific post record within the database. It ensures correct post identification.

Output / Return Values

  • No Return Value

    This method does not return any explicit value upon completion. Its primary purpose is to perform a side effect by updating the view_count in the database. Callers should not expect a return.

Logic / Execution Flow

  • Attempt to execute the following block for database operations:
    • Retrieve the post from the database using PostService.get_post_by_id() with the provided db session and post_id.
    • Check if a post (db_post) was successfully retrieved (i.e., db_post is not None):
      • If db_post exists:
        • Increment the view_count attribute of the db_post object by one.
        • Commit the changes to the database using db.commit() to persist the updated view_count.
  • If any Exception occurs during the execution of the try block:
    • Log an error message using logger.error(), including a descriptive string indicating the failure to increment the view count and the specific exception details.

Usage Tips

  • Call this method whenever a post is successfully viewed by a user to maintain accurate engagement metrics. Ensure post_id is valid and corresponds to an existing post for successful updates. Handle potential network or database issues gracefully.

Additional Notes

  • The method uses a try-except block to catch and log any exceptions during the process, preventing crashes. However, it does not re-raise, potentially masking issues. Consider adding more specific error handling or re-raising for critical failures.

search_posts

public

This method efficiently searches for published blog posts within the database based on a provided search query. It filters by title, content, or excerpt, ensuring only active, visible posts are returned. Ideal for implementing search functionality across the application.
=== " "

Activity Diagram - "search_posts" /app/services/service.pyActivity Diagram - "search_posts"  Inputs: db, search_query, skip, limitInitialize database query for Post modelApply filter for non-deleted posts (deleted_at IS NULL)Apply filter for published posts (is_published = TRUE)Apply search filter to title, content, or excerpt (case-insensitivematch)Order results by date_added in descending orderApply pagination offsetApply pagination limitExecute query and fetch all matching postsreturn List of Post objects   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "search_posts" /app/services/service.pyActivity Diagram - "search_posts"  Inputs: db, search_query, skip, limitInitialize database query for Post modelApply filter for non-deleted posts (deleted_at IS NULL)Apply filter for published posts (is_published = TRUE)Apply search filter to title, content, or excerpt (case-insensitivematch)Order results by date_added in descending orderApply pagination offsetApply pagination limitExecute query and fetch all matching postsreturn List of Post objects   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "search_posts" /app/services/service.pyMethod diagram - "search_posts"  search_postsdb.query.filter.order_by.offset.limit.all()db.query.filter.order_by.offset.limit()db.query.filter.order_by.offset()db.query.filter.order_by()db.query.filter()db.query()and_()or_()Post.title.ilike()Post.content.ilike()Post.excerpt.ilike()Post.date_added.desc()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "search_posts" /app/services/service.pyMethod diagram - "search_posts"  search_postsdb.query.filter.order_by.offset.limit.all()db.query.filter.order_by.offset.limit()db.query.filter.order_by.offset()db.query.filter.order_by()db.query.filter()db.query()and_()or_()Post.title.ilike()Post.content.ilike()Post.excerpt.ilike()Post.date_added.desc()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "search_posts" Sequence Diagram - "search_posts"  search_postsdb. SessionCallersearch_postsdb. SessionPost ModelCallerCallersearch_postssearch_postsdb: Sessiondb: SessionPost ModelPost Modelsearch_postsdb. SessionFunction Callsearch_posts(db, search_query, skip, limit)Query Constructionquery(Post)Initiates a query builder for the Post modelConstruct filter conditionsBuilds complex AND/OR conditions for the queryAccess Post.deleted_atAccess Post.is_publishedAccess Post.titleAccess Post.contentAccess Post.excerptfilter(and_(...))Applies the constructed filter to the queryAccess Post.date_addedorder_by(Post.date_added.desc())Sorts results by date_added in descending orderoffset(skip)Applies pagination offsetlimit(limit)Applies pagination limitQuery Executionall()Executes the query against the database and fetches allresultsList of Post objectsFunction ReturnList of Post objects/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "search_posts" Sequence Diagram - "search_posts"  search_postsdb. SessionCallersearch_postsdb. SessionPost ModelCallerCallersearch_postssearch_postsdb: Sessiondb: SessionPost ModelPost Modelsearch_postsdb. SessionFunction Callsearch_posts(db, search_query, skip, limit)Query Constructionquery(Post)Initiates a query builder for the Post modelConstruct filter conditionsBuilds complex AND/OR conditions for the queryAccess Post.deleted_atAccess Post.is_publishedAccess Post.titleAccess Post.contentAccess Post.excerptfilter(and_(...))Applies the constructed filter to the queryAccess Post.date_addedorder_by(Post.date_added.desc())Sorts results by date_added in descending orderoffset(skip)Applies pagination offsetlimit(limit)Applies pagination limitQuery Executionall()Executes the query against the database and fetches allresultsList of Post objectsFunction ReturnList of Post objects/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def search_posts(db: Session, search_query: str, skip: int = 0, limit: int = 10):

Input Parameters

  • db (Session)

    The SQLAlchemy session object used to interact with the database. This session provides the necessary connection and transaction management for executing queries. It ensures data consistency and proper resource handling during database operations.

  • search_query (str)

    The string containing keywords to search for within post titles, content, or excerpts. This parameter drives the core search functionality, allowing users to find relevant posts. It supports case-insensitive matching for broader results.

  • skip (int)

    The number of records to skip from the beginning of the result set. This parameter is crucial for implementing pagination, allowing clients to retrieve subsequent pages of search results. Defaults to 0 for the first page.

  • limit (int)

    The maximum number of records to return in a single query result. This parameter controls the page size for pagination, preventing excessively large data transfers. Defaults to 10 to provide manageable result sets.

Output / Return Values

  • posts (List[Post])

    A list of Post model instances matching the search criteria. Each Post object represents a published, non-deleted blog entry from the database. This collection forms the paginated search results displayed to users.

Logic / Execution Flow

  • Initiate a database query on the Post model using the provided db session.
  • Apply a filter condition to the query, combining multiple criteria using and_:
    • Ensure Post.deleted_at is None, meaning the post has not been soft-deleted.
    • Ensure Post.is_published is True, meaning the post is publicly visible.
    • Apply an or_ condition to search across multiple Post fields:
      • Check if Post.title contains the search_query (case-insensitive using ilike).
      • Check if Post.content contains the search_query (case-insensitive using ilike).
      • Check if Post.excerpt contains the search_query (case-insensitive using ilike).
  • Order the filtered results by Post.date_added in descending order, showing newer posts first.
  • Apply an offset to skip a specified number of initial results for pagination.
  • Apply a limit to restrict the total number of results returned for the current page.
  • Execute the constructed query using .all() to fetch all matching Post objects from the database.

Usage Tips

  • Always sanitize search_query input to prevent SQL injection vulnerabilities, even though ilike helps. Implement robust input validation before passing user-provided strings to this method for secure database interactions.

  • For performance-critical applications with large datasets, consider adding full-text search indexing to Post.title, Post.content, and Post.excerpt. This significantly speeds up complex text searches compared to ilike operations.

Additional Notes

  • This method implicitly assumes Post model has deleted_at, is_published, title, content, excerpt, and date_added attributes. Ensure your Post model definition includes these fields for correct query execution.

  • The ilike operator is database-specific and might behave differently across various SQL dialects. Verify its exact behavior with your chosen database system to ensure consistent case-insensitive search results.

update_post

public

This method updates an existing blog post's details in the database. It applies changes from `post_update` to the `Post` object, handles slug generation, and manages tag associations. Essential for content management, ensuring data consistency and audit trails.
=== " "

400. PlantUML 1.2026.1[From string (line 619) ] @startuml<style>root {--common-background: #f1f1f1;--note-background: #FEFFDD;...... ( skipping 593 lines )...endifif (post_update.is_published is not None?) then (yes):Update post published status;endifif (post_update.featured_image_url is not None?) then (yes):Update post featured image URL;endifif (post_update.tag_ids is not None?) then (yes):Query Tag objects by IDs;:Assign queried tags to post;endif:Set updated_by to user_id;:Set date_updated to current UTC time; if (database commit or refresh fails?) then (yes):Set exception_thrown = true;else (no):Log successful post update;endifendifCannot find if (Assumed diagram type: activity)
400. PlantUML 1.2026.1[From string (line 683) ] @startuml<style>root {FontName SansSerif  HyperLinkUnderlineThickness 1...... ( skipping 656 lines )...endifif (post_update.is_published is not None?) then (yes):Update post published status;endifif (post_update.featured_image_url is not None?) then (yes):Update post featured image URL;endifif (post_update.tag_ids is not None?) then (yes):Query Tag objects by IDs;:Assign queried tags to post;endif:Set updated_by to user_id;:Set date_updated to current UTC time; if (database commit or refresh fails?) then (yes):Set exception_thrown = true;else (no):Log successful post update;endifendifCannot find if (Assumed diagram type: activity)

Method diagram - "update_post" /app/services/service.pyMethod diagram - "update_post"  update_postdb_posttitleslugcontentexcerptcategory_idis_publishedfeatured_image_urltagsupdated_bydate_updatedgenerate_slug()db.query.filter.all()db.query.filter()db.query()Tag.id.in_()datetime.utcnow()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()PostService.get_post_by_id()get_post_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "update_post" /app/services/service.pyMethod diagram - "update_post"  update_postdb_posttitleslugcontentexcerptcategory_idis_publishedfeatured_image_urltagsupdated_bydate_updatedgenerate_slug()db.query.filter.all()db.query.filter()db.query()Tag.id.in_()datetime.utcnow()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()PostService.get_post_by_id()get_post_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "update_post" Sequence Diagram - "update_post"  PostServicePostServiceDatabaseSessionDatabaseSessionDatabaseSessionDatabaseSessionDatabaseSessionSlugGeneratorLoggerLoggerCallerPostServiceDatabaseSessionSlugGeneratorTagModelLoggerCallerCallerPostServicePostServiceDatabaseSessionDatabaseSessionSlugGeneratorSlugGeneratorTagModelTagModelLoggerLoggerPostServicePostServiceDatabaseSessionDatabaseSessionDatabaseSessionDatabaseSessionDatabaseSessionSlugGeneratorLoggerLoggerUpdate Post Method Callupdate_post(db, post_id, post_update, user_id)Try Blockget_post_by_id(db, post_id)query Post by ID (post_id)db_post_recorddb_post_record is the result of the queryalt[db_post_record is None]None[db_post_record exists]Update post fields if providedopt[post_update.title is not None]Set db_post_record.titleopt[post_update.slug is not None]generate_slug(post_update.slug)generated_slugSet db_post_record.slugopt[post_update.content is not None]Set db_post_record.contentopt[post_update.excerpt is not None]Set db_post_record.excerptopt[post_update.category_id is not None]Set db_post_record.category_idopt[post_update.is_published is not None]Set db_post_record.is_publishedopt[post_update.featured_image_url is not None]Set db_post_record.featured_image_urlopt[post_update.tag_ids is not None]query(TagModel).filter(Tag.id.in_(tag_ids)).all()matching_tagsSet db_post_record.tagsSet db_post_record.updated_by (user_id)Set db_post_record.date_updated (datetime.utcnow())commit()commit_successrefresh(db_post_record)refreshed_db_post_recordinfo(f"Post updated: {db_post_record.title}")db_post_recordException Handlingbreak[Exception as e]rollback()error(f"Error updating post: {str(e)}")raise Exception/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "update_post" Sequence Diagram - "update_post"  PostServicePostServiceDatabaseSessionDatabaseSessionDatabaseSessionDatabaseSessionDatabaseSessionSlugGeneratorLoggerLoggerCallerPostServiceDatabaseSessionSlugGeneratorTagModelLoggerCallerCallerPostServicePostServiceDatabaseSessionDatabaseSessionSlugGeneratorSlugGeneratorTagModelTagModelLoggerLoggerPostServicePostServiceDatabaseSessionDatabaseSessionDatabaseSessionDatabaseSessionDatabaseSessionSlugGeneratorLoggerLoggerUpdate Post Method Callupdate_post(db, post_id, post_update, user_id)Try Blockget_post_by_id(db, post_id)query Post by ID (post_id)db_post_recorddb_post_record is the result of the queryalt[db_post_record is None]None[db_post_record exists]Update post fields if providedopt[post_update.title is not None]Set db_post_record.titleopt[post_update.slug is not None]generate_slug(post_update.slug)generated_slugSet db_post_record.slugopt[post_update.content is not None]Set db_post_record.contentopt[post_update.excerpt is not None]Set db_post_record.excerptopt[post_update.category_id is not None]Set db_post_record.category_idopt[post_update.is_published is not None]Set db_post_record.is_publishedopt[post_update.featured_image_url is not None]Set db_post_record.featured_image_urlopt[post_update.tag_ids is not None]query(TagModel).filter(Tag.id.in_(tag_ids)).all()matching_tagsSet db_post_record.tagsSet db_post_record.updated_by (user_id)Set db_post_record.date_updated (datetime.utcnow())commit()commit_successrefresh(db_post_record)refreshed_db_post_recordinfo(f"Post updated: {db_post_record.title}")db_post_recordException Handlingbreak[Exception as e]rollback()error(f"Error updating post: {str(e)}")raise Exception/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def update_post(db: Session, post_id: int, post_update: PostUpdate, user_id: int) -> Post:

Input Parameters

  • db (Session)

    The SQLAlchemy database session object used for all database operations. Provides the necessary connection and transaction management for fetching and persisting post data effectively.

  • post_id (int)

    The unique integer identifier of the post to be updated. This id is crucial for locating the specific Post record within the database for modification. Ensures correct post targeting.

  • post_update (PostUpdate)

    An object containing the fields to be updated for the post. This Pydantic model specifies which attributes can be modified, allowing partial updates and ensuring data integrity during the update process.

  • user_id (int)

    The unique integer identifier of the user performing the update operation. This id is recorded in the updated_by field, providing an audit trail of who last modified the post.

Output / Return Values

  • updated_post (Post)

    The Post object after successful updates have been applied and committed to the database. This returned object reflects all modifications, including date_updated and updated_by fields, for immediate use.

  • No Return Value

    Returns None if the specified post_id does not correspond to an existing post in the database. This indicates that no post was found for the given identifier, preventing further update attempts.

Exceptions

  • Exception

    Raised for any unexpected errors occurring during the post update process. This generic exception catches unforeseen issues, rolls back the transaction, logs the error, and re-raises for upstream handling.

Logic / Execution Flow

  • Attempt to execute the post update operation within a try block.
    • Retrieve the Post object from the database using post_id by calling PostService.get_post_by_id().
    • Check if the retrieved db_post object is None (indicating the post was not found).
      • If db_post is None, return None immediately.
    • If post_update.title is provided, update db_post.title with the new title.
    • If post_update.slug is provided, generate a new slug using generate_slug() and update db_post.slug.
    • If post_update.content is provided, update db_post.content with the new content.
    • If post_update.excerpt is not None, update db_post.excerpt with the new excerpt.
    • If post_update.category_id is not None, update db_post.category_id with the new category ID.
    • If post_update.is_published is not None, update db_post.is_published with the new publication status.
    • If post_update.featured_image_url is not None, update db_post.featured_image_url with the new URL.
    • If post_update.tag_ids is not None:
      • Query the database for Tag objects whose ids are present in post_update.tag_ids.
      • Assign the retrieved list of tags to db_post.tags, replacing existing associations.
    • Set db_post.updated_by to the provided user_id for auditing purposes.
    • Set db_post.date_updated to the current UTC datetime using datetime.utcnow().
    • Commit the transaction to persist all changes to the database using db.commit().
    • Refresh the db_post object to load any updated data from the database using db.refresh().
    • Log an informational message indicating the successful update of the post, including its title.
    • Return the updated db_post object.
  • Catch any Exception that occurs during the execution of the try block.
    • Rollback the database transaction to undo any partial changes using db.rollback().
    • Log an error message detailing the exception that occurred during the post update.
    • Re-raise the caught Exception to propagate the error further up the call stack.

Usage Tips

  • Ensure post_update only contains fields intended for modification to prevent unintended data changes. Always validate post_id and user_id against existing records before calling this method for robust security.

Additional Notes

  • The method uses datetime.utcnow() for date_updated, ensuring timezone-agnostic timestamps. This is crucial for applications serving users across different time zones, maintaining consistent chronological order for updates.

  • Tag association is handled by replacing the entire tags collection. If partial tag updates are needed, consider a separate method or more granular logic to add/remove specific tags efficiently.

CommentService

Provides static utility methods for managing `Comment` entities within the application's data store. Facilitates creation, retrieval, update, and deletion operations for comments, ensuring data integrity and consistent access patterns. Integrates with a database session for persistent storage.

Class diagram - "CommentService" /app/services/service.pyClass diagram - "CommentService"  CommentServicecreate_comment()get_comment_by_id()get_post_comments()update_comment()delete_comment()approve_comment()create_commentdb_commentComment()db.add()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()get_comment_by_iddb.query.filter.first()db.query.filter()db.query()and_()get_post_commentsquerydb.query.filter()db.query()and_()query.filter()query.order_by.offset.limit.all()query.order_by.offset.limit()query.order_by.offset()query.order_by()Comment.date_added.desc()update_commentdb_commentcontentupdated_bydate_updateddatetime.utcnow()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()CommentService.get_comment_by_id()delete_commentdb_commentdeleted_atupdated_bydatetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()CommentService.get_comment_by_id()approve_commentdb_commentis_approvedupdated_bydb.commit()logger.info()db.rollback()logger.error()str()CommentService.get_comment_by_id()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Class diagram - "CommentService" /app/services/service.pyClass diagram - "CommentService"  CommentServicecreate_comment()get_comment_by_id()get_post_comments()update_comment()delete_comment()approve_comment()create_commentdb_commentComment()db.add()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()get_comment_by_iddb.query.filter.first()db.query.filter()db.query()and_()get_post_commentsquerydb.query.filter()db.query()and_()query.filter()query.order_by.offset.limit.all()query.order_by.offset.limit()query.order_by.offset()query.order_by()Comment.date_added.desc()update_commentdb_commentcontentupdated_bydate_updateddatetime.utcnow()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()CommentService.get_comment_by_id()delete_commentdb_commentdeleted_atupdated_bydatetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()CommentService.get_comment_by_id()approve_commentdb_commentis_approvedupdated_bydb.commit()logger.info()db.rollback()logger.error()str()CommentService.get_comment_by_id()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Methods

approve_comment

public

This method approves a specific comment by setting its approval status to `True`. It updates the `updated_by` field and commits changes to the database. Essential for moderation workflows, ensuring only verified content is visible to users.
=== " "

Activity Diagram - "approve_comment" /app/services/service.pyActivity Diagram - "approve_comment"  Inputs: db, comment_id, user_idTry Block: Attempt Comment ApprovalRetrieve comment by IDIf an exception occurs at any point in the 'yes' branch before the return, the flow implicitly jumps to the 'CatchBlock'.comment found?noyesreturn FalseSet comment.is_approved = TrueSet comment.updated_by = user_idCommit changes to databaseLog successful approvalreturn TrueCatch Block: Handle ExceptionThis block is executed only if an exception occurs in the 'Try Block'.Rollback database changesLog error detailsRaise exception   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "approve_comment" /app/services/service.pyActivity Diagram - "approve_comment"  Inputs: db, comment_id, user_idTry Block: Attempt Comment ApprovalRetrieve comment by IDIf an exception occurs at any point in the 'yes' branch before the return, the flow implicitly jumps to the 'CatchBlock'.comment found?noyesreturn FalseSet comment.is_approved = TrueSet comment.updated_by = user_idCommit changes to databaseLog successful approvalreturn TrueCatch Block: Handle ExceptionThis block is executed only if an exception occurs in the 'Try Block'.Rollback database changesLog error detailsRaise exception   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "approve_comment" /app/services/service.pyMethod diagram - "approve_comment"  approve_commentdb_commentis_approvedupdated_bydb.commit()logger.info()db.rollback()logger.error()str()CommentService.get_comment_by_id()get_comment_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "approve_comment" /app/services/service.pyMethod diagram - "approve_comment"  approve_commentdb_commentis_approvedupdated_bydb.commit()logger.info()db.rollback()logger.error()str()CommentService.get_comment_by_id()get_comment_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "approve_comment" Sequence Diagram - "approve_comment"  approve_commentSessionSessionSessionCommentServiceLoggerLoggerCallerapprove_commentSessionCommentServiceLoggerCallerCallerapprove_commentapprove_commentSessionSessionCommentServiceCommentServiceLoggerLoggerapprove_commentSessionSessionSessionCommentServiceLoggerLoggerMethod Callapprove_comment(db, comment_id, user_id)Try Blockget_comment_by_id(db, comment_id)query comment by id (comment_id)db_commentdb_commentComment not foundalt[db_comment is None]False[db_comment exists]Set db_comment.is_approved = TrueSet db_comment.updated_by = user_idcommit()commit_successinfo(f"Comment approved: {comment_id}")TrueException Blockbreak[Exception as e]rollback()rollback_completeerror(f"Error approving comment: {str(e)}")raise Exception/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "approve_comment" Sequence Diagram - "approve_comment"  approve_commentSessionSessionSessionCommentServiceLoggerLoggerCallerapprove_commentSessionCommentServiceLoggerCallerCallerapprove_commentapprove_commentSessionSessionCommentServiceCommentServiceLoggerLoggerapprove_commentSessionSessionSessionCommentServiceLoggerLoggerMethod Callapprove_comment(db, comment_id, user_id)Try Blockget_comment_by_id(db, comment_id)query comment by id (comment_id)db_commentdb_commentComment not foundalt[db_comment is None]False[db_comment exists]Set db_comment.is_approved = TrueSet db_comment.updated_by = user_idcommit()commit_successinfo(f"Comment approved: {comment_id}")TrueException Blockbreak[Exception as e]rollback()rollback_completeerror(f"Error approving comment: {str(e)}")raise Exception/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def approve_comment(db: Session, comment_id: int, user_id: int) -> bool:

Input Parameters

  • db (Session)

    The SQLAlchemy database session object used for database operations. Provides the connection and transaction management necessary to fetch and update the comment record effectively within the application context.

  • comment_id (int)

    The unique integer identifier of the comment to be approved. This id is crucial for locating the specific Comment record in the database for status modification. Ensures correct comment targeting.

  • user_id (int)

    The unique integer identifier of the user performing the approval action. This user_id is recorded in the updated_by field, providing an audit trail for moderation actions. Essential for accountability.

Output / Return Values

  • approval_status (bool)

    A boolean indicating whether the comment approval operation was successful. Returns True if the comment was found and approved, False if the comment was not found. Useful for UI feedback.

Exceptions

  • Exception

    Raised for any unexpected errors occurring during the comment approval process. This generic exception ensures that all unhandled issues are propagated, allowing higher-level error handling to manage system failures.

Logic / Execution Flow

  • Begin a try block to handle potential database operation errors.
  • Retrieve the Comment object from the database using CommentService.get_comment_by_id() with the provided db session and comment_id.
  • Check if the db_comment object was successfully retrieved (i.e., not None).
    • If db_comment is None (comment not found):
      • Return False to indicate that the approval failed because the comment does not exist.
  • If db_comment is found:
    • Set the is_approved attribute of the db_comment object to True.
    • Set the updated_by attribute of the db_comment object to the provided user_id.
    • Commit the changes to the database using db.commit().
    • Log an informational message indicating the successful approval of the comment using logger.info().
    • Return True to indicate that the comment was successfully approved.
  • If any Exception occurs during the try block:
    • Enter the except Exception as e block.
    • Rollback any pending database changes using db.rollback() to maintain data consistency.
    • Log an error message detailing the exception using logger.error().
    • Re-raise the caught Exception to propagate the error further up the call stack.

Usage Tips

  • Ensure comment_id and user_id are valid integers corresponding to existing records. Calling this method with non-existent IDs will result in False or an exception. Always validate inputs beforehand for robustness.

  • Integrate this method into a secure moderation panel, ensuring only authorized users can approve comments. Implement proper access control checks before invoking approve_comment() to prevent unauthorized content manipulation.

Additional Notes

  • The CommentService.get_comment_by_id() call implies a dependency on a service layer for data access. This abstraction helps maintain separation of concerns and testability within the application architecture.

  • This method performs a database transaction with db.commit() and db.rollback(). This ensures atomicity; either all changes are saved, or none are, preventing partial updates and maintaining data integrity.

create_comment

public

Creates a new comment entry in the database associated with a specific post and user. This method handles the persistence of comment content and metadata, ensuring data integrity and proper attribution within the application.
=== " "

Activity Diagram - "create_comment" /app/services/service.pyActivity Diagram - "create_comment"  Inputs: db, comment_create, post_id, user_idattempt comment creation?successexceptionCreate Comment object from input dataAdd new comment to database sessionCommit transaction to databaseRefresh comment object to load updated stateLog successful comment creationreturn created commentRollback database transactionLog error detailsRe-raise caught exception   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "create_comment" /app/services/service.pyActivity Diagram - "create_comment"  Inputs: db, comment_create, post_id, user_idattempt comment creation?successexceptionCreate Comment object from input dataAdd new comment to database sessionCommit transaction to databaseRefresh comment object to load updated stateLog successful comment creationreturn created commentRollback database transactionLog error detailsRe-raise caught exception   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "create_comment" /app/services/service.pyMethod diagram - "create_comment"  create_commentdb_commentComment()db.add()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "create_comment" /app/services/service.pyMethod diagram - "create_comment"  create_commentdb_commentComment()db.add()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

400. PlantUML 1.2026.1[From string (line 625) ] @startuml<style>root {--common-background: #f1f1f1;--note-background: #FEFFDD;...... ( skipping 599 lines )...logger --> create_comment_method:deactivate logger create_comment_method --> caller: db_commentdeactivate create_comment_methodend break Exception as ecreate_comment_method -> db: rollback()activate dbdb --> create_comment_method:deactivate db create_comment_method -> logger: error(f"Error creating comment: {str(e)}")activate loggerlogger --> create_comment_method:deactivate logger deactivate create_comment_methodcreate_comment_method -[#red]> [*]: raise ExceptionSyntax Error? (Assumed diagram type: sequence)
400. PlantUML 1.2026.1[From string (line 689) ] @startuml<style>root {FontName SansSerif  HyperLinkUnderlineThickness 1...... ( skipping 662 lines )...logger --> create_comment_method:deactivate logger create_comment_method --> caller: db_commentdeactivate create_comment_methodend break Exception as ecreate_comment_method -> db: rollback()activate dbdb --> create_comment_method:deactivate db create_comment_method -> logger: error(f"Error creating comment: {str(e)}")activate loggerlogger --> create_comment_method:deactivate logger deactivate create_comment_methodcreate_comment_method -[#red]> [*]: raise ExceptionSyntax Error? (Assumed diagram type: sequence)

Syntax

def create_comment(db: Session, comment_create: CommentCreate, post_id: int, user_id: int) -> Comment:

Input Parameters

  • db (Session)

    The SQLAlchemy database session object used for interacting with the database. This session manages transactions and persistence operations for the new comment record effectively and reliably.

  • comment_create (CommentCreate)

    A Pydantic schema object containing the data required to create a new comment. This includes the comment's content and optionally its parent comment ID for threaded discussions.

  • post_id (int)

    The unique identifier of the post to which this new comment will be attached. This integer ensures the comment is correctly linked to its parent content within the system.

  • user_id (int)

    The unique identifier of the user who is authoring this comment. This integer establishes the ownership and authorship of the comment for tracking and display purposes.

Output / Return Values

  • db_comment (Comment)

    The newly created Comment object, retrieved from the database after successful persistence. This object includes all database-generated fields like id and timestamps, representing the final stored record.

Exceptions

  • Exception

    Raised for any unexpected errors occurring during the comment creation process. This catch-all ensures that database operations are rolled back and the error is propagated for higher-level handling.

Logic / Execution Flow

  • Begin a try block to handle potential database errors during comment creation.
  • Instantiate a new Comment object, populating its fields from comment_create data, post_id, and user_id.
  • Add the newly created db_comment object to the SQLAlchemy database session for tracking.
  • Commit the transaction to persist the db_comment record into the database permanently.
  • Refresh the db_comment object to load any database-generated attributes, such as its unique id.
  • Log an informational message indicating successful comment creation on the specified post.
  • Return the refreshed db_comment object, representing the successfully stored comment.
  • If any Exception occurs during the try block:
    • Execute the except block to handle the error.
    • Rollback the database session to discard any uncommitted changes and maintain data consistency.
    • Log an error message detailing the failure to create the comment, including the exception details.
    • Re-raise the caught Exception to propagate the error to the calling function for further handling.

Usage Tips

  • Always ensure post_id and user_id correspond to existing records before calling this method. Pre-validation prevents foreign key constraint violations and ensures data integrity within the application.

  • Utilize the CommentCreate Pydantic model for consistent data validation and serialization. This approach standardizes input, reducing errors and improving maintainability across your API endpoints effectively.

Additional Notes

  • The parent_comment_id field allows for nested or threaded comment structures, enabling rich discussion features. Ensure your frontend correctly passes this optional ID for replies to specific comments.

  • This method includes robust error handling with a database rollback, preventing partial data writes upon failure. This ensures that the database remains in a consistent state even during unexpected issues.

delete_comment

public

This method logically deletes a comment by setting its `deleted_at` timestamp. It ensures data integrity by marking records as inactive rather than physically removing them. This approach supports audit trails and potential recovery needs effectively.
=== " "

Activity Diagram - "delete_comment" /app/services/service.pyActivity Diagram - "delete_comment"  Inputs: db, comment_id, user_idTry Block: Attempt Comment DeletionRetrieve comment by IDIf an exception occurs during any operation in this block, execution jumps to the Catch Block.comment not found?yesnoreturn FalseSet deleted_at timestampSet updated_by user IDCommit changes to databaseLog successful deletionreturn TrueCatch Block: Handle ExceptionThis block is executed if an exception is raised in the Try Block.Rollback database transactionLog error detailsRe-raise exceptionFinally Block: CleanupNo explicit 'finally' block in the code.   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "delete_comment" /app/services/service.pyActivity Diagram - "delete_comment"  Inputs: db, comment_id, user_idTry Block: Attempt Comment DeletionRetrieve comment by IDIf an exception occurs during any operation in this block, execution jumps to the Catch Block.comment not found?yesnoreturn FalseSet deleted_at timestampSet updated_by user IDCommit changes to databaseLog successful deletionreturn TrueCatch Block: Handle ExceptionThis block is executed if an exception is raised in the Try Block.Rollback database transactionLog error detailsRe-raise exceptionFinally Block: CleanupNo explicit 'finally' block in the code.   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "delete_comment" /app/services/service.pyMethod diagram - "delete_comment"  delete_commentdb_commentdeleted_atupdated_bydatetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()CommentService.get_comment_by_id()get_comment_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "delete_comment" /app/services/service.pyMethod diagram - "delete_comment"  delete_commentdb_commentdeleted_atupdated_bydatetime.utcnow()db.commit()logger.info()db.rollback()logger.error()str()CommentService.get_comment_by_id()get_comment_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "delete_comment" Sequence Diagram - "delete_comment"  delete_commentSessionSessionCommentServiceLoggerLoggerCallerdelete_commentSessionCommentServiceLoggerCallerCallerdelete_commentdelete_commentSessionSessionCommentServiceCommentServiceLoggerLoggerdelete_commentSessionSessionCommentServiceLoggerLoggerFunction Entrydelete_comment(db, comment_id, user_id)Try BlockAn unexpected error occurred during deletionRetrieve Commentget_comment_by_id(db_session, comment_id)db_comment_recordComment not found in databaseConditional Deletionalt[db_comment_record is None]False[db_comment_record exists]Set db_comment_record.deleted_at = current UTC timeSet db_comment_record.updated_by = user_idcommit()commit_successinfo(Comment deleted message)log_ackTruebreak[Exception as e]rollback()rollback_successerror(Error deleting comment message)log_ackraise Exception/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "delete_comment" Sequence Diagram - "delete_comment"  delete_commentSessionSessionCommentServiceLoggerLoggerCallerdelete_commentSessionCommentServiceLoggerCallerCallerdelete_commentdelete_commentSessionSessionCommentServiceCommentServiceLoggerLoggerdelete_commentSessionSessionCommentServiceLoggerLoggerFunction Entrydelete_comment(db, comment_id, user_id)Try BlockAn unexpected error occurred during deletionRetrieve Commentget_comment_by_id(db_session, comment_id)db_comment_recordComment not found in databaseConditional Deletionalt[db_comment_record is None]False[db_comment_record exists]Set db_comment_record.deleted_at = current UTC timeSet db_comment_record.updated_by = user_idcommit()commit_successinfo(Comment deleted message)log_ackTruebreak[Exception as e]rollback()rollback_successerror(Error deleting comment message)log_ackraise Exception/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def delete_comment(db: Session, comment_id: int, user_id: int) -> bool:

Input Parameters

  • db (Session)

    Provides the database session for executing queries and managing transactions. It is essential for interacting with the persistence layer to retrieve and update comment records.

  • comment_id (int)

    Unique identifier for the comment to be deleted. This integer value precisely targets the specific comment record within the database for modification.

  • user_id (int)

    Identifier of the user performing the deletion. This integer value is recorded in the updated_by field, maintaining an audit trail of who initiated the comment's logical deletion.

Output / Return Values

  • deletion_status (bool)

    Indicates whether the comment was successfully marked as deleted. Returns True upon successful logical deletion and False if the comment was not found, guiding subsequent application logic.

Exceptions

  • Exception

    Raised if any unexpected error occurs during the comment deletion process. This generic exception ensures that all unhandled issues are caught, logged, and re-propagated for higher-level error management.

Logic / Execution Flow

  • Begin a try block to handle potential exceptions during the comment deletion process.
  • Retrieve the comment from the database using CommentService.get_comment_by_id with the provided db session and comment_id.
  • Check if the db_comment object returned from the service call is None (meaning the comment was not found):
    • If db_comment is None:
      • Return False to indicate that the deletion was unsuccessful because the comment does not exist.
  • If db_comment is found (not None):
    • Set the deleted_at attribute of db_comment to the current UTC datetime using datetime.utcnow().
    • Set the updated_by attribute of db_comment to the provided user_id.
    • Commit the transaction to the database using db.commit(), persisting the changes.
    • Log an informational message indicating the successful logical deletion of the comment, including its comment_id.
    • Return True to signify that the comment was successfully marked as deleted.
  • If any Exception occurs during the try block:
    • Enter the except block, catching the generic Exception.
    • Rollback the database transaction using db.rollback() to undo any uncommitted changes.
    • Log an error message detailing the failure to delete the comment, including the exception string.
    • Re-raise the caught Exception to propagate the error further up the call stack for centralized handling.

Usage Tips

  • Always verify user permissions before calling delete_comment to ensure only authorised users can logically remove comments. Implement robust access control checks at the API layer.

  • Consider implementing a soft delete mechanism for all user-generated content, like this method. This preserves data for auditing, recovery, and compliance, avoiding permanent data loss effectively.

Additional Notes

  • This method performs a soft delete, marking the comment as deleted rather than physically removing it. This design choice is crucial for maintaining historical data and supporting potential undelete functionalities.

  • The datetime.utcnow() function is used for deleted_at to ensure timezone-agnostic timestamps. This consistency is vital for applications operating across different geographical regions and timezones.

get_comment_by_id

public

Retrieves a single `Comment` record from the database using its unique identifier. This method ensures only active, non-deleted comments are fetched, providing a reliable way to access specific comment data for display or further processing.
=== " "

Activity Diagram - "get_comment_by_id" /app/services/service.pyActivity Diagram - "get_comment_by_id"  Inputs: db session, comment_idConstruct database query for Comment modelApply filter: Comment ID matches provided comment_idApply filter: Comment is not deleted (deleted_at is None)Execute query and retrieve the first matching commentreturn Retrieved Comment object or None   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "get_comment_by_id" /app/services/service.pyActivity Diagram - "get_comment_by_id"  Inputs: db session, comment_idConstruct database query for Comment modelApply filter: Comment ID matches provided comment_idApply filter: Comment is not deleted (deleted_at is None)Execute query and retrieve the first matching commentreturn Retrieved Comment object or None   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "get_comment_by_id" /app/services/service.pyMethod diagram - "get_comment_by_id"  get_comment_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "get_comment_by_id" /app/services/service.pyMethod diagram - "get_comment_by_id"  get_comment_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "get_comment_by_id" Sequence Diagram - "get_comment_by_id"  get_comment_by_idDatabaseSessionCallerget_comment_by_idDatabaseSessionCommentModelCallerCallerget_comment_by_idget_comment_by_idDatabaseSessionDatabaseSessionCommentModelCommentModelget_comment_by_idDatabaseSessionFunction Callget_comment_by_id(db, comment_id)Database QueryInitiates a query for the Comment modelquery(CommentModel)Filters by comment ID and non-deleted statusfilter(Comment.id == comment_id AND Comment.deleted_atIS NULL)Retrieves the first matching recordfirst()Comment object or NoneFunction ReturnComment object or None/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "get_comment_by_id" Sequence Diagram - "get_comment_by_id"  get_comment_by_idDatabaseSessionCallerget_comment_by_idDatabaseSessionCommentModelCallerCallerget_comment_by_idget_comment_by_idDatabaseSessionDatabaseSessionCommentModelCommentModelget_comment_by_idDatabaseSessionFunction Callget_comment_by_id(db, comment_id)Database QueryInitiates a query for the Comment modelquery(CommentModel)Filters by comment ID and non-deleted statusfilter(Comment.id == comment_id AND Comment.deleted_atIS NULL)Retrieves the first matching recordfirst()Comment object or NoneFunction ReturnComment object or None/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def get_comment_by_id(db: Session, comment_id: int) -> Comment:

Input Parameters

  • db (Session)

    The SQLAlchemy database session object used to interact with the database. This session facilitates executing queries and managing transactions, ensuring data consistency and proper resource handling for all database operations.

  • comment_id (int)

    The unique integer identifier for the Comment record to be retrieved. This id is crucial for precisely locating the desired comment within the database, ensuring accurate and efficient data fetching.

Output / Return Values

  • comment (Comment)

    Returns the Comment object matching the provided comment_id if found and not deleted. If no such comment exists or it is marked as deleted, None is returned, indicating absence of an active record.

Logic / Execution Flow

  • Initiate a database query on the Comment model using the provided db session.
  • Apply a filter condition to select comments where Comment.id matches the comment_id parameter.
  • Add another filter condition using and_ to ensure Comment.deleted_at is None, meaning the comment is not soft-deleted.
  • Execute the query and retrieve the first matching Comment object found.
  • Return the retrieved Comment object, or None if no matching, non-deleted comment is found.

Usage Tips

  • Always check the return value for None after calling get_comment_by_id() to handle cases where the comment does not exist or is soft-deleted. This prevents AttributeError when accessing properties.

  • Utilize this method when you need to fetch a specific comment for detailed viewing or modification. Avoid using it in loops for fetching multiple comments; prefer bulk query methods for performance optimization.

Additional Notes

  • This method implicitly handles soft-deletion by filtering out comments where deleted_at is not None. This ensures that only logically active comments are ever returned, maintaining data integrity and application logic.

  • The @staticmethod decorator indicates this method does not require an instance of the class to be called. It operates purely on its input parameters, making it a utility function for database access.

get_post_comments

public

This method retrieves comments associated with a specific post from the database. It allows pagination and filtering for approved comments, providing a structured list of relevant feedback. This function is crucial for displaying user engagement on individual blog posts.
=== " "

Activity Diagram - "get_post_comments" /app/services/service.pyActivity Diagram - "get_post_comments"  Inputs: db, post_id, skip, limit, approved_onlyInitialize query for comments by post_id and not deletedSkip filtering by approval statusAdd filter for approved commentsyesapproved_only is true?noOrder comments by date_added descendingApply offset for paginationApply limit for paginationExecute query and fetch all commentsreturn List of comments   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "get_post_comments" /app/services/service.pyActivity Diagram - "get_post_comments"  Inputs: db, post_id, skip, limit, approved_onlyInitialize query for comments by post_id and not deletedSkip filtering by approval statusAdd filter for approved commentsyesapproved_only is true?noOrder comments by date_added descendingApply offset for paginationApply limit for paginationExecute query and fetch all commentsreturn List of comments   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "get_post_comments" /app/services/service.pyMethod diagram - "get_post_comments"  get_post_commentsquerydb.query.filter()db.query()and_()query.filter()query.order_by.offset.limit.all()query.order_by.offset.limit()query.order_by.offset()query.order_by()Comment.date_added.desc()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "get_post_comments" /app/services/service.pyMethod diagram - "get_post_comments"  get_post_commentsquerydb.query.filter()db.query()and_()query.filter()query.order_by.offset.limit.all()query.order_by.offset.limit()query.order_by.offset()query.order_by()Comment.date_added.desc()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "get_post_comments" Sequence Diagram - "get_post_comments"  get_post_commentsDatabase SessionDatabase SessionCallerget_post_commentsDatabase SessionCallerCallerget_post_commentsget_post_commentsDatabase SessionDatabase Sessionget_post_commentsDatabase SessionDatabase SessionMethod Callget_post_comments(db, post_id, skip, limit, approved_only)Query Initializationquery(Comment)Initiates a query for Comment objectsquery_objectQuery Filteringquery_object.filter(post_id, deleted_at == None)Applies initial filters for post_id and non-deleted commentsalt[approved_only is True]query_object.filter(is_approved == True)Conditionally applies filter for approved commentsQuery Ordering and Paginationquery_object.order_by(date_added.desc())Orders results by date_added in descending orderquery_object.offset(skip)Applies offset for paginationquery_object.limit(limit)Applies limit for paginationQuery Executionquery_object.all()Executes the constructed query against the databaselist_of_commentsReturn Valuelist_of_comments/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "get_post_comments" Sequence Diagram - "get_post_comments"  get_post_commentsDatabase SessionDatabase SessionCallerget_post_commentsDatabase SessionCallerCallerget_post_commentsget_post_commentsDatabase SessionDatabase Sessionget_post_commentsDatabase SessionDatabase SessionMethod Callget_post_comments(db, post_id, skip, limit, approved_only)Query Initializationquery(Comment)Initiates a query for Comment objectsquery_objectQuery Filteringquery_object.filter(post_id, deleted_at == None)Applies initial filters for post_id and non-deleted commentsalt[approved_only is True]query_object.filter(is_approved == True)Conditionally applies filter for approved commentsQuery Ordering and Paginationquery_object.order_by(date_added.desc())Orders results by date_added in descending orderquery_object.offset(skip)Applies offset for paginationquery_object.limit(limit)Applies limit for paginationQuery Executionquery_object.all()Executes the constructed query against the databaselist_of_commentsReturn Valuelist_of_comments/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def get_post_comments(db: Session, post_id: int, skip: int = 0, limit: int = 20, approved_only: bool = True):

Input Parameters

  • db (Session)

    The SQLAlchemy database session object used for executing queries. Provides the necessary interface to interact with the underlying database, ensuring transactional integrity and efficient data retrieval operations.

  • post_id (int)

    The unique identifier of the post for which comments are to be retrieved. This integer value is essential for filtering comments specific to a particular blog entry.

  • skip (int)

    The number of comments to skip from the beginning of the result set. Useful for pagination, allowing clients to request subsequent pages of comments efficiently. Defaults to zero for initial retrieval.

  • limit (int)

    The maximum number of comments to return in the result set. This integer value controls the size of each page in a paginated response. Defaults to twenty for manageable data chunks.

  • approved_only (bool)

    A boolean flag indicating whether to retrieve only approved comments. When True, only comments marked as approved will be returned, ensuring content moderation. Defaults to True for public display.

Output / Return Values

  • comments_list (List[Comment])

    A list of Comment objects matching the specified criteria. Each object represents a comment with its associated data, ordered by date_added in descending order for chronological display.

Logic / Execution Flow

  • Initialize a database query targeting the Comment model.
  • Filter the query to include comments where Comment.post_id matches the provided post_id and Comment.deleted_at is None.
  • Check if the approved_only parameter is True:
    • If approved_only is True, further filter the query to include only comments where Comment.is_approved is True.
  • Order the filtered query results by Comment.date_added in descending order.
  • Apply an offset to the query results using the skip parameter.
  • Apply a limit to the query results using the limit parameter.
  • Execute the query and retrieve all matching Comment objects as a list.

Usage Tips

  • To efficiently paginate comments, adjust skip and limit parameters based on the current page number. For example, skip = (page_number - 1) * limit ensures correct sequential retrieval of comment pages.

  • When displaying comments publicly, always set approved_only to True to prevent unmoderated content from appearing. This maintains content quality and user experience on the platform.

Additional Notes

  • This method assumes Comment.deleted_at being None signifies an active comment. If soft deletion logic changes, this query filter must be updated accordingly to reflect the new status.

  • The Comment objects returned include all fields, potentially exposing sensitive data if not carefully handled by the calling context. Ensure proper serialization and access control for display.

update_comment

public

Updates an existing comment's content and metadata in the database. This method ensures data integrity by rolling back changes upon error. It is crucial for maintaining dynamic user-generated content within the application.
=== " "

Activity Diagram - "update_comment" /app/services/service.pyActivity Diagram - "update_comment"  Inputs: db, comment_id, comment_update, user_idInitialize operation_succeeded = falseInitialize return_value = NoneTry Block: Attempt Comment UpdateRetrieve comment by IDIf an exception occurs during the operations within the 'Try Block' (before setting operation_succeeded), 'operation_succeeded' will remain false.db_comment is None?yesnoreturn NoneUpdate comment contentSet updated_by user IDSet date_updated to current UTC timeCommit changes to databaseRefresh db_comment objectLog info: Comment updatedSet operation_succeeded = trueSet return_value = db_commentoperation_succeeded is true?yesnoreturn return_valueCatch Block: Handle ExceptionRollback database transactionLog error: Error updating commentRe-raise exception   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Activity Diagram - "update_comment" /app/services/service.pyActivity Diagram - "update_comment"  Inputs: db, comment_id, comment_update, user_idInitialize operation_succeeded = falseInitialize return_value = NoneTry Block: Attempt Comment UpdateRetrieve comment by IDIf an exception occurs during the operations within the 'Try Block' (before setting operation_succeeded), 'operation_succeeded' will remain false.db_comment is None?yesnoreturn NoneUpdate comment contentSet updated_by user IDSet date_updated to current UTC timeCommit changes to databaseRefresh db_comment objectLog info: Comment updatedSet operation_succeeded = trueSet return_value = db_commentoperation_succeeded is true?yesnoreturn return_valueCatch Block: Handle ExceptionRollback database transactionLog error: Error updating commentRe-raise exception   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Method diagram - "update_comment" /app/services/service.pyMethod diagram - "update_comment"  update_commentdb_commentcontentupdated_bydate_updateddatetime.utcnow()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()CommentService.get_comment_by_id()get_comment_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Method diagram - "update_comment" /app/services/service.pyMethod diagram - "update_comment"  update_commentdb_commentcontentupdated_bydate_updateddatetime.utcnow()db.commit()db.refresh()logger.info()db.rollback()logger.error()str()CommentService.get_comment_by_id()get_comment_by_iddb.query.filter.first()db.query.filter()db.query()and_()   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Sequence Diagram - "update_comment" Sequence Diagram - "update_comment"  update_commentCommentServiceSessionSessionSessionSessionLoggerLoggerCallerupdate_commentCommentServiceSessionLoggerCallerCallerupdate_commentupdate_commentCommentServiceCommentServiceSessionSessionLoggerLoggerupdate_commentCommentServiceSessionSessionSessionSessionLoggerLoggerFunction Callupdate_comment(db, comment_id, comment_update,user_id)Try Blockget_comment_by_id(db, comment_id)query(Comment).filter(id=comment_id).first()db_comment_recorddb_commentalt[not db_comment]Comment not foundNone[db_comment exists]Update comment attributesdb_comment.content = comment_update.contentdb_comment.updated_by = user_iddb_comment.date_updated = datetime.utcnow()commit()successrefresh(db_comment)refreshed_db_commentinfo(f"Comment updated: {comment_id}")db_comment[Catch Block: Exception as e]An exception occurredrollback()error(f"Error updating comment: {str(e)}")raise Exception/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.
Sequence Diagram - "update_comment" Sequence Diagram - "update_comment"  update_commentCommentServiceSessionSessionSessionSessionLoggerLoggerCallerupdate_commentCommentServiceSessionLoggerCallerCallerupdate_commentupdate_commentCommentServiceCommentServiceSessionSessionLoggerLoggerupdate_commentCommentServiceSessionSessionSessionSessionLoggerLoggerFunction Callupdate_comment(db, comment_id, comment_update,user_id)Try Blockget_comment_by_id(db, comment_id)query(Comment).filter(id=comment_id).first()db_comment_recorddb_commentalt[not db_comment]Comment not foundNone[db_comment exists]Update comment attributesdb_comment.content = comment_update.contentdb_comment.updated_by = user_iddb_comment.date_updated = datetime.utcnow()commit()successrefresh(db_comment)refreshed_db_commentinfo(f"Comment updated: {comment_id}")db_comment[Catch Block: Exception as e]An exception occurredrollback()error(f"Error updating comment: {str(e)}")raise Exception/app/services/service.py   This diagram is for illustrative purposes only and may not capture all details.Refer to the original codebase for complete understanding.

Syntax

def update_comment(db: Session, comment_id: int, comment_update: CommentUpdate, user_id: int) -> Comment:

Input Parameters

  • db (Session)

    The SQLAlchemy database session object used for database operations. This session manages transactions and persistence for the comment update. It ensures atomicity and consistency of data changes.

  • comment_id (int)

    The unique identifier of the comment to be updated. This int value precisely targets the specific comment record in the database for modification. It ensures the correct comment is located.

  • comment_update (CommentUpdate)

    An object containing the updated content for the comment. This CommentUpdate schema provides the new content string. It encapsulates the data necessary for modifying the existing comment record.

  • user_id (int)

    The unique identifier of the user performing the update. This int value is recorded as updated_by to track who last modified the comment. It provides an audit trail for content changes.

Output / Return Values

  • db_comment (Comment)

    The updated Comment object retrieved from the database after successful modification. This object reflects all changes, including new content and updated timestamps. It confirms the operation's success.

  • No Return Value

    Returned if no comment is found matching the provided comment_id. This indicates that the target comment does not exist in the database. Callers should handle this explicit absence of a comment.

Exceptions

  • Exception

    Raised for any unexpected errors occurring during the comment update process. This generic exception indicates a failure in database operations or other unforeseen issues. The transaction is rolled back.

Logic / Execution Flow

  • Begin a try block to handle potential exceptions during the update process.
  • Retrieve the existing comment from the database using CommentService.get_comment_by_id with db session and comment_id.
  • Check if db_comment was not found (i.e., is None):
    • If db_comment is None, return None immediately, indicating no comment exists.
  • If db_comment exists, update its attributes:
    • Set db_comment.content to comment_update.content.
    • Set db_comment.updated_by to the user_id of the updater.
    • Set db_comment.date_updated to the current UTC time using datetime.utcnow().
  • Commit the changes to the database using db.commit() to persist the updated comment.
  • Refresh the db_comment object from the database using db.refresh() to ensure it reflects the latest state.
  • Log an informational message indicating the successful update of the comment with its comment_id.
  • Return the updated db_comment object.
  • Begin an except Exception as e block to catch any exceptions that occurred during the try block:
    • Roll back the database transaction using db.rollback() to undo any partial changes.
    • Log an error message detailing the exception e that occurred during the update.
    • Re-raise the caught Exception to propagate the error to the calling function.

Usage Tips

  • Always verify the return value of update_comment to handle cases where the comment_id does not exist. Returning None requires explicit handling to prevent downstream errors in your application logic.

  • Ensure comment_update contains only valid and sanitized data before calling this method. Pre-validation prevents database errors and maintains data integrity, enhancing the overall robustness of the system.

Additional Notes

  • The use of datetime.utcnow() for date_updated ensures consistency across different time zones. This is a best practice for timestamping database records, simplifying global data management and comparisons.

  • This method relies on CommentService.get_comment_by_id for initial retrieval. Performance considerations for get_comment_by_id directly impact this update method's efficiency, especially under high load conditions.

FAQs

Why are multiple service classes grouped within a single file?

This design choice centralizes related business logic for content management entities, simplifying initial development and dependency management. It allows for quick access to all core services from one module.

How does the system handle deleted entities?

The system employs a soft deletion strategy by setting a deleted_at timestamp. This preserves historical data and relationships, allowing for potential recovery while logically removing entities from active queries.

What is the purpose of passing user_id to creation and update methods?

Passing user_id ensures proper auditing and attribution for all entity modifications. It records which user performed an action, enhancing accountability and traceability within the system.

Why are Pydantic schemas used for data input and output?

Pydantic schemas provide robust data validation and serialization. They ensure that incoming data conforms to expected structures and types, and outgoing data is consistently formatted, improving API reliability and developer experience.

Insights

Metric Score Level
Complexity 1.00 Very Complex
Security 1.00 Secure
Performance 0.60 Acceptable Performance

Complexity

Medium - God File with Multiple Service Classes

Grouping all service classes (User, Post, Comment, Category, Tag) into a single file increases its size and reduces modularity. Splitting into separate files would improve maintainability.

Low - Repetitive Error Handling Logic

The try...except...db.rollback() pattern is repeated across many methods. A decorator or context manager could centralize this logic, reducing boilerplate and improving consistency.

Performance

Medium - Missing Caching for Frequently Accessed Data

The service lacks caching mechanisms for frequently accessed data like categories or popular posts. This could lead to repeated database queries, impacting response times and database load.

Medium - Potential N+1 Query Issues

When fetching lists of posts or comments with related entities (e.g., author, tags), N+1 queries might occur. Eager loading or selectinload should be considered for optimization.

Medium - Inefficient Search Query for Large Datasets

The search_posts method uses ilike for full-text search, which can be inefficient on large datasets without proper database indexing or a dedicated search solution.