feature/portfolio-admin-auth #2

Merged
rajukottedi merged 4 commits from feature/portfolio-admin-auth into dev 2026-02-15 13:27:59 +05:30
77 changed files with 15190 additions and 224 deletions

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPublishable>false</IsPublishable>

View File

@ -1,30 +1,113 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.9.34701.34
# Visual Studio Version 18
VisualStudioVersion = 18.1.11304.174
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PortBlog.API", "PortBlog.API\PortBlog.API.csproj", "{2E50B5D7-56E2-4E89-8742-BB57FF4245F9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AesEncryption", "AesEncryption\AesEncryption.csproj", "{26654BFD-EE9B-49BA-84BA-9156AC348076}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{868B8641-C2BB-415C-816A-4FB477DA009B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KBR.Cache", "Shared\KBR.Cache\KBR.Cache.csproj", "{DA0B3995-A83A-4D7C-A964-ADFE1F58B1FA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KBR.Shared", "Shared\KBR.Shared\KBR.Shared.csproj", "{1C0F86E4-A791-4150-B9B3-B761925681DD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KBR.Shared.Lite", "Shared\KBR.Share.Lite\KBR.Shared.Lite.csproj", "{F4B7078B-C59A-46B8-881A-C3CEE2634498}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PortBlog.Tests", "PortBlog.Tests\PortBlog.Tests.csproj", "{11106F82-FC17-497D-8747-CF1A84BFA7F8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2E50B5D7-56E2-4E89-8742-BB57FF4245F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2E50B5D7-56E2-4E89-8742-BB57FF4245F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2E50B5D7-56E2-4E89-8742-BB57FF4245F9}.Debug|x64.ActiveCfg = Debug|Any CPU
{2E50B5D7-56E2-4E89-8742-BB57FF4245F9}.Debug|x64.Build.0 = Debug|Any CPU
{2E50B5D7-56E2-4E89-8742-BB57FF4245F9}.Debug|x86.ActiveCfg = Debug|Any CPU
{2E50B5D7-56E2-4E89-8742-BB57FF4245F9}.Debug|x86.Build.0 = Debug|Any CPU
{2E50B5D7-56E2-4E89-8742-BB57FF4245F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2E50B5D7-56E2-4E89-8742-BB57FF4245F9}.Release|Any CPU.Build.0 = Release|Any CPU
{2E50B5D7-56E2-4E89-8742-BB57FF4245F9}.Release|x64.ActiveCfg = Release|Any CPU
{2E50B5D7-56E2-4E89-8742-BB57FF4245F9}.Release|x64.Build.0 = Release|Any CPU
{2E50B5D7-56E2-4E89-8742-BB57FF4245F9}.Release|x86.ActiveCfg = Release|Any CPU
{2E50B5D7-56E2-4E89-8742-BB57FF4245F9}.Release|x86.Build.0 = Release|Any CPU
{26654BFD-EE9B-49BA-84BA-9156AC348076}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{26654BFD-EE9B-49BA-84BA-9156AC348076}.Debug|Any CPU.Build.0 = Debug|Any CPU
{26654BFD-EE9B-49BA-84BA-9156AC348076}.Debug|x64.ActiveCfg = Debug|Any CPU
{26654BFD-EE9B-49BA-84BA-9156AC348076}.Debug|x64.Build.0 = Debug|Any CPU
{26654BFD-EE9B-49BA-84BA-9156AC348076}.Debug|x86.ActiveCfg = Debug|Any CPU
{26654BFD-EE9B-49BA-84BA-9156AC348076}.Debug|x86.Build.0 = Debug|Any CPU
{26654BFD-EE9B-49BA-84BA-9156AC348076}.Release|Any CPU.ActiveCfg = Release|Any CPU
{26654BFD-EE9B-49BA-84BA-9156AC348076}.Release|Any CPU.Build.0 = Release|Any CPU
{26654BFD-EE9B-49BA-84BA-9156AC348076}.Release|x64.ActiveCfg = Release|Any CPU
{26654BFD-EE9B-49BA-84BA-9156AC348076}.Release|x64.Build.0 = Release|Any CPU
{26654BFD-EE9B-49BA-84BA-9156AC348076}.Release|x86.ActiveCfg = Release|Any CPU
{26654BFD-EE9B-49BA-84BA-9156AC348076}.Release|x86.Build.0 = Release|Any CPU
{DA0B3995-A83A-4D7C-A964-ADFE1F58B1FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DA0B3995-A83A-4D7C-A964-ADFE1F58B1FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DA0B3995-A83A-4D7C-A964-ADFE1F58B1FA}.Debug|x64.ActiveCfg = Debug|Any CPU
{DA0B3995-A83A-4D7C-A964-ADFE1F58B1FA}.Debug|x64.Build.0 = Debug|Any CPU
{DA0B3995-A83A-4D7C-A964-ADFE1F58B1FA}.Debug|x86.ActiveCfg = Debug|Any CPU
{DA0B3995-A83A-4D7C-A964-ADFE1F58B1FA}.Debug|x86.Build.0 = Debug|Any CPU
{DA0B3995-A83A-4D7C-A964-ADFE1F58B1FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DA0B3995-A83A-4D7C-A964-ADFE1F58B1FA}.Release|Any CPU.Build.0 = Release|Any CPU
{DA0B3995-A83A-4D7C-A964-ADFE1F58B1FA}.Release|x64.ActiveCfg = Release|Any CPU
{DA0B3995-A83A-4D7C-A964-ADFE1F58B1FA}.Release|x64.Build.0 = Release|Any CPU
{DA0B3995-A83A-4D7C-A964-ADFE1F58B1FA}.Release|x86.ActiveCfg = Release|Any CPU
{DA0B3995-A83A-4D7C-A964-ADFE1F58B1FA}.Release|x86.Build.0 = Release|Any CPU
{1C0F86E4-A791-4150-B9B3-B761925681DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1C0F86E4-A791-4150-B9B3-B761925681DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1C0F86E4-A791-4150-B9B3-B761925681DD}.Debug|x64.ActiveCfg = Debug|Any CPU
{1C0F86E4-A791-4150-B9B3-B761925681DD}.Debug|x64.Build.0 = Debug|Any CPU
{1C0F86E4-A791-4150-B9B3-B761925681DD}.Debug|x86.ActiveCfg = Debug|Any CPU
{1C0F86E4-A791-4150-B9B3-B761925681DD}.Debug|x86.Build.0 = Debug|Any CPU
{1C0F86E4-A791-4150-B9B3-B761925681DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1C0F86E4-A791-4150-B9B3-B761925681DD}.Release|Any CPU.Build.0 = Release|Any CPU
{1C0F86E4-A791-4150-B9B3-B761925681DD}.Release|x64.ActiveCfg = Release|Any CPU
{1C0F86E4-A791-4150-B9B3-B761925681DD}.Release|x64.Build.0 = Release|Any CPU
{1C0F86E4-A791-4150-B9B3-B761925681DD}.Release|x86.ActiveCfg = Release|Any CPU
{1C0F86E4-A791-4150-B9B3-B761925681DD}.Release|x86.Build.0 = Release|Any CPU
{F4B7078B-C59A-46B8-881A-C3CEE2634498}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F4B7078B-C59A-46B8-881A-C3CEE2634498}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F4B7078B-C59A-46B8-881A-C3CEE2634498}.Debug|x64.ActiveCfg = Debug|Any CPU
{F4B7078B-C59A-46B8-881A-C3CEE2634498}.Debug|x64.Build.0 = Debug|Any CPU
{F4B7078B-C59A-46B8-881A-C3CEE2634498}.Debug|x86.ActiveCfg = Debug|Any CPU
{F4B7078B-C59A-46B8-881A-C3CEE2634498}.Debug|x86.Build.0 = Debug|Any CPU
{F4B7078B-C59A-46B8-881A-C3CEE2634498}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F4B7078B-C59A-46B8-881A-C3CEE2634498}.Release|Any CPU.Build.0 = Release|Any CPU
{F4B7078B-C59A-46B8-881A-C3CEE2634498}.Release|x64.ActiveCfg = Release|Any CPU
{F4B7078B-C59A-46B8-881A-C3CEE2634498}.Release|x64.Build.0 = Release|Any CPU
{F4B7078B-C59A-46B8-881A-C3CEE2634498}.Release|x86.ActiveCfg = Release|Any CPU
{F4B7078B-C59A-46B8-881A-C3CEE2634498}.Release|x86.Build.0 = Release|Any CPU
{11106F82-FC17-497D-8747-CF1A84BFA7F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{11106F82-FC17-497D-8747-CF1A84BFA7F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{11106F82-FC17-497D-8747-CF1A84BFA7F8}.Debug|x64.ActiveCfg = Debug|Any CPU
{11106F82-FC17-497D-8747-CF1A84BFA7F8}.Debug|x64.Build.0 = Debug|Any CPU
{11106F82-FC17-497D-8747-CF1A84BFA7F8}.Debug|x86.ActiveCfg = Debug|Any CPU
{11106F82-FC17-497D-8747-CF1A84BFA7F8}.Debug|x86.Build.0 = Debug|Any CPU
{11106F82-FC17-497D-8747-CF1A84BFA7F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{11106F82-FC17-497D-8747-CF1A84BFA7F8}.Release|Any CPU.Build.0 = Release|Any CPU
{11106F82-FC17-497D-8747-CF1A84BFA7F8}.Release|x64.ActiveCfg = Release|Any CPU
{11106F82-FC17-497D-8747-CF1A84BFA7F8}.Release|x64.Build.0 = Release|Any CPU
{11106F82-FC17-497D-8747-CF1A84BFA7F8}.Release|x86.ActiveCfg = Release|Any CPU
{11106F82-FC17-497D-8747-CF1A84BFA7F8}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{DA0B3995-A83A-4D7C-A964-ADFE1F58B1FA} = {868B8641-C2BB-415C-816A-4FB477DA009B}
{1C0F86E4-A791-4150-B9B3-B761925681DD} = {868B8641-C2BB-415C-816A-4FB477DA009B}
{F4B7078B-C59A-46B8-881A-C3CEE2634498} = {868B8641-C2BB-415C-816A-4FB477DA009B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B74EF3B9-68FB-42A1-9635-817DFB28CD9E}
EndGlobalSection

View File

@ -1,4 +1,4 @@
namespace PortBlog.API.Common
namespace PortBlog.API.Common.Constants
{
public static class MailConstants
{

View File

@ -0,0 +1,9 @@
namespace PortBlog.API.Common.Constants
{
public static class OptionNames
{
public const string JwtAuthentication = nameof(JwtAuthentication);
public const string OtpExpiryInMinutes = nameof(OtpExpiryInMinutes);
}
}

View File

@ -0,0 +1,422 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using PortBlog.API.Models;
using PortBlog.API.Services.Contracts;
namespace PortBlog.API.Controllers
{
/// <summary>
/// Controller for administrative actions related to the logged-in candidate and their resume.
/// All endpoints derive the candidate identity from the access token claims.
/// </summary>
[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/admin")]
[Authorize]
public class AdminController(ILogger<CvController> logger, IAdminService adminService) : Controller
{
/// <summary>
/// Get hobbies of the logged-in candidate.
/// </summary>
/// <returns>Hobbies and about details of the candidate</returns>
/// <response code="200">Returns the requested hobbies of the candidate</response>
[HttpGet("GetHobbies")]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<AboutDto>> GetHobbies()
{
try
{
var candidateId = adminService.GetCandidateIdFromClaims(User);
var aboutDetails = await adminService.GetHobbiesAsync(candidateId);
return Ok(aboutDetails);
}
catch (UnauthorizedAccessException ex)
{
logger.LogInformation(ex, "Unauthorized access when fetching hobbies.");
return Unauthorized(ex.Message);
}
catch (Exception ex)
{
logger.LogCritical(ex, "Exception while getting about details.");
return StatusCode(500, "A problem happened while handling your request.");
}
}
/// <summary>
/// Get contact details (candidate with social links) for the logged-in candidate.
/// </summary>
/// <returns>Candidate details with social links</returns>
/// <response code="200">Returns the requested candidate details with social links</response>
[HttpGet("GetCandidateWithSocialLinks")]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<CandidateSocialLinksDto>> GetContact()
{
try
{
var candidateId = adminService.GetCandidateIdFromClaims(User);
var contact = await adminService.GetContactAsync(candidateId);
return Ok(contact);
}
catch (UnauthorizedAccessException ex)
{
logger.LogInformation(ex, "Unauthorized access when fetching contact.");
return Unauthorized(ex.Message);
}
catch (Exception ex)
{
logger.LogCritical(ex, "Exception while getting contact details.");
return StatusCode(500, "A problem happened while handling your request.");
}
}
/// <summary>
/// Get resume for the logged-in candidate.
/// </summary>
/// <returns>Candidate resume</returns>
/// <response code="200">Returns the requested candidate resume</response>
[HttpGet("GetResume")]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<ResumeDto>> GetResume()
{
try
{
var candidateId = adminService.GetCandidateIdFromClaims(User);
var resume = await adminService.GetResumeAsync(candidateId);
return Ok(resume);
}
catch (UnauthorizedAccessException ex)
{
logger.LogInformation(ex, "Unauthorized access when fetching resume.");
return Unauthorized(ex.Message);
}
catch (Exception ex)
{
logger.LogCritical(ex, "Exception while getting resume.");
return StatusCode(500, "A problem happened while handling your request.");
}
}
/// <summary>
/// Get projects for the logged-in candidate.
/// </summary>
/// <returns>Candidate projects</returns>
/// <response code="200">Returns the requested candidate projects</response>
[HttpGet("GetProjects")]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<ProjectsDto>> GetProjects()
{
try
{
var candidateId = adminService.GetCandidateIdFromClaims(User);
var projects = await adminService.GetProjectsAsync(candidateId);
return Ok(projects);
}
catch (UnauthorizedAccessException ex)
{
logger.LogInformation(ex, "Unauthorized access when fetching projects.");
return Unauthorized(ex.Message);
}
catch (Exception ex)
{
logger.LogCritical(ex, "Exception while getting projects.");
return StatusCode(500, "A problem happened while handling your request.");
}
}
/// <summary>
/// Create or update a project for the logged-in candidate's resume.
/// </summary>
[HttpPost("UpsertProject")]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<ProjectDto>> UpsertProject([FromBody] ProjectDto projectDto)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var candidateId = adminService.GetCandidateIdFromClaims(User);
var result = await adminService.UpsertProjectAsync(candidateId, projectDto);
return Ok(result);
}
catch (UnauthorizedAccessException ex)
{
logger.LogInformation(ex, "Unauthorized access when upserting project.");
return Unauthorized(ex.Message);
}
catch (Exception ex)
{
logger.LogCritical(ex, "Exception while upserting project.");
return StatusCode(500, "A problem happened while handling your request.");
}
}
/// <summary>
/// Delete a project from the logged-in candidate's resume.
/// </summary>
/// <param name="projectId">The id of the project to delete</param>
[HttpDelete("DeleteProject/{projectId}")]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult> DeleteProject(int projectId)
{
try
{
var candidateId = adminService.GetCandidateIdFromClaims(User);
var deleted = await adminService.DeleteProjectAsync(candidateId, projectId);
if (!deleted)
{
return NotFound();
}
return Ok();
}
catch (UnauthorizedAccessException ex)
{
logger.LogInformation(ex, "Unauthorized access when deleting project.");
return Unauthorized(ex.Message);
}
catch (KeyNotFoundException ex)
{
logger.LogInformation(ex, "Resume not found when deleting project.");
return NotFound();
}
catch (Exception ex)
{
logger.LogCritical(ex, "Exception while deleting project {ProjectId}.", projectId);
return StatusCode(500, "A problem happened while handling your request.");
}
}
/// <summary>
/// Create, update, or remove hobbies and update the about section for the logged-in candidate.
/// Hobbies present in the list are added or updated; hobbies not in the list are removed.
/// </summary>
[HttpPost("UpsertHobbies")]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<AboutDto>> UpsertHobbies([FromBody] AboutDto aboutDto)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var candidateId = adminService.GetCandidateIdFromClaims(User);
var result = await adminService.UpsertHobbiesAsync(candidateId, aboutDto);
return Ok(result);
}
catch (UnauthorizedAccessException ex)
{
logger.LogInformation(ex, "Unauthorized access when upserting hobbies.");
return Unauthorized(ex.Message);
}
catch (KeyNotFoundException ex)
{
logger.LogInformation(ex, "Resume not found when upserting hobbies.");
return NotFound();
}
catch (Exception ex)
{
logger.LogCritical(ex, "Exception while upserting hobbies.");
return StatusCode(500, "A problem happened while handling your request.");
}
}
/// <summary>
/// Create, update, or remove skills for the logged-in candidate's resume.
/// Skills present in the list are added or updated; skills not in the list are removed.
/// </summary>
[HttpPost("UpsertSkills")]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<IEnumerable<SkillDto>>> UpsertSkills([FromBody] IEnumerable<SkillDto> skillDtos)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var candidateId = adminService.GetCandidateIdFromClaims(User);
var result = await adminService.UpsertSkillsAsync(candidateId, skillDtos);
return Ok(result);
}
catch (UnauthorizedAccessException ex)
{
logger.LogInformation(ex, "Unauthorized access when upserting skills.");
return Unauthorized(ex.Message);
}
catch (Exception ex)
{
logger.LogCritical(ex, "Exception while upserting skills.");
return StatusCode(500, "A problem happened while handling your request.");
}
}
/// <summary>
/// Create, update, or remove academics for the logged-in candidate's resume.
/// Academics present in the list are added or updated; academics not in the list are removed.
/// </summary>
[HttpPost("UpsertAcademics")]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<IEnumerable<AcademicDto>>> UpsertAcademics([FromBody] IEnumerable<AcademicDto> academicDtos)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var candidateId = adminService.GetCandidateIdFromClaims(User);
var result = await adminService.UpsertAcademicsAsync(candidateId, academicDtos);
return Ok(result);
}
catch (UnauthorizedAccessException ex)
{
logger.LogInformation(ex, "Unauthorized access when upserting academics.");
return Unauthorized(ex.Message);
}
catch (Exception ex)
{
logger.LogCritical(ex, "Exception while upserting academics.");
return StatusCode(500, "A problem happened while handling your request.");
}
}
/// <summary>
/// Create, update, or remove experiences for the logged-in candidate's resume.
/// Experiences present in the list are added or updated; experiences not in the list are removed.
/// </summary>
[HttpPost("UpsertExperiences")]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<IEnumerable<ExperienceDto>>> UpsertExperiences([FromBody] IEnumerable<ExperienceDto> experienceDtos)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var candidateId = adminService.GetCandidateIdFromClaims(User);
var result = await adminService.UpsertExperiencesAsync(candidateId, experienceDtos);
return Ok(result);
}
catch (UnauthorizedAccessException ex)
{
logger.LogInformation(ex, "Unauthorized access when upserting experiences.");
return Unauthorized(ex.Message);
}
catch (Exception ex)
{
logger.LogCritical(ex, "Exception while upserting experiences.");
return StatusCode(500, "A problem happened while handling your request.");
}
}
/// <summary>
/// Create, update, or remove certifications for the logged-in candidate's resume.
/// Certifications present in the list are added or updated; certifications not in the list are removed.
/// </summary>
[HttpPost("UpsertCertifications")]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<IEnumerable<CertificationDto>>> UpsertCertifications([FromBody] IEnumerable<CertificationDto> certificationDtos)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var candidateId = adminService.GetCandidateIdFromClaims(User);
var result = await adminService.UpsertCertificationsAsync(candidateId, certificationDtos);
return Ok(result);
}
catch (UnauthorizedAccessException ex)
{
logger.LogInformation(ex, "Unauthorized access when upserting certifications.");
return Unauthorized(ex.Message);
}
catch (Exception ex)
{
logger.LogCritical(ex, "Exception while upserting certifications.");
return StatusCode(500, "A problem happened while handling your request.");
}
}
/// <summary>
/// Create or update contact information (candidate with social links) for the logged-in candidate.
/// </summary>
[HttpPost("UpsertContact")]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<CandidateSocialLinksDto>> UpsertContact([FromBody] CandidateSocialLinksDto contactDto)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var candidateId = adminService.GetCandidateIdFromClaims(User);
var result = await adminService.UpsertContactAsync(candidateId, contactDto);
return Ok(result);
}
catch (UnauthorizedAccessException ex)
{
logger.LogInformation(ex, "Unauthorized access when upserting contact.");
return Unauthorized(ex.Message);
}
catch (KeyNotFoundException ex)
{
logger.LogInformation(ex, "Resume not found when upserting contact.");
return NotFound();
}
catch (Exception ex)
{
logger.LogCritical(ex, "Exception while upserting contact.");
return StatusCode(500, "A problem happened while handling your request.");
}
}
}
}

View File

@ -0,0 +1,188 @@
using Asp.Versioning;
using AutoMapper;
using KBR.Cache;
using Microsoft.AspNetCore.Mvc;
using PortBlog.API.Entities;
using PortBlog.API.Models;
using PortBlog.API.Repositories.Contracts;
using PortBlog.API.Services.Contracts;
namespace PortBlog.API.Controllers
{
/// <summary>
/// Controller for handling authentication-related operations.
/// </summary>
[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/auth")]
public class AuthController(IAuthService authService, IMailService mailService, ICandidateRepository candidateRepository, ILogger<AuthController> logger, IMapper mapper, IConfiguration configuration, ITemplateService templateService, IAppDistributedCache cache) : ControllerBase
{
/// <summary>
/// Generates a One-Time Password (OTP) for the specified candidate and sends it via email.
/// </summary>
/// <param name="email">The email of the candidate for whom the OTP is generated.</param>
/// <returns>An ActionResult indicating the result of the operation.</returns>
[HttpPost("GenerateOtp")]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult> GenerateOtp([FromForm] string email)
{
var messageSendDto = new MessageSendDto();
try
{
var candidate = await candidateRepository.GetCandidateAsync(email);
if (candidate == null)
{
logger.LogInformation("Candidate with email ({Email}) wasn't found.", email);
return NotFound();
}
var candidateDto = mapper.Map<CandidateDto>(candidate);
var otp = await authService.GenerateOtp(email);
var otpModel = new OtpMailModel()
{
OtpCode = otp,
Name = candidateDto.DisplayName,
ExpiryMinutes = configuration.GetValue<int>("OtpExpiryInMinutes", 3)
};
messageSendDto.CandidateId = candidate.CandidateId;
messageSendDto.ToEmail = candidateDto.Email;
messageSendDto.Name = candidateDto.DisplayName;
messageSendDto.Subject = "OTP for Login";
messageSendDto.Content = await templateService.GetViewTemplate("Views/Email/OtpEmailTemplate.cshtml", otpModel);
await mailService.SendAsync(messageSendDto);
return Ok(true);
}
catch (Exception ex)
{
logger.LogCritical(ex, "Exception while sending OTP for {ToEmail}.", messageSendDto.ToEmail);
return StatusCode(500, "A problem happened while handling your request.");
}
}
/// <summary>
/// Verifies the One-Time Password (OTP) for the specified user.
/// </summary>
/// <param name="request">The request containing the user ID and OTP code to verify.</param>
/// <returns>An ActionResult indicating the result of the verification.</returns>
[HttpPost("ValidateOtp")]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult> VerifyOtp([FromBody] VerifyOtpRequest request)
{
try
{
if (request == null || string.IsNullOrEmpty(request.UserId) || string.IsNullOrEmpty(request.OtpCode))
return BadRequest(new { message = "Invalid request data." });
var secretKey = await CacheHelpers.GetUserOtpSecretAsync(cache, request.UserId);
if(secretKey == null)
{
return Unauthorized(new { message = "OTP Expired" });
}
var result = authService.ValidateOtp(secretKey, request.OtpCode);
if (!result)
return Unauthorized(new { message = "Invalid OTP" });
var accessToken = authService.GenerateAccessToken(request.UserId);
var refreshToken = authService.GenerateRefreshToken();
// Store hashed refresh token in DB
await authService.SaveRefreshToken(request.UserId, refreshToken, HttpContext);
// Set HttpOnly cookie
SetRefreshTokenCookie(refreshToken);
return Ok(new { accessToken }); // only access token is returned in response body
}
catch (Exception ex)
{
logger.LogCritical(ex, "Exception while validating OTP for {UserId}.", request?.UserId);
return StatusCode(500, "A problem happened while handling your request.");
}
}
/// <summary>
/// Refreshes the access token using a valid refresh token from the HttpOnly cookie.
/// </summary>
/// <returns>An IActionResult containing the new access token if the refresh token is valid; otherwise, an appropriate error response.</returns>
[HttpPost("RefreshToken")]
public async Task<IActionResult> Refresh()
{
// Read refresh token from HttpOnly cookie
if (!Request.Cookies.TryGetValue("refreshToken", out var refreshToken))
return Unauthorized();
var matchedToken = await authService.GetRefreshToken(refreshToken);
if (matchedToken == null) return Forbid();
// Rotate refresh token
matchedToken.Revoked = true;
var newRefreshToken = authService.GenerateRefreshToken();
var hashedNewToken = BCrypt.Net.BCrypt.HashPassword(newRefreshToken);
var newRefreshEntity = new RefreshToken
{
UserId = matchedToken.UserId,
Token = hashedNewToken,
ExpiryDate = DateTime.UtcNow.AddHours(configuration.GetValue<int>("Jwt:RefreshTokenExpiryInHours", 24)),
JwtId = Guid.NewGuid().ToString(),
DeviceInfo = matchedToken.DeviceInfo,
ReplacedByToken = matchedToken.Token
};
await authService.SaveRefreshToken(newRefreshEntity);
// Update cookie
SetRefreshTokenCookie(newRefreshToken);
var newAccessToken = authService.GenerateAccessToken(matchedToken.User.Email);
return Ok(new { accessToken = newAccessToken });
}
/// <summary>
/// Logs out the current user by removing the refresh token cookie and invalidating the refresh token.
/// </summary>
/// <returns>An IActionResult indicating the result of the logout operation.</returns>
[HttpPost("logout")]
public async Task<IActionResult> Logout()
{
// Remove refresh token cookie
if (Request.Cookies.TryGetValue("refreshToken", out var incoming))
{
await authService.RemoveRefreshToken(incoming);
}
Response.Cookies.Delete("refreshToken", new CookieOptions
{
HttpOnly = true,
Secure = true,
SameSite = SameSiteMode.None,
Expires = DateTime.UtcNow.AddDays(-1)
});
return Ok(new { message = "Logged out successfully" });
}
private void SetRefreshTokenCookie(string refreshToken)
{
var cookieOptions = new CookieOptions
{
HttpOnly = true, // JS cannot access
Secure = true, // HTTPS only
SameSite = SameSiteMode.None, // Prevent CSRF
Expires = DateTime.UtcNow.AddDays(7)
};
Response.Cookies.Append("refreshToken", refreshToken, cookieOptions);
}
}
}

View File

@ -1,6 +1,5 @@
using Asp.Versioning;
using AutoMapper;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using PortBlog.API.Entities;
using PortBlog.API.Models;
@ -11,7 +10,7 @@ namespace PortBlog.API.Controllers
{
[Route("blog/api/v{version:apiVersion}/posts")]
[ApiController]
[ApiVersion(1)]
[ApiVersion("1.0")]
public class BlogController : ControllerBase
{
private readonly ILogger<BlogController> _logger;

View File

@ -1,17 +1,15 @@
using Asp.Versioning;
using AutoMapper;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using PortBlog.API.Entities;
using PortBlog.API.Models;
using PortBlog.API.Repositories.Contracts;
using PortBlog.API.Services.Contracts;
namespace PortBlog.API.Controllers
{
[Route("api/v{versions:apiVersion}/cv")]
[ApiController]
[ApiVersion(1)]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/cv")]
public class CvController : ControllerBase
{
private readonly ILogger<CvController> _logger;
@ -39,7 +37,7 @@ namespace PortBlog.API.Controllers
/// <response code="200">Returns the requested cv of the candidate</response>
[HttpGet("{candidateId}")]
[Obsolete]
[ApiVersion(0.1, Deprecated = true)]
[ApiVersion("0.1", Deprecated = true)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
@ -257,7 +255,7 @@ namespace PortBlog.API.Controllers
var candidateDto = _mapper.Map<CandidateDto>(candidate);
var messageSendDto = _mapper.Map<MessageSendDto>(message);
messageSendDto.ToEmail = candidateDto.Email;
messageSendDto.CandidateName = candidateDto.DisplayName;
messageSendDto.Name = candidateDto.DisplayName;
messageSendDto.CandidateId = candidateDto.CandidateId;
await _mailService.SendAsync(messageSendDto);
return Ok(true);

View File

@ -1,9 +1,11 @@
using Microsoft.AspNetCore.Mvc;
using Asp.Versioning;
using Microsoft.AspNetCore.Mvc;
namespace PortBlog.API.Controllers
{
[Route("api/blog/post")]
[ApiVersionNeutral]
[ApiController]
[Route("api/v{version:apiVersion}/blog/post")]
public class PostController : ControllerBase
{
private readonly ILogger<PostController> _logger;

View File

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore;
using PortBlog.API.DbContexts.Seed;
using PortBlog.API.Entities;
using PortBlog.API.Entities.Mapping;
namespace PortBlog.API.DbContexts
{
@ -37,6 +38,12 @@ namespace PortBlog.API.DbContexts
public DbSet<ClientLog> ClientLogs { get; set; }
public DbSet<Cache> Cache { get; set; }
public DbSet<RefreshToken> RefreshTokens { get; set; }
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Candidate>().HasData(InitialData.GetCandidateData());
@ -50,6 +57,8 @@ namespace PortBlog.API.DbContexts
modelBuilder.Entity<Post>().HasData(InitialData.GetPostsData());
modelBuilder.Entity<Experience>().HasData(InitialData.GetExperiencesData());
modelBuilder.Entity<ExperienceDetails>().HasData(InitialData.GetExperienceDetailsData());
modelBuilder.Entity<User>().HasData(InitialData.GetUsers());
modelBuilder.ApplyConfiguration(new CacheMapping());
base.OnModelCreating(modelBuilder);
}

View File

@ -1,5 +1,4 @@
using PortBlog.API.Entities;
using System.Net.NetworkInformation;
namespace PortBlog.API.DbContexts.Seed
{
@ -373,5 +372,18 @@ namespace PortBlog.API.DbContexts.Seed
};
}
public static List<User> GetUsers()
{
return new List<User>
{
new User
{
UserId = 1,
Username = "rajukottedi",
Email = "bangararaju.kottedi@gmail.com",
}
};
}
}
}

View File

@ -0,0 +1,11 @@
namespace PortBlog.API.Entities
{
public class Cache
{
public string Id { get; set; } = null!;
public byte[] Value { get; set; } = null!;
public DateTime ExpiresAtTime { get; set; }
public long? SlidingExpirationInSeconds { get; set; }
public DateTime? AbsoluteExpiration { get; set; }
}
}

View File

@ -0,0 +1,17 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace PortBlog.API.Entities.Mapping
{
public class CacheMapping : IEntityTypeConfiguration<Cache>
{
public void Configure(EntityTypeBuilder<Cache> builder)
{
builder.HasKey(c => c.Id);
builder.Property(c => c.Id).ValueGeneratedOnAdd();
builder.Property(c => c.ExpiresAtTime).IsRequired();
builder.Property(c => c.Id).HasMaxLength(449).IsRequired();
builder.Property(c => c.Value).IsRequired();
}
}
}

View File

@ -28,7 +28,6 @@ namespace PortBlog.API.Entities
public string Subject { get; set; } = string.Empty;
[Required]
[MaxLength(500)]
public string Content { get; set; } = string.Empty;
public int SentStatus { get; set; } = 0;

View File

@ -0,0 +1,33 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace PortBlog.API.Entities
{
public class RefreshToken
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int TokenId { get; set; }
[Required]
public int UserId { get; set; }
[Required]
public string Token { get; set; }
[Required]
public string JwtId { get; set; }
[Required]
public DateTime ExpiryDate { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public bool Revoked { get; set; } = false;
public string? ReplacedByToken { get; set; }
[Required]
public string DeviceInfo { get; set; }
[ForeignKey(nameof(UserId))]
public User User { get; set; }
}
}

View File

@ -0,0 +1,19 @@
using System.ComponentModel.DataAnnotations;
namespace PortBlog.API.Entities
{
public class User
{
[Key]
public int UserId { get; set; }
[Required]
public string Username { get; set; }
[Required]
public string Email { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public ICollection<RefreshToken> RefreshTokens { get; set; }
}
}

View File

@ -0,0 +1,28 @@
using Asp.Versioning.ApiExplorer;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
public class ConfigureSwaggerOptions : IConfigureOptions<SwaggerGenOptions>
{
private readonly IApiVersionDescriptionProvider _provider;
public ConfigureSwaggerOptions(IApiVersionDescriptionProvider provider)
{
_provider = provider;
}
public void Configure(SwaggerGenOptions options)
{
foreach (var description in _provider.ApiVersionDescriptions)
{
options.SwaggerDoc(
description.GroupName,
new OpenApiInfo
{
Title = "PortBlog API",
Version = description.GroupName
});
}
}
}

View File

@ -19,6 +19,9 @@ namespace PortBlog.API.Extensions
public static IServiceCollection AddServices(this IServiceCollection services)
{
services.AddTransient<IMailService, MailService>();
services.AddTransient<IAuthService, AuthService>();
services.AddTransient<ITemplateService, TemplateService>();
services.AddScoped<IAdminService, AdminService>();
return services;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,515 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace PortBlog.API.Migrations
{
/// <inheritdoc />
public partial class CreateCacheTable : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Cache",
columns: table => new
{
Id = table.Column<string>(type: "varchar(449)", maxLength: 449, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Value = table.Column<byte[]>(type: "longblob", nullable: false),
ExpiresAtTime = table.Column<DateTime>(type: "datetime(6)", nullable: false),
SlidingExpirationInSeconds = table.Column<long>(type: "bigint", nullable: true),
AbsoluteExpiration = table.Column<DateTime>(type: "datetime(6)", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Cache", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7668), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7668) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7674), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7674) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7677), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7677) });
migrationBuilder.UpdateData(
table: "Blogs",
keyColumn: "BlogUrl",
keyValue: "https://bangararaju.kottedi.in/blog",
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7790), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7791) });
migrationBuilder.UpdateData(
table: "Candidates",
keyColumn: "CandidateId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7275), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7304) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7944), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7944) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7948), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7949) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7950), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7951) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7952), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7953) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7954), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7955) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 6,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7957), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7957) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 7,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7958), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7959) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 8,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(8011), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(8011) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7903), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7904) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7908), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7909) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7912), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7913) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7915), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7916) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7625), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7625) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7633), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7633) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7635), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7636) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7638), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7638) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7820), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7817) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7826), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7824) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7830), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7828) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7754), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7755) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7761), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7762) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7765), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7765) });
migrationBuilder.UpdateData(
table: "Resumes",
keyColumn: "ResumeId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7563), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7564) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7705), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7706) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7710), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7711) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7712), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7713) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7714), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7715) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7716), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7717) });
migrationBuilder.UpdateData(
table: "SocialLinks",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7592), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7593) });
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Cache");
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8945), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8945) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8948), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8949) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8950), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8951) });
migrationBuilder.UpdateData(
table: "Blogs",
keyColumn: "BlogUrl",
keyValue: "https://bangararaju.kottedi.in/blog",
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9023), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9023) });
migrationBuilder.UpdateData(
table: "Candidates",
keyColumn: "CandidateId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8726), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8742) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9096), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9096) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9099), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9100) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9101), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9101) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9102), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9102) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9103), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9103) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 6,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9105), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9105) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 7,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9106), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9106) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 8,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9107), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9108) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9068), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9068) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9072), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9073) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9075), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9075) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9077), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9077) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8912), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8913) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8917), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8918) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8919), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8919) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8921), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8921) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9042), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9038) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9047), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9045) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9049), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9048) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8997), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8997) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9003), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9003) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9006), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9006) });
migrationBuilder.UpdateData(
table: "Resumes",
keyColumn: "ResumeId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8874), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8874) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8968), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8968) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8971), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8972) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8973), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8973) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8974), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8974) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8975), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8976) });
migrationBuilder.UpdateData(
table: "SocialLinks",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8894), new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8895) });
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,517 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace PortBlog.API.Migrations
{
/// <inheritdoc />
public partial class MessageContentMaxLength : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Content",
table: "Messages",
type: "longtext",
nullable: false,
oldClrType: typeof(string),
oldType: "varchar(500)",
oldMaxLength: 500)
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(5183), new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(5185) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(6375), new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(6376) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(6564), new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(6565) });
migrationBuilder.UpdateData(
table: "Blogs",
keyColumn: "BlogUrl",
keyValue: "https://bangararaju.kottedi.in/blog",
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(8487), new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(8489) });
migrationBuilder.UpdateData(
table: "Candidates",
keyColumn: "CandidateId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 890, DateTimeKind.Local).AddTicks(2043), new DateTime(2025, 10, 8, 13, 51, 15, 890, DateTimeKind.Local).AddTicks(2090) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 896, DateTimeKind.Local).AddTicks(9986), new DateTime(2025, 10, 8, 13, 51, 15, 896, DateTimeKind.Local).AddTicks(9994) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(902), new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(903) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(908), new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(909) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(912), new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(913) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(916), new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(917) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 6,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(931), new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(932) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 7,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(936), new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(937) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 8,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(940), new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(941) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 896, DateTimeKind.Local).AddTicks(2643), new DateTime(2025, 10, 8, 13, 51, 15, 896, DateTimeKind.Local).AddTicks(2652) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 896, DateTimeKind.Local).AddTicks(4851), new DateTime(2025, 10, 8, 13, 51, 15, 896, DateTimeKind.Local).AddTicks(4852) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 896, DateTimeKind.Local).AddTicks(4859), new DateTime(2025, 10, 8, 13, 51, 15, 896, DateTimeKind.Local).AddTicks(4861) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 896, DateTimeKind.Local).AddTicks(4866), new DateTime(2025, 10, 8, 13, 51, 15, 896, DateTimeKind.Local).AddTicks(4867) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(447), new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(450) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(1567), new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(1568) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(1680), new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(1681) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(1686), new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(1686) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 895, DateTimeKind.Local).AddTicks(4722), new DateTime(2025, 10, 8, 13, 51, 15, 895, DateTimeKind.Local).AddTicks(3517) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 895, DateTimeKind.Local).AddTicks(5740), new DateTime(2025, 10, 8, 13, 51, 15, 895, DateTimeKind.Local).AddTicks(5735) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 895, DateTimeKind.Local).AddTicks(5747), new DateTime(2025, 10, 8, 13, 51, 15, 895, DateTimeKind.Local).AddTicks(5744) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(4258), new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(4259) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(6406), new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(6411) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(6419), new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(6420) });
migrationBuilder.UpdateData(
table: "Resumes",
keyColumn: "ResumeId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 892, DateTimeKind.Local).AddTicks(2802), new DateTime(2025, 10, 8, 13, 51, 15, 892, DateTimeKind.Local).AddTicks(2819) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(9417), new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(9419) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(241), new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(242) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(246), new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(246) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(249), new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(250) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(253), new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(254) });
migrationBuilder.UpdateData(
table: "SocialLinks",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 892, DateTimeKind.Local).AddTicks(6490), new DateTime(2025, 10, 8, 13, 51, 15, 892, DateTimeKind.Local).AddTicks(6498) });
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Content",
table: "Messages",
type: "varchar(500)",
maxLength: 500,
nullable: false,
oldClrType: typeof(string),
oldType: "longtext")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7668), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7668) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7674), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7674) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7677), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7677) });
migrationBuilder.UpdateData(
table: "Blogs",
keyColumn: "BlogUrl",
keyValue: "https://bangararaju.kottedi.in/blog",
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7790), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7791) });
migrationBuilder.UpdateData(
table: "Candidates",
keyColumn: "CandidateId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7275), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7304) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7944), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7944) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7948), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7949) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7950), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7951) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7952), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7953) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7954), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7955) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 6,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7957), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7957) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 7,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7958), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7959) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 8,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(8011), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(8011) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7903), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7904) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7908), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7909) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7912), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7913) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7915), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7916) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7625), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7625) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7633), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7633) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7635), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7636) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7638), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7638) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7820), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7817) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7826), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7824) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7830), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7828) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7754), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7755) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7761), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7762) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7765), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7765) });
migrationBuilder.UpdateData(
table: "Resumes",
keyColumn: "ResumeId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7563), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7564) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7705), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7706) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7710), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7711) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7712), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7713) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7714), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7715) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7716), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7717) });
migrationBuilder.UpdateData(
table: "SocialLinks",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7592), new DateTime(2025, 10, 1, 18, 35, 50, 567, DateTimeKind.Local).AddTicks(7593) });
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,495 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace PortBlog.API.Migrations
{
/// <inheritdoc />
public partial class User_RefreshTokens : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(4652), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(4653) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(5447), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(5448) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(5558), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(5559) });
migrationBuilder.UpdateData(
table: "Blogs",
keyColumn: "BlogUrl",
keyValue: "https://bangararaju.kottedi.in/blog",
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(3195), new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(3196) });
migrationBuilder.UpdateData(
table: "Candidates",
keyColumn: "CandidateId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 690, DateTimeKind.Local).AddTicks(9239), new DateTime(2025, 10, 28, 11, 34, 41, 690, DateTimeKind.Local).AddTicks(9275) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(3656), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(3657) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4150), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4150) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4152), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4153) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4154), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4155) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4156), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4156) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 6,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4161), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4161) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 7,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4163), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4163) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 8,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4164), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4165) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(375), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(377) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(1466), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(1467) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(1471), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(1472) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(1475), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(1475) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(2045), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(2046) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(2725), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(2725) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(2728), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(2729) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(2730), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(2731) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(7094), new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(6266) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(7426), new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(7423) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(7429), new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(7428) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(911), new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(912) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(2038), new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(2039) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(2042), new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(2043) });
migrationBuilder.UpdateData(
table: "Resumes",
keyColumn: "ResumeId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 691, DateTimeKind.Local).AddTicks(7935), new DateTime(2025, 10, 28, 11, 34, 41, 691, DateTimeKind.Local).AddTicks(7944) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(7751), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(7757) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(8313), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(8314) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(8316), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(8317) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(8318), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(8318) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(8320), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(8320) });
migrationBuilder.UpdateData(
table: "SocialLinks",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 691, DateTimeKind.Local).AddTicks(9726), new DateTime(2025, 10, 28, 11, 34, 41, 691, DateTimeKind.Local).AddTicks(9728) });
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(5183), new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(5185) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(6375), new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(6376) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(6564), new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(6565) });
migrationBuilder.UpdateData(
table: "Blogs",
keyColumn: "BlogUrl",
keyValue: "https://bangararaju.kottedi.in/blog",
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(8487), new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(8489) });
migrationBuilder.UpdateData(
table: "Candidates",
keyColumn: "CandidateId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 890, DateTimeKind.Local).AddTicks(2043), new DateTime(2025, 10, 8, 13, 51, 15, 890, DateTimeKind.Local).AddTicks(2090) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 896, DateTimeKind.Local).AddTicks(9986), new DateTime(2025, 10, 8, 13, 51, 15, 896, DateTimeKind.Local).AddTicks(9994) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(902), new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(903) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(908), new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(909) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(912), new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(913) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(916), new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(917) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 6,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(931), new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(932) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 7,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(936), new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(937) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 8,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(940), new DateTime(2025, 10, 8, 13, 51, 15, 897, DateTimeKind.Local).AddTicks(941) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 896, DateTimeKind.Local).AddTicks(2643), new DateTime(2025, 10, 8, 13, 51, 15, 896, DateTimeKind.Local).AddTicks(2652) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 896, DateTimeKind.Local).AddTicks(4851), new DateTime(2025, 10, 8, 13, 51, 15, 896, DateTimeKind.Local).AddTicks(4852) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 896, DateTimeKind.Local).AddTicks(4859), new DateTime(2025, 10, 8, 13, 51, 15, 896, DateTimeKind.Local).AddTicks(4861) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 896, DateTimeKind.Local).AddTicks(4866), new DateTime(2025, 10, 8, 13, 51, 15, 896, DateTimeKind.Local).AddTicks(4867) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(447), new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(450) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(1567), new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(1568) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(1680), new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(1681) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(1686), new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(1686) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 895, DateTimeKind.Local).AddTicks(4722), new DateTime(2025, 10, 8, 13, 51, 15, 895, DateTimeKind.Local).AddTicks(3517) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 895, DateTimeKind.Local).AddTicks(5740), new DateTime(2025, 10, 8, 13, 51, 15, 895, DateTimeKind.Local).AddTicks(5735) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 895, DateTimeKind.Local).AddTicks(5747), new DateTime(2025, 10, 8, 13, 51, 15, 895, DateTimeKind.Local).AddTicks(5744) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(4258), new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(4259) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(6406), new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(6411) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(6419), new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(6420) });
migrationBuilder.UpdateData(
table: "Resumes",
keyColumn: "ResumeId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 892, DateTimeKind.Local).AddTicks(2802), new DateTime(2025, 10, 8, 13, 51, 15, 892, DateTimeKind.Local).AddTicks(2819) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(9417), new DateTime(2025, 10, 8, 13, 51, 15, 893, DateTimeKind.Local).AddTicks(9419) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(241), new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(242) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(246), new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(246) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(249), new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(250) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(253), new DateTime(2025, 10, 8, 13, 51, 15, 894, DateTimeKind.Local).AddTicks(254) });
migrationBuilder.UpdateData(
table: "SocialLinks",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 8, 13, 51, 15, 892, DateTimeKind.Local).AddTicks(6490), new DateTime(2025, 10, 8, 13, 51, 15, 892, DateTimeKind.Local).AddTicks(6498) });
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,561 @@
using System;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace PortBlog.API.Migrations
{
/// <inheritdoc />
public partial class User_RefreshTokens_Rerun : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Users",
columns: table => new
{
UserId = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Username = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Email = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Users", x => x.UserId);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "RefreshTokens",
columns: table => new
{
TokenId = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
UserId = table.Column<int>(type: "int", nullable: false),
Token = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
JwtId = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ExpiryDate = table.Column<DateTime>(type: "datetime(6)", nullable: false),
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
Revoked = table.Column<bool>(type: "tinyint(1)", nullable: false),
ReplacedByToken = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
DeviceInfo = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_RefreshTokens", x => x.TokenId);
table.ForeignKey(
name: "FK_RefreshTokens_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "UserId",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(8319), new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(8321) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(8990), new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(8991) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(9095), new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(9096) });
migrationBuilder.UpdateData(
table: "Blogs",
keyColumn: "BlogUrl",
keyValue: "https://bangararaju.kottedi.in/blog",
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(6331), new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(6332) });
migrationBuilder.UpdateData(
table: "Candidates",
keyColumn: "CandidateId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 597, DateTimeKind.Local).AddTicks(6457), new DateTime(2025, 10, 28, 11, 53, 55, 597, DateTimeKind.Local).AddTicks(6491) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6348), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6349) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6828), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6829) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6831), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6832) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6834), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6834) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6836), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6836) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 6,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6842), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6842) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 7,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6844), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6844) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 8,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6846), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6846) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(3165), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(3167) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(4192), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(4193) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(4197), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(4197) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(4201), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(4201) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(5682), new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(5683) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(6359), new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(6360) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(6363), new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(6363) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(6365), new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(6366) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(87), new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(9329) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(390), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(387) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(394), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(392) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(4003), new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(4005) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(5048), new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(5049) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(5120), new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(5120) });
migrationBuilder.UpdateData(
table: "Resumes",
keyColumn: "ResumeId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(1505), new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(1512) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(784), new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(787) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(1478), new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(1481) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(1484), new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(1484) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(1486), new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(1486) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(1488), new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(1488) });
migrationBuilder.UpdateData(
table: "SocialLinks",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(3502), new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(3506) });
migrationBuilder.InsertData(
table: "Users",
columns: new[] { "UserId", "CreatedAt", "Email", "Username" },
values: new object[] { 1, new DateTime(2025, 10, 28, 6, 23, 55, 601, DateTimeKind.Utc).AddTicks(8545), "bangararaju.kottedi@gmail.com", "rajukottedi" });
migrationBuilder.CreateIndex(
name: "IX_RefreshTokens_UserId",
table: "RefreshTokens",
column: "UserId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "RefreshTokens");
migrationBuilder.DropTable(
name: "Users");
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(4652), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(4653) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(5447), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(5448) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(5558), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(5559) });
migrationBuilder.UpdateData(
table: "Blogs",
keyColumn: "BlogUrl",
keyValue: "https://bangararaju.kottedi.in/blog",
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(3195), new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(3196) });
migrationBuilder.UpdateData(
table: "Candidates",
keyColumn: "CandidateId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 690, DateTimeKind.Local).AddTicks(9239), new DateTime(2025, 10, 28, 11, 34, 41, 690, DateTimeKind.Local).AddTicks(9275) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(3656), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(3657) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4150), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4150) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4152), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4153) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4154), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4155) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4156), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4156) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 6,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4161), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4161) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 7,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4163), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4163) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 8,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4164), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(4165) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(375), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(377) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(1466), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(1467) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(1471), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(1472) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(1475), new DateTime(2025, 10, 28, 11, 34, 41, 694, DateTimeKind.Local).AddTicks(1475) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(2045), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(2046) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(2725), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(2725) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(2728), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(2729) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(2730), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(2731) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(7094), new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(6266) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(7426), new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(7423) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(7429), new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(7428) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(911), new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(912) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(2038), new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(2039) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(2042), new DateTime(2025, 10, 28, 11, 34, 41, 693, DateTimeKind.Local).AddTicks(2043) });
migrationBuilder.UpdateData(
table: "Resumes",
keyColumn: "ResumeId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 691, DateTimeKind.Local).AddTicks(7935), new DateTime(2025, 10, 28, 11, 34, 41, 691, DateTimeKind.Local).AddTicks(7944) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(7751), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(7757) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(8313), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(8314) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(8316), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(8317) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(8318), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(8318) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(8320), new DateTime(2025, 10, 28, 11, 34, 41, 692, DateTimeKind.Local).AddTicks(8320) });
migrationBuilder.UpdateData(
table: "SocialLinks",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 34, 41, 691, DateTimeKind.Local).AddTicks(9726), new DateTime(2025, 10, 28, 11, 34, 41, 691, DateTimeKind.Local).AddTicks(9728) });
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,509 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace PortBlog.API.Migrations
{
/// <inheritdoc />
public partial class User_RefreshTokens_Update : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(5159), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(5160) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(5783), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(5784) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(5866), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(5866) });
migrationBuilder.UpdateData(
table: "Blogs",
keyColumn: "BlogUrl",
keyValue: "https://bangararaju.kottedi.in/blog",
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(1546), new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(1547) });
migrationBuilder.UpdateData(
table: "Candidates",
keyColumn: "CandidateId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 779, DateTimeKind.Local).AddTicks(2626), new DateTime(2025, 10, 29, 7, 27, 45, 779, DateTimeKind.Local).AddTicks(2659) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(394), new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(395) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(804), new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(805) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(807), new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(807) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(808), new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(808) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(810), new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(810) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 6,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(815), new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(815) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 7,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(816), new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(817) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 8,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(818), new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(818) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(7573), new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(7579) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(8490), new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(8490) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(8494), new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(8494) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(8497), new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(8497) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(2948), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(2949) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(3600), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(3601) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(3603), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(3604) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(3605), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(3606) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(4486), new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(3878) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(4730), new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(4727) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(4733), new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(4731) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(9719), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(9721) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(628), new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(629) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(632), new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(633) });
migrationBuilder.UpdateData(
table: "Resumes",
keyColumn: "ResumeId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 779, DateTimeKind.Local).AddTicks(9805), new DateTime(2025, 10, 29, 7, 27, 45, 779, DateTimeKind.Local).AddTicks(9812) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(7273), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(7274) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(7731), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(7731) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(7733), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(7733) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(7735), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(7735) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(7736), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(7737) });
migrationBuilder.UpdateData(
table: "SocialLinks",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(1156), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(1157) });
migrationBuilder.UpdateData(
table: "Users",
keyColumn: "UserId",
keyValue: 1,
column: "CreatedAt",
value: new DateTime(2025, 10, 29, 1, 57, 45, 782, DateTimeKind.Utc).AddTicks(1816));
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(8319), new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(8321) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(8990), new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(8991) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(9095), new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(9096) });
migrationBuilder.UpdateData(
table: "Blogs",
keyColumn: "BlogUrl",
keyValue: "https://bangararaju.kottedi.in/blog",
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(6331), new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(6332) });
migrationBuilder.UpdateData(
table: "Candidates",
keyColumn: "CandidateId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 597, DateTimeKind.Local).AddTicks(6457), new DateTime(2025, 10, 28, 11, 53, 55, 597, DateTimeKind.Local).AddTicks(6491) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6348), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6349) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6828), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6829) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6831), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6832) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6834), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6834) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6836), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6836) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 6,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6842), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6842) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 7,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6844), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6844) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 8,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6846), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(6846) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(3165), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(3167) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(4192), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(4193) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(4197), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(4197) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(4201), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(4201) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(5682), new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(5683) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(6359), new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(6360) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(6363), new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(6363) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(6365), new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(6366) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(87), new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(9329) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(390), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(387) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(394), new DateTime(2025, 10, 28, 11, 53, 55, 601, DateTimeKind.Local).AddTicks(392) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(4003), new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(4005) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(5048), new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(5049) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(5120), new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(5120) });
migrationBuilder.UpdateData(
table: "Resumes",
keyColumn: "ResumeId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(1505), new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(1512) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(784), new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(787) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(1478), new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(1481) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(1484), new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(1484) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(1486), new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(1486) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(1488), new DateTime(2025, 10, 28, 11, 53, 55, 600, DateTimeKind.Local).AddTicks(1488) });
migrationBuilder.UpdateData(
table: "SocialLinks",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(3502), new DateTime(2025, 10, 28, 11, 53, 55, 599, DateTimeKind.Local).AddTicks(3506) });
migrationBuilder.UpdateData(
table: "Users",
keyColumn: "UserId",
keyValue: 1,
column: "CreatedAt",
value: new DateTime(2025, 10, 28, 6, 23, 55, 601, DateTimeKind.Utc).AddTicks(8545));
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,537 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace PortBlog.API.Migrations
{
/// <inheritdoc />
public partial class updaterefreshtoken : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "ReplacedByToken",
table: "RefreshTokens",
type: "longtext",
nullable: true,
oldClrType: typeof(string),
oldType: "longtext")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(1251), new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(1252) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(2024), new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(2024) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(2184), new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(2184) });
migrationBuilder.UpdateData(
table: "Blogs",
keyColumn: "BlogUrl",
keyValue: "https://bangararaju.kottedi.in/blog",
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(9145), new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(9146) });
migrationBuilder.UpdateData(
table: "Candidates",
keyColumn: "CandidateId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 299, DateTimeKind.Local).AddTicks(5480), new DateTime(2025, 11, 13, 19, 20, 39, 299, DateTimeKind.Local).AddTicks(5515) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(462), new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(464) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(988), new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(988) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(991), new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(991) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(993), new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(993) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(994), new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(995) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 6,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(1004), new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(1005) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 7,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(1006), new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(1007) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 8,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(1008), new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(1009) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(6786), new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(6793) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(7965), new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(7966) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(7970), new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(7971) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(8081), new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(8081) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(8352), new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(8353) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(9201), new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(9201) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(9204), new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(9205) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(9207), new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(9208) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(2910), new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(2155) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(3231), new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(3229) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(3236), new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(3233) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(6787), new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(6789) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(7979), new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(7980) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(7983), new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(7984) });
migrationBuilder.UpdateData(
table: "Resumes",
keyColumn: "ResumeId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(4308), new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(4316) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(3819), new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(3820) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(4333), new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(4333) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(4335), new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(4336) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(4337), new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(4338) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(4339), new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(4340) });
migrationBuilder.UpdateData(
table: "SocialLinks",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(6144), new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(6145) });
migrationBuilder.UpdateData(
table: "Users",
keyColumn: "UserId",
keyValue: 1,
column: "CreatedAt",
value: new DateTime(2025, 11, 13, 13, 50, 39, 303, DateTimeKind.Utc).AddTicks(2327));
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.UpdateData(
table: "RefreshTokens",
keyColumn: "ReplacedByToken",
keyValue: null,
column: "ReplacedByToken",
value: "");
migrationBuilder.AlterColumn<string>(
name: "ReplacedByToken",
table: "RefreshTokens",
type: "longtext",
nullable: false,
oldClrType: typeof(string),
oldType: "longtext",
oldNullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(5159), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(5160) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(5783), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(5784) });
migrationBuilder.UpdateData(
table: "Academics",
keyColumn: "AcademicId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(5866), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(5866) });
migrationBuilder.UpdateData(
table: "Blogs",
keyColumn: "BlogUrl",
keyValue: "https://bangararaju.kottedi.in/blog",
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(1546), new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(1547) });
migrationBuilder.UpdateData(
table: "Candidates",
keyColumn: "CandidateId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 779, DateTimeKind.Local).AddTicks(2626), new DateTime(2025, 10, 29, 7, 27, 45, 779, DateTimeKind.Local).AddTicks(2659) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(394), new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(395) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(804), new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(805) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(807), new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(807) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(808), new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(808) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(810), new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(810) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 6,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(815), new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(815) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 7,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(816), new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(817) });
migrationBuilder.UpdateData(
table: "ExperienceDetails",
keyColumn: "Id",
keyValue: 8,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(818), new DateTime(2025, 10, 29, 7, 27, 45, 782, DateTimeKind.Local).AddTicks(818) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(7573), new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(7579) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(8490), new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(8490) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(8494), new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(8494) });
migrationBuilder.UpdateData(
table: "Experiences",
keyColumn: "ExperienceId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(8497), new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(8497) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(2948), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(2949) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(3600), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(3601) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(3603), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(3604) });
migrationBuilder.UpdateData(
table: "Hobbies",
keyColumn: "HobbyId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(3605), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(3606) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(4486), new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(3878) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(4730), new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(4727) });
migrationBuilder.UpdateData(
table: "Posts",
keyColumn: "PostId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(4733), new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(4731) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(9719), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(9721) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(628), new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(629) });
migrationBuilder.UpdateData(
table: "Projects",
keyColumn: "ProjectId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(632), new DateTime(2025, 10, 29, 7, 27, 45, 781, DateTimeKind.Local).AddTicks(633) });
migrationBuilder.UpdateData(
table: "Resumes",
keyColumn: "ResumeId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 779, DateTimeKind.Local).AddTicks(9805), new DateTime(2025, 10, 29, 7, 27, 45, 779, DateTimeKind.Local).AddTicks(9812) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(7273), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(7274) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 2,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(7731), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(7731) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 3,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(7733), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(7733) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 4,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(7735), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(7735) });
migrationBuilder.UpdateData(
table: "Skills",
keyColumn: "SkillId",
keyValue: 5,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(7736), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(7737) });
migrationBuilder.UpdateData(
table: "SocialLinks",
keyColumn: "Id",
keyValue: 1,
columns: new[] { "CreatedDate", "ModifiedDate" },
values: new object[] { new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(1156), new DateTime(2025, 10, 29, 7, 27, 45, 780, DateTimeKind.Local).AddTicks(1157) });
migrationBuilder.UpdateData(
table: "Users",
keyColumn: "UserId",
keyValue: 1,
column: "CreatedAt",
value: new DateTime(2025, 10, 29, 1, 57, 45, 782, DateTimeKind.Utc).AddTicks(1816));
}
}
}

View File

@ -17,7 +17,7 @@ namespace PortBlog.API.Migrations
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.4")
.HasAnnotation("ProductVersion", "9.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
@ -75,35 +75,35 @@ namespace PortBlog.API.Migrations
new
{
AcademicId = 1,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8945),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(1251),
Degree = "High School",
EndYear = 2007,
Institution = "Pragati Little Public School",
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8945),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(1252),
ResumeId = 1,
StartYear = 2006
},
new
{
AcademicId = 2,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8948),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(2024),
Degree = "Intermediate",
DegreeSpecialization = "MPC",
EndYear = 2009,
Institution = "Sri Chaitanya Junior College",
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8949),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(2024),
ResumeId = 1,
StartYear = 2007
},
new
{
AcademicId = 3,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8950),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(2184),
Degree = "BTech",
DegreeSpecialization = "ECE",
EndYear = 2013,
Institution = "Kakinada Institute of Technology & Science",
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8951),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(2184),
ResumeId = 1,
StartYear = 2009
});
@ -144,13 +144,38 @@ namespace PortBlog.API.Migrations
new
{
BlogUrl = "https://bangararaju.kottedi.in/blog",
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9023),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(9145),
Description = "Your Hub for Tech, DIY, and Innovation",
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9023),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(9146),
Name = "Engineer's Odyssey"
});
});
modelBuilder.Entity("PortBlog.API.Entities.Cache", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd()
.HasMaxLength(449)
.HasColumnType("varchar(449)");
b.Property<DateTime?>("AbsoluteExpiration")
.HasColumnType("datetime(6)");
b.Property<DateTime>("ExpiresAtTime")
.HasColumnType("datetime(6)");
b.Property<long?>("SlidingExpirationInSeconds")
.HasColumnType("bigint");
b.Property<byte[]>("Value")
.IsRequired()
.HasColumnType("longblob");
b.HasKey("Id");
b.ToTable("Cache");
});
modelBuilder.Entity("PortBlog.API.Entities.Candidate", b =>
{
b.Property<int>("CandidateId")
@ -213,13 +238,13 @@ namespace PortBlog.API.Migrations
{
CandidateId = 1,
Address = "Samalkot, Andhra Pradesh, India",
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8726),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 299, DateTimeKind.Local).AddTicks(5480),
Dob = new DateTime(1992, 5, 6, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "bangararaju.kottedi@gmail.com",
FirstName = "Bangara Raju",
Gender = "Male",
LastName = "Kottedi",
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8742),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 299, DateTimeKind.Local).AddTicks(5515),
Phone = "+91 9441212187"
});
});
@ -366,11 +391,11 @@ namespace PortBlog.API.Migrations
{
ExperienceId = 1,
Company = "Agility E Services",
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9068),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(6786),
Description = "",
EndDate = new DateTime(2016, 4, 25, 0, 0, 0, 0, DateTimeKind.Unspecified),
Location = "Hyderabad",
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9068),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(6793),
ResumeId = 1,
StartDate = new DateTime(2015, 9, 2, 0, 0, 0, 0, DateTimeKind.Unspecified),
Title = "Jr. Software Engineer"
@ -379,11 +404,11 @@ namespace PortBlog.API.Migrations
{
ExperienceId = 2,
Company = "Agility",
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9072),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(7965),
Description = "",
EndDate = new DateTime(2022, 1, 31, 0, 0, 0, 0, DateTimeKind.Unspecified),
Location = "Kuwait",
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9073),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(7966),
ResumeId = 1,
StartDate = new DateTime(2016, 5, 12, 0, 0, 0, 0, DateTimeKind.Unspecified),
Title = "Web Developer"
@ -392,11 +417,11 @@ namespace PortBlog.API.Migrations
{
ExperienceId = 3,
Company = "Agility",
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9075),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(7970),
Description = "",
EndDate = new DateTime(2022, 10, 31, 0, 0, 0, 0, DateTimeKind.Unspecified),
Location = "Kuwait",
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9075),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(7971),
ResumeId = 1,
StartDate = new DateTime(2022, 2, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
Title = "Senior Web Developer"
@ -405,11 +430,11 @@ namespace PortBlog.API.Migrations
{
ExperienceId = 4,
Company = "Agility E Services",
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9077),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(8081),
Description = "",
EndDate = new DateTime(2024, 4, 12, 0, 0, 0, 0, DateTimeKind.Unspecified),
Location = "Hyderabad",
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9077),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(8081),
ResumeId = 1,
StartDate = new DateTime(2022, 11, 4, 0, 0, 0, 0, DateTimeKind.Unspecified),
Title = "Technology Specialist"
@ -457,73 +482,73 @@ namespace PortBlog.API.Migrations
new
{
Id = 1,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9096),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(462),
Details = "Worked on the YouTube Captions team, in Javascript and Python to plan, to design and develop the full stack to add and edit Automatic Speech Recognition captions.",
ExperienceId = 1,
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9096),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(464),
Order = 1
},
new
{
Id = 2,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9099),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(988),
Details = "Worked on the YouTube Captions team, in Javascript and Python to plan, to design and develop the full stack to add and edit Automatic Speech Recognition captions.",
ExperienceId = 1,
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9100),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(988),
Order = 2
},
new
{
Id = 3,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9101),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(991),
Details = "Worked on the YouTube Captions team, in Javascript and Python to plan, to design and develop the full stack to add and edit Automatic Speech Recognition captions.",
ExperienceId = 2,
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9101),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(991),
Order = 1
},
new
{
Id = 4,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9102),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(993),
Details = "Worked on the YouTube Captions team, in Javascript and Python to plan, to design and develop the full stack to add and edit Automatic Speech Recognition captions.",
ExperienceId = 2,
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9102),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(993),
Order = 2
},
new
{
Id = 5,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9103),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(994),
Details = "Worked on the YouTube Captions team, in Javascript and Python to plan, to design and develop the full stack to add and edit Automatic Speech Recognition captions.",
ExperienceId = 3,
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9103),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(995),
Order = 1
},
new
{
Id = 6,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9105),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(1004),
Details = "Worked on the YouTube Captions team, in Javascript and Python to plan, to design and develop the full stack to add and edit Automatic Speech Recognition captions.",
ExperienceId = 3,
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9105),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(1005),
Order = 2
},
new
{
Id = 7,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9106),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(1006),
Details = "Worked on the YouTube Captions team, in Javascript and Python to plan, to design and develop the full stack to add and edit Automatic Speech Recognition captions.",
ExperienceId = 4,
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9106),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(1007),
Order = 1
},
new
{
Id = 8,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9107),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(1008),
Details = "Worked on the YouTube Captions team, in Javascript and Python to plan, to design and develop the full stack to add and edit Automatic Speech Recognition captions.",
ExperienceId = 4,
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9108),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 303, DateTimeKind.Local).AddTicks(1009),
Order = 2
});
});
@ -578,10 +603,10 @@ namespace PortBlog.API.Migrations
new
{
HobbyId = 1,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8912),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(8352),
Description = "Crafting Professional-Quality Websites with Precision.",
Icon = "fa-square-terminal",
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8913),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(8353),
Name = "Web Development",
Order = 1,
ResumeId = 1
@ -589,10 +614,10 @@ namespace PortBlog.API.Migrations
new
{
HobbyId = 2,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8917),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(9201),
Description = "Streamlining and Simplifying Complex Tasks through Automation.",
Icon = "fa-robot",
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8918),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(9201),
Name = "Automation",
Order = 2,
ResumeId = 1
@ -600,10 +625,10 @@ namespace PortBlog.API.Migrations
new
{
HobbyId = 3,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8919),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(9204),
Description = "Sharing the knowledge and insights Ive gathered along my journey.",
Icon = "fa-typewriter",
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8919),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(9205),
Name = "Blogging",
Order = 3,
ResumeId = 1
@ -611,10 +636,10 @@ namespace PortBlog.API.Migrations
new
{
HobbyId = 4,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8921),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(9207),
Description = "Exploring, embracing, and leveraging the latest advancements.",
Icon = "fa-lightbulb-gear",
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8921),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(9208),
Name = "Technology",
Order = 4,
ResumeId = 1
@ -634,8 +659,7 @@ namespace PortBlog.API.Migrations
b.Property<string>("Content")
.IsRequired()
.HasMaxLength(500)
.HasColumnType("varchar(500)");
.HasColumnType("longtext");
b.Property<DateTime>("CreatedDate")
.HasColumnType("datetime(6)");
@ -687,7 +711,7 @@ namespace PortBlog.API.Migrations
.HasMaxLength(200)
.HasColumnType("varchar(200)");
b.Property<string>("Categories")
b.PrimitiveCollection<string>("Categories")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("varchar(200)");
@ -750,10 +774,10 @@ namespace PortBlog.API.Migrations
BlogUrl = "https://bangararaju.kottedi.in/blog",
Categories = "[\"Welcome\"]",
Comments = 0,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9042),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(2910),
Description = "Hello World",
Likes = 0,
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9038),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(2155),
PostUrl = "https://bangararaju.kottedi.in/blog/hello-world",
Slug = "hello-world",
Title = "Hello World",
@ -765,10 +789,10 @@ namespace PortBlog.API.Migrations
BlogUrl = "https://bangararaju.kottedi.in/blog",
Categories = "[\"Welcome\"]",
Comments = 0,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9047),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(3231),
Description = "Hello World",
Likes = 0,
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9045),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(3229),
PostUrl = "https://bangararaju.kottedi.in/blog/hello-world",
Slug = "hello-world",
Title = "Hello World",
@ -780,10 +804,10 @@ namespace PortBlog.API.Migrations
BlogUrl = "https://bangararaju.kottedi.in/blog",
Categories = "[\"Welcome\"]",
Comments = 0,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9049),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(3236),
Description = "Hello World",
Likes = 0,
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9048),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 302, DateTimeKind.Local).AddTicks(3233),
PostUrl = "https://bangararaju.kottedi.in/blog/hello-world",
Slug = "hello-world",
Title = "Hello World",
@ -799,7 +823,7 @@ namespace PortBlog.API.Migrations
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("ProjectId"));
b.Property<string>("Categories")
b.PrimitiveCollection<string>("Categories")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("varchar(200)");
@ -881,10 +905,10 @@ namespace PortBlog.API.Migrations
{
ProjectId = 1,
Categories = "[\"Web Development\"]",
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8997),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(6787),
Description = "Business Process Management",
ImagePath = "bpm.jpg",
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8997),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(6789),
Name = "Transfora (Business Process Management)",
Responsibilities = "Developing, Testing, Support",
ResumeId = 1,
@ -895,10 +919,10 @@ namespace PortBlog.API.Migrations
{
ProjectId = 2,
Categories = "[\"Web Design\"]",
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9003),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(7979),
Description = "Business Process Management",
ImagePath = "hcm.jpg",
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9003),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(7980),
Name = "Human Captial Management",
Responsibilities = "Developing, Testing, Support",
ResumeId = 1,
@ -909,10 +933,10 @@ namespace PortBlog.API.Migrations
{
ProjectId = 3,
Categories = "[\"Web Development\"]",
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9006),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(7983),
Description = "Business Process Management",
ImagePath = "hms.png",
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(9006),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(7984),
Name = "Transfora (Business Process Management)",
Responsibilities = "Hosting, Integrating, Monitoring",
ResumeId = 1,
@ -921,6 +945,48 @@ namespace PortBlog.API.Migrations
});
});
modelBuilder.Entity("PortBlog.API.Entities.RefreshToken", b =>
{
b.Property<int>("TokenId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("TokenId"));
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<string>("DeviceInfo")
.IsRequired()
.HasColumnType("longtext");
b.Property<DateTime>("ExpiryDate")
.HasColumnType("datetime(6)");
b.Property<string>("JwtId")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("ReplacedByToken")
.HasColumnType("longtext");
b.Property<bool>("Revoked")
.HasColumnType("tinyint(1)");
b.Property<string>("Token")
.IsRequired()
.HasColumnType("longtext");
b.Property<int>("UserId")
.HasColumnType("int");
b.HasKey("TokenId");
b.HasIndex("UserId");
b.ToTable("RefreshTokens");
});
modelBuilder.Entity("PortBlog.API.Entities.Resume", b =>
{
b.Property<int>("ResumeId")
@ -969,8 +1035,8 @@ namespace PortBlog.API.Migrations
ResumeId = 1,
About = "I'm Full Stack Developer with 8+ years of hands-on experience in .NET development. Passionate and driven professional with expertise in .NET WebAPI, Angular, CI/CD, and a growing proficiency in Azure. I've successfully delivered robust applications, prioritizing efficiency and user experience. While I'm currently in the early stages of exploring Azure, I'm eager to expand my skill set and leverage cloud technologies to enhance scalability and performance. Known for my proactive approach and dedication to continuous learning, I'm committed to staying abreast of the latest technologies and methodologies to drive innovation and deliver exceptional results.",
CandidateId = 1,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8874),
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8874),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(4308),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(4316),
Order = 1,
Title = "Full Stack Developer"
});
@ -1071,8 +1137,8 @@ namespace PortBlog.API.Migrations
new
{
SkillId = 1,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8968),
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8968),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(3819),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(3820),
Name = "Web Development",
ProficiencyLevel = 80,
ResumeId = 1
@ -1080,8 +1146,8 @@ namespace PortBlog.API.Migrations
new
{
SkillId = 2,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8971),
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8972),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(4333),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(4333),
Name = "Web Development",
ProficiencyLevel = 80,
ResumeId = 1
@ -1089,8 +1155,8 @@ namespace PortBlog.API.Migrations
new
{
SkillId = 3,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8973),
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8973),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(4335),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(4336),
Name = "Web Development",
ProficiencyLevel = 80,
ResumeId = 1
@ -1098,8 +1164,8 @@ namespace PortBlog.API.Migrations
new
{
SkillId = 4,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8974),
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8974),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(4337),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(4338),
Name = "Web Development",
ProficiencyLevel = 80,
ResumeId = 1
@ -1107,8 +1173,8 @@ namespace PortBlog.API.Migrations
new
{
SkillId = 5,
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8975),
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8976),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(4339),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 301, DateTimeKind.Local).AddTicks(4340),
Name = "Web Development",
ProficiencyLevel = 80,
ResumeId = 1
@ -1181,14 +1247,47 @@ namespace PortBlog.API.Migrations
{
Id = 1,
BlogUrl = "https://bangararaju.kottedi.in/blog",
CreatedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8894),
CreatedDate = new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(6144),
GitHub = "https://github.com/rajukottedi",
Linkedin = "https://in.linkedin.com/in/bangara-raju-kottedi-299072109",
ModifiedDate = new DateTime(2024, 5, 7, 23, 8, 7, 980, DateTimeKind.Local).AddTicks(8895),
ModifiedDate = new DateTime(2025, 11, 13, 19, 20, 39, 300, DateTimeKind.Local).AddTicks(6145),
ResumeId = 1
});
});
modelBuilder.Entity("PortBlog.API.Entities.User", b =>
{
b.Property<int>("UserId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("UserId"));
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("Username")
.IsRequired()
.HasColumnType("longtext");
b.HasKey("UserId");
b.ToTable("Users");
b.HasData(
new
{
UserId = 1,
CreatedAt = new DateTime(2025, 11, 13, 13, 50, 39, 303, DateTimeKind.Utc).AddTicks(2327),
Email = "bangararaju.kottedi@gmail.com",
Username = "rajukottedi"
});
});
modelBuilder.Entity("PortBlog.API.Entities.Academic", b =>
{
b.HasOne("PortBlog.API.Entities.Resume", "Resume")
@ -1277,6 +1376,17 @@ namespace PortBlog.API.Migrations
b.Navigation("Resume");
});
modelBuilder.Entity("PortBlog.API.Entities.RefreshToken", b =>
{
b.HasOne("PortBlog.API.Entities.User", "User")
.WithMany("RefreshTokens")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("PortBlog.API.Entities.Resume", b =>
{
b.HasOne("PortBlog.API.Entities.Candidate", "Candidate")
@ -1360,6 +1470,11 @@ namespace PortBlog.API.Migrations
b.Navigation("SocialLinks");
});
modelBuilder.Entity("PortBlog.API.Entities.User", b =>
{
b.Navigation("RefreshTokens");
});
#pragma warning restore 612, 618
}
}

View File

@ -2,7 +2,7 @@
{
public class AcademicDto
{
public int AcademicId { get; set; }
public int? AcademicId { get; set; }
public string Institution { get; set; } = string.Empty;

View File

@ -2,7 +2,7 @@
{
public class CertificationDto
{
public int CertificationId { get; set; }
public int? CertificationId { get; set; }
public string CertificationName { get; set; } = string.Empty;

View File

@ -2,7 +2,7 @@
{
public class ExperienceDetailsDto
{
public int Id { get; set; }
public int? Id { get; set; }
public string Details { get; set; } = string.Empty;

View File

@ -4,7 +4,7 @@ namespace PortBlog.API.Models
{
public class ExperienceDto
{
public int ExperienceId { get; set; }
public int? ExperienceId { get; set; }
public string Title { get; set; } = string.Empty;
@ -12,10 +12,31 @@ namespace PortBlog.API.Models
public string Company { get; set; } = string.Empty;
public string? Location { get; set; }
/// <summary>
/// Full start date for write operations (e.g. "2020-01-01").
/// </summary>
public DateTime? StartDate { get; set; }
/// <summary>
/// Full end date for write operations. Null means "Present".
/// </summary>
public DateTime? EndDate { get; set; }
/// <summary>
/// Read-only display value: start year (e.g. "2020"). Mapped from entity on read.
/// </summary>
public string StartYear { get; set; } = string.Empty;
/// <summary>
/// Read-only display value: end year (e.g. "2023" or "Present"). Mapped from entity on read.
/// </summary>
public string EndYear { get; set; } = string.Empty;
/// <summary>
/// Read-only display value: formatted period (e.g. "Jan 2020 - Mar 2023"). Mapped from entity on read.
/// </summary>
public string Period { get; set; } = string.Empty;
public ICollection<ExperienceDetailsDto> Details { get; set; } = new List<ExperienceDetailsDto>();

View File

@ -2,7 +2,7 @@
{
public class HobbyDto
{
public int HobbyId { get; set; }
public int? HobbyId { get; set; }
public string Name { get; set; } = string.Empty;

View File

@ -11,5 +11,7 @@
public string Password { get; set; } = string.Empty;
public bool Enable { get; set; } = false;
public string Domain { get; set; } = string.Empty;
}
}

View File

@ -9,8 +9,6 @@ namespace PortBlog.API.Models
public string FromEmail { get; set; } = string.Empty;
public string CandidateName { get; set; } = string.Empty;
public string ToEmail { get; set; } = string.Empty;
public string Subject { get; set; } = string.Empty;

View File

@ -0,0 +1,9 @@
namespace PortBlog.API.Models
{
public class OtpMailModel
{
public string Name { get; set; } = string.Empty;
public string OtpCode { get; set; } = string.Empty;
public int ExpiryMinutes { get; set; } = 3;
}
}

View File

@ -4,7 +4,7 @@ namespace PortBlog.API.Models
{
public class ProjectDto
{
public int ProjectId { get; set; }
public int? ProjectId { get; set; }
public string Name { get; set; } = string.Empty;

View File

@ -2,7 +2,7 @@
{
public class SkillDto
{
public int SkillId { get; set; }
public int? SkillId { get; set; }
public string Name { get; set; } = string.Empty;

View File

@ -0,0 +1,8 @@
namespace PortBlog.API.Models
{
public class VerifyOtpRequest
{
public string UserId { get; set; } = string.Empty;
public string OtpCode { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,11 @@
namespace PortBlog.API.Options
{
public class JwtAuthenticationOptions
{
required public string SecretKey { get; set; }
required public int AccessTokenExpiryInMinutes { get; set; }
required public int RefreshTokenExpiryInHours { get; set; }
}
}

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
@ -9,23 +9,32 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Asp.Versioning.Mvc" Version="8.1.1" />
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.1.0" />
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.4">
<PackageReference Include="AutoMapper" Version="15.0.1" />
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.10" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="9.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.2" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
<PackageReference Include="serilog.sinks.console" Version="5.0.1" />
<PackageReference Include="serilog.sinks.file" Version="5.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Otp.NET" Version="1.4.0" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="9.0.0" />
<PackageReference Include="Razor.Templating.Core" Version="2.1.0" />
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
<PackageReference Include="serilog.sinks.console" Version="6.0.0" />
<PackageReference Include="serilog.sinks.file" Version="7.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.6" />
</ItemGroup>
<ItemGroup>
<Content Include="Images\**" CopyToPublishDirectory="PreserveNewest" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\KBR.Cache\KBR.Cache.csproj" />
</ItemGroup>
</Project>

View File

@ -4,6 +4,128 @@
<name>PortBlog.API</name>
</assembly>
<members>
<member name="T:PortBlog.API.Controllers.AdminController">
<summary>
Controller for administrative actions related to the logged-in candidate and their resume.
All endpoints derive the candidate identity from the access token claims.
</summary>
</member>
<member name="M:PortBlog.API.Controllers.AdminController.#ctor(Microsoft.Extensions.Logging.ILogger{PortBlog.API.Controllers.CvController},PortBlog.API.Services.Contracts.IAdminService)">
<summary>
Controller for administrative actions related to the logged-in candidate and their resume.
All endpoints derive the candidate identity from the access token claims.
</summary>
</member>
<member name="M:PortBlog.API.Controllers.AdminController.GetHobbies">
<summary>
Get hobbies of the logged-in candidate.
</summary>
<returns>Hobbies and about details of the candidate</returns>
<response code="200">Returns the requested hobbies of the candidate</response>
</member>
<member name="M:PortBlog.API.Controllers.AdminController.GetContact">
<summary>
Get contact details (candidate with social links) for the logged-in candidate.
</summary>
<returns>Candidate details with social links</returns>
<response code="200">Returns the requested candidate details with social links</response>
</member>
<member name="M:PortBlog.API.Controllers.AdminController.GetResume">
<summary>
Get resume for the logged-in candidate.
</summary>
<returns>Candidate resume</returns>
<response code="200">Returns the requested candidate resume</response>
</member>
<member name="M:PortBlog.API.Controllers.AdminController.GetProjects">
<summary>
Get projects for the logged-in candidate.
</summary>
<returns>Candidate projects</returns>
<response code="200">Returns the requested candidate projects</response>
</member>
<member name="M:PortBlog.API.Controllers.AdminController.UpsertProject(PortBlog.API.Models.ProjectDto)">
<summary>
Create or update a project for the logged-in candidate's resume.
</summary>
</member>
<member name="M:PortBlog.API.Controllers.AdminController.DeleteProject(System.Int32)">
<summary>
Delete a project from the logged-in candidate's resume.
</summary>
<param name="projectId">The id of the project to delete</param>
</member>
<member name="M:PortBlog.API.Controllers.AdminController.UpsertHobbies(PortBlog.API.Models.AboutDto)">
<summary>
Create, update, or remove hobbies and update the about section for the logged-in candidate.
Hobbies present in the list are added or updated; hobbies not in the list are removed.
</summary>
</member>
<member name="M:PortBlog.API.Controllers.AdminController.UpsertSkills(System.Collections.Generic.IEnumerable{PortBlog.API.Models.SkillDto})">
<summary>
Create, update, or remove skills for the logged-in candidate's resume.
Skills present in the list are added or updated; skills not in the list are removed.
</summary>
</member>
<member name="M:PortBlog.API.Controllers.AdminController.UpsertAcademics(System.Collections.Generic.IEnumerable{PortBlog.API.Models.AcademicDto})">
<summary>
Create, update, or remove academics for the logged-in candidate's resume.
Academics present in the list are added or updated; academics not in the list are removed.
</summary>
</member>
<member name="M:PortBlog.API.Controllers.AdminController.UpsertExperiences(System.Collections.Generic.IEnumerable{PortBlog.API.Models.ExperienceDto})">
<summary>
Create, update, or remove experiences for the logged-in candidate's resume.
Experiences present in the list are added or updated; experiences not in the list are removed.
</summary>
</member>
<member name="M:PortBlog.API.Controllers.AdminController.UpsertCertifications(System.Collections.Generic.IEnumerable{PortBlog.API.Models.CertificationDto})">
<summary>
Create, update, or remove certifications for the logged-in candidate's resume.
Certifications present in the list are added or updated; certifications not in the list are removed.
</summary>
</member>
<member name="M:PortBlog.API.Controllers.AdminController.UpsertContact(PortBlog.API.Models.CandidateSocialLinksDto)">
<summary>
Create or update contact information (candidate with social links) for the logged-in candidate.
</summary>
</member>
<member name="T:PortBlog.API.Controllers.AuthController">
<summary>
Controller for handling authentication-related operations.
</summary>
</member>
<member name="M:PortBlog.API.Controllers.AuthController.#ctor(PortBlog.API.Services.Contracts.IAuthService,PortBlog.API.Services.Contracts.IMailService,PortBlog.API.Repositories.Contracts.ICandidateRepository,Microsoft.Extensions.Logging.ILogger{PortBlog.API.Controllers.AuthController},AutoMapper.IMapper,Microsoft.Extensions.Configuration.IConfiguration,PortBlog.API.Services.Contracts.ITemplateService,KBR.Cache.IAppDistributedCache)">
<summary>
Controller for handling authentication-related operations.
</summary>
</member>
<member name="M:PortBlog.API.Controllers.AuthController.GenerateOtp(System.String)">
<summary>
Generates a One-Time Password (OTP) for the specified candidate and sends it via email.
</summary>
<param name="email">The email of the candidate for whom the OTP is generated.</param>
<returns>An ActionResult indicating the result of the operation.</returns>
</member>
<member name="M:PortBlog.API.Controllers.AuthController.VerifyOtp(PortBlog.API.Models.VerifyOtpRequest)">
<summary>
Verifies the One-Time Password (OTP) for the specified user.
</summary>
<param name="request">The request containing the user ID and OTP code to verify.</param>
<returns>An ActionResult indicating the result of the verification.</returns>
</member>
<member name="M:PortBlog.API.Controllers.AuthController.Refresh">
<summary>
Refreshes the access token using a valid refresh token from the HttpOnly cookie.
</summary>
<returns>An IActionResult containing the new access token if the refresh token is valid; otherwise, an appropriate error response.</returns>
</member>
<member name="M:PortBlog.API.Controllers.AuthController.Logout">
<summary>
Logs out the current user by removing the refresh token cookie and invalidating the refresh token.
</summary>
<returns>An IActionResult indicating the result of the logout operation.</returns>
</member>
<member name="M:PortBlog.API.Controllers.CvController.Get(System.Int32)">
<summary>
Get CV details of the candidate by candidateid.
@ -181,6 +303,78 @@
<member name="M:PortBlog.API.Migrations.Dataupdate.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
<inheritdoc />
</member>
<member name="T:PortBlog.API.Migrations.CreateCacheTable">
<inheritdoc />
</member>
<member name="M:PortBlog.API.Migrations.CreateCacheTable.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
<inheritdoc />
</member>
<member name="M:PortBlog.API.Migrations.CreateCacheTable.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
<inheritdoc />
</member>
<member name="M:PortBlog.API.Migrations.CreateCacheTable.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
<inheritdoc />
</member>
<member name="T:PortBlog.API.Migrations.MessageContentMaxLength">
<inheritdoc />
</member>
<member name="M:PortBlog.API.Migrations.MessageContentMaxLength.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
<inheritdoc />
</member>
<member name="M:PortBlog.API.Migrations.MessageContentMaxLength.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
<inheritdoc />
</member>
<member name="M:PortBlog.API.Migrations.MessageContentMaxLength.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
<inheritdoc />
</member>
<member name="T:PortBlog.API.Migrations.User_RefreshTokens">
<inheritdoc />
</member>
<member name="M:PortBlog.API.Migrations.User_RefreshTokens.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
<inheritdoc />
</member>
<member name="M:PortBlog.API.Migrations.User_RefreshTokens.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
<inheritdoc />
</member>
<member name="M:PortBlog.API.Migrations.User_RefreshTokens.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
<inheritdoc />
</member>
<member name="T:PortBlog.API.Migrations.User_RefreshTokens_Rerun">
<inheritdoc />
</member>
<member name="M:PortBlog.API.Migrations.User_RefreshTokens_Rerun.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
<inheritdoc />
</member>
<member name="M:PortBlog.API.Migrations.User_RefreshTokens_Rerun.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
<inheritdoc />
</member>
<member name="M:PortBlog.API.Migrations.User_RefreshTokens_Rerun.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
<inheritdoc />
</member>
<member name="T:PortBlog.API.Migrations.User_RefreshTokens_Update">
<inheritdoc />
</member>
<member name="M:PortBlog.API.Migrations.User_RefreshTokens_Update.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
<inheritdoc />
</member>
<member name="M:PortBlog.API.Migrations.User_RefreshTokens_Update.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
<inheritdoc />
</member>
<member name="M:PortBlog.API.Migrations.User_RefreshTokens_Update.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
<inheritdoc />
</member>
<member name="T:PortBlog.API.Migrations.updaterefreshtoken">
<inheritdoc />
</member>
<member name="M:PortBlog.API.Migrations.updaterefreshtoken.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
<inheritdoc />
</member>
<member name="M:PortBlog.API.Migrations.updaterefreshtoken.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
<inheritdoc />
</member>
<member name="M:PortBlog.API.Migrations.updaterefreshtoken.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
<inheritdoc />
</member>
<member name="T:PortBlog.API.Models.CvDto">
<summary>
CV details of the candidate
@ -251,6 +445,31 @@
The project categories of all the projects
</summary>
</member>
<member name="P:PortBlog.API.Models.ExperienceDto.StartDate">
<summary>
Full start date for write operations (e.g. "2020-01-01").
</summary>
</member>
<member name="P:PortBlog.API.Models.ExperienceDto.EndDate">
<summary>
Full end date for write operations. Null means "Present".
</summary>
</member>
<member name="P:PortBlog.API.Models.ExperienceDto.StartYear">
<summary>
Read-only display value: start year (e.g. "2020"). Mapped from entity on read.
</summary>
</member>
<member name="P:PortBlog.API.Models.ExperienceDto.EndYear">
<summary>
Read-only display value: end year (e.g. "2023" or "Present"). Mapped from entity on read.
</summary>
</member>
<member name="P:PortBlog.API.Models.ExperienceDto.Period">
<summary>
Read-only display value: formatted period (e.g. "Jan 2020 - Mar 2023"). Mapped from entity on read.
</summary>
</member>
<member name="T:PortBlog.API.Models.ResumeDto">
<summary>
CV details of the candidate
@ -271,5 +490,216 @@
The work experiences of the candidate
</summary>
</member>
<member name="T:PortBlog.API.Repositories.ResumeRepository">
<summary>
Repository for managing resume-related data access and operations.
</summary>
</member>
<member name="M:PortBlog.API.Repositories.ResumeRepository.GetLatestResumeForCandidateAsync(System.Int32,System.Boolean)">
<summary>
Retrieves the latest resume for a candidate, optionally including related data.
</summary>
<param name="candidateId">The ID of the candidate.</param>
<param name="includeOtherData">If true, includes related data such as academics, experiences, social links, etc.</param>
<returns>The latest <see cref="T:PortBlog.API.Entities.Resume"/> for the candidate, or null if not found.</returns>
</member>
<member name="T:PortBlog.API.Services.AdminService">
<summary>
Service for administrative operations related to candidates, resumes, and their associated data.
</summary>
</member>
<member name="M:PortBlog.API.Services.AdminService.#ctor(PortBlog.API.Repositories.Contracts.ICandidateRepository,PortBlog.API.Repositories.Contracts.IResumeRepository,AutoMapper.IMapper)">
<summary>
Service for administrative operations related to candidates, resumes, and their associated data.
</summary>
</member>
<member name="T:PortBlog.API.Services.AuthService">
<summary>
Provides authentication services such as OTP generation, validation, and JWT token management.
</summary>
</member>
<member name="M:PortBlog.API.Services.AuthService.#ctor(Microsoft.Extensions.Configuration.IConfiguration,KBR.Cache.IAppDistributedCache,PortBlog.API.DbContexts.CvBlogContext)">
<summary>
Provides authentication services such as OTP generation, validation, and JWT token management.
</summary>
</member>
<member name="M:PortBlog.API.Services.AuthService.GenerateOtp(System.String,System.Threading.CancellationToken)">
<summary>
Generates a one-time password (OTP) for the specified email address and stores the secret key in the cache.
</summary>
<param name="email">The email address for which to generate the OTP.</param>
<param name="ct">A cancellation token that can be used to cancel the operation.</param>
<returns>A task that represents the asynchronous operation. The task result contains the generated OTP as a string.</returns>
</member>
<member name="M:PortBlog.API.Services.AuthService.ValidateOtp(System.String,System.String)">
<summary>
Validates the provided OTP against the secret key.
</summary>
<param name="secretKey">The Base32 encoded secret key.</param>
<param name="otp">The OTP to validate.</param>
<returns>True if the OTP is valid; otherwise, false.</returns>
</member>
<member name="M:PortBlog.API.Services.AuthService.GenerateAccessToken(System.String)">
<summary>
Generates a JWT access token for the specified username.
</summary>
<param name="username">The username for which to generate the access token.</param>
<returns>The generated JWT access token as a string.</returns>
</member>
<member name="M:PortBlog.API.Services.AuthService.GenerateRefreshToken">
<summary>
Generates a secure random refresh token as a Base64-encoded string.
</summary>
<returns>The generated refresh token.</returns>
</member>
<member name="M:PortBlog.API.Services.AuthService.SaveRefreshToken(System.String,System.String,Microsoft.AspNetCore.Http.HttpContext)">
<summary>
Saves a refresh token for the specified user email and associates it with the current HTTP context.
</summary>
<param name="userEmail">The email address of the user.</param>
<param name="refreshToken">The refresh token to be saved.</param>
<param name="httpContext">The current HTTP context containing request information.</param>
<returns>A task that represents the asynchronous save operation.</returns>
</member>
<member name="M:PortBlog.API.Services.AuthService.SaveRefreshToken(PortBlog.API.Entities.RefreshToken)">
<summary>
Saves a refresh token entity to the database.
</summary>
<param name="refreshToken">The refresh token entity to save.</param>
<returns>A task that represents the asynchronous save operation.</returns>
</member>
<member name="M:PortBlog.API.Services.AuthService.GetRefreshToken(System.String)">
<summary>
Retrieves a valid, non-revoked, and non-expired refresh token entity matching the provided refresh token string.
</summary>
<param name="refreshToken">The refresh token string to validate and retrieve.</param>
<returns>
A task that represents the asynchronous operation. The task result contains the matching <see cref="T:PortBlog.API.Entities.RefreshToken"/> entity if found and valid; otherwise, throws <see cref="T:System.InvalidOperationException"/>.
</returns>
<exception cref="T:System.InvalidOperationException">Thrown if no valid refresh token is found.</exception>
</member>
<member name="M:PortBlog.API.Services.AuthService.RemoveRefreshToken(System.String)">
<summary>
Revokes (removes) a refresh token by marking it as revoked in the database if it is valid and not expired.
</summary>
<param name="refreshToken">The refresh token to revoke.</param>
<returns>A task that represents the asynchronous revoke operation.</returns>
</member>
<member name="T:PortBlog.API.Services.Contracts.IAdminService">
<summary>
Service for administrative operations related to candidates, resumes, and their associated data.
</summary>
</member>
<member name="T:PortBlog.API.Services.Contracts.IAuthService">
<summary>
Provides authentication-related services such as OTP generation, token management, and refresh token handling.
</summary>
</member>
<member name="M:PortBlog.API.Services.Contracts.IAuthService.GenerateOtp(System.String,System.Threading.CancellationToken)">
<summary>
Generates a one-time password (OTP) for the specified email.
</summary>
<param name="email">The email address to generate the OTP for.</param>
<param name="ct">A cancellation token.</param>
<returns>The generated OTP as a string.</returns>
</member>
<member name="M:PortBlog.API.Services.Contracts.IAuthService.ValidateOtp(System.String,System.String)">
<summary>
Validates the provided OTP against the secret key.
</summary>
<param name="secretKey">The secret key used for validation.</param>
<param name="otp">The OTP to validate.</param>
<returns>True if the OTP is valid; otherwise, false.</returns>
</member>
<member name="M:PortBlog.API.Services.Contracts.IAuthService.GenerateAccessToken(System.String)">
<summary>
Generates an access token for the specified username.
</summary>
<param name="username">The username for which to generate the access token.</param>
<returns>The generated access token as a string.</returns>
</member>
<member name="M:PortBlog.API.Services.Contracts.IAuthService.GenerateRefreshToken">
<summary>
Generates a new refresh token.
</summary>
<returns>The generated refresh token as a string.</returns>
</member>
<member name="M:PortBlog.API.Services.Contracts.IAuthService.SaveRefreshToken(System.String,System.String,Microsoft.AspNetCore.Http.HttpContext)">
<summary>
Saves the refresh token for the specified user and HTTP context.
</summary>
<param name="userId">The user ID.</param>
<param name="refreshToken">The refresh token to save.</param>
<param name="httpContext">The HTTP context.</param>
</member>
<member name="M:PortBlog.API.Services.Contracts.IAuthService.SaveRefreshToken(PortBlog.API.Entities.RefreshToken)">
<summary>
Saves the specified refresh token.
</summary>
<param name="refreshToken">The refresh token entity to save.</param>
</member>
<member name="M:PortBlog.API.Services.Contracts.IAuthService.GetRefreshToken(System.String)">
<summary>
Retrieves the refresh token entity for the specified token string.
</summary>
<param name="refreshToken">The refresh token string.</param>
<returns>The corresponding <see cref="T:PortBlog.API.Entities.RefreshToken"/> entity.</returns>
</member>
<member name="M:PortBlog.API.Services.Contracts.IAuthService.RemoveRefreshToken(System.String)">
<summary>
Removes the specified refresh token.
</summary>
<param name="refreshToken">The refresh token to remove.</param>
</member>
<member name="T:PortBlog.API.Services.MailService">
<summary>
Provides functionality for sending emails and logging message activity.
</summary>
<remarks>
Initializes a new instance of the <see cref="T:PortBlog.API.Services.MailService"/> class.
</remarks>
<param name="configuration">The application configuration.</param>
<param name="logger">The logger instance.</param>
<param name="mailRepository">The mail repository for storing messages.</param>
<param name="mapper">The AutoMapper instance.</param>
</member>
<member name="M:PortBlog.API.Services.MailService.#ctor(Microsoft.Extensions.Configuration.IConfiguration,Microsoft.Extensions.Logging.ILogger{PortBlog.API.Services.MailService},PortBlog.API.Repositories.Contracts.IMailRepository,AutoMapper.IMapper)">
<summary>
Provides functionality for sending emails and logging message activity.
</summary>
<remarks>
Initializes a new instance of the <see cref="T:PortBlog.API.Services.MailService"/> class.
</remarks>
<param name="configuration">The application configuration.</param>
<param name="logger">The logger instance.</param>
<param name="mailRepository">The mail repository for storing messages.</param>
<param name="mapper">The AutoMapper instance.</param>
</member>
<member name="M:PortBlog.API.Services.MailService.SendAsync(PortBlog.API.Models.MessageSendDto)">
<summary>
Sends an email message asynchronously using the provided message details.
</summary>
<param name="messageSendDto">The message details to send.</param>
<returns>A task representing the asynchronous operation.</returns>
</member>
<member name="T:PortBlog.API.Services.TemplateService">
<summary>
Provides functionality to render Razor view templates with a specified model.
</summary>
</member>
<member name="M:PortBlog.API.Services.TemplateService.GetViewTemplate``1(System.String,``0)">
<summary>
Renders a Razor view template at the specified path using the provided model.
</summary>
<typeparam name="T">The type of the model to pass to the view.</typeparam>
<param name="viewPath">The path to the Razor view template.</param>
<param name="model">The model to use when rendering the view.</param>
<returns>A task that represents the asynchronous operation. The task result contains the rendered view as a string.</returns>
</member>
<member name="T:Program">
<summary>
Auto-generated public partial Program class for top-level statement apps.
</summary>
</member>
</members>
</doc>

View File

@ -35,6 +35,16 @@ namespace PortBlog.API.Profiles
(
dest => dest.EndYear,
opts => opts.MapFrom(src => src.EndDate != null ? src.EndDate.Value.Year.ToString() : "Present")
)
.ForMember
(
dest => dest.StartDate,
opts => opts.MapFrom(src => src.StartDate)
)
.ForMember
(
dest => dest.EndDate,
opts => opts.MapFrom(src => src.EndDate)
);
CreateMap<ExperienceDetails, ExperienceDetailsDto>();
CreateMap<Project, ProjectDto>()

View File

@ -1,33 +1,37 @@
using Asp.Versioning;
using Asp.Versioning.ApiExplorer;
using KBR.Cache.Extensions;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.FileProviders;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using PortBlog.API.DbContexts;
using PortBlog.API.Extensions;
using PortBlog.API.Middleware;
using Serilog;
using System.Reflection;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
var loggerConfiguration = new LoggerConfiguration();
if (builder.Environment.IsDevelopment())
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console()
.WriteTo.File("logs/portblog.txt", rollingInterval: RollingInterval.Day)
.CreateLogger();
loggerConfiguration = loggerConfiguration.MinimumLevel.Debug()
.WriteTo.Console();
}
else
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
loggerConfiguration = loggerConfiguration.MinimumLevel.Information();
}
Log.Logger = loggerConfiguration
.WriteTo.File("logs/portblog.txt", rollingInterval: RollingInterval.Day)
.CreateLogger();
}
var urls = builder.Configuration.GetSection("Urls");
@ -39,10 +43,12 @@ if (!string.IsNullOrEmpty(urls.Value))
}
var allowedCorsOrigins = builder.Configuration.GetSection("AllowedCorsOrigins");
string[] origins = [];
if (!String.IsNullOrEmpty(allowedCorsOrigins.Value))
{
var origins = allowedCorsOrigins.Value.Split(",");
origins = allowedCorsOrigins.Value.Split(",", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
}
builder.Services.AddCors(options =>
{
@ -51,9 +57,10 @@ if (!String.IsNullOrEmpty(allowedCorsOrigins.Value))
{
policy.WithOrigins(origins);
policy.AllowAnyHeader();
policy.AllowAnyMethod();
policy.AllowCredentials();
});
});
}
builder.Host.UseSerilog();
@ -71,16 +78,16 @@ builder.Services.AddEndpointsApiExplorer();
var connectionString = builder.Configuration.GetConnectionString("PortBlogDBConnectionString");
if (builder.Configuration.GetValue<bool>("ConnectionStrings:Encryption"))
{
connectionString = builder.Configuration.DecryptConnectionString(connectionString);
}
if (string.IsNullOrEmpty(connectionString))
{
throw new Exception("Connection string cannot be empty");
}
if (builder.Configuration.GetValue<bool>("ConnectionStrings:Encryption"))
{
connectionString = builder.Configuration.DecryptConnectionString(connectionString);
}
builder.Services
.AddDbContext<CvBlogContext>(dbContextOptions
=> dbContextOptions.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)));
@ -88,38 +95,26 @@ builder.Services
builder.Services.AddRepositories();
builder.Services.AddServices();
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
builder.Services.AddAutoMapper(cfg => cfg.AddMaps(AppDomain.CurrentDomain.GetAssemblies()));
builder.Services.AddCache(builder.Configuration);
// Registering API Versioning Specification services
builder.Services.AddApiVersioning(setupAction =>
builder.Services
.AddApiVersioning(options =>
{
setupAction.ReportApiVersions = true;
setupAction.AssumeDefaultVersionWhenUnspecified = true;
setupAction.DefaultApiVersion = new ApiVersion(1, 0);
}).AddMvc()
.AddApiExplorer(setupAction =>
options.DefaultApiVersion = new ApiVersion(1, 0);
options.AssumeDefaultVersionWhenUnspecified = true;
options.ReportApiVersions = true;
})
.AddMvc() // IMPORTANT
.AddApiExplorer(options =>
{
setupAction.SubstituteApiVersionInUrl = true;
options.GroupNameFormat = "'v'V";
options.SubstituteApiVersionInUrl = true;
});
var apiVersionDescriptionProvider = builder.Services.BuildServiceProvider()
.GetRequiredService<IApiVersionDescriptionProvider>();
builder.Services.AddSwaggerGen(c =>
{
foreach(var description in apiVersionDescriptionProvider.ApiVersionDescriptions)
{
c.SwaggerDoc(
$"{description.GroupName}",
new()
{
Title = "Portfolio Blog API",
Version = description.ApiVersion.ToString(),
Description = "Through this API you can access candidate cv details and along with other details."
});
}
// XML Comments file for API Documentation
var xmlCommentsFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlCommentsFullPath = $"{Path.Combine(AppContext.BaseDirectory, xmlCommentsFile)}";
@ -146,17 +141,64 @@ builder.Services.AddSwaggerGen(c =>
In = ParameterLocation.Header
};
var requirement = new OpenApiSecurityRequirement()
// JWT Bearer Security Definition
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
{key, new List<string> {} }
Description = "JWT Authorization header using the Bearer scheme.\nExample: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..'",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.Http,
Scheme = "Bearer",
BearerFormat = "JWT"
});
var bearerScheme = new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
};
var requirement = new OpenApiSecurityRequirement
{
{ key, new List<string>() },
{ bearerScheme, new List<string>() }
};
c.AddSecurityRequirement(requirement);
});
var app = builder.Build();
builder.Services.ConfigureOptions<ConfigureSwaggerOptions>();
app.UseCors();
var jwtKey = builder.Configuration["Jwt:Key"];
if (string.IsNullOrEmpty(jwtKey))
{
throw new Exception("JWT key cannot be null or empty. Please check your configuration.");
}
var key = Encoding.UTF8.GetBytes(jwtKey);
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = builder.Configuration["Jwt:Issuer"],
ValidAudience = builder.Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(key)
};
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
@ -169,8 +211,15 @@ if (app.Environment.IsDevelopment())
app.UseSwagger();
app.UseSwaggerUI(setupAction =>
{
var descriptions = app.DescribeApiVersions();
foreach(var description in descriptions)
// Get the IApiVersionDescriptionProvider from the app's service provider
var apiVersionDescriptionProvider = app.Services.GetRequiredService<IApiVersionDescriptionProvider>();
foreach (var d in apiVersionDescriptionProvider.ApiVersionDescriptions)
{
Console.WriteLine($"GroupName: {d.GroupName}");
}
foreach (var description in apiVersionDescriptionProvider.ApiVersionDescriptions)
{
setupAction.SwaggerEndpoint(
$"/swagger/{description.GroupName}/swagger.json",
@ -188,10 +237,16 @@ app.UseStaticFiles(new StaticFileOptions()
RequestPath = new PathString("/images")
});
app.UseAuthorization();
app.UseRouting();
app.UseCors();
app.UseMiddleware<ApiKeyMiddleware>();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();

View File

@ -1,33 +1,23 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:37113",
"sslPort": 44357
}
},
{
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5039",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:5039"
},
"PortBlog.API": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7013;http://localhost:5039",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"dotnetRunMessages": true,
"applicationUrl": "https://localhost:7013;http://localhost:5039"
},
"IIS Express": {
"commandName": "IISExpress",
@ -37,5 +27,14 @@
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
},
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:37113",
"sslPort": 44357
}
}
}

View File

@ -23,5 +23,10 @@ namespace PortBlog.API.Repositories
{
return await _cvBlogContext.Candidates.FirstOrDefaultAsync(c => c.CandidateId == id);
}
public async Task<Candidate?> GetCandidateAsync(string email)
{
return await _cvBlogContext.Candidates.FirstOrDefaultAsync(c => c.Email == email);
}
}
}

View File

@ -6,6 +6,8 @@ namespace PortBlog.API.Repositories.Contracts
{
Task<Candidate?> GetCandidateAsync(int id);
Task<Candidate?> GetCandidateAsync(string email);
Task<bool> CandidateExistAsync(int candidateId);
}
}

View File

@ -15,5 +15,72 @@ namespace PortBlog.API.Repositories.Contracts
Task<Resume?> GetProjectsAsync(int candidateId);
Task<Blog?> GetBlogAsync(int candidate);
// Added for admin write operations used by controllers
Task<Resume?> GetByIdAsync(int resumeId);
Task<Resume?> GetByIdWithCollectionsAsync(int resumeId);
Task<Project?> GetProjectAsync(int projectId);
Task<Hobby?> GetHobbyAsync(int hobbyId);
Task<IEnumerable<Hobby>> GetHobbiesByResumeIdAsync(int resumeId);
Task<Candidate?> GetCandidateByIdAsync(int candidateId);
void AddProject(Project project);
void UpdateProject(Project project);
void RemoveProject(Project project);
void AddHobby(Hobby hobby);
void UpdateHobby(Hobby hobby);
void RemoveHobby(Hobby hobby);
void AddSkill(Skill skill);
void UpdateSkill(Skill skill);
void RemoveSkill(Skill skill);
void AddAcademic(Academic academic);
void UpdateAcademic(Academic academic);
void RemoveAcademic(Academic academic);
void AddExperience(Experience experience);
void UpdateExperience(Experience experience);
void RemoveExperience(Experience experience);
void AddExperienceDetails(ExperienceDetails details);
void UpdateExperienceDetails(ExperienceDetails details);
void RemoveExperienceDetails(ExperienceDetails details);
void AddCertification(Certification certification);
void UpdateCertification(Certification certification);
void RemoveCertification(Certification certification);
void AddResume(Resume resume);
void UpdateResume(Resume resume);
void UpdateCandidate(Candidate candidate);
void AddSocialLink(SocialLinks socialLink);
void UpdateSocialLink(SocialLinks socialLink);
Task<bool> SaveChangesAsync();
}
}

