Important Notice

While using ChatGPT, don't copy-paste exact content. Read carefully and make necessary changes.

1. Introduction

We use RapiDoc for documenting API endpoints, providing a structured, user-friendly interface for accessing endpoint details, parameters, and response formats.

For technical code documentation, we utilize Doxygen to ensure detailed, consistent documentation directly within the codebase, capturing function details, data structures, and internal workings.

2. Controllers Documentation Standards

2.1. Class
2.1.1 For API Documentation
Row Code

using CodePulse.API.Data;
using CodePulse.API.Models.Domain;
using CodePulse.API.Models.DTO;
using CodePulse.API.Repositories.Interface;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using System.Net.WebSockets;

namespace CodePulse.API.Controllers
{
    public class CategoriesController : ControllerBase
    {

    }
}
Add Metadata Attributes

    using CodePulse.API.Data;
    using CodePulse.API.Models.Domain;
    using CodePulse.API.Models.DTO;
    using CodePulse.API.Repositories.Interface;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Mvc;
    using Swashbuckle.AspNetCore.Annotations;
    using System.Net.WebSockets;

    namespace CodePulse.API.Controllers
    {

    [Route("sioniq/[controller]")]
    [ApiController]
    [Produces("application/json")]
    public class CategoriesController : ControllerBase
    {

    }
    }
With XML Comments
Use ChatGpt

Copy paste the row code in the ChatGpt and type "Inclulde XML Comments in the code".


using CodePulse.API.Data;
using CodePulse.API.Models.Domain;
using CodePulse.API.Models.DTO;
using CodePulse.API.Repositories.Interface;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using System.Net.WebSockets;

namespace CodePulse.API.Controllers
{

/// <summary>
/// Controller to manage category-related operations.
/// </summary>
/// <remarks>
/// This controller is responsible for handling HTTP requests related to categories, including CRUD operations.
/// It uses the <see cref="ICategoryRepository" /> to interact with the underlying data store and returns
/// results in JSON format.
/// </remarks>

[Route("sioniq/[controller]")]
[ApiController]
[Produces("application/json")]
public class CategoriesController : ControllerBase
{

}
}
2.1.2 For Code Documentation

No need to do any thing for code documentation[Doxygen] for controller class

2.2 Post Method
2.2.1 For API Documentation
Without XML Comments

public async Task CreateCategory(CreateCategoryRequestDto request)
{
        if (!ModelState.IsValid)
        {
           return BadRequest(ModelState);
        }

        var category = new Category
        {
           Name = request.Name,
           UrlHandle = request.UrlHandle
        };

        await categoryRepository.CreateAsync(category);

        var response = new CategoryDto
        {
           Id = category.Id,
           Name = category.Name,
           UrlHandle = category.UrlHandle
        };

        return Ok(response);
}
Add Metadata Attributes

[HttpPost]
[ProducesResponseType(typeof(CategoryDto), 200)]
[ProducesResponseType(400)]
public async Task CreateCategory(CreateCategoryRequestDto request)
{
        if (!ModelState.IsValid)
        {
           return BadRequest(ModelState);
        }

        var category = new Category
        {
           Name = request.Name,
           UrlHandle = request.UrlHandle
        };

        await categoryRepository.CreateAsync(category);

        var response = new CategoryDto
        {
           Id = category.Id,
           Name = category.Name,
           UrlHandle = category.UrlHandle
        };

        return Ok(response);
}
With XML Comments
Use ChatGpt

Copy paste the row code in the ChatGpt and type "Inclulde XML Comments in the code".


/// <summary>
/// Creates a new category based on the provided data.
/// </summary>
/// <param name="request">The request object containing the data for the new category.</param>
/// <returns>An IActionResult representing the outcome of the creation operation.</returns>
/// <response code="200">Returns the created CategoryDto object.</response>
/// <response code="400">If the provided data is invalid.</response>

