This solution is structured according to the principles of Clean Architecture and Domain-Driven Design (DDD) to ensure separation of concerns, modularity, and scalability. Each layer has a clearly defined responsibility:
- Domain contains core business entities and logic.
- Application defines interfaces and orchestrates use cases.
- Infrastructure handles data access, external APIs, and integrations.
- Web serves as the entry point with Razor Views and MVC Controllers.
Responsibility: Contains domain models, entities, value objects, and domain logic. This is the core of the application β your business rules and data structures. It should be independent of all other layers (no external dependencies).
Responsibility: Orchestrates domain logic and services, implements use cases. Contains services, interfaces, and DTOs (Data Transfer Objects). Handles communication between the Infrastructure and Domain layers. Defines interfaces that the Infrastructure layer implements.
Responsibility: Provides technical implementations and integrations. Handles database access (repositories, DbContext), external services (e.g., Azure Blob Storage), and implements interfaces from the Application layer.
Responsibility: User interface and presentation logic. Includes Controllers, Views, ViewModels, application startup and middleware configuration.
Responsibility: Testing all layers of the application. Includes unit tests, integration tests, and system tests.
The structure below reflects this layered architecture:
SG01G02_MVC/
βββ SG01G02_MVC.Application/
β βββ DTOs/
β β βββ ProductDto.cs - Data Transfer Object for product data
β β βββ ReviewDto.cs - DTO for product reviews and ratings
β β βββ ReviewResponseDto.cs - Response wrapper for review API responses
β βββ Interfaces/
β β βββ IAuthService.cs - Authentication service contract
β β βββ IBlobStorageService.cs - Blob storage interface for managing file uploads and downloads
β β βββ IFeatureToggleService.cs - Feature flag interface to control runtime toggles like Mock API usage
β β βββ IKeyVaultService.cs - Interface for accessing secrets from Azure Key Vault
β β βββ ILoggingService.cs - Logging abstraction to route logs to different sinks
β β βββ ILoggingServiceFactory.cs - Factory for resolving appropriate logging service based on context
β β βββ IProductRepository.cs - Product data access contract
β β βββ IProductService.cs - Product business logic contract
β β βββ IReviewApiClient.cs - Review API client contract
β β βββ IReviewService.cs - Review management contract
β β βββ IUserRepository.cs - User data access contract
β βββ Services/
β β βββ AuthService.cs - Authentication implementation
β β βββ ProductReviewSyndService.cs - Service that synchronizes products with the external review API
β β βββ ProductService.cs - Product business logic implementation
β β βββ ReviewService.cs - Review logic implementation
β βββ SG01G02_MVC.Application.csproj
β
βββ SG01G02_MVC.Domain/
β βββ Entities/
β β βββ AppUser.cs - User entity with role-based access
β β βββ CartItem.cs - Shopping cart line item entity
β β βββ Order.cs - Customer order entity
β β βββ Product.cs - Product entity with business rules
β βββ SG01G02_MVC.Domain.csproj
β
βββ SG01G02_MVC.Infrastructure/
β βββ Configuration/
β β βββ BlobStorageConfigurator.cs - Sets up dependency injection for blob storage services
β β βββ ConfigurationLoader.cs - Centralized utility for reading configuration sources
β β βββ DatabaseConfigurator.cs - Registers and configures database access via EF Core
β β βββ DependencyInjection.cs - Registers core infrastructure services (feature toggles, logging, etc.)
β β βββ KeyVaultConfigurator.cs - Injects Azure Key Vault-based config into the app
β βββ Data/
β β βββ AppDbContext.cs - Entity Framework Core context
β βββ External/
β β βββ DisabledReviewApiClient.cs - Stub implementation that throws to simulate external API downtime
β β βββ DualReviewApiClient.cs - Smart API wrapper that prioritizes one review API and falls back to another
β β βββ MockReviewApiClient.cs - Simulated IReviewApiClient for local or test environments
β β βββ ReviewApiClient.cs - Real implementation of IReviewApiClient using HttpClient
β β βββ ReviewApiClientConverter.cs - Helper to safely parse external review API values (e.g., product ID)
β βββ Migrations/ - Entity Framework - Database migrations
β βββ Repositories/
β β βββ CartRepository.cs - Shopping cart data access
β β βββ EfProductRepository.cs - EF Core product repository
β β βββ OrderRepository.cs - Order data access
β β βββ ProductRepository.cs - In-memory mock repository for local testing or fallback scenarios
β β βββ ReviewRepository.cs - Review data access
β β βββ UserRepository.cs - User data access implementation
β βββ Services/
β β βββ BlobStorageService.cs - Azure Blob Storage integration
β β βββ DatabaseHealthCheck.cs - Database connectivity monitoring
β β βββ FeatureToggleService.cs - Implementation of IFeatureToggleService backed by app config
β β βββ InMemoryBlobStorageService.cs - In-memory blob storage for testing without Azure
β β βββ KeyVaultService.cs - Azure Key Vault integration service for retrieving secrets securely
β β βββ LoggingService.cs - Concrete logger that implements ILoggingService
β β βββ LoggingServiceFactory.cs - Factory responsible for returning appropriate logging services
β βββ SG01G02_MVC.Infrastructure.csproj
β
βββ SG01G02_MVC.Tests/
β βββ Controllers/
β β βββ AdminControllerTests.cs - Admin functionality tests
β β βββ CatalogueControllerTests.cs - Unit tests for product catalogue display logic
β β βββ LoginControllerTests.cs - Authentication flow tests
β β βββ ReviewControllerTests.cs - Unit tests for review submission and fetch actions
β βββ Helpers/
β β βββ TestBase.cs - Common test setup and utilities
β β βββ TestDbContextFactory.cs - Test database context factory
β βββ Services/
β β βββ AuthServiceTests.cs - Authentication logic tests
β β βββ FakeProductRepository.cs - In-memory product repository
β β βββ ProductServiceTests.cs - Product business logic tests
β β βββ ReviewServiceTests.cs - Unit tests for core review service logic
β βββ SG01G02_MVC.Infrastructure.Tests/
β
βββ SG01G02_MVC.Web/
β βββ Configuration/
β β βββ AppConfigurator.cs - Bootstraps app-wide middleware and settings
β β βββ ServiceConfigurator.cs - Configures service registrations and DI setup
β βββ Controllers/
β β βββ AdminController.cs - Product management
β β βββ CartController.cs - Shopping cart operations
β β βββ CatalogueController.cs - Product browsing
β β βββ HomeController.cs - Landing page and navigation
β β βββ ImageController.cs - Image upload management
β β βββ LoginController.cs - Authentication handling
β β βββ ReviewController.cs - MVC controller for handling product reviews
β β βββ StaffController.cs - Order management
β βββ Middleware/
β β βββ SessionTrackingMiddleware.cs - Middleware to monitor and log session activities
β βββ Models/
β β βββ ErrorViewModel.cs - Error page data
β β βββ LoginViewModel.cs - Login form data
β β βββ ProductViewModel.cs - Product display data
β β βββ ReviewSubmissionViewModel.cs - View model for binding submitted review form data
β βββ Properties/
β β βββ launchSettings.json - Development launch profiles for different environments
β βββ Services/
β β βββ IUserSessionService.cs - Session management contract
β β βββ SeederHelper.cs - Initial data seeding
β β βββ UserSessionService.cs - Session implementation
β βββ Views/
β β βββ Admin/
β β β βββ Create.cshtml - Product creation form
β β β βββ Delete.cshtml - Product deletion confirmation
β β β βββ Edit.cshtml - Product editing form
β β β βββ Index.cshtml - Product management dashboard
β β βββ Cart/
β β β βββ Index.cshtml - Shopping cart view
β β βββ Catalogue/
β β β βββ Details.cshtml - Product details view
β β β βββ Index.cshtml - Product listing view
β β βββ Home/
β β β βββ Index.cshtml - Landing page view
β β βββ Login/
β β β βββ Index.cshtml - Login form view
β β βββ Shared/
β β β βββ _Layout.cshtml - Master page template
β β β βββ _Layout.cshtml.css - Master page styling
β β β βββ _ValidationScriptsPartial.cshtml - Client-side validation
β β β βββ DatabaseUnavailable.cshtml - Database error page
β β β βββ Error.cshtml - Error page template
β β βββ Staff/
β β β βββ Edit.cshtml - Order management view
β β β βββ Index.cshtml - Staff dashboard
β β βββ _ViewImports.cshtml - View imports
β β βββ _ViewStart.cshtml - View configuration
β βββ wwwroot/ - Static files (CSS, JS, images)
β βββ appsettings.Development.json - Development configuration
β βββ appsettings.Development.Local.json - Optional developer-specific overrides for dev config
β βββ appsettings.json - Base configuration
β βββ Program.cs - Application startup
β βββ SG01G02_MVC.Web.csproj
β
βββ SG01G02_MVC.sln
βββ Dockerfile - Container definition
βββ docker-compose.yml - Multi-container setup
βββ .gitignore - Git ignore rules
βββ README.md - Project documentationThe project can be built and run entirely through Docker using either:
docker-compose upThis will:
- Run the published .NET MVC app using the image from Docker Hub
- Expose the application at http://localhost:8080
- No local database is started β the CI/CD pipeline will inject the connection string to PostgreSQL hosted externally
docker build -t mymh/sg01g02mvc:latest .docker push mymh/sg01g02mvc:latestBuilds the MVC App into a Docker Image and sends it to the Docker Hub. Watchtower is running in a Docker Container on the Azure VM Appserver that will pull the image and restart the container if it detects a new image. The app is running on port 8080. And it checks every 30 seconds for a new image.
Can also be forced to pull the image by running the following command in the Azure VM Appserver:
curl -H "Authorization: Bearer $WATCHTOWER_TOKEN" -X POST http://$APP_IP:8080/v1/updateProduction environments always use PostgreSQL (via Azure Key Vault / CI/CD).
SQLite is used only as a fallback for local development.
- Add migration if needed:
dotnet ef migrations add <MigrationName> --project SG01G02_MVC.Infrastructure --startup-project SG01G02_MVC.Web- Apply migration to your local SQLite dev database:
dotnet ef database update --project SG01G02_MVC.Infrastructure --startup-project SG01G02_MVC.Web- The SQLite .db file must never be committed to Git or uploaded to any shared storage.
- The database contains seeded login credentials and is for dev use only.
- Check that .gitignore includes: *.db
The application uses PostgreSQL in production environments, with a fallback to SQLite only in development. The database configuration follows this priority:
- Environment Variable:
POSTGRES_CONNECTION_STRING(injected by CI/CD) - Azure Key Vault:
PostgresConnectionStringsecret - Development Fallback: SQLite (only in Development environment)
-
Production Deployment:
- Connection string is injected via CI/CD pipeline
- Azure Key Vault integration for secure credential storage
- Automatic migrations on application startup
-
Database Migrations:
# List available migrations dotnet ef migrations list # Apply migrations to PostgreSQL dotnet ef database update
-
Health Checks:
- Visit
/dbinfoendpoint to verify database connectivity - Health check endpoint at
/healthmonitors database status
- Visit
- Production credentials are managed through Azure Key Vault
- Connection strings are injected by CI/CD pipeline
- Database access is restricted to the application's network
- Regular security audits and updates are performed
This project supports appsettings.{Environment}.Local.json for local overrides. It's loaded via ConfigurationLoader in the Infrastructure layer. This file is ignored by Git for safe local secrets.
We have three roles (admin, staff, customer) which is handled through the database. Access rules are controlled via session and role handling in Razor. Session is 30 minutes or until log-off and roles are set upon validation on log-in. Using Data annotation and safety measures like hashed passwords to handle secure logins.
- Project Leader: Anton Lindgren
- Project Leader: Olof Bengtsson
- Project Leader: Pierre Nilsson
- MOV/MS 365 Technician: Max Oredson
- MOV/MS 365 Technician: Pontus Kroon
CLO has been in charge of the development of the MerchStore and the Cloud Solution for the store.
CLO integrates modern DevOps methodologies with fullstack application development to deliver a secure and scalable cloud-native solution.
The platform is built on Azure, with infrastructure and deployment pipelines fully automated using Terraform, Ansible, and GitHub Actions. Azure Key Vault, Blob Storage, and Reverse Proxy via Nginx ensure secure, efficient, and resilient operations.
The CI/CD pipelines cover both infrastructure and application deployment, with secrets managed mainly via Keyvault and GitHub Secrets for Ci/Cd to access keyvault.
Fredrik SvΓ€rd worked as DevOps and Fullstack engineer. Establishing the cloud architecture, security layers, CI/CD flows, and contributing to both backend and frontend in ASP.NET Core MVC.
Niklas HΓ€ll designed the backend structure using Domain-Driven Design (DDD), developed core features with .NET 9.0, PostgreSQL, and Razor, and authored technical documentation. He also built mock APIs and Dockerized the application for consistent deployments.