View File

@ -1,11 +1,13 @@
using Microsoft.EntityFrameworkCore;
using PortBlog.API.DbContexts;
using PortBlog.API.Entities;
using PortBlog.API.Models;
using PortBlog.API.Repositories.Contracts;
namespace PortBlog.API.Repositories
{
/// <summary>
/// Repository for managing resume-related data access and operations.
/// </summary>
public class ResumeRepository : IResumeRepository
{
private readonly CvBlogContext _cvBlogContext;
@ -14,6 +16,13 @@ namespace PortBlog.API.Repositories
{
_cvBlogContext = cvBlogContext;
}
/// <summary>
/// Retrieves the latest resume for a candidate, optionally including related data.
/// </summary>
/// <param name="candidateId">The ID of the candidate.</param>
/// <param name="includeOtherData">If true, includes related data such as academics, experiences, social links, etc.</param>
/// <returns>The latest <see cref="Resume"/> for the candidate, or null if not found.</returns>
public async Task<Resume?> GetLatestResumeForCandidateAsync(int candidateId, bool includeOtherData)
{
if (includeOtherData)
@ -83,5 +92,180 @@ namespace PortBlog.API.Repositories
return result?.SocialLinks?.Blog;
}
// New read helpers
public async Task<Resume?> GetByIdAsync(int resumeId)
{
return await _cvBlogContext.Resumes.FirstOrDefaultAsync(r => r.ResumeId == resumeId);
}
public async Task<Resume?> GetByIdWithCollectionsAsync(int resumeId)
{
return await _cvBlogContext.Resumes
.Include(r => r.Skills)
.Include(r => r.Academics)
.Include(r => r.Experiences)
.ThenInclude(e => e.Details)
.Include(r => r.Certifications)
.Include(r => r.Projects)
.FirstOrDefaultAsync(r => r.ResumeId == resumeId);
}
public async Task<Project?> GetProjectAsync(int projectId)
{
return await _cvBlogContext.Projects.FirstOrDefaultAsync(p => p.ProjectId == projectId);
}
public async Task<Hobby?> GetHobbyAsync(int hobbyId)
{
return await _cvBlogContext.Hobbies.FirstOrDefaultAsync(h => h.HobbyId == hobbyId);
}
public async Task<IEnumerable<Hobby>> GetHobbiesByResumeIdAsync(int resumeId)
{
return await _cvBlogContext.Hobbies.Where(h => h.ResumeId == resumeId).ToListAsync();
}
public async Task<Candidate?> GetCandidateByIdAsync(int candidateId)
{
return await _cvBlogContext.Candidates
.FirstOrDefaultAsync(c => c.CandidateId == candidateId);
}
// New write helpers
public void AddProject(Project project)
{
_cvBlogContext.Projects.Add(project);
}
public void UpdateProject(Project project)
{
_cvBlogContext.Projects.Update(project);
}
public void RemoveProject(Project project)
{
_cvBlogContext.Projects.Remove(project);
}
public void AddHobby(Hobby hobby)
{
_cvBlogContext.Hobbies.Add(hobby);
}
public void UpdateHobby(Hobby hobby)
{
_cvBlogContext.Hobbies.Update(hobby);
}
public void RemoveHobby(Hobby hobby)
{
_cvBlogContext.Hobbies.Remove(hobby);
}
public void AddSkill(Skill skill)
{
_cvBlogContext.Skills.Add(skill);
}
public void UpdateSkill(Skill skill)
{
_cvBlogContext.Skills.Update(skill);
}
public void RemoveSkill(Skill skill)
{
_cvBlogContext.Skills.Remove(skill);
}
public void AddAcademic(Academic academic)
{
_cvBlogContext.Academics.Add(academic);
}
public void UpdateAcademic(Academic academic)
{
_cvBlogContext.Academics.Update(academic);
}
public void RemoveAcademic(Academic academic)
{
_cvBlogContext.Academics.Remove(academic);
}
public void AddExperience(Experience experience)
{
_cvBlogContext.Experiences.Add(experience);
}
public void UpdateExperience(Experience experience)
{
_cvBlogContext.Experiences.Update(experience);
}
public void RemoveExperience(Experience experience)
{
_cvBlogContext.Experiences.Remove(experience);
}
public void AddExperienceDetails(ExperienceDetails details)
{
_cvBlogContext.ExperienceDetails.Add(details);
}
public void UpdateExperienceDetails(ExperienceDetails details)
{
_cvBlogContext.ExperienceDetails.Update(details);
}
public void RemoveExperienceDetails(ExperienceDetails details)
{
_cvBlogContext.ExperienceDetails.Remove(details);
}
public void AddCertification(Certification certification)
{
_cvBlogContext.Certifications.Add(certification);
}
public void UpdateCertification(Certification certification)
{
_cvBlogContext.Certifications.Update(certification);
}
public void RemoveCertification(Certification certification)
{
_cvBlogContext.Certifications.Remove(certification);
}
public void AddResume(Resume resume)
{
_cvBlogContext.Resumes.Add(resume);
}
public void UpdateResume(Resume resume)
{
_cvBlogContext.Resumes.Update(resume);
}
public void UpdateCandidate(Candidate candidate)
{
_cvBlogContext.Candidates.Update(candidate);
}
public void AddSocialLink(SocialLinks socialLink)
{
_cvBlogContext.SocialLinks.Add(socialLink);
}
public void UpdateSocialLink(SocialLinks socialLink)
{
_cvBlogContext.SocialLinks.Update(socialLink);
}
public async Task<bool> SaveChangesAsync()
{
return (await _cvBlogContext.SaveChangesAsync() >= 0);
}
}
}

View File

@ -0,0 +1,552 @@
using System.Security.Claims;
using AutoMapper;
using PortBlog.API.Entities;
using PortBlog.API.Models;
using PortBlog.API.Repositories.Contracts;
using PortBlog.API.Services.Contracts;
namespace PortBlog.API.Services
{
/// <summary>
/// Service for administrative operations related to candidates, resumes, and their associated data.
/// </summary>
public class AdminService(ICandidateRepository candidateRepository, IResumeRepository resumeRepository, IMapper mapper) : IAdminService
{
public int GetCandidateIdFromClaims(ClaimsPrincipal user)
{
var candidateIdClaim = user.FindFirst("CandidateId")?.Value;
if (string.IsNullOrEmpty(candidateIdClaim) || !int.TryParse(candidateIdClaim, out var candidateId))
{
throw new UnauthorizedAccessException("CandidateId claim is missing or invalid.");
}
return candidateId;
}
public async Task<AboutDto?> GetHobbiesAsync(int candidateId)
{
var aboutDetails = await resumeRepository.GetHobbiesAsync(candidateId);
return aboutDetails != null ? mapper.Map<AboutDto>(aboutDetails) : null;
}
public async Task<CandidateSocialLinksDto?> GetContactAsync(int candidateId)
{
var contact = await resumeRepository.GetCandidateWithSocialLinksAsync(candidateId);
return contact != null ? mapper.Map<CandidateSocialLinksDto>(contact) : null;
}
public async Task<ResumeDto?> GetResumeAsync(int candidateId)
{
var resume = await resumeRepository.GetResumeAsync(candidateId);
return resume != null ? mapper.Map<ResumeDto>(resume) : null;
}
public async Task<ProjectsDto?> GetProjectsAsync(int candidateId)
{
var projects = await resumeRepository.GetProjectsAsync(candidateId);
return projects != null ? mapper.Map<ProjectsDto>(projects) : null;
}
public async Task<ProjectDto> UpsertProjectAsync(int candidateId, ProjectDto projectDto)
{
var resumeWithCollections = await GetOrCreateResumeWithCollectionsAsync(candidateId);
Project? projectEntity = null;
if (projectDto.ProjectId > 0)
{
projectEntity = await resumeRepository.GetProjectAsync(projectDto.ProjectId.Value);
}
if (projectEntity == null)
{
projectEntity = new Project
{
Name = projectDto.Name,
Description = projectDto.Description,
Categories = projectDto.Categories ?? Array.Empty<string>(),
Roles = projectDto.Roles != null ? string.Join(",", projectDto.Roles) : null,
Responsibilities = projectDto.Responsibilities != null ? string.Join(",", projectDto.Responsibilities) : null,
TechnologiesUsed = projectDto.TechnologiesUsed != null ? string.Join(",", projectDto.TechnologiesUsed) : null,
Challenges = projectDto.Challenges,
LessonsLearned = projectDto.LessonsLearned,
Impact = projectDto.Impact,
StartDate = projectDto.StartDate == default ? null : projectDto.StartDate,
EndDate = projectDto.EndDate == default ? null : projectDto.EndDate,
ImagePath = projectDto.ImagePath,
Status = projectDto.Status,
ResumeId = resumeWithCollections.ResumeId
};
resumeRepository.AddProject(projectEntity);
}
else
{
projectEntity.Name = projectDto.Name;
projectEntity.Description = projectDto.Description;
projectEntity.Categories = projectDto.Categories ?? Array.Empty<string>();
projectEntity.Roles = projectDto.Roles != null ? string.Join(",", projectDto.Roles) : projectEntity.Roles;
projectEntity.Responsibilities = projectDto.Responsibilities != null ? string.Join(",", projectDto.Responsibilities) : projectEntity.Responsibilities;
projectEntity.TechnologiesUsed = projectDto.TechnologiesUsed != null ? string.Join(",", projectDto.TechnologiesUsed) : projectEntity.TechnologiesUsed;
projectEntity.Challenges = projectDto.Challenges;
projectEntity.LessonsLearned = projectDto.LessonsLearned;
projectEntity.Impact = projectDto.Impact;
projectEntity.StartDate = projectDto.StartDate == default ? projectEntity.StartDate : projectDto.StartDate;
projectEntity.EndDate = projectDto.EndDate == default ? projectEntity.EndDate : projectDto.EndDate;
projectEntity.ImagePath = projectDto.ImagePath;
projectEntity.Status = projectDto.Status;
resumeRepository.UpdateProject(projectEntity);
}
await resumeRepository.SaveChangesAsync();
return mapper.Map<ProjectDto>(projectEntity);
}
public async Task<bool> DeleteProjectAsync(int candidateId, int projectId)
{
var resume = await resumeRepository.GetLatestResumeForCandidateAsync(candidateId, includeOtherData: false)
?? throw new KeyNotFoundException($"Resume for candidate {candidateId} not found.");
var project = await resumeRepository.GetProjectAsync(projectId);
if (project == null || project.ResumeId != resume.ResumeId)
{
return false;
}
resumeRepository.RemoveProject(project);
await resumeRepository.SaveChangesAsync();
return true;
}
public async Task<AboutDto> UpsertHobbiesAsync(int candidateId, AboutDto aboutDto)
{
var resume = await resumeRepository.GetLatestResumeForCandidateAsync(candidateId, includeOtherData: false)
?? throw new KeyNotFoundException($"Resume for candidate {candidateId} not found.");
// Update About
if (!string.IsNullOrWhiteSpace(aboutDto.About))
{
resume.About = aboutDto.About;
resumeRepository.UpdateResume(resume);
}
// Upsert Hobbies
var existingHobbies = (await resumeRepository.GetHobbiesByResumeIdAsync(resume.ResumeId)).ToList();
var incomingIds = aboutDto.Hobbies.Where(h => h.HobbyId > 0).Select(h => h.HobbyId).ToHashSet();
foreach (var existing in existingHobbies)
{
if (!incomingIds.Contains(existing.HobbyId))
{
resumeRepository.RemoveHobby(existing);
}
}
var order = 1;
var resultEntities = new List<Hobby>();
foreach (var hobbyDto in aboutDto.Hobbies)
{
Hobby? hobbyEntity = null;
if (hobbyDto.HobbyId > 0)
{
hobbyEntity = existingHobbies.FirstOrDefault(h => h.HobbyId == hobbyDto.HobbyId);
}
if (hobbyEntity == null)
{
hobbyEntity = new Hobby
{
Name = hobbyDto.Name,
Description = hobbyDto.Description,
Icon = hobbyDto.Icon,
ResumeId = resume.ResumeId,
Order = order
};
resumeRepository.AddHobby(hobbyEntity);
}
else
{
hobbyEntity.Name = hobbyDto.Name;
hobbyEntity.Description = hobbyDto.Description;
hobbyEntity.Icon = hobbyDto.Icon;
hobbyEntity.Order = order;
resumeRepository.UpdateHobby(hobbyEntity);
}
resultEntities.Add(hobbyEntity);
order++;
}
await resumeRepository.SaveChangesAsync();
return new AboutDto
{
About = resume.About,
Hobbies = mapper.Map<ICollection<HobbyDto>>(resultEntities)
};
}
public async Task<CandidateSocialLinksDto> UpsertContactAsync(int candidateId, CandidateSocialLinksDto contactDto)
{
var resume = await resumeRepository.GetCandidateWithSocialLinksAsync(candidateId)
?? throw new KeyNotFoundException($"Resume with candidate id {candidateId} not found.");
if (!string.IsNullOrWhiteSpace(contactDto.Title))
{
resume.Title = contactDto.Title;
resumeRepository.UpdateResume(resume);
}
if (contactDto.Candidate != null && resume.Candidate != null)
{
resume.Candidate.FirstName = contactDto.Candidate.FirstName;
resume.Candidate.LastName = contactDto.Candidate.LastName;
resume.Candidate.Email = contactDto.Candidate.Email;
resume.Candidate.Phone = contactDto.Candidate.Phone;
resume.Candidate.Address = contactDto.Candidate.Address;
resumeRepository.UpdateCandidate(resume.Candidate);
}
if (contactDto.SocialLinks != null)
{
if (resume.SocialLinks == null)
{
resume.SocialLinks = new SocialLinks
{
ResumeId = resume.ResumeId,
GitHub = contactDto.SocialLinks.GitHub,
Linkedin = contactDto.SocialLinks.Linkedin,
Instagram = contactDto.SocialLinks.Instagram,
Facebook = contactDto.SocialLinks.Facebook,
Twitter = contactDto.SocialLinks.Twitter,
PersonalWebsite = contactDto.SocialLinks.PersonalWebsite,
BlogUrl = contactDto.SocialLinks.BlogUrl
};
resumeRepository.AddSocialLink(resume.SocialLinks);
}
else
{
resume.SocialLinks.GitHub = contactDto.SocialLinks.GitHub;
resume.SocialLinks.Linkedin = contactDto.SocialLinks.Linkedin;
resume.SocialLinks.Instagram = contactDto.SocialLinks.Instagram;
resume.SocialLinks.Facebook = contactDto.SocialLinks.Facebook;
resume.SocialLinks.Twitter = contactDto.SocialLinks.Twitter;
resume.SocialLinks.PersonalWebsite = contactDto.SocialLinks.PersonalWebsite;
resume.SocialLinks.BlogUrl = contactDto.SocialLinks.BlogUrl;
resumeRepository.UpdateSocialLink(resume.SocialLinks);
}
}
await resumeRepository.SaveChangesAsync();
var updatedContact = await resumeRepository.GetCandidateWithSocialLinksAsync(candidateId);
return mapper.Map<CandidateSocialLinksDto>(updatedContact);
}
public async Task<IEnumerable<SkillDto>> UpsertSkillsAsync(int candidateId, IEnumerable<SkillDto> skillDtos)
{
var resumeWithCollections = await GetOrCreateResumeWithCollectionsAsync(candidateId);
UpsertSkills(resumeWithCollections, skillDtos.ToList());
await resumeRepository.SaveChangesAsync();
var updatedResume = await resumeRepository.GetByIdWithCollectionsAsync(resumeWithCollections.ResumeId);
return mapper.Map<IEnumerable<SkillDto>>(updatedResume?.Skills ?? []);
}
public async Task<IEnumerable<AcademicDto>> UpsertAcademicsAsync(int candidateId, IEnumerable<AcademicDto> academicDtos)
{
var resumeWithCollections = await GetOrCreateResumeWithCollectionsAsync(candidateId);
UpsertAcademics(resumeWithCollections, academicDtos.ToList());
await resumeRepository.SaveChangesAsync();
var updatedResume = await resumeRepository.GetByIdWithCollectionsAsync(resumeWithCollections.ResumeId);
return mapper.Map<IEnumerable<AcademicDto>>(updatedResume?.Academics ?? []);
}
public async Task<IEnumerable<ExperienceDto>> UpsertExperiencesAsync(int candidateId, IEnumerable<ExperienceDto> experienceDtos)
{
var resumeWithCollections = await GetOrCreateResumeWithCollectionsAsync(candidateId);
UpsertExperiences(resumeWithCollections, experienceDtos.ToList());
await resumeRepository.SaveChangesAsync();
var updatedResume = await resumeRepository.GetByIdWithCollectionsAsync(resumeWithCollections.ResumeId);
return mapper.Map<IEnumerable<ExperienceDto>>(updatedResume?.Experiences ?? []);
}
public async Task<IEnumerable<CertificationDto>> UpsertCertificationsAsync(int candidateId, IEnumerable<CertificationDto> certificationDtos)
{
var resumeWithCollections = await GetOrCreateResumeWithCollectionsAsync(candidateId);
UpsertCertifications(resumeWithCollections, certificationDtos.ToList());
await resumeRepository.SaveChangesAsync();
var updatedResume = await resumeRepository.GetByIdWithCollectionsAsync(resumeWithCollections.ResumeId);
return mapper.Map<IEnumerable<CertificationDto>>(updatedResume?.Certifications ?? []);
}
#region Private Helpers
private async Task<Resume> GetOrCreateResumeWithCollectionsAsync(int candidateId)
{
var resume = await resumeRepository.GetLatestResumeForCandidateAsync(candidateId, includeOtherData: false);
if (resume == null)
{
resume = new Resume
{
CandidateId = candidateId,
About = string.Empty,
Order = 1
};
resumeRepository.AddResume(resume);
await resumeRepository.SaveChangesAsync();
}
return await resumeRepository.GetByIdWithCollectionsAsync(resume.ResumeId)
?? throw new InvalidOperationException("Failed to reload resume with collections.");
}
private void UpsertSkills(Resume resume, ICollection<SkillDto> skillDtos)
{
var existingSkills = resume.Skills.ToList();
var incomingIds = skillDtos.Where(s => s.SkillId > 0).Select(s => s.SkillId).ToHashSet();
foreach (var existing in existingSkills)
{
if (!incomingIds.Contains(existing.SkillId))
{
resumeRepository.RemoveSkill(existing);
}
}
foreach (var skillDto in skillDtos)
{
var skillEntity = skillDto.SkillId > 0
? existingSkills.FirstOrDefault(s => s.SkillId == skillDto.SkillId)
: null;
if (skillEntity == null)
{
resumeRepository.AddSkill(new Skill
{
Name = skillDto.Name,
Description = skillDto.Description,
ProficiencyLevel = skillDto.ProficiencyLevel,
ResumeId = resume.ResumeId
});
}
else
{
skillEntity.Name = skillDto.Name;
skillEntity.Description = skillDto.Description;
skillEntity.ProficiencyLevel = skillDto.ProficiencyLevel;
resumeRepository.UpdateSkill(skillEntity);
}
}
}
private void UpsertAcademics(Resume resume, ICollection<AcademicDto> academicDtos)
{
var existingAcademics = resume.Academics.ToList();
var incomingIds = academicDtos.Where(a => a.AcademicId > 0).Select(a => a.AcademicId).ToHashSet();
foreach (var existing in existingAcademics)
{
if (!incomingIds.Contains(existing.AcademicId))
{
resumeRepository.RemoveAcademic(existing);
}
}
foreach (var academicDto in academicDtos)
{
var academicEntity = academicDto.AcademicId > 0
? existingAcademics.FirstOrDefault(a => a.AcademicId == academicDto.AcademicId)
: null;
if (academicEntity == null)
{
resumeRepository.AddAcademic(new Academic
{
Institution = academicDto.Institution,
StartYear = academicDto.StartYear,
EndYear = academicDto.EndYear,
Degree = academicDto.Degree,
DegreeSpecialization = academicDto.DegreeSpecialization,
ResumeId = resume.ResumeId
});
}
else
{
academicEntity.Institution = academicDto.Institution;
academicEntity.StartYear = academicDto.StartYear;
academicEntity.EndYear = academicDto.EndYear;
academicEntity.Degree = academicDto.Degree;
academicEntity.DegreeSpecialization = academicDto.DegreeSpecialization;
resumeRepository.UpdateAcademic(academicEntity);
}
}
}
private void UpsertExperiences(Resume resume, ICollection<ExperienceDto> experienceDtos)
{
var existingExperiences = resume.Experiences.ToList();
var incomingIds = experienceDtos.Where(e => e.ExperienceId > 0).Select(e => e.ExperienceId).ToHashSet();
foreach (var existing in existingExperiences)
{
if (!incomingIds.Contains(existing.ExperienceId))
{
foreach (var detail in existing.Details.ToList())
{
resumeRepository.RemoveExperienceDetails(detail);
}
resumeRepository.RemoveExperience(existing);
}
}
foreach (var experienceDto in experienceDtos)
{
var experienceEntity = experienceDto.ExperienceId > 0
? existingExperiences.FirstOrDefault(e => e.ExperienceId == experienceDto.ExperienceId)
: null;
if (experienceEntity == null)
{
experienceEntity = new Experience
{
Title = experienceDto.Title,
Description = experienceDto.Description,
Company = experienceDto.Company,
Location = experienceDto.Location ?? string.Empty,
StartDate = experienceDto.StartDate ?? DateTime.UtcNow,
EndDate = experienceDto.EndDate,
ResumeId = resume.ResumeId
};
resumeRepository.AddExperience(experienceEntity);
var detailOrder = 1;
foreach (var detailDto in experienceDto.Details)
{
resumeRepository.AddExperienceDetails(new ExperienceDetails
{
Details = detailDto.Details,
Order = detailOrder++,
Experience = experienceEntity
});
}
}
else
{
experienceEntity.Title = experienceDto.Title;
experienceEntity.Description = experienceDto.Description;
experienceEntity.Company = experienceDto.Company;
if (!string.IsNullOrWhiteSpace(experienceDto.Location))
experienceEntity.Location = experienceDto.Location;
if (experienceDto.StartDate.HasValue)
experienceEntity.StartDate = experienceDto.StartDate.Value;
experienceEntity.EndDate = experienceDto.EndDate;
resumeRepository.UpdateExperience(experienceEntity);
UpsertExperienceDetails(experienceEntity, experienceDto.Details);
}
}
}
private void UpsertExperienceDetails(Experience experience, ICollection<ExperienceDetailsDto> detailDtos)
{
var existingDetails = experience.Details.ToList();
var incomingIds = detailDtos.Where(d => d.Id > 0).Select(d => d.Id).ToHashSet();
foreach (var existing in existingDetails)
{
if (!incomingIds.Contains(existing.Id))
{
resumeRepository.RemoveExperienceDetails(existing);
}
}
var order = 1;
foreach (var detailDto in detailDtos)
{
var detailEntity = detailDto.Id > 0
? existingDetails.FirstOrDefault(d => d.Id == detailDto.Id)
: null;
if (detailEntity == null)
{
resumeRepository.AddExperienceDetails(new ExperienceDetails
{
Details = detailDto.Details,
Order = order,
ExperienceId = experience.ExperienceId
});
}
else
{
detailEntity.Details = detailDto.Details;
detailEntity.Order = order;
resumeRepository.UpdateExperienceDetails(detailEntity);
}
order++;
}
}
private void UpsertCertifications(Resume resume, ICollection<CertificationDto> certificationDtos)
{
var existingCertifications = resume.Certifications.ToList();
var incomingIds = certificationDtos.Where(c => c.CertificationId > 0).Select(c => c.CertificationId).ToHashSet();
foreach (var existing in existingCertifications)
{
if (!incomingIds.Contains(existing.CertificationId))
{
resumeRepository.RemoveCertification(existing);
}
}
foreach (var certDto in certificationDtos)
{
var existingCert = certDto.CertificationId > 0
? existingCertifications.FirstOrDefault(c => c.CertificationId == certDto.CertificationId)
: null;
if (existingCert == null)
{
resumeRepository.AddCertification(new Certification
{
CertificationName = certDto.CertificationName,
IssuingOrganization = certDto.IssuingOrganization,
CertificationLink = certDto.CertificationLink,
IssueDate = certDto.IssueDate,
ExpiryDate = certDto.ExpiryDate,
ResumeId = resume.ResumeId
});
}
else
{
existingCert.CertificationName = certDto.CertificationName;
existingCert.IssuingOrganization = certDto.IssuingOrganization;
existingCert.CertificationLink = certDto.CertificationLink;
existingCert.IssueDate = certDto.IssueDate;
existingCert.ExpiryDate = certDto.ExpiryDate;
resumeRepository.UpdateCertification(existingCert);
}
}
}
#endregion
}
}

