Haskovo silluette
© 2024 nikolagsiderov.dev

Hello, I'm
Nikola Siderov.

I'm a young and enthusiastic full-stack software developer with over 5.5 years of experience in building, maintaining and improving applications. I specialize in web-based technologies including .NET, Web API, React, Next.js, JavaScript, TypeScript and many more.


I am consistent, using the latest standards and proven principles in my field. Quality and well-structured software systems are priority for me.


I thrive in both collaborative teams and remote work setups. Based in Plovdiv, I’m ready to deliver impactful solutions.


Work

Full Stack Software Developer

TSD Services • Full-Time • May 2024 - Present

Remote

Working as a full-stack software developer for a client company in the water management industry. The project aims to develop a central monitoring system for various properties and devices, used for real-time tracking and control.

My responsibilities are involved in the development of three web applications:

  • React-based client application: Implementation of UI components and features based on detailed UI/UX concepts provided by the design team.
  • Angular-based administrative application: Implementation of UI components and features.
  • Back-end business logic development, along with building .NET Web API endpoints.
  • Contribution and maintenance of the technical documentation.
  • Collaboration with team members to ensure seamless development.

Work experience with React, Angular, JavaScript, TypeScript, TailwindCSS & .NET.

ReactAngularGit.NETC#JavaScriptTypeScriptJSONTailwindCSS

Full Stack Software Developer

TSD Software • Full-Time • Dec 2020 - May 2024

Remote

Development and maintenance of an American-based client CRM system in the sales industry using integration with Salesforce and Microsoft Dynamics 365.

Initially, my role was to maintain and develop new features on their existing platforms. However, as the project’s frameworks were outdated and this limited further development, I was tasked to rebuild one of the two platforms using React. This included setting up the project architecture, selecting appropriate third-party libraries, and managing the state efficiently.

Work consists of Dynamics 365 and Salesforce custom development, continuous integration and delivery, Azure cloud administration, SSL certifications management and web platform development using .NET, React, JavaScript, Azure SQL Databases & Entity Framework Core.

Development of a closed company platform - BPM software system designed to include CRM, MIS & any further custom solutions required from the business.

C#DotNetJavaScriptReactAzureMicrosoft Azure DevOpsMicrosoft Azure PipelinesMicrosoft Dynamics 365SalesforceAzure SQL DatabasesEntity Franework Core

.NET Software Developer

TSD Services • Full-Time • Jun 2019 - Dec 2020

Plovdiv, Bulgaria

Building, maintaining and CI/CD on various internal company and client projects.

Development of a closed company platform - BPM software system designed to include CRM, MIS & any further custom solutions required from the business.

Working with .NET Framework, Azure, Azure AD B2C, ASP.NET MVC, SQL Server, JavaScript, JSON, jQuery, Microsoft Graph.

C#GitAzureASP.NETJavaScriptAzure SQL DatabasesJSONjQuery

Education

Software University, SoftUni

Successfully completed several courses in the path of .NET, C#, HTML & CSS, object-oriented programming, SQL, Git and more.

Misc

Sports, Hobbies, etc.

I plan and develop new projects with the idea of improving my technical skills and keeping up with the latest technology trends.

I attend various amateur sports events, mainly short and long-distance running.

I regularly go hiking in the mountain with friends.

I enjoy reading biography and history books when I have the time.

I am a former professional football freestyler with numerous participations in public events and tournaments.

In 2016, I won the Cartoon Network Academy and got the opportunity to travel to London, England to visit Arsenal's youth training center, where we did a training session with Lucas Podolski.

React with TypeScript, TailwindCSS and NextJS web application client with an integration with Sanity.io

bulgarianhistory.com

Building interactive educational history applications using React with TypeScript, TailwindCSS, NextJS web application client with integration for Sanity.io, React Native mobile application development and Adobe Illustrator & After Effects work with custom built scalable vector graphics.

The web application bulgarianhistory.com showcases Bulgaria history through interactive maps with timelines, annotated events, and cultural landmarks. It highlights political changes, population movements, and natural features shaping history. Features include zoom, search, and clickable elements for detailed exploration, supported by citations for accuracy.

Example imageExample imageExample imageExample imageExample imageExample image

Adobe Illustrator

The core tool I use to build scalable vector graphics and artwork of historical maps with multi-level layers.

Adobe After Effects

Used for animations, visual effects, and motion picture compositing.

Web Client

Using React as front-end framework to develop sophisticated user interfaces.

Logo Development

The logo design inspired by the Bulgarian Lev, blending national pride with modern aesthetics.

React with JavaScript, Material UI, NextJS web application client with a back-end server side with background workers written in .NET 6. Database integration with SQLite.

Auction System Application

Auction authentication implementation

Explanation

This code defines two asynchronous functions, authenticate and renew, which handle user authentication and token renewal using Axios for HTTP requests. The authenticate function sends user credentials to the /authentication/authenticate endpoint, sets a refresh token as a cookie, decodes its expiration time using the jwt-decode library, and stores an access token using a Redux dispatch. If successful, it returns true. The renew function sends a refresh token to the /authentication/renew endpoint to get a new access token and refresh token, follows the same procedure for setting and decoding the tokens, and removes the refresh token cookie if an error occurs, then returns true if successful. Both functions log any errors encountered during the process.

JavaScript
1import axios from "./base/axios";
2import cookies from "js-cookie";
3import jwt from "jwt-decode";
4import { set } from "../context/features/accessTokenSlice";
5
6export const authenticate = async (dispatch, values) => {
7 let success = false;
8
9 await axios
10 .post("/authentication/authenticate", values)
11 .then(function (response) {
12 // Set refresh token in cookie
13 const decoded = jwt(response.data.refreshToken);
14 cookies.set("auth_jwt_refresh_token", response.data.refreshToken, {
15 expires: new Date(decoded.exp * 1000),
16 });
17
18 dispatch(set(response.data.accessToken));
19 success = true;
20 })
21 .catch(function (error) {
22 console.log(error);
23 });
24
25 return success;
26};
27
28export const renew = async (dispatch, refreshToken) => {
29 let success = false;
30
31 await axios
32 .post("/authentication/renew", { value: refreshToken })
33 .then(function (response) {
34 // Set refresh token in cookie
35 const decoded = jwt(response.data.refreshToken);
36 cookies.set("auth_jwt_refresh_token", response.data.refreshToken, {
37 expires: new Date(decoded.exp * 1000),
38 });
39
40 dispatch(set(response.data.accessToken));
41 success = true;
42 })
43 .catch(function (error) {
44 console.log(error);
45 cookies.remove("auth_jwt_refresh_token");
46 });
47
48 return success;
49};
Background service written in .NET

OrderCollector

Defines an OrderCollector class that extends BackgroundService to periodically process and create orders in a background task. The service uses an ItemService to interact with the database, initialized with a DataContext configured to use SQLite. In the ExecuteAsync method, which runs continuously until a cancellation is requested, the service logs its activity and retrieves items with pending orders. For each pending order, it retrieves the item's bidding history, creates a new order for the highest bid, and stores this order using itemService. It then retrieves all pending orders to notify the relevant parties, pausing for a second between iterations. The ILogger is used for logging information about the service's operations.

C#
1using Data;
2using Data.DTOs;
3using Infrastructure.Enums;
4using Infrastructure.Services;
5using Microsoft.EntityFrameworkCore;
6
7namespace Background
8{
9 public class OrderCollector : BackgroundService
10 {
11 private readonly ILogger<OrderCollector> _logger;
12 private ItemService itemService;
13
14 public OrderCollector(ILogger<OrderCollector> logger)
15 {
16 _logger = logger;
17
18 var optionsBuilder = new DbContextOptionsBuilder<DataContext>();
19 optionsBuilder.UseSqlServer(Configuration.DatabaseConnectionString);
20 itemService = new ItemService(new DataContext(optionsBuilder.Options));
21 }
22
23 protected override async Task ExecuteAsync(CancellationToken stoppingToken)
24 {
25 while (!stoppingToken.IsCancellationRequested)
26 {
27 _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
28
29 var itemsPendingOrders = itemService.GetItemsPendingOrders();
30
31 foreach (var itemPendingOrder in itemsPendingOrders)
32 {
33 var itemHistory = itemService.GetHistory(itemPendingOrder.ID);
34
35 if (itemHistory.Count() > 0)
36 {
37 var lastBidding = itemHistory.OrderByDescending(x => x.BidAmount).FirstOrDefault()!;
38 var pendingOrder = new Order(lastBidding.UserID, itemPendingOrder.CreatedByID, (int)OrderStatuses.Pending, lastBidding.BidAmount);
39
40 itemService.CreateOrder(pendingOrder, itemPendingOrder);
41 }
42 }
43
44 var pendingOrders = itemService.GetPendingOrders();
45
46 // notify seller and buyer for created order...
47
48 await Task.Delay(1000, stoppingToken);
49 }
50 }
51 }
52}

Built a web-based auction application with various functionalities and features, such as a real-time bidding system and history, live updates, push notification system, reviewal process and auction sniping software prevention techniques.

.NET based, Blazor & MVC as web clients, consuming from a Web API. Services operating with a custom ORM framework, retrieving data from a SQL Server database.

Home Management System

One layer above the custom written object-relational mapper

Custom written mapping layer

Defines a class that extends MapperService and includes method GetCollection<T> to retrieve filtered collection of objects. The GetCollection<T> method takes an expression filter and applies it to fetch data. It identifies the server model type for the generic type T using reflection and dynamically retrieves the appropriate GetObjects method from the BaseFacade. The method then converts the expression filter to a compatible type for the server model using the ConvertExpression method. After filtering the server models, it converts these models back to view models using MapperService.GetViewModelCollection and returns the result as a list of type T. Utilizing reflection extensively to handle generic types and dynamically invoke methods at runtime.

