This project is a rewrite of my original college project which - compared to this - was very poorly written and insecure
Originally, it was written using PHP. This is written using C# on .NET 6 and 9
It's also rewritten to utilize my Azure and DevOps skills since I had earned Microsoft's Azure Certifications and needed a way to prove my skills with a project
View the AZ-400 that I prepared for and took here
As of right now, the solution is completed locally, and in Azure
Scroll down to the Demos section to see it in Azure
Initially I intended to make it cloud-native but I'd rather have it cloud-ready since "native" means it only runs in the cloud
The definition of "cloud-native" seems to be up for debate from what I've seen and it makes sense as to why it is one
NOTE: Since this project is a proof-of-concept, the payment system isn't integrated
NOTE: A Wiki is now available on how the solution is built, ensure to have a look at it 🥹
In the beginning, it was a distributed monolith with a frontend and backend API with a single database shared between both the projects
The API has been broken down into microservices which then invited a backend-for-frontend to have a single point of entry into the microservices from the frontend
The solution now comprises of 10 runnable projects with 18 projects in total
- A very simple and easy to navigate user interface
 - An Admin Portal protected by ASP.NET Core Identity
- Admin Portal features:
- View the database structure [even though it's split]
 - Add and update tyre catalog with the ability to add and update images
 - View undelivered orders and mark them as delivered
 - View the receipt of an order
 
 - Related commits:
- admin: efficiently use the partial view for the tyres table
 - implement functionality to add tyres
 - implement functionality for updating tyres
 - implement the logic for the shopping cart and the placing of orders
 - implement the viewing of orders in the admin portal
 - implement the viewing of receipts from the admin portal
 - admin portal: use restful routing for updating a tyre
 - add a missing feature to set the tyre's availability and adjust what customers see accordingly
 - create an image service
 - azure: implement the cloud version of the image service
 - the blob client has the uri 😐
 
 
 - Admin Portal features:
 - A custom footer with a link to the commit on GitHub referencing the version its built on
 - Customers can perform updates to their account, add addresses, view their previous orders, reset their password and delete their account
- Related commits:
- implement the logic for addresses in the account
 - fix the post request for add new address
 - implement the logic for the shopping cart and the placing of orders
 - implement the viewing of orders on the account
 - account: ensure a customer makes their first address a preferred one
 - implement the functionality to reset password
 
 
 - Related commits:
 - An email service that sends emails with FluentEmail using embedded razor templates
- Emails sent:
- A receipt when a user completes an order
 - Sends the user a token to reset their password
 
 - Related commits:
 
 - Emails sent:
 
- The entire architecture is protected using IdentityServer4
 - User login session management
 - Hybrid-encryption for customer data on POST and PUT requests
 - Custom authorization requirements and policies for customers and the administrator. Customers can only access their own data
 
- Utilizing the repository pattern to access the database and perform CRUD operations
 - AutoMapper is used to map between database entities and models returned to the client
 - Using middleware to return a ProblemDetails model when a non-success status code is returned
- Related commits:
 
 - Protected by IdentityServer4 and custom authorization policies
- Related commits:
 
 - [WIP] An efficient API versioning strategy
- Related commits:
- resolve some of the duplication
 - cleanup: centralize models-library using statements in a globalusings.cs file
 - models: align with the semver versioning strategy and introduce model wrappers
 - models: allow backwards compatibility
 - models: introduce a static class called AvailableModels that's tied to a version of the models and allow the model type to be specified in the model wrapper
 - models: the model version doesn't need to be static
 
 
 - Related commits:
 
- An API Gateway to have a single point of entry into the microservices as exposing the APIs to the world without it is not a best practice
- Related commits:
 
 - Effectively dealing with cross-cutting concerns like logging and distributed tracing
- Related commits:
- prep for centralized logging with serilog and elasticsearch
 - the days and nights were long and so too, was the logging spree
 - containerize and MOSTLY orchestrate the solution locally
 - centralize the logging configuration in a shared library
 - implement rabbitmq and complete the architecture locally
 - implement a more correct way to maintain distributed tracing over a message bus
 - okay, duplication is a bit too high
 
 
 - Related commits:
 - The codebase version with a link to the commit on GitHub is used to enrich the logs. This is useful in the following ways:
- Tracing back to new code that's causing failures to occur
 - In a system where security is a priority, if a developer goes rogue and decides to allow fraud to occur by modifying the code, it can be traced back to them and can be under investigation
- CODE REVIEWS ARE IMPORTANT
 
 - Related commits:
 
 - An efficient data synchronization strategy across microservices
 - Site Reliability Engineering possibilities like creating an actionable alerting strategy and monitoring application health
- Related commits:
- the days and nights were long and so too, was the logging spree
 - communicate to users that the system is degraded
 - implement application health checks
 - enable the system degraded state by default when using docker compose
 - implement liveness checks
 - perform the liveness checks from the health checks ui
 - azure: instrument the solution with application insights telemetry
 - overhaul the existing health checks
 - implement environment specific health checks
 - azure: implement the system-degraded toggler azure function app
 
 
 - Related commits:
 
- An easy-to-maintain codebase that's polyrepo-ready
- Related commits:
 
 - A build system optimized with CMake to make the local building and running of the solution seamless
 - All projects are versioned according to the codebase version
 - Little (unavoidable) technical debt due to necessary code duplication
 - Sonarcloud is used to provide feedback on technical debt to which I take and clean up the solution
- Related commits:
 
 
- C# 10 and .NET 6 [Paperback]
- Author: Mark J. Price
 
 
- Designing and Implementing Microsoft DevOps Solutions (AZ-400)
- Authors: John Savill | David Tucker | Neil Morrissey | Marcel de Vries | Chris Behrens | Adam Bertram | Daniel Krzyczkowski
 
 - Developing Solutions for Microsoft Azure (AZ-204)
- Authors: Matthew Kruczek | Anthony Nocentino | Mike Pfeiffer | Mark Heath | David Tucker | Thomas Claudius Huber | Sahil Malik | Reza Salehi | James Millar | Daniel Krzyczkowski | Matthew Soucoup
 
 - ASP.NET Microservices
- Authors: Antonio Goncalves | Roland Guijt | Gill Cleeren | Neil Morrissey | Kevin Dockx | Mark Heath | Marcel de Vries | Steve Gordan | Rag Dhiman
 
 - Certified Kubernetes Administrator (CKA)
- Author: Anthony Nocentino
 
 
- Building a Web App with ASP.NET Core 5, MVC, Entity Framework Core, Bootstrap, and Angular
- Author: Shawn Wildermuth
 
 - ASP.NET Core 6 Web API Fundamentals
- Author: Kevin Dockx
 
 - ASP.NET Core 6 Fundamentals
- Author: Gill Cleeren
 
 - Your Microservices Transition
- Author: Rag Dhiman
 
 - Microservices Architecture: The Design Principles
- Author: Rag Dhiman
 
 - Securing ASP.NET Core 3 with OAuth2 and OpenID Connect
- Author: Kevin Dockx
 
 - Cryptography in .NET 6
- Author: Stephen Haunts
 
 - Logging and Monitoring in ASP.NET Core 6
- Author: Erik Dahl
 
 - RabbitMQ by Example
- Author: Stephen Haunts
 
 - Building ASP.NET Core 3 Hosted Services and .NET Core 3 Worker Services
- Author: Steve Gordan
 
 - Fundamentals of Docker and Kubernetes for .NET 5 Developers
- Author: Erik Dahl
 
 - Deploying ASP.NET Core 6 Using Kubernetes
- Author: Marcel de Vries
 
 - Securing ASP.NET Core 6 with OAuth2 and OpenID Connect
- Author: Kevin Dockx
 
 - Deploying Azure Resources Using Bicep
- Author: Ben Weissman
 
 - The IT Ops Sessions: ARM Templates vs. Terraform
- Author: Tim Warner
 
 - ASP.NET Core 6 Performance
- Author: Erik Dahl
 
 - Documenting an ASP.NET Core 6 Web API Using Swagger
- Author: Kevin Dockx
 
 - Globalization and Internationalization in .NET 6
- Author: Filip Ekberg
 
 
- John Savill's Technical Training
- Author: John Savill
 
 
- Sending Email in C# using FluentEmail
- Author: IAmTimCorey
 
 - Intro to Health Checks in .NET Core
- Author: IAmTimCorey
 
 - Intro to Redis in C# - Caching Made Easy
- Author: IAmTimCorey
 
 - RabbitMQ Custom Docker Image with Custom Configuration and Definitions
- Author: Mike Møller Nielsen
 
 - Leveling up data: Upgrade from EF6 to EF7 and blast off! | .NET Conf 2022
- Author: dotnet
 
 - Authoring and deploying Azure resources with Bicep | Azure Friday
- Author: Microsoft Azure
 
 
- Microsoft Learn
 - Stack Overflow [Obviously]
 - How export or import RabbitMQ configuration
 - Docker Security Cheat Sheet
 
- Visual Studio 2022 17.12.1 or later
 - Latest .NET SDK 6 and 9
 - CMake 3.29.0 or later
 - An Instance of SQL Server 2022 Express [Default, not named]
 - SQL Server Management Studio
 - WSL 1.0.3 [this is the version that I stick to because the Docker Engine fails to start on anything newer]
 - Docker Desktop
 - PowerToys 0.77.0 or later [For the hosts file editor and environment variables utility]
 
- 
Ensure to set environment variables listed in the
RequiredEnvironmentVariables.txtfile- Press 🪟 and search for 
Edit environment variables for your account - When setting this for the first time, restart your computer
 
 - Press 🪟 and search for 
 - 
All build scripts are in the
scriptsfolder - 
In order to build, I've provided four options for you:
build.cmdwhich is the regular buildbuild-with-docker.cmdto run with docker-composebuild-with-services.cmdwhich is the regular build + elasticsearch, kibana and rabbitmq orchestrated with docker-compose- Kubernetes:
- All scripts for Kubernetes are in the 
scripts/kubernetesfolder and should be run in order00-applied-once.cmd- Note: This adds the nginx ingress to the cluster from the original repo
 
01-build-images.cmd02-deploy.cmd03-delete.cmd
 
 - All scripts for Kubernetes are in the 
 
 - 
NOTE: For Docker builds, run the
pull-required-docker-images.cmdscript beforehand - 
Once you run either
build.cmdorbuild-with-services.cmd, CMake will generaterun-all.cmd - 
Thereafter, run
run-all.cmdwhich will start all applications minimized and launch the site, simulating orchestration