[HttpPost]
[ProducesResponseType(typeof(CategoryDto), 200)]
[ProducesResponseType(400)]
public async Task CreateCategory(CreateCategoryRequestDto request)
{
    if (!ModelState.IsValid)
    {
    return BadRequest(ModelState);
    }

    var category = new Category
    {
    Name = request.Name,
    UrlHandle = request.UrlHandle
    };

    await categoryRepository.CreateAsync(category);

    var response = new CategoryDto
    {
    Id = category.Id,
    Name = category.Name,
    UrlHandle = category.UrlHandle
    };

    return Ok(response);
}
2.2.2 For Code Documentation
Use ChatGpt

Copy paste the row code in the ChatGpt and type "Doxygen-compatible comments in the /*! ... */ format, along with code snippets for each step".


/// <summary>
/// Creates a new category based on the provided data.
/// </summary>
/// <param name="request">The request object containing the data for the new category.</param>
/// <returns>An IActionResult representing the outcome of the creation operation.</returns>
/// <response code="200">Returns the created CategoryDto object.</response>
/// <response code="400">If the provided data is invalid.</response>

[HttpPost]
[ProducesResponseType(typeof(CategoryDto), 200)]
[ProducesResponseType(400)]
public async TaskCreateCategory(CreateCategoryRequestDto request)
{
/*!
* @brief Validate the model state.
* @details Checks if the `request` object meets the model requirements.
* If the model state is invalid, it returns a 400 Bad Request response with the validation errors.
*
* @code
* if (!ModelState.IsValid)
* {
*     return BadRequest(ModelState);
* }
* @endcode
*/
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}

/*!
* @brief Convert `CreateCategoryRequestDto` to `Category` domain model.
* @details Creates a new `Category` object and populates it with data from `request`.
* This prepares the data to be stored in the repository.
*
* @code
* var category = new Category
* {
*     Name = request.Name,
*     UrlHandle = request.UrlHandle
* };
* @endcode
*/
var category = new Category
{
Name = request.Name,
UrlHandle = request.UrlHandle
};

/*!
* @brief Save the new category to the repository.
* @details Calls the repository's `CreateAsync` method to insert the new category into the database.
* This is an asynchronous operation.
*
* @code
* await categoryRepository.CreateAsync(category);
* @endcode
*/
await categoryRepository.CreateAsync(category);

/*!
* @brief Prepare the response DTO.
* @details Creates a `CategoryDto` object containing the details of the created category,
* including the `Id` assigned by the repository, and maps the values from the `Category` domain model.
*
* @code
* var response = new CategoryDto
* {
*     Id = category.Id,
*     Name = category.Name,
*     UrlHandle = category.UrlHandle
* };
* @endcode
*/
var response = new CategoryDto
{
Id = category.Id,
Name = category.Name,
UrlHandle = category.UrlHandle
};

/*!
* @brief Return the response with the created category data.
* @details Sends an HTTP 200 OK response with the newly created category in the form of a `CategoryDto` object.
*
* @code
* return Ok(response);
* @endcode
*/
return Ok(response);
}
2.3 Get Method
2.3.1 For API Documentation
Row Code

public async Task GetAllCategories()
{
     var categories = await categoryRepository.GetAllAsync();
     var response = new List();
     
     foreach (var category in categories)
     {
        response.Add(new CategoryDto
        {
            Id = category.Id,
            Name = category.Name,
            UrlHandle = category.UrlHandle
        });
     }
return Ok(response);
}
Add Metadata Attributes

[HttpGet]
[ProducesResponseType(typeof(List), 200)]
public async TaskGetAllCategories()
{
    var categories = await categoryRepository.GetAllAsync();
    var response = new List();

    foreach (var category in categories)
    {
    response.Add(new CategoryDto
    {
       Id = category.Id,
       Name = category.Name,
       UrlHandle = category.UrlHandle
       });
    }
    return Ok(response);
}
With XML Comments
Use ChatGpt

Copy paste the row code in the ChatGpt and type "Inclulde XML Comments in the code".


/// <summary>
/// Retrieves all categories.
/// </summary>
/// <returns>An IActionResult representing the list of categories.</returns>
/// <response code="200">Returns a list of CategoryDto objects.</response>
[HttpGet]
[ProducesResponseType(typeof(List), 200)]
public async TaskGetAllCategories()
{
    var categories = await categoryRepository.GetAllAsync();
    var response = new List();

    foreach (var category in categories)
    {
    response.Add(new CategoryDto
    {
       Id = category.Id,
       Name = category.Name,
       UrlHandle = category.UrlHandle
       });
    }
    return Ok(response);
}
2.3.2 For Code Documentation
Use ChatGpt

Copy paste the row code in the ChatGpt and type "Doxygen-compatible comments in the /*! ... */ format, along with code snippets for each step".


Refere Section 2.2.2
2.4 Put Method
2.4.1 For API Documentation
Row Code

public async TaskEditCategory([FromRoute] Guid id, UpdateCategoryRequestDto request)
{
    var category = new Category
    {
        Id = id,
        Name = request.Name,
        UrlHandle = request.UrlHandle
    };

    category = await categoryRepository.UpdateAsync(category);

    if (category is null)
    {
        return NotFound();
    }

    var response = new CategoryDto
    {
        Id = category.Id,
        Name = category.Name,
        UrlHandle = category.UrlHandle
    };

    return Ok(response);
}
Add Metadata Attributes

[HttpPut]
[Route("{id:guid}")]
[ProducesResponseType(typeof(CategoryDto), 200)]
public async TaskEditCategory([FromRoute] Guid id, UpdateCategoryRequestDto request)
{
    var category = new Category
    {
        Id = id,
        Name = request.Name,
        UrlHandle = request.UrlHandle
    };
    
    category = await categoryRepository.UpdateAsync(category);
    
    if (category is null)
    {
        return NotFound();
    }
    
    var response = new CategoryDto
    {
        Id = category.Id,
        Name = category.Name,
        UrlHandle = category.UrlHandle
    };
    
    return Ok(response);
}
With XML Comments
Use ChatGpt

Copy paste the row code in the ChatGpt and type "Inclulde XML Comments in the code".


/// <summary>
/// Edits an existing category identified by its unique GUID.
/// </summary>
/// <param name="id">The unique identifier of the category to edit.</param>
/// <param name="request">The data transfer object containing the updated category information.</param>
/// <returns>An IActionResult representing the outcome of the operation.</returns>
/// <response code="200">Returns the updated CategoryDto if the operation is successful.</response>
/// <response code="404">If the category with the specified ID was not found.</response>
[HttpPut]
[Route("{id:guid}")]
[ProducesResponseType(typeof(CategoryDto), 200)]
public async TaskEditCategory([FromRoute] Guid id, UpdateCategoryRequestDto request)
{
   var category = new Category
   {
      Id = id,
      Name = request.Name,
      UrlHandle = request.UrlHandle
   };
   
   category = await categoryRepository.UpdateAsync(category);
   
   if (category is null)
   {
      return NotFound();
   }
   
   var response = new CategoryDto
   {
      Id = category.Id,
      Name = category.Name,
      UrlHandle = category.UrlHandle
   };

return Ok(response);
}
2.4.2 For Code Documentation
Use ChatGpt

Copy paste the row code in the ChatGpt and type "Doxygen-compatible comments in the /*! ... */ format, along with code snippets for each step".


Refere Section 2.2.2
2.5 Delete Method
2.5.1 For API Documentation
Row Code
    
public async TaskDeleteCategory([FromRoute] Guid id)
{
    var category = await categoryRepository.DeleteAsync(id);

    if (category is null)
    {
       return NotFound();
    }

    var response = new Category
    {
       Id = category.Id,
       Name = category.Name,
       UrlHandle = category.UrlHandle
    };

    return Ok(response);
}
Add Metadata Attributes

[HttpDelete]
[Route("{id:guid}")]
[ProducesResponseType(typeof(Category), 200)]
public async TaskDeleteCategory([FromRoute] Guid id)
{
    var category = await categoryRepository.DeleteAsync(id);

    if (category is null)
    {
       return NotFound();
    }

    var response = new Category
    {
       Id = category.Id,
       Name = category.Name,
       UrlHandle = category.UrlHandle
    };

    return Ok(response);
}
With XML Comments
Use ChatGpt

Copy paste the row code in the ChatGpt and type "Inclulde XML Comments in the code".


///DELETE: /api/categories/{id}
/// <summary>
/// Deletes a category identified by its unique GUID.
/// </summary>
/// <param name="id">The unique identifier of the category to delete.</param>
/// <returns>An IActionResult representing the outcome of the deletion operation.</returns>
/// <response code="200">Returns the deleted Category if the operation is successful.</response>
/// <response code="404">If the category with the specified ID was not found.</response>
[HttpDelete]
[Route("{id:guid}")]
[ProducesResponseType(typeof(Category), 200)]
public async TaskDeleteCategory([FromRoute] Guid id)
{
    var category = await categoryRepository.DeleteAsync(id);

    if (category is null)
    {
       return NotFound();
    }

    var response = new Category
    {
       Id = category.Id,
       Name = category.Name,
       UrlHandle = category.UrlHandle
    };

    return Ok(response);
}
2.5.2 For Code Documentation
Use ChatGpt

Copy paste the row code in the ChatGpt and type "Doxygen-compatible comments in the /*! ... */ format, along with code snippets for each step".


Refere Section 2.2.2

3. Class [Other than Controllers,Domain and DTO]

3.1. For Code Documentation [Doxygen]
Row Code

public class CategoryRepository : ICategoryRepository
{
    private readonly ApplicationDbContext dbContext;
            
    public CategoryRepository(ApplicationDbContext dbContext)
    {
        this.dbContext = dbContext;
    }
            
    public async Task<Category> CreateAsync(Category category)
    {
        await dbContext.Categories.AddAsync(category);
        await dbContext.SaveChangesAsync();

        return category;
    }
            
    public async Task<Category?> DeleteAsync(Guid id)
    {
        var existingCategory = await dbContext.Categories.FirstOrDefaultAsync(c => c.Id == id);
        if (existingCategory is null)
        {
            return null;
        }
        dbContext.Categories.Remove(existingCategory);
        await dbContext.SaveChangesAsync();
        return existingCategory;
    }
    
    public async Task<IEnumerable<Category>> GetAllAsync()
    {
        return await dbContext.Categories.ToListAsync();
    }
            
    public async Task<Category?> GetById(Guid id)
    {
        return await dbContext.Categories.FirstOrDefaultAsync(x => x.Id == id);
    }
            
    public async Task<Category?> UpdateAsync(Category category)
    {
        var existingCategory = await dbContext.Categories.FirstOrDefaultAsync(x => x.Id == category.Id);
        if (existingCategory != null)
        {
            dbContext.Entry(existingCategory).CurrentValues.SetValues(category);
            await dbContext.SaveChangesAsync();
            return category;
        }
        return null;
    }
}
Use ChatGpt

Copy paste the row code in the ChatGpt and type "Doxygen-compatible comments outside and inside each method using the /*! ... */ format, along with code snippets for each step".

With Comments

/// <summary>
/// Repository class for managing Category entities in the database.
/// </summary>
public class CategoryRepository : ICategoryRepository
{
    private readonly ApplicationDbContext dbContext;

    /*!
     * \brief Constructor to initialize the CategoryRepository with the provided DbContext.
     * \param dbContext The database context for accessing categories in the database.
     */
    public CategoryRepository(ApplicationDbContext dbContext)
    {
        this.dbContext = dbContext;
    }

    /*!
     * \brief Asynchronously creates a new Category entity in the database.
     * \param category The Category object to be added to the database.
     * \return The newly created Category object.
     * 
     * This method adds the provided category to the database context and saves the changes asynchronously.
     */
    public async Task<Category> CreateAsync(Category category)
    {
        /*! Add the category to the database context */
        await dbContext.Categories.AddAsync(category);

        /*! Save changes to the database */
        await dbContext.SaveChangesAsync();

        /*! Return the created category */
        return category;
    }

    /*!
     * \brief Asynchronously deletes a Category entity by its unique identifier.
     * \param id The unique identifier of the Category to be deleted.
     * \return The deleted Category object if it exists; otherwise, null.
     * 
     * This method first retrieves the category by its ID, then deletes it if found.
     */
    public async Task<Category?> DeleteAsync(Guid id)
    {
        /*! Find the category with the specified ID */
        var existingCategory = await dbContext.Categories.FirstOrDefaultAsync(c => c.Id == id);

        /*! Return null if no category is found with the specified ID */
        if (existingCategory is null)
        {
            return null;
        }

        /*! Remove the found category from the database context */
        dbContext.Categories.Remove(existingCategory);

        /*! Save changes to the database */
        await dbContext.SaveChangesAsync();

        /*! Return the deleted category */
        return existingCategory;
    }

    /*!
     * \brief Asynchronously retrieves all Category entities from the database.
     * \return A list of all Category objects in the database.
     * 
     * This method retrieves all categories as a list from the database.
     */
    public async Task<IEnumerable<Category>> GetAllAsync()
    {
        /*! Fetch and return all categories in the database */
        return await dbContext.Categories.ToListAsync();
    }

    /*!
     * \brief Asynchronously retrieves a Category entity by its unique identifier.
     * \param id The unique identifier of the Category to retrieve.
     * \return The Category object if found; otherwise, null.
     * 
     * This method retrieves the category matching the specified ID.
     */
    public async Task<Category?> GetById(Guid id)
    {
        /*! Find and return the category with the specified ID, or null if not found */
        return await dbContext.Categories.FirstOrDefaultAsync(x => x.Id == id);
    }

    /*!
     * \brief Asynchronously updates an existing Category entity in the database.
     * \param category The Category object with updated values.
     * \return The updated Category object if the update was successful; otherwise, null.
     * 
     * This method checks if the category exists, and if so, updates it with the new values.
     */
    public async Task<Category?> UpdateAsync(Category category)
    {
        /*! Find the existing category with the specified ID */
        var existingCategory = await dbContext.Categories.FirstOrDefaultAsync(x => x.Id == category.Id);

        /*! Check if the category exists */
        if (existingCategory != null)
        {
            /*! Update the existing category with new values from the input category */
            dbContext.Entry(existingCategory).CurrentValues.SetValues(category);

            /*! Save the updated category to the database */
            await dbContext.SaveChangesAsync();

            /*! Return the updated category */
            return category;
        }

        /*! Return null if the category was not found */
        return null;
    }
}

4. Domain and DTO Classes

4.1. Use XML Comments
Row Code

public class BlogPost
{
    public Guid Id { get; set; }
    public string Title { get; set; }
    public string Shortdescription { get; set; }
    public string Content { get; set; }
    public string FeaturedImageUrl { get; set; }
    public string UrlHandle { get; set; }
    public DateTime PublishedDate { get; set; }
    public string Author { get; set; }
    public bool IsVisible { get; set; }           
    public ICollection<Category> Categories { get; set; }
}
Use ChatGpt

Copy paste the row code in the ChatGpt and type "XML comments for properties.".

With XML Comments

