Skip to content

padmarajan26/NestPulse

Repository files navigation

NestPulse API

Fractional Property Investment Advisor - UAE Real Estate

A production-grade .NET 10 backend that helps fractional property investors answer "What should I do next, and why?"

Given an investor's goals, risk appetite, time horizon, and existing holdings, NestPulse scores available properties across 5 weighted factors, recommends optimal allocations, projects returns over 1 to 10 years, and flags when a portfolio is ready for a full mortgage.

Built to demonstrate senior backend engineering capabilities in the proptech and fintech space; clean architecture, SOLID principles, RESTful API design, and Azure-ready infrastructure.


The Problem This Solves

Fractional property investment platforms let investors own portions of UAE properties from as little as AED 500. As a portfolio grows across multiple properties, most platforms show investors what they have — but not what they should do next.

NestPulse is the backend engine that fills that gap. It analyses an investor's current holdings and available capital, scores all available properties for suitability, and recommends the optimal next move - with full reasoning broken down by factor.


Architecture

  • NestPulse.Domain → Entities, Value Objects, Enums, Repository Interfaces
  • NestPulse.Application → DTOs, Service Interfaces, Scoring Engine, Calculators, Validators
  • NestPulse.Infrastructure → Repositories, Cache, External API Client, Enrichment Service, DI
  • NestPulse.API → Controllers, Middleware, Auth, Program.cs
  • NestPulse.Infrastructure.Tests → Unit tests - PropertyEnrichmentServiceTest
  • NestPulse.Application.Tests → Unit tests - Scoring, Calculator, Recommendation, Portfolio, Property, Services

Dependency flow is strictly inward - Domain has zero external dependencies. Infrastructure implements Domain interfaces - the Application layer never knows what's behind them.


Key Engineering Decisions

Decision Approach Why
Architecture Clean Architecture Separation of concerns, independently testable layers
Repository pattern IPropertyRepository interface Swap seed data ↔ live API with zero application changes
Cache abstraction ICacheService interface Swap in-memory ↔ Redis via config, no code changes
Validation Custom ValidationException Collects ALL field errors before throwing - never stops at first failure
Error handling GlobalExceptionMiddleware Consistent JSON error responses, structured logging, no stack trace leakage
Authentication JWT Bearer Stateless, Azure AD B2C ready - swap DemoUsers for B2C with config change only
Logging Serilog Structured logs to console + rolling daily files, request logging middleware
External API Provider-agnostic naming PropertyApiClient, PropertyRepository - External URL lives in config only
Enrichment PropertyEnrichmentService Transforms raw API listings into domain entities using Dubai rental index benchmarks

API Endpoints

Method Endpoint Auth Description
POST /api/v1/auth/token None Get JWT bearer token
GET /api/v1/properties Bearer All available properties
POST /api/v1/portfolio/analyse Bearer Analyse existing portfolio
POST /api/v1/portfolio/recommend Bearer Get next investment recommendation

Swagger UI available at / when running locally.


Suitability Scoring

Each property is scored out of 100 across 5 weighted factors:

Factor Weight What it measures
Yield Alignment 35% Does the yield match the investor's income/growth goal?
Risk Tag Match 25% Does the property risk tier fit the investor's appetite?
Time Horizon Fit 20% Does the holding period suit when returns materialise?
Funding Availability 10% Is there enough funding left to invest meaningfully?
Diversification Benefit 10% Does this property add a new area to the portfolio?

Data Sources

Seed data (default): 10 properties modelled on publicly available UAE listings with yield figures derived from the Dubai rental index.

Live API (optional): External property listings API returning real UAE for-sale properties. Enriched with area-level yield benchmarks via PropertyEnrichmentService.

To switch - one config change, zero code changes:

// appsettings.json
"UseExternalPropertyApi": true,
"PropertyApi": {
  "BaseUrl": "https://your-api-url",
  "ApiKey": "your-key",
  "ApiHost": "your-host"
}

Caching Strategy

Data Cache Key TTL
Property listings properties:all 1 hour
Recommendation results Hash of input profile 15 minutes

Currently running in-memory cache via InMemoryCacheService. RedisCacheService is fully implemented and ready - swap registration in DependencyInjection.cs by setting ConnectionStrings:Redis in config. Zero application layer changes required.


Authentication

JWT Bearer token authentication. Demo credentials for testing:

Email Password
demo@nestpulse.com demo123
investor@nestpulse.com invest123

Production path: Replace DemoUsers with Azure AD B2C - three config lines, zero controller changes. The [Authorize] attributes stay exactly as they are.


Quick Start

git clone https://github.com/yourusername/nestpulse.git
cd nestpulse
dotnet restore
dotnet run --project NestPulse.API

Navigate to https://localhost:{port} - Swagger UI loads at root.

Get a token first:

POST /api/v1/auth/token
{
  "email": "demo@nestpulse.com",
  "password": "demo123"
}

Click Authorize in Swagger, paste the token, then call any endpoint.


Running Tests

dotnet test

Test coverage includes:

Test Class Coverage
PortfolioServiceTests Analyse portfolio
PropertyServiceTests Analyse get property, with and without cache
SuitabilityScorerServiceTests All 5 scoring components, all combinations
PortfolioCalculatorServiceTests Blended yield, diversification, projections, crossover, allocation
PropertyEnrichmentServiceTests Area extraction, yield lookup, risk tag derivation, full enrichment
RecommendationServiceTests End-to-end recommendation flow with mocked dependencies
PropertyEnrichmentServiceTests Test all enrichment methods

Sample Request — Recommend

POST /api/v1/portfolio/recommend
Authorization: Bearer {token}

{
  "profile": {
    "existingHoldings": [
      {
        "propertyId": "prop-001",
        "propertyName": "Studio in Bayz Tower",
        "location": "Business Bay, Dubai",
        "area": "Business Bay",
        "amountInvested": 5000,
        "grossYieldPercent": 7.72,
        "oneYearReturnPercent": 10.61
      }
    ],
    "availableAmount": 5000,
    "goal": 1,
    "riskAppetite": 2,
    "timeHorizon": 3
  }
}

Enum values:

Field Values
goal 1=PassiveIncome, 2=CapitalGrowth, 3=Both
riskAppetite 1=Conservative, 2=Balanced, 3=Aggressive
timeHorizon 1=OneYear, 3=ThreeYears, 5=FiveYears, 10=TenYears

Project Roadmap

  • Clean Architecture scaffold
  • Domain entities and value objects
  • Suitability scoring engine
  • Portfolio analysis and projections
  • Mortgage crossover logic
  • External property API integration
  • Property enrichment service
  • JWT authentication
  • Global exception handling
  • Structured logging with Serilog
  • In-memory cache with Redis interface ready
  • Docker + docker-compose
  • Azure App Service deployment
  • Azure Key Vault integration
  • Azure AD B2C authentication
  • React frontend

Tech Stack

Layer Technology
Runtime .NET 8, ASP.NET Core Web API
Architecture Clean Architecture, SOLID, DI
Testing xUnit, Moq, FluentAssertions
Logging Serilog — Console + rolling file sinks
Auth JWT Bearer — Azure AD B2C ready
Caching In-memory — Redis interface implemented
API Docs Swagger / Swashbuckle
External Data Provider-agnostic property listings API

About

NestPulse is a production-grade .NET 10 backend that guides fractional property investors in the UAE - given an investor's goals, risk appetite, and existing holdings, NestPulse scores available properties across 5 weighted factors, recommends optimal allocations, projects returns , and flags when a portfolio is ready for a full mortgage.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages