Skip to content

Property Management Microservices Architecture

This document outlines the updated microservice architecture with schema-per-service approach using a single PostgreSQL database.

Architecture Overview

The system now consists of 8 microservices using a single database with 6 schemas approach:

📁 Database Structure (PropertyManagementDB)

📁 PropertyManagementDB (PostgreSQL)
├── 🗂️ identity (Identity Service - auth, users, roles)
├── 🗂️ core (User, Organization, Property Services - users, orgs, properties, units, tenants)
├── 🗂️ operations (Operations Service - maintenance, vendors, work orders)
├── 🗂️ financial (Financial Service - invoices, payments, expenses)
├── 🗂️ communication (Community, Notifications Services - notifications, messages, events)
└── 🗂️ shared (Shared Resources - documents, settings, audit logs)

Microservices

1. *Identity Service

  • Schema: identity
  • Port: 5001
  • Responsibilities:
  • Authentication & Authorization
  • JWT token management
  • Basic user accounts
  • Role assignments
  • Multi-factor authentication

2. User Service

  • Schema: core
  • Port: 5002
  • Responsibilities:
  • Extended user profiles
  • User preferences
  • Cross-service role management
  • Profile documents
  • User service role assignments

3. Organization Service

  • Schema: core
  • Port: 5003
  • Responsibilities:
  • Multi-tenant organization management
  • Subscription management
  • Organization settings
  • Domain management

4. Property Service

  • Schema: core
  • Port: 5004
  • Responsibilities:
  • Property management
  • Building management
  • Unit management
  • Tenant management
  • Lease management

5. Financial Service

  • Schema: financial
  • Port: 5005
  • Responsibilities:
  • Invoice generation
  • Payment processing
  • Expense tracking
  • Maintenance fees
  • Financial reporting

6. Operations Service

  • Schema: operations
  • Port: 5006
  • Responsibilities:
  • Maintenance requests
  • Work order management
  • Vendor management
  • Staff management
  • Visitor management

7. Community Service

  • Schema: communication
  • Port: 5007
  • Responsibilities:
  • Community events
  • Marketplace listings
  • Event registrations
  • Community management

8. Notifications Service

  • Schema: communication
  • Port: 5008
  • Responsibilities:
  • Email/SMS/Push notifications
  • In-app messaging
  • Notification templates
  • Communication channels

Authentication & Authorization Flow

1. Token Generation

sequenceDiagram
    participant Client
    participant Gateway as API Gateway
    participant Identity as Identity Service
    participant User as User Service

    Client->>Gateway: Login Request
    Gateway->>Identity: Authenticate User
    Identity-->>Gateway: JWT Token + User Claims
    Gateway-->>Client: JWT Token

    Note over Identity: Token includes: sub, org_id, roles, permissions

2. Token Validation

sequenceDiagram
    participant Client
    participant Gateway as API Gateway
    participant Service as Microservice

    Client->>Gateway: API Request + JWT
    Gateway->>Gateway: Validate JWT (signature, expiry)
    Gateway->>Service: Forward Request + User Context
    Service->>Service: Authorize based on claims
    Service-->>Gateway: Response
    Gateway-->>Client: Response

Token Claims Structure

{
  "sub": "user-id",
  "email": "user@example.com",
  "org_id": "organization-id",
  "org_roles": ["PropertyManager", "Admin"],
  "permissions": ["property:read", "tenant:manage"],
  "tenant_profile_id": "tenant-id", 
  "jti": "token-id",
  "iat": 1640995200,
  "exp": 1641001200,
  "aud": "PropertyManagement"
}

Data Architecture Principles

Schema Ownership

  • identity: Owned by Identity Service
  • core: Shared by User, Organization, Property Services
  • operations: Owned by Operations Service
  • financial: Owned by Financial Service
  • communication: Shared by Community, Notifications Services
  • shared: Common resources for all services

Cross-Service Data Access

  • No direct database calls between services
  • Use HTTP APIs for immediate data needs
  • Use events for eventual consistency
  • User context passed via JWT claims

Service Communication Patterns

1. Synchronous (HTTP)

  • User profile lookups
  • Organization validation
  • Real-time data requirements

2. Asynchronous (Events)

  • User registration → Profile creation
  • Lease creation → Unit status update
  • Payment processing → Invoice status update

Development Setup

Prerequisites

  • .NET 9.0 SDK
  • Docker Desktop
  • PostgreSQL (via Docker)
  • Node.js 18+ (for frontend)

Getting Started

  1. Clone and restore packages:

    git clone <repository-url>
    cd property_managment
    dotnet restore
    

  2. Start infrastructure:

    docker-compose up -d
    

  3. Run the application:

    dotnet run --project src/AppHost/PropertyManagement.AppHost
    

  4. Initialize database with schemas:

    psql -h localhost -U postgres -d PropertyManagementDB -f documentations/docs/development/postgresql-schema-microservices.sql
    

Build Commands

# Build all services
dotnet build

# Build specific service
dotnet build src/Services/User/PropertyManagement.User.WebApi

# Run specific service
dotnet run --project src/Services/User/PropertyManagement.User.WebApi

API Endpoints

Service Discovery

Service Endpoints (via API Gateway)

  • Identity: /api/identity/*
  • User: /api/users/*
  • Organization: /api/organizations/*
  • Property: /api/properties/*
  • Financial: /api/financial/*
  • Operations: /api/operations/*
  • Community: /api/community/*
  • Notifications: /api/notifications/*

Configuration

Connection Strings (per schema)

{
  "ConnectionStrings": {
    "IdentityConnection": "Host=localhost;Database=PropertyManagementDB;Username=postgres;Password=postgres;Schema=identity;",
    "CoreConnection": "Host=localhost;Database=PropertyManagementDB;Username=postgres;Password=postgres;Schema=core;",
    "OperationsConnection": "Host=localhost;Database=PropertyManagementDB;Username=postgres;Password=postgres;Schema=operations;",
    "FinancialConnection": "Host=localhost;Database=PropertyManagementDB;Username=postgres;Password=postgres;Schema=financial;",
    "CommunicationConnection": "Host=localhost;Database=PropertyManagementDB;Username=postgres;Password=postgres;Schema=communication;"
  }
}

Service URLs

{
  "ServiceUrls": {
    "IdentityService": "https://localhost:5001",
    "UserService": "https://localhost:5002", 
    "OrganizationService": "https://localhost:5003",
    "PropertyService": "https://localhost:5004",
    "FinancialService": "https://localhost:5005",
    "OperationsService": "https://localhost:5006",
    "CommunityService": "https://localhost:5007",
    "NotificationsService": "https://localhost:5008",
    "ApiGateway": "https://localhost:5000"
  }
}

Testing

Health Checks

All services expose health check endpoints:

curl http://localhost:5002/health  # User Service
curl http://localhost:5003/health  # Organization Service  
curl http://localhost:5005/health  # Financial Service

Unit Tests

# Run all tests
dotnet test

# Run service-specific tests
dotnet test tests/Unit/Services/User/

Security Considerations

JWT Validation

  • API Gateway: Validates signature, expiry, audience
  • Services: Additional claim-based authorization
  • Token Rotation: Short-lived access tokens (15 min)

Database Security

  • Schema isolation: Each service accesses only its schemas
  • Row-level security: Multi-tenant data isolation
  • Connection pooling: Service-specific connection strings

Monitoring & Observability

Aspire Dashboard Features

  • Service health status
  • Database connections
  • Request tracing
  • Performance metrics
  • Log aggregation

Custom Metrics

  • API response times
  • Database query performance
  • Authentication success rates
  • Error rates per service

Next Steps

  1. Implement service-specific repositories and business logic
  2. Add comprehensive API documentation (OpenAPI/Swagger)
  3. Implement event-driven communication
  4. Add comprehensive integration tests
  5. Set up CI/CD pipelines
  6. Implement distributed tracing
  7. Add caching strategies
  8. Implement rate limiting

Benefits of This Architecture

Advantages

  • Single Database: Simplified infrastructure and ACID transactions
  • Schema Isolation: Logical separation without network overhead
  • Balanced Services: Not too fine-grained, not monolithic
  • JWT-based Auth: Stateless, scalable authentication
  • Clear Boundaries: Well-defined service responsibilities

Considerations

  • Database coupling: Services share database infrastructure
  • Schema migration: Coordinate changes across services
  • Testing complexity: Integration tests require full database setup

This architecture provides a balanced approach between microservices benefits and operational simplicity, perfect for a property management system of this complexity.