/// <summary>
/// Represents a blog post with content, metadata, and categories.
/// </summary>
public class BlogPost
{
    /// <summary>
    /// Gets or sets the unique identifier for the blog post.
    /// </summary>
    public Guid Id { get; set; }

    /// <summary>
    /// Gets or sets the title of the blog post.
    /// </summary>
    public string Title { get; set; }

    /// <summary>
    /// Gets or sets a short description or summary of the blog post.
    /// </summary>
    public string Shortdescription { get; set; }

    /// <summary>
    /// Gets or sets the main content of the blog post.
    /// </summary>
    public string Content { get; set; }

    /// <summary>
    /// Gets or sets the URL of the featured image for the blog post.
    /// </summary>
    public string FeaturedImageUrl { get; set; }

    /// <summary>
    /// Gets or sets the URL handle for the blog post, used in URLs for SEO.
    /// </summary>
    public string UrlHandle { get; set; }

    /// <summary>
    /// Gets or sets the date the blog post was published.
    /// </summary>
    public DateTime PublishedDate { get; set; }

    /// <summary>
    /// Gets or sets the author of the blog post.
    /// </summary>
    public string Author { get; set; }

    /// <summary>
    /// Gets or sets a value indicating whether the blog post is visible to readers.
    /// </summary>
    public bool IsVisible { get; set; }

    /// <summary>
    /// Gets or sets the collection of categories associated with the blog post.
    /// </summary>
    public ICollection<Category> Categories { get; set; }
}
4.2. Use Annotations
Validation Annotations

Validation attributes are used to enforce rules on data properties in the model classes.

Data Formatting Annotations

These attributes help format the data when it’s displayed or sent in a response.

Relational Data Annotations

In domain classes, these attributes help define relationships for Entity Framework Core.

Use ChatGpt

Copy paste the row code in the ChatGpt and type "Add annotations in this code".

With Annotations

/// <summary>
/// Represents a blog post with content, metadata, and categories.
/// </summary>
public class BlogPost
{
    /// <summary>
    /// Gets or sets the unique identifier for the blog post.
    /// </summary>  
    [Required]  // Indicates that this field is required
    public Guid Id { get; set; }

    /// <summary>
    /// Gets or sets the title of the blog post.
    /// </summary>
    [Required]  // Title must be provided
    [StringLength(100, MinimumLength = 5)]  // Title length constraint
    public string Title { get; set; }

    /// <summary>
    /// Gets or sets a short description or summary of the blog post.
    /// </summary>
    [StringLength(250)]  // Description length constraint
    public string Shortdescription { get; set; }

    /// <summary>
    /// Gets or sets the main content of the blog post.
    /// </summary>
    [Required]  // Content is required
    public string Content { get; set; }

    /// <summary>
    /// Gets or sets the URL of the featured image for the blog post.
    /// </summary>
    [Url]  // Ensures the value is a valid URL
    public string FeaturedImageUrl { get; set; }

    /// <summary>
    /// Gets or sets the URL handle for the blog post, used in URLs for SEO.
    /// </summary>
    [Required]  // UrlHandle is required
    [StringLength(50)]  // Limiting the length of the URL handle
    public string UrlHandle { get; set; }

    /// <summary>
    /// Gets or sets the date the blog post was published.
    /// </summary>
    [Required]  // PublishedDate is required
    [DataType(DataType.DateTime)]  // Specifies that it's a date-time value
    public DateTime PublishedDate { get; set; }

    /// <summary>
    /// Gets or sets the author of the blog post.
    /// </summary>
    [Required]  // Author is required
    [StringLength(100)]  // Limit to 100 characters
    public string Author { get; set; }

    /// <summary>
    /// Gets or sets a value indicating whether the blog post is visible to readers.
    /// </summary>
    public bool IsVisible { get; set; }

    /// <summary>
    /// Gets or sets the collection of categories associated with the blog post.
    /// </summary>
    [Required]  // Categories is required
    public ICollection<Category> Categories { get; set; }
}