@bluealba/platform-cli 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +278 -15
- package/docs/404.mdx +5 -0
- package/docs/architecture/api-explorer.mdx +478 -0
- package/docs/architecture/architecture-diagrams.mdx +12 -0
- package/docs/architecture/authentication-system.mdx +903 -0
- package/docs/architecture/authorization-system.mdx +886 -0
- package/docs/architecture/bootstrap.mdx +1442 -0
- package/docs/architecture/gateway-architecture.mdx +845 -0
- package/docs/architecture/multi-tenancy.mdx +1150 -0
- package/docs/architecture/overview.mdx +776 -0
- package/docs/architecture/scheduler.mdx +818 -0
- package/docs/architecture/shell.mdx +885 -0
- package/docs/architecture/ui-extension-points.mdx +781 -0
- package/docs/architecture/user-states.mdx +794 -0
- package/docs/development/overview.mdx +21 -0
- package/docs/development/workflow.mdx +914 -0
- package/docs/getting-started/core-concepts.mdx +892 -0
- package/docs/getting-started/installation.mdx +780 -0
- package/docs/getting-started/overview.mdx +83 -0
- package/docs/getting-started/quick-start.mdx +940 -0
- package/docs/guides/adding-documentation-sites.mdx +1367 -0
- package/docs/guides/creating-services.mdx +1736 -0
- package/docs/guides/creating-ui-modules.mdx +1860 -0
- package/docs/guides/identity-providers.mdx +1007 -0
- package/docs/guides/mermaid-diagrams.mdx +212 -0
- package/docs/guides/using-feature-flags.mdx +1059 -0
- package/docs/guides/working-with-rooms.mdx +566 -0
- package/docs/index.mdx +57 -0
- package/docs/platform-cli/commands.mdx +604 -0
- package/docs/platform-cli/overview.mdx +195 -0
- package/package.json +5 -2
- package/skills/ba-platform/platform-cli.skill.md +26 -0
- package/skills/ba-platform/platform.skill.md +35 -0
- package/templates/application-monorepo-template/gitignore +95 -0
- package/templates/bootstrap-service-template/Dockerfile.development +1 -1
- package/templates/bootstrap-service-template/gitignore +57 -0
- package/templates/bootstrap-service-template/package.json +1 -1
- package/templates/bootstrap-service-template/src/main.ts +6 -16
- package/templates/customization-ui-module-template/Dockerfile.development +1 -1
- package/templates/customization-ui-module-template/gitignore +73 -0
- package/templates/nestjs-service-module-template/Dockerfile.development +1 -1
- package/templates/nestjs-service-module-template/gitignore +56 -0
- package/templates/platform-init-template/{{platformName}}-core/gitignore +97 -0
- package/templates/platform-init-template/{{platformName}}-core/local/.env.example +1 -1
- package/templates/platform-init-template/{{platformName}}-core/local/platform-docker-compose.yml +1 -1
- package/templates/platform-init-template/{{platformName}}-core/local/{{platformName}}-core-docker-compose.yml +0 -1
- package/templates/react-ui-module-template/Dockerfile +1 -1
- package/templates/react-ui-module-template/Dockerfile.development +1 -3
- package/templates/react-ui-module-template/caddy/Caddyfile +1 -1
- package/templates/react-ui-module-template/gitignore +72 -0
- package/templates/react-ui-module-template/Dockerfile_nginx +0 -11
- package/templates/react-ui-module-template/nginx/default.conf +0 -23
|
@@ -0,0 +1,776 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Architecture Overview
|
|
3
|
+
description: Comprehensive overview of the Blue Alba Platform architecture - gateway, microservices, micro-frontends, and technology stack
|
|
4
|
+
sidebar:
|
|
5
|
+
order: 0
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
import { Card, CardGrid, Aside, Tabs, TabItem, Code } from '@astrojs/starlight/components';
|
|
9
|
+
import { Zoom } from 'starlight-image-zoom/components';
|
|
10
|
+
import MermaidDiagram from '~/components/MermaidDiagram.astro';
|
|
11
|
+
import ExcalidrawDiagram from '~/components/ExcalidrawDiagram.astro';
|
|
12
|
+
import highestLevelLayers from '~/assets/architecture/highest-level-layers.excalidraw';
|
|
13
|
+
import mediumLevelLayers from '~/assets/architecture/medium-level-layers.excalidraw';
|
|
14
|
+
|
|
15
|
+
The Blue Alba Platform is a sophisticated, enterprise-grade application platform built on modern architectural patterns. It can be logically understood as a set of layers where lower levels provide the foundation and architecture resolving cross-cutting concerns, while upper layers focus on enabling business functionality and use cases.
|
|
16
|
+
|
|
17
|
+
<Aside type="tip">
|
|
18
|
+
All diagrams on this page support zoom and pan. Use the zoom controls or hold Ctrl/Cmd and scroll to zoom. Click and drag to pan around larger diagrams. Click the code icon to view or copy the raw Mermaid source.
|
|
19
|
+
</Aside>
|
|
20
|
+
|
|
21
|
+
## Architectural View
|
|
22
|
+
|
|
23
|
+
This is the highest-level overview of the Platform.
|
|
24
|
+
|
|
25
|
+
<ExcalidrawDiagram diagram={highestLevelLayers} title="Platform Layers - Highest Level" height="400px" />
|
|
26
|
+
|
|
27
|
+
These layers contain different elements that can be zoomed in.
|
|
28
|
+
|
|
29
|
+
<ExcalidrawDiagram diagram={mediumLevelLayers} title="Platform Layers - Medium Level" height="600px" />
|
|
30
|
+
|
|
31
|
+
Applications are business-related logical units that might contain one or more microservices (APIs, cron jobs, batch processing, etc.) as well as micro-frontend UI elements.
|
|
32
|
+
|
|
33
|
+
This document provides a comprehensive overview of the system architecture, design principles, and technology choices.
|
|
34
|
+
|
|
35
|
+
## Architectural Vision
|
|
36
|
+
|
|
37
|
+
The Blue Alba Platform is designed to be:
|
|
38
|
+
|
|
39
|
+
- **Modular**: Composed of independent, deployable services and UIs
|
|
40
|
+
- **Scalable**: Horizontally scalable microservices and micro-frontends
|
|
41
|
+
- **Secure**: Multi-layered security with authentication, authorization, and tenant isolation
|
|
42
|
+
- **Extensible**: Plugin-based architecture for custom applications and services
|
|
43
|
+
- **Multi-Tenant**: Complete data and configuration isolation per tenant
|
|
44
|
+
- **Developer-Friendly**: Rich tooling, clear conventions, and comprehensive SDKs
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Platform Topology
|
|
49
|
+
|
|
50
|
+
The platform is organized as a set of layers: an optional reverse proxy terminates SSL, the gateway handles authentication, authorization, and routing, UI micro-frontends and backend microservices sit behind it, and shared infrastructure (PostgreSQL) is accessed by both the gateway and services. A one-time bootstrap process provisions the catalog and initial configuration via the gateway API.
|
|
51
|
+
|
|
52
|
+
Client services never communicate directly with each other — all inter-service calls are routed through the gateway using an API Key. Platform internal services (Bootstrap, Rooms, etc.) use the `SERVICE_ACCESS_SECRET` instead, which is reserved for platform-owned components.
|
|
53
|
+
|
|
54
|
+
<MermaidDiagram
|
|
55
|
+
title="Platform Topology"
|
|
56
|
+
height="600px"
|
|
57
|
+
code={`---
|
|
58
|
+
config:
|
|
59
|
+
layout: elk
|
|
60
|
+
theme: neutral
|
|
61
|
+
---
|
|
62
|
+
flowchart LR
|
|
63
|
+
subgraph MFE["Microfrontends"]
|
|
64
|
+
Shell(["SHELL UI"])
|
|
65
|
+
Admin["ADMIN UI"]
|
|
66
|
+
DocUI["DOCUMENTATION UI"]
|
|
67
|
+
ClientUI["Client UIs"]
|
|
68
|
+
end
|
|
69
|
+
subgraph PLATFORM["Platform services"]
|
|
70
|
+
Rooms(["Rooms Service"])
|
|
71
|
+
end
|
|
72
|
+
subgraph CLIENT_SVCS["Client services"]
|
|
73
|
+
Bootstrap(["Bootstrap Service"])
|
|
74
|
+
CSvc1["Client service 1"]
|
|
75
|
+
CSvc2["Client service 2"]
|
|
76
|
+
end
|
|
77
|
+
subgraph CLUSTER["Cluster — Catalog"]
|
|
78
|
+
GW["Gateway"]
|
|
79
|
+
MFE
|
|
80
|
+
PLATFORM
|
|
81
|
+
CLIENT_SVCS
|
|
82
|
+
end
|
|
83
|
+
Admin -- Mount at --> Shell
|
|
84
|
+
DocUI -- Mount at --> Shell
|
|
85
|
+
ClientUI -- Mount at --> Shell
|
|
86
|
+
GW -- "Server side rendering\\nIndex.html" --> Shell
|
|
87
|
+
GW -- routing --> Rooms & CSvc1 & CSvc2
|
|
88
|
+
Bootstrap -- SERVICE_ACCESS_SECRET --> GW
|
|
89
|
+
Browser["BROWSER"] -- JWT Cookie --> GW
|
|
90
|
+
APIClient["API Client"] -- API Key --> GW
|
|
91
|
+
ClientSvcA["Client Service A"] -- "API Key\\n(inter-service call)" --> GW`}
|
|
92
|
+
/>
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## High-Level Architecture
|
|
97
|
+
|
|
98
|
+
<MermaidDiagram
|
|
99
|
+
title="Blue Alba Platform - High-Level Architecture"
|
|
100
|
+
height="600px"
|
|
101
|
+
code={`flowchart LR
|
|
102
|
+
subgraph CLIENT["CLIENT LAYER"]
|
|
103
|
+
Browser["Browser"]
|
|
104
|
+
API["API Client"]
|
|
105
|
+
end
|
|
106
|
+
subgraph GATEWAY["GATEWAY LAYER"]
|
|
107
|
+
PAE["Gateway Service<br>• HTTP/2 & WebSocket Support<br>• Authentication & Authorization<br>• Request Routing & Proxying<br>• Tenant Context Resolution<br>• Platform Context Management<br>• Catalog Integration"]
|
|
108
|
+
end
|
|
109
|
+
subgraph UI["UI LAYER"]
|
|
110
|
+
Shell["Shell UI"]
|
|
111
|
+
Admin["Admin UI"]
|
|
112
|
+
Custom["Custom UIs"]
|
|
113
|
+
end
|
|
114
|
+
subgraph SERVICES["SERVICE LAYER"]
|
|
115
|
+
Scheduler["Scheduler Service<br>"]
|
|
116
|
+
CustomSvc["Custom Services<br>"]
|
|
117
|
+
end
|
|
118
|
+
subgraph FUNCTIONS["FUNCTIONS"]
|
|
119
|
+
Lambda1["Lambda Fn 1"]
|
|
120
|
+
Lambda2["Lambda Fn 2"]
|
|
121
|
+
end
|
|
122
|
+
subgraph INFRA["INFRASTRUCTURE LAYER"]
|
|
123
|
+
Postgres[("PostgreSQL")]
|
|
124
|
+
end
|
|
125
|
+
Browser --> PAE
|
|
126
|
+
API --> PAE
|
|
127
|
+
PAE --> UI & SERVICES & FUNCTIONS
|
|
128
|
+
UI --> INFRA
|
|
129
|
+
SERVICES --> INFRA`}
|
|
130
|
+
/>
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## System Components
|
|
135
|
+
|
|
136
|
+
### 1. Gateway Layer
|
|
137
|
+
|
|
138
|
+
The **PAE NestJS Gateway Service** is the central nervous system of the platform.
|
|
139
|
+
|
|
140
|
+
<CardGrid>
|
|
141
|
+
<Card title="Authentication" icon="approve-check">
|
|
142
|
+
- Multi-IDP support (Okta, EntraId, OneLogin, Github, Cognito)
|
|
143
|
+
- JWT-based sessions with HTTP-only cookies
|
|
144
|
+
- API key authentication
|
|
145
|
+
- Service-to-service authentication
|
|
146
|
+
- User impersonation
|
|
147
|
+
</Card>
|
|
148
|
+
|
|
149
|
+
<Card title="Authorization" icon="shield">
|
|
150
|
+
- RBAC enforcement at gateway level
|
|
151
|
+
- Operation-based access control
|
|
152
|
+
- Resource-level permissions
|
|
153
|
+
- Tenant-scoped authorization
|
|
154
|
+
</Card>
|
|
155
|
+
|
|
156
|
+
<Card title="Routing & Proxying" icon="random">
|
|
157
|
+
- Dynamic route resolution via catalog
|
|
158
|
+
- Request proxying to microservices
|
|
159
|
+
- Lambda function integration
|
|
160
|
+
- WebSocket proxying
|
|
161
|
+
- HTTP/2 multiplexing
|
|
162
|
+
</Card>
|
|
163
|
+
|
|
164
|
+
<Card title="Context Management" icon="seti:json">
|
|
165
|
+
- Tenant context resolution
|
|
166
|
+
- User context propagation
|
|
167
|
+
- Application context tracking
|
|
168
|
+
- Request tracing and correlation
|
|
169
|
+
</Card>
|
|
170
|
+
</CardGrid>
|
|
171
|
+
|
|
172
|
+
### 2. Micro-Frontend Layer
|
|
173
|
+
|
|
174
|
+
UI applications are built as **React-based micro-frontends** using single-spa.
|
|
175
|
+
|
|
176
|
+
**Shell UI**: The orchestrator that:
|
|
177
|
+
- Loads and mounts micro-frontends dynamically
|
|
178
|
+
- Provides shared navigation and layout
|
|
179
|
+
- Manages authentication state
|
|
180
|
+
- Coordinates tenant selection
|
|
181
|
+
- Handles global error boundaries
|
|
182
|
+
|
|
183
|
+
**Feature UIs**: Independent micro-frontends that:
|
|
184
|
+
- Implement specific application features
|
|
185
|
+
- Register with the catalog
|
|
186
|
+
- Share common UI components via `pae-ui-react-core`
|
|
187
|
+
- Use `pae-ui-react-sdk` for build configuration
|
|
188
|
+
|
|
189
|
+
### 3. Microservices Layer
|
|
190
|
+
|
|
191
|
+
Backend services are built with **NestJS** or **Express**.
|
|
192
|
+
|
|
193
|
+
**Service Characteristics**:
|
|
194
|
+
- Domain-driven design
|
|
195
|
+
- RESTful APIs with OpenAPI documentation
|
|
196
|
+
- Event-driven communication via Kafka
|
|
197
|
+
- PostgreSQL for persistence
|
|
198
|
+
- Knex or TypeORM for database access
|
|
199
|
+
- Register with catalog on startup
|
|
200
|
+
- Receive platform context via headers
|
|
201
|
+
|
|
202
|
+
### 4. Shared Libraries
|
|
203
|
+
|
|
204
|
+
The platform provides shared libraries for consistency:
|
|
205
|
+
|
|
206
|
+
<CardGrid>
|
|
207
|
+
<Card title="pae-core-lib" icon="seti:npm">
|
|
208
|
+
Core domain entities, authorization logic, catalog types, and utilities used by both frontend and backend
|
|
209
|
+
</Card>
|
|
210
|
+
|
|
211
|
+
<Card title="pae-service-nestjs-sdk" icon="seti:npm">
|
|
212
|
+
NestJS utilities: decorators, guards, interceptors, and platform integration helpers
|
|
213
|
+
</Card>
|
|
214
|
+
|
|
215
|
+
<Card title="pae-ui-react-sdk" icon="seti:npm">
|
|
216
|
+
React micro-frontend SDK with Webpack configuration, development server, and build tools
|
|
217
|
+
</Card>
|
|
218
|
+
|
|
219
|
+
<Card title="pae-ui-react-core" icon="seti:npm">
|
|
220
|
+
Shared React components, hooks, utilities, and authorization components
|
|
221
|
+
</Card>
|
|
222
|
+
</CardGrid>
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Request Flow
|
|
227
|
+
|
|
228
|
+
### Gateway Guard Chain and Request Lifecycle
|
|
229
|
+
|
|
230
|
+
Every inbound request passes through a sequential chain of NestJS guards before being proxied. Each guard either enriches the request context and passes control forward, or short-circuits the chain with an appropriate HTTP error.
|
|
231
|
+
|
|
232
|
+
<MermaidDiagram
|
|
233
|
+
title="Gateway Guard Chain and Request Lifecycle"
|
|
234
|
+
height="700px"
|
|
235
|
+
code={`sequenceDiagram
|
|
236
|
+
participant B as Browser
|
|
237
|
+
participant N as nginx
|
|
238
|
+
participant CG as CatalogGuard
|
|
239
|
+
participant AG as AuthGuard
|
|
240
|
+
participant IG as ImpersonationGuard
|
|
241
|
+
participant TG as TenantGuard
|
|
242
|
+
participant TRG as TenantRouteGuard
|
|
243
|
+
participant AZG as AuthorizationGuard
|
|
244
|
+
participant PS as ProxyService
|
|
245
|
+
participant SVC as Backend Service
|
|
246
|
+
|
|
247
|
+
B->>N: HTTPS Request
|
|
248
|
+
N->>CG: HTTP (SSL terminated)
|
|
249
|
+
CG-->>CG: Resolve target module from catalog
|
|
250
|
+
CG->>AG: targetModule resolved (or 404)
|
|
251
|
+
AG-->>AG: Validate JWT cookie / API key
|
|
252
|
+
AG->>IG: AuthUser set (or 401)
|
|
253
|
+
IG-->>IG: Check impersonation headers
|
|
254
|
+
IG->>TG: Effective user identity
|
|
255
|
+
TG-->>TG: Resolve tenant from subdomain/header
|
|
256
|
+
TG->>TRG: Tenant context (or 403)
|
|
257
|
+
TRG-->>TRG: Validate tenant has access to route
|
|
258
|
+
TRG->>AZG: OK (or 403)
|
|
259
|
+
AZG-->>AZG: Check user RBAC operations
|
|
260
|
+
AZG->>PS: Authorized (or 403)
|
|
261
|
+
PS->>SVC: HTTP + x-forwarded-user, x-forwarded-tenant, x-forwarded-user-operations headers
|
|
262
|
+
SVC-->>PS: Response (business logic)
|
|
263
|
+
PS-->>B: Response`}
|
|
264
|
+
/>
|
|
265
|
+
|
|
266
|
+
### Typical Request Lifecycle
|
|
267
|
+
|
|
268
|
+
```
|
|
269
|
+
1. Client Request
|
|
270
|
+
↓
|
|
271
|
+
2. Gateway: SSL Termination (HTTPS → HTTP/2)
|
|
272
|
+
↓
|
|
273
|
+
3. Gateway: Authentication (JWT validation, cookie extraction)
|
|
274
|
+
↓
|
|
275
|
+
4. Gateway: Tenant Resolution (subdomain, URL pattern, cookie)
|
|
276
|
+
↓
|
|
277
|
+
5. Gateway: Platform Context Setup (tenant, user, application)
|
|
278
|
+
↓
|
|
279
|
+
6. Gateway: Route Resolution (catalog lookup)
|
|
280
|
+
↓
|
|
281
|
+
7. Gateway: Authorization Check (RBAC, operations, rules)
|
|
282
|
+
↓
|
|
283
|
+
8. Gateway: Add Forward Headers (user, tenant, context)
|
|
284
|
+
↓
|
|
285
|
+
9. Gateway: Proxy Request to Service
|
|
286
|
+
↓
|
|
287
|
+
10. Service: Receive Context via Headers
|
|
288
|
+
↓
|
|
289
|
+
11. Service: Process Business Logic
|
|
290
|
+
↓
|
|
291
|
+
12. Service: Return Response
|
|
292
|
+
↓
|
|
293
|
+
13. Gateway: Forward Response to Client
|
|
294
|
+
↓
|
|
295
|
+
14. Client: Render UI
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Example: User Views Orders
|
|
299
|
+
|
|
300
|
+
<Tabs>
|
|
301
|
+
<TabItem label="1. Initial Request">
|
|
302
|
+
```http
|
|
303
|
+
GET https://acme.platform.com/orders HTTP/2
|
|
304
|
+
Cookie: auth_token=eyJhbGciOiJIUzI1NiIs...
|
|
305
|
+
Host: acme.platform.com
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
User navigates to orders page in their browser.
|
|
309
|
+
</TabItem>
|
|
310
|
+
|
|
311
|
+
<TabItem label="2. Gateway Processing">
|
|
312
|
+
```typescript
|
|
313
|
+
// Gateway extracts and validates JWT
|
|
314
|
+
const user = jwtService.verify(cookieToken);
|
|
315
|
+
// { username: 'john@acme.com', tenantId: 'acme', ... }
|
|
316
|
+
|
|
317
|
+
// Resolves tenant from subdomain
|
|
318
|
+
const tenant = await tenantResolver.resolve('acme.platform.com');
|
|
319
|
+
// { id: 'acme', name: 'ACME Corp', ... }
|
|
320
|
+
|
|
321
|
+
// Looks up route in catalog
|
|
322
|
+
const targetModule = catalog.resolve('/orders');
|
|
323
|
+
// { name: 'orders-service', url: 'http://orders:4001', ... }
|
|
324
|
+
|
|
325
|
+
// Checks authorization
|
|
326
|
+
const authorized = await authz.authorize(user, targetModule, 'GET', '/orders');
|
|
327
|
+
// true (user has 'orders.read' operation)
|
|
328
|
+
```
|
|
329
|
+
</TabItem>
|
|
330
|
+
|
|
331
|
+
<TabItem label="3. Service Request">
|
|
332
|
+
```http
|
|
333
|
+
GET http://orders-service:4001/orders HTTP/1.1
|
|
334
|
+
x-forwarded-user-id: john@acme.com
|
|
335
|
+
x-forwarded-user-name: John Doe
|
|
336
|
+
x-forwarded-tenant: eyJ0ZW5hbnRJZCI6ImFjbWUifQ==
|
|
337
|
+
x-forwarded-user-operations: orders.read,orders.write
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
Gateway forwards request with platform context headers.
|
|
341
|
+
</TabItem>
|
|
342
|
+
|
|
343
|
+
<TabItem label="4. Service Response">
|
|
344
|
+
```json
|
|
345
|
+
{
|
|
346
|
+
"orders": [
|
|
347
|
+
{
|
|
348
|
+
"id": "ord-123",
|
|
349
|
+
"tenantId": "acme",
|
|
350
|
+
"customerId": "cust-456",
|
|
351
|
+
"total": 99.99,
|
|
352
|
+
"status": "PENDING"
|
|
353
|
+
}
|
|
354
|
+
]
|
|
355
|
+
}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
Service returns orders filtered by tenant.
|
|
359
|
+
</TabItem>
|
|
360
|
+
</Tabs>
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## Service Communication Patterns
|
|
365
|
+
|
|
366
|
+
The platform supports two distinct communication patterns depending on the caller and use case.
|
|
367
|
+
|
|
368
|
+
<Tabs>
|
|
369
|
+
<TabItem label="HTTP via Gateway">
|
|
370
|
+
All external client traffic flows through the gateway. The catalog resolves the target service using longest-prefix matching on the request path, and the gateway enriches the forwarded request with platform context headers.
|
|
371
|
+
|
|
372
|
+
<MermaidDiagram
|
|
373
|
+
title="HTTP Request via Gateway"
|
|
374
|
+
height="450px"
|
|
375
|
+
code={`sequenceDiagram
|
|
376
|
+
participant Client
|
|
377
|
+
participant Gateway
|
|
378
|
+
participant Catalog
|
|
379
|
+
participant Service
|
|
380
|
+
|
|
381
|
+
Client->>Gateway: GET /api/orders/123
|
|
382
|
+
Gateway->>Catalog: resolveTargetModule("/api/orders/123")
|
|
383
|
+
Note over Catalog: Longest prefix match<br/>against module baseUrls
|
|
384
|
+
Catalog-->>Gateway: orders-service @ http://orders:4001
|
|
385
|
+
Gateway->>Service: GET /123\\n+ x-forwarded-user\\n+ x-forwarded-tenant\\n+ x-forwarded-user-operations
|
|
386
|
+
Service-->>Gateway: Response data
|
|
387
|
+
Gateway-->>Client: Response data`}
|
|
388
|
+
/>
|
|
389
|
+
</TabItem>
|
|
390
|
+
|
|
391
|
+
<TabItem label="Service-to-Service">
|
|
392
|
+
Internal services authenticate with the gateway using the shared `SERVICE_ACCESS_SECRET`. The gateway detects this credential, creates a service account identity, and forwards the request with appropriate context headers.
|
|
393
|
+
|
|
394
|
+
<MermaidDiagram
|
|
395
|
+
title="Service-to-Service Authentication"
|
|
396
|
+
height="450px"
|
|
397
|
+
code={`sequenceDiagram
|
|
398
|
+
participant SvcA as Service A
|
|
399
|
+
participant Gateway
|
|
400
|
+
participant SvcB as Service B
|
|
401
|
+
|
|
402
|
+
SvcA->>Gateway: GET /api/service-b/data\\nAuthorization: Bearer SERVICE_ACCESS_SECRET
|
|
403
|
+
Note over Gateway: AuthGuard detects SERVICE_ACCESS_SECRET\\nCreates service account identity
|
|
404
|
+
Gateway->>SvcB: GET /api/service-b/data\\n+ x-forwarded-user: service-a
|
|
405
|
+
SvcB-->>Gateway: Response
|
|
406
|
+
Gateway-->>SvcA: Response`}
|
|
407
|
+
/>
|
|
408
|
+
</TabItem>
|
|
409
|
+
</Tabs>
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
413
|
+
## Micro-Frontend Loading
|
|
414
|
+
|
|
415
|
+
The shell and feature UIs are loaded dynamically using single-spa and ES Module import maps. The gateway's orchestrator service generates the bootstrap HTML that wires together all registered UI modules at runtime, so new micro-frontends can be added to the catalog without rebuilding the shell.
|
|
416
|
+
|
|
417
|
+
<MermaidDiagram
|
|
418
|
+
title="Micro-Frontend Bootstrap and Runtime Loading"
|
|
419
|
+
height="700px"
|
|
420
|
+
code={`sequenceDiagram
|
|
421
|
+
participant B as Browser
|
|
422
|
+
participant GW as Gateway
|
|
423
|
+
participant Orch as OrchestratorService
|
|
424
|
+
participant Cat as Catalog
|
|
425
|
+
participant Shell as Shell UI
|
|
426
|
+
participant MFE as Feature UI (MFE)
|
|
427
|
+
|
|
428
|
+
B->>GW: GET / (initial page load)
|
|
429
|
+
GW->>Orch: Generate HTML for shell route
|
|
430
|
+
Orch->>Cat: Get all UI modules (type=app/tool/utility)
|
|
431
|
+
Cat-->>Orch: [shell-ui, admin-ui, crm-ui, ...]
|
|
432
|
+
Orch-->>GW: HTML with:\\n- ES Module import maps\\n- single-spa bootstrap script\\n- window.__PAE_GLOBAL_STATE__
|
|
433
|
+
GW-->>B: HTML document
|
|
434
|
+
|
|
435
|
+
Note over B: Browser parses import maps,\\nloads single-spa runtime
|
|
436
|
+
|
|
437
|
+
B->>GW: GET /shell-ui/pae-shell-ui.js
|
|
438
|
+
GW->>Shell: Proxy to Shell UI server :9004
|
|
439
|
+
Shell-->>B: Shell bundle (React + single-spa lifecycle)
|
|
440
|
+
|
|
441
|
+
Note over B: Shell mounts, renders layout\\nUser navigates to /crm
|
|
442
|
+
|
|
443
|
+
B->>GW: GET /crm-ui/mycompany-crm-ui.js
|
|
444
|
+
GW->>MFE: Proxy to CRM UI server
|
|
445
|
+
MFE-->>B: CRM bundle
|
|
446
|
+
|
|
447
|
+
Note over B: single-spa mounts CRM app\\ninto #pae-shell-ui-content`}
|
|
448
|
+
/>
|
|
449
|
+
|
|
450
|
+
---
|
|
451
|
+
|
|
452
|
+
## Security Architecture
|
|
453
|
+
|
|
454
|
+
### Authentication Flow (OAuth 2.0 / PKCE)
|
|
455
|
+
|
|
456
|
+
The platform uses the Authorization Code flow with PKCE for browser-based authentication. The gateway acts as the OAuth client, exchanging codes for tokens with the identity provider and issuing a signed platform JWT stored in an HTTP-only cookie. No OAuth tokens are ever sent to the browser.
|
|
457
|
+
|
|
458
|
+
<MermaidDiagram
|
|
459
|
+
title="OAuth 2.0 PKCE Authentication Flow"
|
|
460
|
+
height="650px"
|
|
461
|
+
code={`sequenceDiagram
|
|
462
|
+
participant B as Browser
|
|
463
|
+
participant GW as Gateway
|
|
464
|
+
participant IDP as Identity Provider\\n(Okta / EntraId / etc.)
|
|
465
|
+
participant DB as PostgreSQL
|
|
466
|
+
|
|
467
|
+
B->>GW: GET /auth/login?provider=okta
|
|
468
|
+
GW->>GW: Generate PKCE code_verifier + code_challenge\\nGenerate state token (CSRF protection)
|
|
469
|
+
GW-->>B: 302 Redirect to IDP /authorize
|
|
470
|
+
B->>IDP: GET /authorize?client_id=...&code_challenge=...&state=...
|
|
471
|
+
IDP-->>B: Login page
|
|
472
|
+
B->>IDP: Credentials + MFA
|
|
473
|
+
IDP-->>B: 302 to /auth/callback?code=XXX&state=YYY
|
|
474
|
+
B->>GW: GET /auth/callback?code=XXX&state=YYY
|
|
475
|
+
GW->>GW: Validate state token
|
|
476
|
+
GW->>IDP: POST /token (code + code_verifier + client_secret)
|
|
477
|
+
IDP-->>GW: { access_token, id_token, refresh_token }
|
|
478
|
+
GW->>IDP: GET /userinfo (Bearer access_token)
|
|
479
|
+
IDP-->>GW: { sub, email, name, groups }
|
|
480
|
+
GW->>DB: Upsert user record + sync group memberships
|
|
481
|
+
GW->>GW: Sign platform JWT with configured secret
|
|
482
|
+
GW-->>B: Set-Cookie: auth_token=JWT (httpOnly, secure, sameSite=Lax)
|
|
483
|
+
GW-->>B: 302 Redirect to /`}
|
|
484
|
+
/>
|
|
485
|
+
|
|
486
|
+
### Authorization Flow
|
|
487
|
+
|
|
488
|
+
```
|
|
489
|
+
1. Request arrives at gateway
|
|
490
|
+
2. Gateway extracts user from JWT
|
|
491
|
+
3. Gateway checks for user's allowed resources
|
|
492
|
+
4. Gateway resolves target module from catalog
|
|
493
|
+
5. Gateway checks if user has required operations
|
|
494
|
+
6. Gateway evaluates rules
|
|
495
|
+
7. If authorized, request proxied to service
|
|
496
|
+
8. Service receives user context via headers
|
|
497
|
+
9. Service performs additional authorization if needed
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
---
|
|
501
|
+
|
|
502
|
+
## Catalog and Bootstrap Lifecycle
|
|
503
|
+
|
|
504
|
+
The catalog drives all routing and authorization decisions at runtime. It is populated during the bootstrap phase by a one-time service that registers modules, roles, and operations via the gateway REST API. At runtime the catalog is served from an in-memory cache that is invalidated whenever a catalog entry is updated through the API.
|
|
505
|
+
|
|
506
|
+
<MermaidDiagram
|
|
507
|
+
title="Catalog Bootstrap and Runtime Cache Lifecycle"
|
|
508
|
+
height="650px"
|
|
509
|
+
code={`flowchart TD
|
|
510
|
+
subgraph BOOTSTRAP["Bootstrap Phase (run-once at startup)"]
|
|
511
|
+
BS["Bootstrap Service"]
|
|
512
|
+
JSON["Module definitions\\nRoles and Operations\\nInitial users"]
|
|
513
|
+
BS -->|reads| JSON
|
|
514
|
+
BS -->|"POST /catalog\\n(SERVICE_ACCESS_SECRET)"| GW_API["Gateway REST API"]
|
|
515
|
+
GW_API -->|INSERT| DB_CAT[("catalog table\\nPostgreSQL")]
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
subgraph RUNTIME["Runtime Phase"]
|
|
519
|
+
REQ["Incoming Request\\nGET /api/orders/123"]
|
|
520
|
+
CAT_SVC["CatalogService"]
|
|
521
|
+
CACHE["In-Memory Cache"]
|
|
522
|
+
DB_RT[("PostgreSQL")]
|
|
523
|
+
RESOLVE["resolveTargetModule()\\nLongest prefix match"]
|
|
524
|
+
TARGET["orders-service\\nhttp://orders:4001"]
|
|
525
|
+
|
|
526
|
+
REQ --> CAT_SVC
|
|
527
|
+
CAT_SVC -->|cache hit| CACHE
|
|
528
|
+
CACHE -.->|cache miss| DB_RT
|
|
529
|
+
DB_RT -.->|populate cache| CACHE
|
|
530
|
+
CAT_SVC --> RESOLVE --> TARGET
|
|
531
|
+
end
|
|
532
|
+
|
|
533
|
+
subgraph INVALIDATION["Cache Invalidation"]
|
|
534
|
+
API_UPDATE["PUT /catalog/:id"]
|
|
535
|
+
EE["EventEmitter2\\ncatalog:changed"]
|
|
536
|
+
FLUSH["Flush in-memory cache"]
|
|
537
|
+
|
|
538
|
+
API_UPDATE --> EE --> FLUSH
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
DB_CAT -.->|loaded on startup| CACHE`}
|
|
542
|
+
/>
|
|
543
|
+
|
|
544
|
+
---
|
|
545
|
+
|
|
546
|
+
## Multi-Tenancy
|
|
547
|
+
|
|
548
|
+
Each request is scoped to a specific tenant resolved from the incoming hostname or headers. The gateway propagates tenant identity to downstream services via base64-encoded forwarded headers. Services built with the platform SDK extract these headers automatically to enforce row-level tenant isolation in database queries.
|
|
549
|
+
|
|
550
|
+
<MermaidDiagram
|
|
551
|
+
title="Multi-Tenant Request Isolation"
|
|
552
|
+
height="400px"
|
|
553
|
+
code={`flowchart LR
|
|
554
|
+
subgraph REQUEST["Incoming Request"]
|
|
555
|
+
R["GET /api/orders\\nHost: acme.platform.com\\nCookie: auth_token=JWT{tenantId:'acme'}"]
|
|
556
|
+
end
|
|
557
|
+
subgraph GATEWAY["Gateway Processing"]
|
|
558
|
+
TR["Tenant Resolver\\nsubdomain to 'acme'"]
|
|
559
|
+
CTX["Platform Context\\ntenant: acme\\nuser: john@acme.com"]
|
|
560
|
+
HDR["Forwarded Headers\\nx-forwarded-tenant: base64(acme)\\nx-forwarded-user: john@acme.com\\nx-forwarded-user-operations: orders.read"]
|
|
561
|
+
end
|
|
562
|
+
subgraph SERVICE["Backend Service"]
|
|
563
|
+
MW["SDK Auth Middleware\\nreads x-forwarded-* headers\\nbuilds req.user + req.tenant"]
|
|
564
|
+
QUERY["DB Query\\nWHERE tenant_id = 'acme'"]
|
|
565
|
+
RESULT["Tenant-isolated\\nresults"]
|
|
566
|
+
end
|
|
567
|
+
R --> TR --> CTX --> HDR --> MW --> QUERY --> RESULT`}
|
|
568
|
+
/>
|
|
569
|
+
|
|
570
|
+
---
|
|
571
|
+
|
|
572
|
+
## Technology Stack
|
|
573
|
+
|
|
574
|
+
### Backend Technologies
|
|
575
|
+
|
|
576
|
+
<CardGrid stagger>
|
|
577
|
+
<Card title="NestJS 10.x" icon="seti:nestjs">
|
|
578
|
+
Enterprise framework for scalable Node.js applications with dependency injection, decorators, and modular architecture
|
|
579
|
+
</Card>
|
|
580
|
+
|
|
581
|
+
<Card title="Fastify 4.x" icon="rocket">
|
|
582
|
+
High-performance HTTP server with HTTP/2, WebSocket support, and built-in schema validation
|
|
583
|
+
</Card>
|
|
584
|
+
|
|
585
|
+
<Card title="Express 4.x" icon="seti:javascript">
|
|
586
|
+
Minimal and flexible web framework for lightweight microservices
|
|
587
|
+
</Card>
|
|
588
|
+
|
|
589
|
+
<Card title="TypeScript 5.8" icon="seti:typescript">
|
|
590
|
+
Strongly-typed JavaScript with advanced type system for better developer experience
|
|
591
|
+
</Card>
|
|
592
|
+
|
|
593
|
+
<Card title="PostgreSQL 15+" icon="seti:db">
|
|
594
|
+
Robust relational database with JSONB support for flexible schemas
|
|
595
|
+
</Card>
|
|
596
|
+
|
|
597
|
+
<Card title="Knex.js" icon="seti:db">
|
|
598
|
+
SQL query builder with migrations and transaction support
|
|
599
|
+
</Card>
|
|
600
|
+
|
|
601
|
+
<Card title="Passport.js" icon="approve-check">
|
|
602
|
+
Flexible authentication middleware with strategies for OAuth, JWT, API keys
|
|
603
|
+
</Card>
|
|
604
|
+
|
|
605
|
+
<Card title="Apache Kafka" icon="seti:config">
|
|
606
|
+
Distributed event streaming for asynchronous communication between services
|
|
607
|
+
</Card>
|
|
608
|
+
</CardGrid>
|
|
609
|
+
|
|
610
|
+
### Frontend Technologies
|
|
611
|
+
|
|
612
|
+
<CardGrid stagger>
|
|
613
|
+
<Card title="React 18" icon="seti:react">
|
|
614
|
+
Modern UI library with concurrent rendering and automatic batching
|
|
615
|
+
</Card>
|
|
616
|
+
|
|
617
|
+
<Card title="single-spa" icon="puzzle">
|
|
618
|
+
Micro-frontend framework for composing multiple applications into one
|
|
619
|
+
</Card>
|
|
620
|
+
|
|
621
|
+
<Card title="Webpack 5" icon="seti:webpack">
|
|
622
|
+
Module bundler with code splitting and federation for micro-frontends
|
|
623
|
+
</Card>
|
|
624
|
+
|
|
625
|
+
<Card title="React Query" icon="seti:graphql">
|
|
626
|
+
Powerful data fetching and state management for server state
|
|
627
|
+
</Card>
|
|
628
|
+
|
|
629
|
+
<Card title="React Router 6" icon="random">
|
|
630
|
+
Declarative routing for React applications
|
|
631
|
+
</Card>
|
|
632
|
+
</CardGrid>
|
|
633
|
+
|
|
634
|
+
### Infrastructure
|
|
635
|
+
|
|
636
|
+
<CardGrid>
|
|
637
|
+
<Card title="Docker" icon="seti:docker">
|
|
638
|
+
Containerization for consistent deployment across environments
|
|
639
|
+
</Card>
|
|
640
|
+
|
|
641
|
+
<Card title="Turborepo" icon="seti:config">
|
|
642
|
+
Monorepo build system with intelligent caching and parallel execution
|
|
643
|
+
</Card>
|
|
644
|
+
|
|
645
|
+
<Card title="Node.js 20+" icon="seti:nodejs">
|
|
646
|
+
JavaScript runtime with ES modules and modern JavaScript features
|
|
647
|
+
</Card>
|
|
648
|
+
|
|
649
|
+
<Card title="npm Workspaces" icon="seti:npm">
|
|
650
|
+
Monorepo package management with shared dependencies
|
|
651
|
+
</Card>
|
|
652
|
+
</CardGrid>
|
|
653
|
+
|
|
654
|
+
---
|
|
655
|
+
|
|
656
|
+
## Design Principles
|
|
657
|
+
|
|
658
|
+
### 1. Separation of Concerns
|
|
659
|
+
|
|
660
|
+
Each component has a clear responsibility:
|
|
661
|
+
- **Gateway**: Authentication, authorization, routing
|
|
662
|
+
- **Services**: Business logic and data persistence
|
|
663
|
+
- **UIs**: User interaction and presentation
|
|
664
|
+
- **Libraries**: Shared utilities and components
|
|
665
|
+
|
|
666
|
+
### 2. Single Responsibility
|
|
667
|
+
|
|
668
|
+
Services and modules focus on specific domains:
|
|
669
|
+
- Habits Service → Habit tracking
|
|
670
|
+
- Scheduler Service → Scheduling
|
|
671
|
+
- Admin UI → Platform administration
|
|
672
|
+
|
|
673
|
+
### 3. API Gateway Pattern
|
|
674
|
+
|
|
675
|
+
All external traffic flows through the gateway:
|
|
676
|
+
- Centralized authentication and authorization
|
|
677
|
+
- Consistent error handling and logging
|
|
678
|
+
- Rate limiting and throttling
|
|
679
|
+
- Request tracing and monitoring
|
|
680
|
+
|
|
681
|
+
### 4. Micro-Frontend Architecture
|
|
682
|
+
|
|
683
|
+
UIs are independently deployable:
|
|
684
|
+
- Teams can work autonomously
|
|
685
|
+
- Deploy features without full application rebuild
|
|
686
|
+
- Technology diversity (if needed)
|
|
687
|
+
- Incremental upgrades
|
|
688
|
+
|
|
689
|
+
### 5. Security in Depth
|
|
690
|
+
|
|
691
|
+
Multiple layers of security:
|
|
692
|
+
- SSL/TLS encryption
|
|
693
|
+
- JWT authentication
|
|
694
|
+
- Operation-based authorization
|
|
695
|
+
- Tenant isolation
|
|
696
|
+
|
|
697
|
+
---
|
|
698
|
+
|
|
699
|
+
## Monitoring and Observability
|
|
700
|
+
|
|
701
|
+
<CardGrid>
|
|
702
|
+
<Card title="Logging" icon="seti:text">
|
|
703
|
+
Structured JSON logs with correlation IDs for request tracing
|
|
704
|
+
</Card>
|
|
705
|
+
|
|
706
|
+
<Card title="Metrics" icon="seti:graphql">
|
|
707
|
+
OpenTelemetry integration for distributed tracing
|
|
708
|
+
</Card>
|
|
709
|
+
|
|
710
|
+
<Card title="Health Checks" icon="approve-check">
|
|
711
|
+
All services expose health endpoints
|
|
712
|
+
</Card>
|
|
713
|
+
|
|
714
|
+
<Card title="Audit Trail" icon="seti:lock">
|
|
715
|
+
All mutations logged with user and timestamp
|
|
716
|
+
</Card>
|
|
717
|
+
</CardGrid>
|
|
718
|
+
|
|
719
|
+
---
|
|
720
|
+
|
|
721
|
+
## Deployment Architecture
|
|
722
|
+
|
|
723
|
+
The platform can be deployed in various configurations:
|
|
724
|
+
|
|
725
|
+
<Tabs>
|
|
726
|
+
<TabItem label="Development">
|
|
727
|
+
```
|
|
728
|
+
Local Development:
|
|
729
|
+
- Docker Compose for all services
|
|
730
|
+
- Hot reload for services and UIs
|
|
731
|
+
- Local PostgreSQL and Kafka
|
|
732
|
+
- Self-signed SSL certificates
|
|
733
|
+
```
|
|
734
|
+
</TabItem>
|
|
735
|
+
|
|
736
|
+
<TabItem label="Staging">
|
|
737
|
+
```
|
|
738
|
+
Staging Environment:
|
|
739
|
+
- Kubernetes cluster (EKS, GKE, AKS)
|
|
740
|
+
- Managed PostgreSQL (RDS, Cloud SQL)
|
|
741
|
+
- Managed Kafka (MSK, Confluent Cloud)
|
|
742
|
+
- SSL certificates from Let's Encrypt
|
|
743
|
+
- Single replica per service
|
|
744
|
+
```
|
|
745
|
+
</TabItem>
|
|
746
|
+
|
|
747
|
+
<TabItem label="Production">
|
|
748
|
+
```
|
|
749
|
+
Production Environment:
|
|
750
|
+
- Multi-region Kubernetes
|
|
751
|
+
- PostgreSQL with read replicas
|
|
752
|
+
- Kafka cluster with replication
|
|
753
|
+
- CDN for static assets (CloudFront, Cloudflare)
|
|
754
|
+
- Auto-scaling based on metrics
|
|
755
|
+
- Multiple replicas per service
|
|
756
|
+
- Backup and disaster recovery
|
|
757
|
+
```
|
|
758
|
+
</TabItem>
|
|
759
|
+
</Tabs>
|
|
760
|
+
|
|
761
|
+
---
|
|
762
|
+
|
|
763
|
+
## Next Steps
|
|
764
|
+
|
|
765
|
+
Explore the detailed architecture documentation:
|
|
766
|
+
|
|
767
|
+
- **[Gateway Architecture](/_/docs/architecture/gateway-architecture/)** - Deep dive into the gateway service, guard chain, and proxy configuration
|
|
768
|
+
- **[Authentication System](/_/docs/architecture/authentication-system/)** - Authentication flows and IDP integration
|
|
769
|
+
- **[Authorization System](/_/docs/architecture/authorization-system/)** - RBAC model and permission checking
|
|
770
|
+
- **[Multi-Tenancy](/_/docs/architecture/multi-tenancy/)** - Tenant isolation and context management
|
|
771
|
+
- **[API Explorer](/_/docs/architecture/api-explorer/)** - Interactive API documentation and testing
|
|
772
|
+
- **[Bootstrap](/_/docs/architecture/bootstrap/)** - Platform bootstrap process and configuration
|
|
773
|
+
- **[Scheduler Service](/_/docs/architecture/scheduler/)** - Job scheduling and recurring task management
|
|
774
|
+
- **[Shell UI](/_/docs/architecture/shell/)** - Platform shell architecture and customization
|
|
775
|
+
- **[UI Extension Points](/_/docs/architecture/ui-extension-points/)** - UI extension mechanism and patterns
|
|
776
|
+
- **[User States](/_/docs/architecture/user-states/)** - User-specific state storage and preferences
|