Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions docs/hcp/architectures.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
---
id: architectures
title: Architecture Strategies
sidebar_label: Architecture Strategies
---

# 🧩 Combining HCP Modules: Architecture Strategies

## Overview

The Health Composable Platform (HCP) is built around a modular architecture that enables flexible composition of features. Each module—such as EHR, Therapy and Monitoring, User Authentication, Booking, and Notification—is composed of a set of microservices designed to be **independent and reusable**.

Depending on the organizational and technical context, modules can be deployed in two different architectural strategies:

1. **Isolated Modules in Separate Kubernetes Namespaces**
2. **Unified Deployment in a Single Kubernetes Namespace**

This document outlines both approaches and provides a comparison to help you choose the right setup for your needs.

---

## 1 Isolated Modules in Separate Kubernetes Namespaces

### 🏗️ Description

In this model, each module is deployed into its **own Kubernetes namespace**. It includes:

- A **dedicated API Gateway** for routing requests specific to the module.
- A **dedicated CRUD Service** for managing persistence related to that module's data.
- Its own business-specific microservices and configurations.

This model emphasizes **separation of concerns** and **domain isolation**.

### ✅ Pros

| Benefit | Description |
|--------|-------------|
| 🔒 **Security** | Each namespace can have its own access controls, limiting surface area and blast radius. |
| 🧩 **Modularity** | Modules are fully decoupled, making them easier to develop, test, and deploy independently. |
| 🛠️ **Scalability** | You can scale individual modules based on usage (e.g., scale EHR separately from Notifications). |
| 🧪 **Resilience** | Faults or failures in one module do not impact others. |
| 🔁 **Reusability** | Modules can be reused across multiple projects or customers in an isolated fashion. |

### ❌ Cons

| Limitation | Description |
|-----------|-------------|
| ⚙️ **Operational Complexity** | Requires managing multiple gateways, CRUD services, and namespaces. |
| 💰 **Resource Overhead** | More services running in parallel means higher infrastructure costs. |
| 📡 **Cross-Module Communication** | Interactions between modules may require explicit service mesh configurations or gateway routing. |

---

## 2 Unified Deployment in a Single Kubernetes Namespace

### 🏗️ Description

In this strategy, all module components are deployed into a **single Kubernetes namespace**. It includes:

- A **shared API Gateway** that exposes all the APIs across modules.
- A **shared CRUD Service** that interfaces with all databases or collections.
- All module-specific microservices running side by side.

This setup is often used in simpler deployments or early development stages.

### ✅ Pros

| Benefit | Description |
|--------|-------------|
| 🚀 **Simplicity** | Easier to configure, deploy, and monitor as everything is centralized. |
| 💸 **Cost-Effective** | Reduces infrastructure footprint by consolidating common services like the API Gateway and CRUD. |
| 📦 **Faster Setup** | Ideal for proof-of-concepts, demos, or environments with limited DevOps resources. |
| 🧍‍♂️ **Easier Management** | Fewer components to manage and maintain. |

### ❌ Cons

| Limitation | Description |
|-----------|-------------|
| ⚠️ **Tight Coupling** | Makes it harder to evolve or deploy modules independently. |
| 🔐 **Security Risks** | Less granularity in access control—risk of overexposure if RBAC isn’t strictly enforced. |
| 🧪 **Lack of Isolation** | Bugs or issues in one module may affect the others. |
| 🧱 **Scalability Limitations** | All modules scale together, which may lead to inefficiencies. |

---

## Choosing the Right Strategy

| Use Case | Recommended Strategy |
|----------|----------------------|
| **Large-scale or multi-tenant deployment** | Isolated namespaces |
| **Independent team development per module** | Isolated namespaces |
| **Simple or MVP-level application** | Single namespace |
| **Tight DevOps control or low resource environment** | Single namespace |
| **Projects requiring strong fault isolation** | Isolated namespaces |

---

## Transitioning from Unified to Isolated

It's common to **start with a unified namespace** during the initial phases of development and later **migrate to an isolated namespace strategy** as the platform grows. The modular design of HCP makes this transition smooth, as services are already defined independently.

---

## Architecture Examples

### Isolated Namespaces Example

![Isolated Namespaces](./img/svg-files/hcp.modules.svg)

### Unified Namespace Example

![Unified Namespace](./img/svg-files/hcp.unique.svg)

130 changes: 130 additions & 0 deletions docs/hcp/img/drawio-files/hcp.modules.drawio
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36" version="27.0.6">
<diagram name="Page-1" id="6AMU0Ud-SFyGVthSRizk">
<mxGraphModel dx="1251" dy="735" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="Wx-3gpha0FLeQevEmSP5-50" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="60" y="60" width="830" height="940" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-26" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=none;align=left;dashed=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="90" y="440" width="370" height="200" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-3" value="Form Service Backend" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="120" y="143" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-4" value="Form Service Frontend" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="305" y="143" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-20" value="Device Manager" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="120" y="483" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-21" value="Therapy and Monitoring&amp;nbsp; Manager" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="305" y="483" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-25" value="&lt;font&gt;Therapy and Monitoring&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="105" y="440" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-27" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=none;align=left;dashed=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="490" y="610" width="370" height="330" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-28" value="Authentication Service&amp;nbsp;&lt;div&gt;/&amp;nbsp;&lt;div&gt;Auth0 Client&lt;/div&gt;&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="520" y="668" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-29" value="User Manager Service" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="705" y="668" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-30" value="&lt;font&gt;Auth User Module&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="520" y="610" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-31" value="Authorization Service" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="520" y="755" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-32" value="Login Site" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="705" y="755" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-33" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=none;align=left;dashed=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="90" y="688" width="370" height="255" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-34" value="Appointment Manager" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="120" y="731" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-35" value="Teleconsultation Service Backend" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="305" y="731" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-36" value="&lt;font&gt;Booking Module&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="130" y="688" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-37" value="&lt;span style=&quot;caret-color: rgba(0, 0, 0, 0);&quot;&gt;Teleconsultation Service Frontend&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="120" y="818" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-39" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=none;align=left;dashed=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="490" y="100" width="370" height="410" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-40" value="Notification Manager" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="520" y="143" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-41" value="Mail Service" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="705" y="143" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-42" value="&lt;font&gt;Notification Module&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=14;" vertex="1" parent="1">
<mxGeometry x="520" y="100" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-43" value="&lt;span style=&quot;caret-color: rgba(0, 0, 0, 0);&quot;&gt;SMS Service&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="520" y="230" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-44" value="Email Builder" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="705" y="230" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-45" value="&lt;span style=&quot;caret-color: rgba(0, 0, 0, 0);&quot;&gt;Timer Service&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="520" y="320" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-46" value="&lt;span style=&quot;caret-color: rgba(0, 0, 0, 0);&quot;&gt;Files Service&lt;/span&gt;" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="705" y="320" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-51" value="API Gateway" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;fillColor=#f8cecc;strokeColor=#b85450;" vertex="1" parent="1">
<mxGeometry x="540" y="900" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-52" value="CRUD Service" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1">
<mxGeometry x="705" y="840" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-53" value="API Gateway" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;fillColor=#f8cecc;strokeColor=#b85450;" vertex="1" parent="1">
<mxGeometry x="215" y="913" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-54" value="CRUD Service" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1">
<mxGeometry x="305" y="818" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-55" value="API Gateway" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;fillColor=#f8cecc;strokeColor=#b85450;" vertex="1" parent="1">
<mxGeometry x="155" y="610" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-56" value="CRUD Service" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1">
<mxGeometry x="305" y="570" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-57" value="CRUD Service" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1">
<mxGeometry x="705" y="410" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-58" value="API Gateway" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;fillColor=#f8cecc;strokeColor=#b85450;" vertex="1" parent="1">
<mxGeometry x="530" y="480" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-1" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=none;align=left;dashed=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="90" y="100" width="370" height="290" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-12" value="&lt;font style=&quot;font-size: 14px;&quot;&gt;Electronic Health Record&lt;/font&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="100" y="100" width="180" height="30" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-5" value="Fhir Adapter" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="120" y="230" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-6" value="Fhir Server" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;" vertex="1" parent="1">
<mxGeometry x="305" y="230" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-59" value="CRUD Service" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1">
<mxGeometry x="305" y="320" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Wx-3gpha0FLeQevEmSP5-60" value="API Gateway" style="rounded=1;whiteSpace=wrap;html=1;fontSize=13;fillColor=#f8cecc;strokeColor=#b85450;" vertex="1" parent="1">
<mxGeometry x="120" y="360" width="120" height="60" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>
Loading