C#
1using APPartment.Data.Server.Base;
2using APPartment.ORM.Framework.Declarations;
3using System;
4using System.Collections.Generic;
5using System.Linq;
6using System.Linq.Expressions;
7using System.Reflection;
8
9namespace APPartment.Infrastructure.Services.Base
10{
11 public class BaseCRUDService : MapperService
12 {
13 ...
14
15 public List<T> GetCollection<T>(Expression<Func<T, bool>> filter)
16 where T : class, IBaseObject, new()
17 {
18 var serverModelType = GetServerModelType<T>();
19
20 var getObjectsFilteredFunc = typeof(BaseFacade)
21 .GetMethods(BindingFlags.Public | BindingFlags.Instance)
22 .Where(x => x.Name.Equals(nameof(BaseFacade.GetObjects)))
23 .LastOrDefault()
24 .MakeGenericMethod(serverModelType);
25
26 var convertFilterFunc = typeof(MapperService)
27 .GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
28 .Where(x => x.Name.Equals(nameof(ConvertExpression)))
29 .FirstOrDefault()
30 .MakeGenericMethod(typeof(T), serverModelType);
31
32 var convertedFilter = convertFilterFunc.Invoke(this, new object[] { filter });
33
34 var serverModels = getObjectsFilteredFunc
35 .Invoke(BaseFacade, new object[] { convertedFilter });
36
37 var toViewModelFunc = typeof(MapperService)
38 .GetMethods(BindingFlags.Public | BindingFlags.Instance)
39 .Where(x => x.Name.Equals(nameof(MapperService.GetViewModelCollection)))
40 .FirstOrDefault()
41 .MakeGenericMethod(typeof(T), serverModelType);
42
43 var result = toViewModelFunc.Invoke(this, new object[] { serverModels }) as List<T>;
44
45 return result;
46 }
Piece of code from my very own object-relational mapper

Custom written ORM

Defines a DaoContext class that provides data access operations for retrieving objects from a SQL database. The class initializes an ExpressionToSql converter for translating LINQ expressions to SQL queries. A SqlConnection is then established using the default connection string, and a SqlCommand executes the query. The results are read using a SqlDataReader, and while the reader processes the records, it populates the object result with the retrieved data. The method uses generic constraints to ensure that T implements the IBaseObject interface and has a parameterless constructor.

C#
1using System;
2using System.Linq;
3using System.Linq.Expressions;
4using System.Reflection;
5using System.Data.SqlClient;
6using System.Collections.Generic;
7using APPartment.ORM.Framework.Tools;
8using APPartment.ORM.Framework.Declarations;
9using APPartment.ORM.Framework.Attributes;
10using System.ComponentModel.DataAnnotations.Schema;
11using APPartment.Common;
12using APPartment.ORM.Framework.Enums;
13
14namespace APPartment.ORM.Framework.Core
15{
16 public class DaoContext
17 {
18 private ExpressionToSql expressionToSql;
19
20 public DaoContext()
21 {
22 expressionToSql = new ExpressionToSql();
23 }
24
25 public T SelectGetObject<T>(T result, long ID)
26 where T : class, IBaseObject, new()
27 {
28 var table = GetTableName<T>();
29 var query = SqlQueryProvider.SelectBusinessObjectByID(table, ID.ToString());
30
31 using (SqlConnection conn = new SqlConnection(Configuration.DefaultConnectionString))
32 using (SqlCommand cmd = new SqlCommand(query, conn))
33 {
34 conn.Open();
35 var reader = cmd.ExecuteReader();
36
37 while (reader.Read())

At start, Entity Framework Core with code first approach was used, then I migrated to database first, later on EF Core was entirely removed and I developed my own custom object-relational mapping framework.

The project was also initially started with a MVC architecture, with all the business logic implemented in the controller levels. After which, a new Web API project was initialized with a proper business layer where the business logic was migrated. The MVC project send requests to the API and retrieved responses in the form of view-models to display in its views.

This was incomplete and the MVC architecture was redundant, having to support its controllers (only to make calls to the API). I implemented a new web client, under the hood of Blazor, using latest .NET 5. Now, the new web client was dynamic and was just that - a web client, nothing more.

Technical stack built in experience

All of the above-listed images, videos and vectors are actual design recordings of the applications. All maps listed in the Bulgaria history project are made by me using the Adobe ecosystem: Illustrator, Photoshop, etc.

Feel free to contact me via email nikolagsiderov@gmail.com or by messaging me in my LinkedIn page

React
Angular
Tailwind CSS
TypeScript
JavaScript
JSON
Material UI
NextJS
CSS
HTML
Redux
Git
Adobe Illustrator
Adobe Photoshop
React
Angular
Tailwind CSS
TypeScript
JavaScript
JSON
Material UI
NextJS
CSS
HTML
Redux
Git
Adobe Illustrator
Adobe Photoshop
React
Angular
Tailwind CSS
TypeScript
JavaScript
JSON
Material UI
NextJS
CSS
HTML
Redux
Git
Adobe Illustrator
Adobe Photoshop
.NET
Azure
ASP.NET
Bootstrap
C#
Databases
DevOps
Dynamics 365
GitHub
jQuery
Salesforce
SQL
SQL Local
Pipelines
.NET
Azure
ASP.NET
Bootstrap
C#
Databases
DevOps
Dynamics 365
GitHub
jQuery
Salesforce
SQL
SQL Local
Pipelines
.NET
Azure
ASP.NET
Bootstrap
C#
Databases
DevOps
Dynamics 365
GitHub
jQuery
Salesforce
SQL
SQL Local
Pipelines