View File

@ -0,0 +1,192 @@
using KBR.Cache;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using OtpNet;
using PortBlog.API.DbContexts;
using PortBlog.API.Entities;
using PortBlog.API.Services.Contracts;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
namespace PortBlog.API.Services
{
/// <summary>
/// Provides authentication services such as OTP generation, validation, and JWT token management.
/// </summary>
public class AuthService(IConfiguration configuration, IAppDistributedCache cache, CvBlogContext context) : IAuthService
{
/// <summary>
/// Generates a one-time password (OTP) for the specified email address and stores the secret key in the cache.
/// </summary>
/// <param name="email">The email address for which to generate the OTP.</param>
/// <param name="ct">A cancellation token that can be used to cancel the operation.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains the generated OTP as a string.</returns>
public async Task<string> GenerateOtp(string email, CancellationToken ct = default)
{
var secretKey = KeyGeneration.GenerateRandomKey(20);
var secretKeyBase32 = Base32Encoding.ToString(secretKey);
var otp = this.GenerateOtp(secretKeyBase32);
await CacheHelpers.SetUserSecretsCacheAsync(cache, email, secretKeyBase32, ct);
return otp;
}
/// <summary>
/// Validates the provided OTP against the secret key.
/// </summary>
/// <param name="secretKey">The Base32 encoded secret key.</param>
/// <param name="otp">The OTP to validate.</param>
/// <returns>True if the OTP is valid; otherwise, false.</returns>
public bool ValidateOtp(string secretKey, string otp)
{
var key = Base32Encoding.ToBytes(secretKey);
var otpExpiryInMinutes = configuration.GetValue<int>("OtpExpiryInMinutes", 3);
var totp = new Totp(key, step: otpExpiryInMinutes * 60);
return totp.VerifyTotp(DateTime.UtcNow, otp, out long _, VerificationWindow.RfcSpecifiedNetworkDelay);
}
/// <summary>
/// Generates a JWT access token for the specified username.
/// </summary>
/// <param name="username">The username for which to generate the access token.</param>
/// <returns>The generated JWT access token as a string.</returns>
public string GenerateAccessToken(string username)
{
var candidate = context.Candidates.FirstOrDefault(c => c.Email == username);
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, username),
new Claim(ClaimTypes.Role, "Admin")
};
if (candidate != null)
{
claims.Add(new Claim("CandidateId", candidate.CandidateId.ToString()));
}
var jwtKey = configuration["Jwt:Key"];
if (string.IsNullOrEmpty(jwtKey))
throw new InvalidOperationException("JWT key is not configured.");
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtKey));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
// Safely read expiry minutes from configuration with a fallback default
var mins = configuration.GetValue<int?>("Jwt:AccessTokenExpiryInMinutes") ?? 5;
var token = new JwtSecurityToken(
issuer: configuration["Jwt:Issuer"],
audience: configuration["Jwt:Audience"],
claims: claims,
expires: DateTime.UtcNow.AddMinutes(mins),
signingCredentials: creds
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
/// <summary>
/// Generates a secure random refresh token as a Base64-encoded string.
/// </summary>
/// <returns>The generated refresh token.</returns>
public string GenerateRefreshToken()
{
return Convert.ToBase64String(RandomNumberGenerator.GetBytes(64));
}
/// <summary>
/// Saves a refresh token for the specified user email and associates it with the current HTTP context.
/// </summary>
/// <param name="userEmail">The email address of the user.</param>
/// <param name="refreshToken">The refresh token to be saved.</param>
/// <param name="httpContext">The current HTTP context containing request information.</param>
/// <returns>A task that represents the asynchronous save operation.</returns>
public async Task SaveRefreshToken(string userEmail, string refreshToken, HttpContext httpContext)
{
var user = await GetUser(userEmail) ?? throw new InvalidOperationException("User not found.");
// Store hashed refresh token in DB
var hashedToken = BCrypt.Net.BCrypt.HashPassword(refreshToken);
context.RefreshTokens.Add(new RefreshToken
{
UserId = user.UserId,
Token = hashedToken,
ExpiryDate = DateTime.UtcNow.AddHours(configuration.GetValue<int>("Jwt:RefreshTokenExpiryInHours", 24)),
JwtId = Guid.NewGuid().ToString(),
DeviceInfo = httpContext.Request.Headers.UserAgent.ToString()
});
await context.SaveChangesAsync();
}
/// <summary>
/// Saves a refresh token entity to the database.
/// </summary>
/// <param name="refreshToken">The refresh token entity to save.</param>
/// <returns>A task that represents the asynchronous save operation.</returns>
public async Task SaveRefreshToken(RefreshToken refreshToken)
{
context.RefreshTokens.Add(refreshToken);
await context.SaveChangesAsync();
}
/// <summary>
/// Retrieves a valid, non-revoked, and non-expired refresh token entity matching the provided refresh token string.
/// </summary>
/// <param name="refreshToken">The refresh token string to validate and retrieve.</param>
/// <returns>
/// A task that represents the asynchronous operation. The task result contains the matching <see cref="RefreshToken"/> entity if found and valid; otherwise, throws <see cref="InvalidOperationException"/>.
/// </returns>
/// <exception cref="InvalidOperationException">Thrown if no valid refresh token is found.</exception>
public async Task<RefreshToken> GetRefreshToken(string refreshToken)
{
// Find user and validate refresh token
var refreshEntity = await context.RefreshTokens
.Include(rt => rt.User)
.Where(rt => !rt.Revoked && rt.ExpiryDate > DateTime.UtcNow)
.ToListAsync();
var token = refreshEntity.FirstOrDefault(rt => BCrypt.Net.BCrypt.Verify(refreshToken, rt.Token)) ?? throw new InvalidOperationException("Refresh token not found or invalid.");
return token;
}
/// <summary>
/// Revokes (removes) a refresh token by marking it as revoked in the database if it is valid and not expired.
/// </summary>
/// <param name="refreshToken">The refresh token to revoke.</param>
/// <returns>A task that represents the asynchronous revoke operation.</returns>
public async Task RemoveRefreshToken(string refreshToken)
{
var tokens = await context.RefreshTokens
.Where(rt => rt.Revoked == false && rt.ExpiryDate > DateTime.UtcNow)
.ToListAsync();
var refreshTokenEntity = tokens
.FirstOrDefault(rt => BCrypt.Net.BCrypt.Verify(refreshToken, rt.Token));
if (refreshTokenEntity != null)
{
refreshTokenEntity.Revoked = true;
await context.SaveChangesAsync();
}
}
private async Task<User?> GetUser(string userEmail)
{
return await context.Users.FirstOrDefaultAsync(u => u.Email == userEmail);
}
private string GenerateOtp(string secretKey)
{
var key = Base32Encoding.ToBytes(secretKey);
var otpExpiryInMinutes = configuration.GetValue<int>("OtpExpiryInMinutes", 3);
var totp = new Totp(key, otpExpiryInMinutes * 60);
return totp.ComputeTotp(DateTime.UtcNow);
}
}
}

