Skip to content

syedmuhammadabid/subscription-api

Repository files navigation

Subscription API

A production-grade subscription management REST API built with .NET 10, PostgreSQL, and Docker.

Features

  • Authentication & Authorization — JWT-based auth with role-based access control (User/Admin)
  • Customer Management — Full CRUD with soft delete
  • Subscription Plans — Create and manage plans (Basic, Premium, Enterprise)
  • Subscription Module — Subscribe, renew, cancel with business rule enforcement
  • Global Exception Handling — Standardized error responses via custom middleware
  • Validation — FluentValidation with automatic request validation
  • Logging — Structured logging with Serilog (console + rolling file)
  • Pagination & Filtering — Search, sort, and paginate all list endpoints
  • API Documentation — Interactive Scalar UI with JWT support

Tech Stack

Technology Purpose
.NET 10 Web framework
PostgreSQL Database
Entity Framework Core ORM
JWT Bearer Authentication
FluentValidation Request validation
Serilog Structured logging
Scalar API documentation
Docker Containerization

Project Structure

src/
├── Controllers/          # API endpoints
├── Services/             # Business logic
├── Repositories/         # Data access layer (generic repository)
├── Models/               # Database entities
├── DTOs/                 # Request/response objects
├── Validators/           # FluentValidation validators
├── Middleware/           # Exception handling, validation filter
├── Exceptions/           # Custom exception types
├── Data/                 # DbContext and EF Core config
└── Program.cs            # Application entry point

API Endpoints

Authentication

Method Endpoint Auth Description
POST /api/auth/register No Register a new user
POST /api/auth/login No Login and receive JWT token

Customers

Method Endpoint Auth Description
POST /api/customers User Create a customer
GET /api/customers User List customers (paginated)
GET /api/customers/{id} User Get customer by ID
PUT /api/customers/{id} User Update customer
DELETE /api/customers/{id} User Soft delete customer

Subscription Plans

Method Endpoint Auth Description
POST /api/plans Admin Create a plan
GET /api/plans Public List plans (paginated)
GET /api/plans/{id} User Get plan by ID
PUT /api/plans/{id} Admin Update plan
DELETE /api/plans/{id} Admin Deactivate plan

Subscriptions

Method Endpoint Auth Description
POST /api/subscriptions User Subscribe customer to plan
POST /api/subscriptions/{id}/renew User Renew subscription
POST /api/subscriptions/{id}/cancel User Cancel subscription
GET /api/subscriptions User List all (paginated/filtered)
GET /api/subscriptions/active User Get active subscriptions
GET /api/subscriptions/customer/{id} User Get customer's subscriptions

Getting Started

Prerequisites

Run with Docker

docker-compose up --build

The API will be available at http://localhost:8080.

Run Locally

  1. Start PostgreSQL (or use Docker for just the DB):

    docker-compose up db
  2. Set user secrets:

    dotnet user-secrets set "Jwt:Key" "your-secret-key-at-least-32-chars"
    dotnet user-secrets set "ConnectionStrings:DefaultConnection" "Host=localhost;Database=subscriptiondb;Username=postgres;Password=subscription1234"
  3. Run migrations:

    dotnet ef database update
  4. Run the application:

    dotnet run

The API will be available at http://localhost:5108.

API Documentation

Scalar UI is available in development mode at:

http://localhost:5108/scalar/v1

Configuration

Variable Description
ConnectionStrings__DefaultConnection PostgreSQL connection string
Jwt__Key Secret key for JWT signing (min 32 chars)
Jwt__Issuer JWT issuer
Jwt__Audience JWT audience
ASPNETCORE_ENVIRONMENT Set to Development for Scalar UI

Architecture

Request → ExceptionMiddleware → Serilog → ValidationFilter → Controller → Service → Repository → DbContext → PostgreSQL

Key Design Decisions

  • Repository Pattern — Abstracts data access for testability
  • Custom ExceptionsNotFoundException, ConflictException, AppException map to HTTP status codes
  • Global Exception Middleware — Eliminates try/catch in controllers; produces consistent error responses
  • Soft Delete — Customers are never permanently deleted; IsDeleted flag with query filter
  • Renewal ChainRenewedFromId tracks subscription renewal history

Entity Relationships

User (1) ←→ (1) Customer
Customer (1) ←→ (Many) CustomerSubscription
SubscriptionPlan (1) ←→ (Many) CustomerSubscription
CustomerSubscription → (self) RenewedFrom

Error Response Format

All errors return a consistent JSON structure:

{
  "statusCode": 404,
  "message": "Customer with ID 99 not found",
  "detail": null,
  "timestamp": "2026-05-18T10:00:00Z",
  "traceId": "0HN4ABC123..."
}

Pagination Response Format

{
  "data": [],
  "page": 1,
  "pageSize": 10,
  "totalCount": 25,
  "totalPages": 3,
  "hasPrevious": false,
  "hasNext": true
}

Business Rules

  • Customers cannot have duplicate active subscriptions to the same plan
  • Only active or expired subscriptions can be renewed
  • Cancelled subscriptions cannot be renewed
  • Plans must be active to subscribe or renew
  • Renewal starts from the current subscription's end date (or now if expired)
  • Only admins can create, update, or deactivate plans

About

A production-grade subscription management REST API built with .NET 10, PostgreSQL, and Docker.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors