Skip to content

A scalable and modular transportation management backend built with ASP.NET Core and Clean Architecture. Features include advanced ticket ordering, role-based authentication with JWT, transaction tracking, and PDF ticket generation.

License

Notifications You must be signed in to change notification settings

MehrdadShirvani/AlibabaClone-Backend

Repository files navigation

Transportation Management App – Backend

πŸ“About the Project

Welcome to the backend of the Transportation Management App, a robust and scalable system designed to manage travelers, routes, ticketing, and vehicle operations. This project is architected with Clean Architecture principles to ensure high modularity, testability, and long-term maintainability. This project is inspired by sites like Booking.com and Alibaba.ir

πŸ’‘ This backend is designed to work seamlessly with the Transportation Management Frontend, a React-based SPA that consumes the RESTful APIs exposed by this project.


πŸ› οΈ Tech Stack

Layer Technologies
Presentation (API) ASP.NET Core .NET Microsoft.Extensions.DependencyInjection EF Core Design System.IdentityModel.Tokens.Jwt
Newtonsoft.Json
Application C# AutoMapper
Infrastructure C#, EF Core QuestPDF EF Core SQL Server EF Core Proxies EF Core Tools JWT Bearer
Domain C#

🧭Architecture Overview

This project follows Clean Architecture as its foundation, separating the system into clearly defined layers:

πŸŒ€ Core Layers

CleanArchitecture

Reference: View this article

1. Domain Layer

Description:
Contains the Enterprise Business Rules – the core of the system. This layer is completely independent of any frameworks or infrastructure.

Includes:

  • Entities: Pure business objects like Account, Person, TicketOrder
  • Enums and Rules: Domain constraints and constants
  • Interfaces: Contracts like IEntity<TKey>, IRepository<T>

Domain Modeling Details:

ERD

  • βœ… ERD follows Third Normal Form (3NF) to avoid redundancy and ensure referential integrity.
  • βœ… Uses a Code-First Approach: database schema generated from C# model classes.
  • βœ… Base Entity & Interface provide consistency and generic flexibility:
public interface IEntity<TKey>
{
    public TKey Id { get; set; }
}
  • Generic base class Entity<TKey> standardizes ID usage:
public class Account : Entity<long>
{
    public required string PhoneNumber { get; set; }
    public required string Password { get; set; }
    public string? Email { get; set; }
    public long? PersonId { get; set; }
    public decimal CurrentBalance { get; private set; }

    public virtual Person? Person { get; set; }
    public virtual BankAccountDetail? BankAccountDetail { get; set; }
    public virtual ICollection<Transaction> Transactions { get; set; }
    public virtual ICollection<TicketOrder> BoughtTicketOrders { get; set; }
    public virtual ICollection<AccountRole> AccountRoles { get; set; }
    public virtual ICollection<Person> CreatedPeople { get; set; }

    public void Deposit(decimal amount) { ... }
    public void Withdraw(decimal amount) { ... }
}

2. Application Layer

Description:
Contains the Use Cases and orchestrates domain logic without depending on external concerns. Acts as the bridge between the domain and outside world (e.g., API controllers).

Key Responsibilities:

  1. Application Services - Defines service contracts like IAuthService, ITransportationService
    • Operates on DTOs, uses repositories and domain logic
    • Returns structured Result<T> objects
  2. Use of DTOs + AutoMapper
    • Entities are never exposed directly to the API
    • Uses Data Transfer Objects (DTOs) to control data flow
    • Maps entities to DTOs and vice versa, using AutoMapper:
CreateMap<City, CityDto>();
  1. Result Wrapping with Result<T>

    • All service responses are wrapped in a Result<T> class, which:
      • Unifies success/error response logic
      • Enhances readability
      • Avoids throwing exceptions for business flow
      • Enables easy status mapping at controller level Example structure:
    public class Result<T>
    {
        public ResultStatus Status { get; set; }
        public string? ErrorMessage { get; set; }
        public T? Data { get; set; }
        public bool IsSuccess => Status == ResultStatus.Success;
    
        public static Result<T> Success(T data) => ... };
        public static Result<T> Error(string errorMessage) => ... };
        public static Result<T> NotFound() => new() { ... };
        public static Result<T> Unauthorized() => new() {... };
    }

    With corresponding status enum:

    public enum ResultStatus
    {
        Success,
        NotFound,
        ValidationError,
        Conflict,
        Unauthorized,
        Forbidden,
        Error
    }

3. Infrastructure Layer

Description: This layer provides the actual implementations of interfaces defined in the Domain and Application layers. It deals with data access, external services, file storage, and configuration of frameworks like Entity Framework.


Entity Framework Core (EF Core) The project uses EF Core as the ORM (Object-Relational Mapper) for interacting with a SQL-based relational database (SQL Server).

  • The DbContext implementation is called ApplicationDBContext, which manages access to all entities and repositories.
  • Repositories are injected into services via dependency injection and work through ApplicationDbContext.