View File

@ -0,0 +1,37 @@
using System.Security.Claims;
using PortBlog.API.Models;
namespace PortBlog.API.Services.Contracts
{
/// <summary>
/// Service for administrative operations related to candidates, resumes, and their associated data.
/// </summary>
public interface IAdminService
{
int GetCandidateIdFromClaims(ClaimsPrincipal user);
Task<AboutDto?> GetHobbiesAsync(int candidateId);
Task<CandidateSocialLinksDto?> GetContactAsync(int candidateId);
Task<ResumeDto?> GetResumeAsync(int candidateId);
Task<ProjectsDto?> GetProjectsAsync(int candidateId);
Task<ProjectDto> UpsertProjectAsync(int candidateId, ProjectDto projectDto);
Task<bool> DeleteProjectAsync(int candidateId, int projectId);
Task<AboutDto> UpsertHobbiesAsync(int candidateId, AboutDto aboutDto);
Task<IEnumerable<SkillDto>> UpsertSkillsAsync(int candidateId, IEnumerable<SkillDto> skillDtos);
Task<IEnumerable<AcademicDto>> UpsertAcademicsAsync(int candidateId, IEnumerable<AcademicDto> academicDtos);
Task<IEnumerable<ExperienceDto>> UpsertExperiencesAsync(int candidateId, IEnumerable<ExperienceDto> experienceDtos);
Task<IEnumerable<CertificationDto>> UpsertCertificationsAsync(int candidateId, IEnumerable<CertificationDto> certificationDtos);
Task<CandidateSocialLinksDto> UpsertContactAsync(int candidateId, CandidateSocialLinksDto contactDto);
}
}

View File

@ -0,0 +1,66 @@
using PortBlog.API.Entities;
namespace PortBlog.API.Services.Contracts
{
/// <summary>
/// Provides authentication-related services such as OTP generation, token management, and refresh token handling.
/// </summary>
public interface IAuthService
{
/// <summary>
/// Generates a one-time password (OTP) for the specified email.
/// </summary>
/// <param name="email">The email address to generate the OTP for.</param>
/// <param name="ct">A cancellation token.</param>
/// <returns>The generated OTP as a string.</returns>
Task<string> GenerateOtp(string email, CancellationToken ct = default);
/// <summary>
/// Validates the provided OTP against the secret key.
/// </summary>
/// <param name="secretKey">The secret key used for validation.</param>
/// <param name="otp">The OTP to validate.</param>
/// <returns>True if the OTP is valid; otherwise, false.</returns>
bool ValidateOtp(string secretKey, string otp);
/// <summary>
/// Generates an access token for the specified username.
/// </summary>
/// <param name="username">The username for which to generate the access token.</param>
/// <returns>The generated access token as a string.</returns>
string GenerateAccessToken(string username);
/// <summary>
/// Generates a new refresh token.
/// </summary>
/// <returns>The generated refresh token as a string.</returns>
string GenerateRefreshToken();
/// <summary>
/// Saves the refresh token for the specified user and HTTP context.
/// </summary>
/// <param name="userId">The user ID.</param>
/// <param name="refreshToken">The refresh token to save.</param>
/// <param name="httpContext">The HTTP context.</param>
Task SaveRefreshToken(string userId, string refreshToken, HttpContext httpContext);
/// <summary>
/// Saves the specified refresh token.
/// </summary>
/// <param name="refreshToken">The refresh token entity to save.</param>
Task SaveRefreshToken(RefreshToken refreshToken);
/// <summary>
/// Retrieves the refresh token entity for the specified token string.
/// </summary>
/// <param name="refreshToken">The refresh token string.</param>
/// <returns>The corresponding <see cref="RefreshToken"/> entity.</returns>
Task<RefreshToken> GetRefreshToken(string refreshToken);
/// <summary>
/// Removes the specified refresh token.
/// </summary>
/// <param name="refreshToken">The refresh token to remove.</param>
Task RemoveRefreshToken(string refreshToken);
}
}

View File

@ -0,0 +1,7 @@
namespace PortBlog.API.Services.Contracts
{
public interface ITemplateService
{
Task<string> GetViewTemplate<T>(string viewPath, T model);
}
}

View File

@ -1,5 +1,6 @@
using AutoMapper;
using PortBlog.API.Common;
using KBR.Shared.Mail;
using PortBlog.API.Common.Constants;
using PortBlog.API.Entities;
using PortBlog.API.Models;
using PortBlog.API.Repositories.Contracts;
@ -9,29 +10,32 @@ using System.Net.Mail;
namespace PortBlog.API.Services
{
public class MailService : IMailService
/// <summary>
/// Provides functionality for sending emails and logging message activity.
/// </summary>
/// <remarks>
/// Initializes a new instance of the <see cref="MailService"/> class.
/// </remarks>
/// <param name="configuration">The application configuration.</param>
/// <param name="logger">The logger instance.</param>
/// <param name="mailRepository">The mail repository for storing messages.</param>
/// <param name="mapper">The AutoMapper instance.</param>
public class MailService(IConfiguration configuration, ILogger<MailService> logger, IMailRepository mailRepository, IMapper mapper) : IMailService
{
private readonly ILogger<MailService> _logger;
private readonly IConfiguration _configuration;
private readonly IMailRepository _mailRepository;
private readonly IMapper _mapper;
public MailService(IConfiguration configuration, ILogger<MailService> logger, IMailRepository mailRepository, IMapper mapper)
{
_logger = logger;
_configuration = configuration;
_mailRepository = mailRepository;
_mapper = mapper;
}
/// <summary>
/// Sends an email message asynchronously using the provided message details.
/// </summary>
/// <param name="messageSendDto">The message details to send.</param>
/// <returns>A task representing the asynchronous operation.</returns>
public async Task SendAsync(MessageSendDto messageSendDto)
{
_logger.LogInformation($"Sending message from {messageSendDto.Name} ({messageSendDto.FromEmail}).");
logger.LogInformation("Sending message from {Name} ({FromEmail}).", messageSendDto.Name, messageSendDto.FromEmail);
messageSendDto.Subject = $"Message from {messageSendDto.Name}: Portfolio";
var messageEntity = _mapper.Map<Message>(messageSendDto);
var messageEntity = mapper.Map<Message>(messageSendDto);
try
{
var mailSettings = _configuration.GetSection("MailSettings").Get<MailSettingsDto>();
var mailSettings = configuration.GetSection("MailSettings").Get<MailSettingsDto>();
if (mailSettings != null && mailSettings.Enable)
{
@ -44,30 +48,34 @@ namespace PortBlog.API.Services
client.EnableSsl = true;
client.Credentials = new NetworkCredential(mailSettings.Email, mailSettings.Password);
using (var messageMessage = new MailMessage(
from: new MailAddress(messageSendDto.FromEmail),
to: new MailAddress(messageSendDto.ToEmail, messageSendDto.CandidateName)
))
{
using var mailMessage = new MailMessage(
from: new MailAddress(mailSettings.Email),
to: new MailAddress(MailHelpers.ReplaceEmailDomain(messageSendDto.ToEmail, mailSettings.Domain), messageSendDto.Name)
);
messageMessage.Subject = messageSendDto.Subject;
messageMessage.Body = messageSendDto.Content;
mailMessage.Subject = messageSendDto.Subject;
mailMessage.Body = messageSendDto.Content;
mailMessage.IsBodyHtml = true;
client.Send(messageMessage);
client.Send(mailMessage);
messageSendDto.SentStatus = (int)MailConstants.MailStatus.Success;
}
}
_mailRepository.AddMessage(messageEntity);
await _mailRepository.SaveChangesAsync();
mailRepository.AddMessage(messageEntity);
await mailRepository.SaveChangesAsync();
}
}
catch (Exception ex)
{
_logger.LogCritical($"Exception while sending mail from {new MailAddress(messageSendDto.FromEmail, messageSendDto.Name)}", ex);
logger.LogCritical(
"Exception while sending mail from {FromEmail} ({Name}): {Exception}",
messageSendDto.FromEmail,
messageSendDto.Name,
ex.Message
);
messageSendDto.SentStatus = (int)MailConstants.MailStatus.Failed;
_mailRepository.AddMessage(messageEntity);
await _mailRepository.SaveChangesAsync();
mailRepository.AddMessage(messageEntity);
await mailRepository.SaveChangesAsync();
throw new Exception();
}
}

View File

@ -0,0 +1,23 @@
using PortBlog.API.Services.Contracts;
using Razor.Templating.Core;
namespace PortBlog.API.Services
{
/// <summary>
/// Provides functionality to render Razor view templates with a specified model.
/// </summary>
public class TemplateService : ITemplateService
{
/// <summary>
/// Renders a Razor view template at the specified path using the provided model.
/// </summary>
/// <typeparam name="T">The type of the model to pass to the view.</typeparam>
/// <param name="viewPath">The path to the Razor view template.</param>
/// <param name="model">The model to use when rendering the view.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains the rendered view as a string.</returns>
public async Task<string> GetViewTemplate<T>(string viewPath, T model)
{
return await RazorTemplateEngine.RenderAsync(viewPath, model);
}
}
}

View File

@ -0,0 +1,67 @@
@model PortBlog.API.Models.OtpMailModel
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>OTP Verification</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
body {
background-color: #f7f8fa;
font-family: 'Segoe UI', Arial, sans-serif;
margin: 0;
padding: 0;
color: #333;
}
.container {
background-color: #ffffff;
max-width: 500px;
margin: 40px auto;
padding: 30px;
border-radius: 10px;
box-shadow: 0 3px 8px rgba(0,0,0,0.1);
}
h2 {
color: #0078D7;
margin-bottom: 10px;
}
p {
font-size: 15px;
line-height: 1.6;
}
.otp {
display: inline-block;
background-color: #0078D7;
color: #ffffff;
padding: 12px 24px;
font-size: 20px;
font-weight: bold;
letter-spacing: 4px;
border-radius: 6px;
margin: 20px 0;
}
.footer {
font-size: 12px;
color: #999;
text-align: center;
margin-top: 30px;
}
</style>
</head>
<body>
<div class="container">
<h2>OTP Verification</h2>
<p>Hello @Model.Name,</p>
<p>Your One-Time Password (OTP) for verification is:</p>
<div class="otp">@Model.OtpCode</div>
<p>This OTP will expire in <strong>@Model.ExpiryMinutes minutes</strong>.</p>
<p>If you did not request this, please ignore this email.</p>
<div class="footer">
&copy; @DateTime.Now.Year Portfolio. All rights reserved.
</div>
</div>
</body>
</html>

View File

@ -4,6 +4,18 @@
"Encryption": "false",
"Key": "rgdBsYjrgQV9YaE+6QFK5oyTOWwbl2bSWkuc2JXcIyw="
},
"Cache": {
"ConnectionString": "SERVER=192.168.0.197; DATABASE=cv_blog; UID=PortBlogDevUser; PWD=p@$$w0rd1234;Allow User Variables=true;",
"Provider": "SqlServer"
},
"Jwt": {
"Key": "6JSHxgeot3Z1Obwhk4bvY2UoiFyH3tGq1FHXaaMuO5i",
"Issuer": "https://localhost:7013/",
"Audience": "http://localhost:4200",
"AccessTokenExpiryInMinutes": 1,
"RefreshTokenExpiryInHours": 1
},
"OTPExpiryInMinutes": 3,
"Logging": {
"LogLevel": {
"Default": "Information",
@ -12,11 +24,12 @@
},
"XApiKey": "c6eAXYcNT873TT7BfMgQyS4ii7hxa53TLEUN7pAGaaU=",
"MailSettings": {
"Enable": false,
"Host": "smtp.gmail.com",
"Enable": true,
"Host": "mail.kottedi.in",
"Port": 587,
"Email": "",
"Password": ""
"Email": "noreply@kottedi.in",
"Password": "MAINore.4356",
"Domain": "kottedi.in"
},
"AllowedCorsOrigins": "http://localhost:4000,http://127.0.0.1:4000"
"AllowedCorsOrigins": "http://localhost:4200,http://127.0.0.1:4200"
}

View File

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,96 @@

using KBR.Shared.Cache;
using Microsoft.Extensions.Caching.Distributed;
namespace KBR.Cache
{
internal class AppDistributedCache : IAppDistributedCache
{
private readonly IDistributedCache _cache;
private readonly DistributedCacheEntryOptions _entryOptions;
public AppDistributedCache(IDistributedCache cache)
{
this._cache = cache;
this._entryOptions = new DistributedCacheEntryOptions();
}
public T Get<T>(string key)
where T : class
{
if (this._cache.Get(key) is var result && result != null)
{
return result.FromByteArray<T>();
}
return default;
}
public async Task<T> GetAsync<T>(string key, CancellationToken cancellationToken = default)
where T : class
{
var result = await this._cache.GetAsync(key, cancellationToken);
if (result != null)
{
return result.FromByteArray<T>();
}
return default;
}
public void Set<T>(string key, T obj, DistributedCacheEntryOptions? entryOptions = default)
{
this._cache.Set(key, obj.ToByteArray(), entryOptions ?? this._entryOptions);
}
public async Task SetAsync<T>(string key, T obj, DistributedCacheEntryOptions? entryOptions = default, CancellationToken cancellationToken = default)
{
await this._cache.SetAsync(key, obj.ToByteArray(), entryOptions ?? this._entryOptions, cancellationToken);
}
public void Remove(string key)
{
this._cache.Remove(key);
}
public async Task RemoveAsync(string key, CancellationToken cancellationToken = default)
{
await this._cache.RemoveAsync(key, cancellationToken);
}
public TItem GetOrCreate<TItem>(string key, Func<TItem> factory)
where TItem : class
{
byte[] result = this._cache.Get(key);
var resultData = result?.FromByteArray<TItem>();
if (result == null || resultData == null)
{
var data = factory();
this._cache.Set(key, data.ToByteArray(), this._entryOptions);
return data;
}
return resultData;
}
public async Task<TItem> GetOrCreateAsync<TItem>(string key, Func<Task<TItem>> factory, CancellationToken cancellationToken = default)
where TItem : class
{
byte[] result = await this._cache.GetAsync(key, cancellationToken);
var resultData = result?.FromByteArray<TItem>();
if (result == null || resultData == null)
{
var data = await factory();
if (data != null)
{
await this._cache.SetAsync(key, data.ToByteArray(), this._entryOptions, cancellationToken);
}
return data;
}
return resultData;
}
}
}

View File

@ -0,0 +1,24 @@
using KBR.Shared.Cache.Models;
using Microsoft.Extensions.Caching.Distributed;
namespace KBR.Cache
{
public static class CacheHelpers
{
private static readonly string _userOtpSecrets = nameof(_userOtpSecrets);
private static string UserOtpSecretKey(string key) => $"{_userOtpSecrets}-{key}";
public static async Task SetUserSecretsCacheAsync(IAppDistributedCache cache, string userId, string secret, CancellationToken cancellationToken = default)
{
await cache.SetAsync(UserOtpSecretKey(userId), secret, new DistributedCacheEntryOptions { AbsoluteExpiration = DateTime.UtcNow.AddMinutes(3) }, cancellationToken);
}
public static async Task<string> GetUserOtpSecretAsync(IAppDistributedCache cache, string userId, CancellationToken cancellationToken = default)
{
var key = await cache.GetAsync<string>(UserOtpSecretKey(userId), cancellationToken);
return key;
}
}
}

View File

@ -0,0 +1,11 @@
namespace KBR.Cache.Constants
{
public static class CacheProviders
{
public const string InMemory = nameof(InMemory);
public const string SqlServer = nameof(SqlServer);
public const string Redis = nameof(Redis);
}
}

View File

@ -0,0 +1,47 @@
using KBR.Cache.Constants;
using KBR.Cache.Options;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using System.Diagnostics.CodeAnalysis;
namespace KBR.Cache.Extensions
{
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddCache([NotNull] this IServiceCollection services, IConfiguration configuration)
{
// Ensure the 'Microsoft.Extensions.Options.ConfigurationExtensions' package is referenced in your project
var cacheOptions = configuration.GetSection("Cache").Get<CacheOptions>();
if (cacheOptions == null || cacheOptions.Provider == CacheProviders.InMemory)
{
services.AddDistributedMemoryCache();
}
else if (cacheOptions.Provider == CacheProviders.SqlServer)
{
services.AddDistributedMySqlCache(options =>
{
options.ConnectionString = cacheOptions.ConnectionString;
options.TableName = "Cache";
});
}
else if (cacheOptions.Provider == CacheProviders.Redis)
{
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = cacheOptions.ConnectionString;
options.InstanceName = "SampleInstance";
});
}
else
{
throw new Exception("Cache options are not valid");
}
services.TryAddSingleton<IAppDistributedCache, AppDistributedCache>();
return services;
}
}
}

View File

@ -0,0 +1,27 @@
using Microsoft.Extensions.Caching.Distributed;
namespace KBR.Cache
{
public interface IAppDistributedCache
{
T Get<T>(string key)
where T : class;
Task<T> GetAsync<T>(string key, CancellationToken cancellationToken = default)
where T : class;
void Remove(string key);
Task RemoveAsync(string key, CancellationToken cancellationToken = default);
void Set<T>(string key, T obj, DistributedCacheEntryOptions? options = default);
Task SetAsync<T>(string key, T obj, DistributedCacheEntryOptions? options = default, CancellationToken cancellationToken = default);
TItem GetOrCreate<TItem>(string key, Func<TItem> factory)
where TItem : class;
Task<TItem> GetOrCreateAsync<TItem>(string key, Func<Task<TItem>> factory, CancellationToken cancellationToken = default)
where TItem : class;
}
}

View File

@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.9" />
<PackageReference Include="Microsoft.Extensions.Caching.SqlServer" Version="9.0.9" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="9.0.9" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.9" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.9" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.9" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.9" />
<PackageReference Include="Microsoft.Extensions.Options" Version="9.0.9" />
<PackageReference Include="Pomelo.Extensions.Caching.MySql" Version="2.2.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\KBR.Share.Lite\KBR.Shared.Lite.csproj" />
<ProjectReference Include="..\KBR.Shared\KBR.Shared.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,9 @@
namespace KBR.Cache.Options
{
public class CacheOptions
{
public string Provider { get; set; } = null!;
public string? ConnectionString { get; set; }
}
}

View File

@ -0,0 +1,76 @@
using Newtonsoft.Json;
namespace KBR.Shared.Lite.Extensions
{
public static class JsonExtensions
{
public static T? ToObject<T>(string value)
{
return JsonConvert.DeserializeObject<T>(value);
}
public static T? ToObjectSystemText<T>(string value)
{
return System.Text.Json.JsonSerializer.Deserialize<T>(value);
}
public static T? ToObject<T>(string value, Type destType)
{
var result = JsonConvert.DeserializeObject(value, destType);
if (result is null)
{
return default;
}
return (T)result;
}
public static object? ToObject(string value, Type destType)
{
return ToObject<object?>(value, destType);
}
public static T? ToObject<T>(string value, JsonConverter[] converters)
{
return JsonConvert.DeserializeObject<T>(value, converters);
}
public static T? ToObject<T>(string value, Type destType, JsonConverter[] converters)
{
var result = JsonConvert.DeserializeObject(value, destType, converters);
if (result is null)
{
return default;
}
return (T)result;
}
public static string ToJson<T>(T value)
{
return JsonConvert.SerializeObject(value);
}
public static string ToJsonSystemText<T>(T value)
{
return System.Text.Json.JsonSerializer.Serialize(value);
}
public static string ToJson<T>(T value, JsonSerializerSettings jsonSerializerSettings)
{
return JsonConvert.SerializeObject(value, jsonSerializerSettings);
}
public static byte[] ToUtf8Bytes(object obj)
{
return System.Text.Json.JsonSerializer.SerializeToUtf8Bytes(obj);
}
public static T? ToObject<T>(byte[] utf8Json)
{
return System.Text.Json.JsonSerializer.Deserialize<T>(utf8Json);
}
}
}

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,28 @@
using KBR.Shared.Lite.Extensions;
namespace KBR.Shared.Cache
{
public static class CacheExtensions
{
public static byte[] ToByteArray(this object obj)
{
if (obj is not null)
{
return JsonExtensions.ToUtf8Bytes(obj);
}
return Array.Empty<byte>();
}
public static T? FromByteArray<T>(this byte[] byteArray)
where T : class
{
if (byteArray is null)
{
return default;
}
return JsonExtensions.ToObject<T>(byteArray);
}
}
}

View File

@ -0,0 +1,21 @@
using KBR.Shared.Cache.Models;
using Microsoft.Extensions.Caching.Distributed;
namespace KBR.Shared.Cache
{
public static class CacheHelpers
{
private static readonly string _userSessions = nameof(_userSessions);
private static string UserSessionsKey(string key) => $"{_userSessions}-{key}";
public static async Task SetUserSessionsCacheAsync(IAppDistributedCache cache, string userId, UserSessionModel sessions, CancellationToken cancellationToken = default)
{
await cache.SetAsync(UserSessionsKey(userId), sessions, GetOptions(), cancellationToken);
}
private static DistributedCacheEntryOptions GetOptions()
{
return new DistributedCacheEntryOptions { AbsoluteExpiration = DateTime.MaxValue };
}
}
}

View File

@ -0,0 +1,27 @@
using Microsoft.Extensions.Caching.Distributed;
namespace KBR.Shared.Cache
{
public interface IAppDistributedCache
{
T Get<T>(string key)
where T : class;
Task<T> GetAsync<T>(string key, CancellationToken cancellationToken = default)
where T : class;
void Remove(string key);
Task RemoveAsync(string key, CancellationToken cancellationToken = default);
void Set<T>(string key, T obj, DistributedCacheEntryOptions? options = default);
Task SetAsync<T>(string key, T obj, DistributedCacheEntryOptions? options = default, CancellationToken cancellationToken = default);
TItem GetOrCreate<TItem>(string key, Func<TItem> factory)
where TItem : class;
Task<TItem> GetOrCreateAsync<TItem>(string key, Func<Task<TItem>> factory, CancellationToken cancellationToken = default)
where TItem : class;
}
}

View File

@ -0,0 +1,15 @@
namespace KBR.Shared.Cache.Models
{
public class UserSessionModel
{
public UserSessionModel()
{
Alive = new();
Killed = new();
}
public List<string> Alive { get; set; }
public List<string> Killed { get; set; }
}
}

View File

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="9.0.9" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\KBR.Share.Lite\KBR.Shared.Lite.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,21 @@
namespace KBR.Shared.Mail
{
public static class MailHelpers
{
// Replace email with other domain passed as a parameter
public static string ReplaceEmailDomain(string email, string newDomain)
{
if (string.IsNullOrWhiteSpace(email))
throw new ArgumentException("Email cannot be null or empty.", nameof(email));
if (string.IsNullOrWhiteSpace(newDomain))
throw new ArgumentException("New domain cannot be null or empty.", nameof(newDomain));
var atIndex = email.IndexOf('@');
if (atIndex == -1)
throw new ArgumentException("Invalid email format.", nameof(email));
return $"{email.Substring(0, atIndex + 1)}{newDomain}";
}
}
}