Entity Configurations EF Core configurations are applied using the Fluent API, via IEntityTypeConfiguration<T> classes. Example:

public class AccountConfiguration : IEntityTypeConfiguration<Account>
{
    public void Configure(EntityTypeBuilder<Account> builder)
    {
        builder.HasKey(a => a.Id);
        builder.Property(a => a.Id).ValueGeneratedOnAdd();

        builder.Property(a => a.PhoneNumber)
            .IsRequired()
            .IsUnicode(false)
            .HasMaxLength(20);

        //...

		//Relationships
        builder.HasOne(a => a.Person)
            .WithOne()
            .HasForeignKey<Account>(a => a.PersonId)
            .OnDelete(DeleteBehavior.Restrict);
    }
}

Migrations

  • The project follows Code-First Migrations using EF Core.

  • Database schema is automatically created and updated using:

    dotnet ef migrations add InitialCreate
    dotnet ef database update
  • This enables safe, version-controlled database evolution as the domain model changes.


Repository Pattern & Unit of Work This app uses the Repository Pattern and Unit of Work to encapsulate data access logic and abstract away infrastructure concerns like Entity Framework Core.

Benefits:

  • Abstraction from ORM
  • Better Code Organization
  • Improved Testability
  • Encapsulation of Query Logic
  • Centralized and Consistent Data Access

Implementation Structure:

  1. Interfaces in the Domain Layer
    • IRepository<T>: Generic base repository interface
    • IEntityRepository or other entity-specific interfaces (e.g., ITicketOrderRepository)
    • These define contracts for data access and allow the application and domain layers to remain independent of implementation details.
  2. Implementations in the Infrastructure Layer
    • Repository<T>: A generic implementation of IRepository<T> using Entity Framework
    • Entity-specific repositories (e.g., TicketOrderRepository) implement their respective interfaces
    • Infrastructure-specific logic like query optimizations and eager loading are encapsulated here
  3. Unit of Work
    • Wraps repository access in a single transactional boundary
    • Guarantees:
      • Data Consistency
      • Performance
      • Atomicity across multiple repositories

4. Presentation Layer (API)

Description:
This layer contains the HTTP API controllers that expose the application's features to clients like the React frontend, mobile apps, or third-party services.


Responsibilities:

  • Provides RESTful endpoints for all operations (CRUD, queries, authentication)
  • Maps HTTP verbs to application services (GET, POST, PUT, PATCH, DELETE)
  • Accepts and returns DTOs – never exposes domain entities
  • Keeps logic minimal – delegates all behavior to the Application Layer
  • Uses attributes and filters for model validation, authorization, and routing
  • Returns structured HTTP responses with meaningful status codes (200, 201, 400, 404, 500, etc.)

REST Compliance: The presentation layer adheres to REST principles like:

  • Statelessness
  • Resource identification via URIs
  • Proper use of HTTP methods
  • Standard status codes

Dependency Injection Setup The app uses constructor-based dependency injection to wire up all services and repositories via the built-in .NET Core DI container.

All interfaces from the Domain and Application layers are registered with their Infrastructure or Application implementations in Program.cs:

builder.Services.AddScoped<ICityRepository, CityRepository>();
builder.Services.AddScoped<ILocationRepository, LocationRepository>();
builder.Services.AddScoped<IAuthService, AuthService>();
builder.Services.AddScoped<ITransportationService, TransportationService>();
//...

This approach:

  • Promotes loose coupling
  • Supports easy testing and mocking
  • Enables lifetime control (Scoped, Singleton, Transient)
  • Keeps project modular and extendable

🧩 Key Features

Core Functionality

  • Full CRUD support for all domain entities.
  • Advanced Transportation Search: Supports optional filters like vehicleType, departure/arrival cities, and start/end time.
  • Ticket Ordering System:
    • Supports both individual and group purchases.
    • Allows one buyer and multiple travelers.
    • Coupon support and auto-generated PDF ticket using QuestPDF.
  • Transaction Logging & Reports:
    • All transactions (e.g., top-up, ticket purchase) are logged.
    • Export account transaction history as CSV.

Authentication & Authorization

  • Custom JWT Authentication:
    • Auth token is generated with a custom method, embedding account roles and account data.
    • Each Account supports multiple roles through a join table (AccountRole).
  • Role-Based Authorization integrated into API endpoints.
  • Password Hashing using SHA256 for secure credential storage.

User & Account Management

  • Add and manage personal details, bank account information, and saved people.
  • View and manage traveler profiles associated with ticket orders.

Architecture & Scalability

  • Built with Clean Architecture principles: layered, testable, decoupled.
  • Interface-driven Services (e.g., IAuthService, ITransportationService) for modular growth.
  • AutoMapper used to separate DTOs from domain models cleanly.
  • Structured response handling with a Result wrapper for service responses.
  • Dependency Injection used throughout for loose coupling and flexibility.
  • Persistence-Agnostic: Business logic is decoupled from EF Core and SQL Server.

Testability & Maintainability

  • High testability through separation of concerns and use of interfaces.
  • Easy to switch out implementations or add new providers thanks to DI and layered structure.
  • Application layer remains untouched when swapping infrastructure components.

πŸ“ Project Structure

/src
 ┣ /Domain
 ┃ ┣ Aggregates/
 ┃ ┣ Framework/
 ┃   ┣ Base/
 ┃   ┣ Interfaces/
 ┣ /Application
 ┃ ┣ DTOs/
 ┃ ┣ Interfaces/
 ┃ ┣ Mappers/
 ┃ ┣ Result/
 ┃ ┣ Services/
 ┃ β”— Utils/
 ┣ /Infrastructure
 ┃ ┣ Persistence/
 ┃ ┣ ExternalAPIs/
 ┃ β”— Mappings/
 ┣ /WebAPI
 ┃ ┣ Authentication/
 ┃ ┣ Controllers/
 ┃ ┣ appsettings.json
 ┃ β”— Program.cs
 β”— /Tests
   ┣ Unit/
   β”— Integration/

πŸ” Security

The backend uses JWT (JSON Web Token) authentication with role-based access control to secure API endpoints.

Highlights:

  • βœ… Stateless: No server-side session; each request carries a token.
  • πŸ” Roles Included: User roles are embedded in the token payload and enforced via policy-based authorization.
  • πŸ“¦ Library Used: Microsoft.AspNetCore.Authentication.JwtBearer
  • 🎯 Ideal for SPAs like the React frontend.

Tokens follow the standard Header.Payload.Signature structure, and are passed via the Authorization: Bearer <token> header.


🌐 API Design Principles

This backend adheres to RESTful design principles for clarity, scalability, and consistency across client-server communication.

Key REST Principles Followed

  1. Statelessness
    Each HTTP request contains all necessary information; no server-side session state is maintained.

  2. Resource Identification via URIs
    Resources like accounts, tickets, and transportations are identified using clean, noun-based endpoints.

  3. Standard HTTP Methods

    • GET – Retrieve data
    • POST – Create new records
    • PUT – Fully update existing records
    • DELETE – Remove a resource
  4. Standard HTTP Status Codes
    Responses use appropriate status codes like:

    • 200 OK
    • 201 Created
    • 404 Not Found
    • 500 Internal Server Error

πŸš€ Getting Started

If you're planning to test or contribute to the project, make sure to:

πŸ”€ 1. Switch to the develop Branch

The develop branch contains the latest features and active work in progress.

git checkout develop

βš™οΈ 2. Configure appsettings.json

βœ… Add Database Connection

Update your connection string in appsettings.json:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=YOUR_SERVER;Database=YOUR_DB;Trusted_Connection=True;TrustServerCertificate=True"
  }
}

Make sure the values match your local SQL Server setup.


πŸ” Add JWT Settings

To enable JWT-based authentication, also include:

"Jwt": {
  "Key": "YOUR_SECRET_KEY_HERE",
  "Issuer": "YOUR_APP_NAME_OR_DOMAIN",
  "Audience": "MyAppUsers",
  "ExpiryMinutes": 360
}

πŸ—„οΈ 3. Run Database Migrations

To create the schema and apply the current migrations:

dotnet ef migrations add InitialCreate
dotnet ef database update

βœ… This sets up your SQL database using the current domain models and Entity Framework configuration.


πŸ§ͺ Testing


🀝 Contributing

We follow Clean Architecture not just in code but in our workflow. PRs should:

  • Target the correct layer.
  • Avoid leaking infrastructure logic into core layers.
  • Include tests for new business logic.

πŸ“š Resources

Architecture and Design

Entity Framework Core (EF Core)

Repository & Unit of Work Patterns

AutoMapper

RESTful API Principles

JWT Authentication

Miscellaneous

  • QuestPDF (PDF generation library example used in project):
    QuestPDF GitHub

πŸ¦β€πŸ”₯ Order of the Phoenix

This project is part of the first initiative by The Order of the Phoenix β€” a student-led movement aimed at building a culture of self-driven learning, teamwork, and meaningful project development. What started as a grassroots .NET learning group evolved into a full-stack travel management system inspired by platforms like Alibaba.ir, built with clean architecture on the backend and a modern React frontend.

πŸ”— For more information, and to explore the full documentation and creation process, visit: ASP.NET Project Documentation

I should specially thank:

Amin Ghoorchian

Ali Taherzadeh

For their guidance, help and accompaniment.


πŸ“ License

MIT License – see LICENSE file for details.

About

A scalable and modular transportation management backend built with ASP.NET Core and Clean Architecture. Features include advanced ticket ordering, role-based authentication with JWT, transaction tracking, and PDF ticket generation.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published