@bluealba/platform-cli 1.0.0 → 1.0.2

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.
Files changed (42) hide show
  1. package/dist/index.js +351 -18
  2. package/docs/404.mdx +5 -0
  3. package/docs/architecture/api-explorer.mdx +478 -0
  4. package/docs/architecture/architecture-diagrams.mdx +12 -0
  5. package/docs/architecture/authentication-system.mdx +903 -0
  6. package/docs/architecture/authorization-system.mdx +886 -0
  7. package/docs/architecture/bootstrap.mdx +1442 -0
  8. package/docs/architecture/gateway-architecture.mdx +845 -0
  9. package/docs/architecture/multi-tenancy.mdx +1150 -0
  10. package/docs/architecture/overview.mdx +776 -0
  11. package/docs/architecture/scheduler.mdx +818 -0
  12. package/docs/architecture/shell.mdx +885 -0
  13. package/docs/architecture/ui-extension-points.mdx +781 -0
  14. package/docs/architecture/user-states.mdx +794 -0
  15. package/docs/development/overview.mdx +21 -0
  16. package/docs/development/workflow.mdx +914 -0
  17. package/docs/getting-started/core-concepts.mdx +892 -0
  18. package/docs/getting-started/installation.mdx +780 -0
  19. package/docs/getting-started/overview.mdx +83 -0
  20. package/docs/getting-started/quick-start.mdx +940 -0
  21. package/docs/guides/adding-documentation-sites.mdx +1367 -0
  22. package/docs/guides/creating-services.mdx +1736 -0
  23. package/docs/guides/creating-ui-modules.mdx +1860 -0
  24. package/docs/guides/identity-providers.mdx +1007 -0
  25. package/docs/guides/mermaid-diagrams.mdx +212 -0
  26. package/docs/guides/using-feature-flags.mdx +1059 -0
  27. package/docs/guides/working-with-rooms.mdx +566 -0
  28. package/docs/index.mdx +57 -0
  29. package/docs/platform-cli/commands.mdx +604 -0
  30. package/docs/platform-cli/overview.mdx +195 -0
  31. package/package.json +5 -2
  32. package/skills/ba-platform/platform-cli.skill.md +26 -0
  33. package/skills/ba-platform/platform.skill.md +35 -0
  34. package/templates/application-monorepo-template/gitignore +95 -0
  35. package/templates/bootstrap-service-template/gitignore +57 -0
  36. package/templates/bootstrap-service-template/src/main.ts +6 -16
  37. package/templates/customization-ui-module-template/gitignore +73 -0
  38. package/templates/nestjs-service-module-template/gitignore +56 -0
  39. package/templates/platform-init-template/{{platformName}}-core/gitignore +97 -0
  40. package/templates/react-ui-module-template/Dockerfile +1 -1
  41. package/templates/react-ui-module-template/caddy/Caddyfile +1 -1
  42. package/templates/react-ui-module-template/gitignore +72 -0
@@ -0,0 +1,892 @@
1
+ ---
2
+ title: Core Concepts
3
+ description: Essential concepts of the Blue Alba Platform - Applications, Modules, Operations, Roles, Rules, Tenants, and Catalog
4
+ ---
5
+
6
+ import { Card, CardGrid, Aside, Tabs, TabItem } from '@astrojs/starlight/components';
7
+
8
+ Understanding these core concepts is essential for working effectively with the Blue Alba Platform. These building blocks form the foundation of the platform's architecture and authorization system.
9
+
10
+ ## Platform Building Blocks
11
+
12
+ <CardGrid stagger>
13
+ <Card title="Applications" icon="seti:folder">
14
+ Logical groupings of related functionality that users interact with. Examples: "Customer Portal", "Admin Console", "Analytics Dashboard".
15
+ </Card>
16
+
17
+ <Card title="Modules" icon="puzzle">
18
+ Deployable units of code - either a backend service or frontend UI. Modules belong to Applications and can be shared across them.
19
+ </Card>
20
+
21
+ <Card title="Operations" icon="approve-check">
22
+ The most granular level of permissions. Every action a user can perform (read, write, delete, approve) is an Operation.
23
+ </Card>
24
+
25
+ <Card title="Roles" icon="seti:config">
26
+ Collections of Operations that define what a user can do. Examples: "Admin", "Viewer", "Editor".
27
+ </Card>
28
+
29
+ <Card title="Rules" icon="seti:license">
30
+ Authorization logic that allows or denies Operations based on conditions. Rules implement business authorization logic.
31
+ </Card>
32
+
33
+ <Card title="Tenants" icon="codeberg">
34
+ Isolated instances of the platform for different customers or organizations. Each tenant has separate data, users, and configurations.
35
+ </Card>
36
+
37
+ <Card title="Catalog" icon="open-book">
38
+ Dynamic registry of Applications and Modules that enables runtime discovery and routing of services.
39
+ </Card>
40
+
41
+ <Card title="Platform Context" icon="seti:json">
42
+ Request-scoped information about the current tenant, user, and application being accessed.
43
+ </Card>
44
+ </CardGrid>
45
+
46
+ ---
47
+
48
+ ## Applications
49
+
50
+ **Applications** are the highest-level organizational concept in the platform. They represent logical groupings of functionality that make sense to end users.
51
+
52
+ ### What is an Application?
53
+
54
+ An Application is:
55
+ - A **named collection** of related features (e.g., "Customer Portal", "Administration")
56
+ - A **logical grouping** of one or more Modules (UIs and services)
57
+ - A **unit of access control** - users are granted access to Applications
58
+ - An **entry point** in the navigation menu
59
+
60
+ ### Application Structure
61
+
62
+ ```typescript
63
+ interface Application {
64
+ id: string;
65
+ name: string; // Unique identifier (e.g., "admin-portal")
66
+ displayName: string;
67
+ description: string;
68
+ modules: Module[]; // Associated modules
69
+ allowedByDefault: boolean; // Application visible to all users without manual assignment
70
+ }
71
+ ```
72
+
73
+ ### Example Applications
74
+
75
+ <Tabs>
76
+ <TabItem label="Administration">
77
+ **Application**: Platform Administration
78
+
79
+ **Purpose**: Manage users, roles, applications, and platform configuration
80
+
81
+ **Modules**:
82
+ - Admin UI (frontend)
83
+ - User Management Service (backend)
84
+ - Application Catalog Service (backend)
85
+ </TabItem>
86
+
87
+ <TabItem label="Customer Portal">
88
+ **Application**: Customer Self-Service Portal
89
+
90
+ **Purpose**: Allow customers to view orders, submit tickets, manage profile
91
+
92
+ **Modules**:
93
+ - Customer Portal UI (frontend)
94
+ - Orders Service (backend)
95
+ - Ticketing Service (backend)
96
+ </TabItem>
97
+
98
+ <TabItem label="Analytics">
99
+ **Application**: Analytics Dashboard
100
+
101
+ **Purpose**: View business metrics and reports
102
+
103
+ **Modules**:
104
+ - Analytics UI (frontend)
105
+ - Reporting Service (backend)
106
+ </TabItem>
107
+ </Tabs>
108
+
109
+ <Aside type="tip">
110
+ Think of Applications as the items you see in the main navigation menu. Each Application groups related features that users access together.
111
+ </Aside>
112
+
113
+ ---
114
+
115
+ ## Modules
116
+
117
+ **Modules** are the deployable units of code - the actual services and UIs that make up your platform.
118
+
119
+ ### What is a Module?
120
+
121
+ A Module is:
122
+ - A **deployable artifact** (a service or UI application)
123
+ - Either a **backend service** (microservice) or **frontend UI** (micro-frontend)
124
+ - A **registered entity** in the application catalog
125
+ - A **route target** that the gateway can proxy to
126
+
127
+ ### Module Types
128
+
129
+ There are six types of modules:
130
+
131
+ **UI Modules** (Frontend) [app]
132
+ - React-based micro-frontends
133
+ - Loaded dynamically by the Shell UI
134
+ - Built with `pae-ui-react-sdk`
135
+ - Examples: Customer Portal UI, CRM UI
136
+
137
+ **Tool Modules** (Frontend) [tool]
138
+ - React-based micro-frontends that provide platform utilities and administration features
139
+ - Appear in the navbar tools section rather than the application selector
140
+ - Built with `pae-ui-react-sdk`
141
+ - Examples: Admin UI, Documentation UI
142
+
143
+ **Service Modules** (Backend) [service]
144
+ - NestJS or Express-based microservices
145
+ - Registered with the gateway
146
+ - Handle business logic and data persistence
147
+ - Examples: Habits Service, Scheduler Service
148
+
149
+ **Utility** (Frontend) [utility]
150
+ - React-based micro-frontends
151
+ - It is loaded by the browser but is not mounted on a DOM element.
152
+ - Provides reusable elements such as components, styles, and utility functions.
153
+ - Examples: pae-ui-react-core
154
+
155
+ **Cloud Function** (Backend) [cloud-function]
156
+ - Support for running serverless functions
157
+
158
+ **Documentation Modules** (Documentation) [documentation]
159
+ - Documentation sites created using the [Blue Alba Platform Documentation Template](/_/docs/guides/adding-documentation-sites/).
160
+
161
+ ### Module Structure
162
+
163
+ ```typescript
164
+ interface Module {
165
+ name: string; // Unique identifier
166
+ displayName: string;
167
+ description: string;
168
+ type: 'app' | 'tool' | 'service' | 'utility' | 'cloud-function' | 'documentation'; // Module type
169
+
170
+ applicationId: string; // Parent application
171
+ baseUrl: string;
172
+ host: string;
173
+ port: number;
174
+
175
+ dependsOn: string[];
176
+
177
+ // Only for 'app' and 'tool' types
178
+ ui: {
179
+ "route": string;
180
+ "mountAtSelector": "#pae-shell-ui-content",
181
+ "bundleFile": string; // file path
182
+ "customProps": {}
183
+ }
184
+
185
+ authorization: {
186
+ "operations": string[];
187
+ "routes": {}
188
+ }
189
+
190
+ }
191
+ ```
192
+
193
+ ### Module Registration
194
+
195
+ Modules register themselves with the gateway's catalog on startup:
196
+
197
+ <Tabs>
198
+ <TabItem label="Service Module">
199
+ ```typescript
200
+ // In a backend service
201
+ const module = {
202
+ code: 'habits-service',
203
+ name: 'Habits Tracking Service',
204
+ type: 'SERVICE',
205
+ applicationId: 'habits-app',
206
+ serviceUrl: 'http://pae-habits-service:4002',
207
+ routes: [
208
+ { path: '/habits', method: 'GET' },
209
+ { path: '/habits/:id', method: 'GET' },
210
+ { path: '/habits', method: 'POST' }
211
+ ]
212
+ };
213
+
214
+ // Register with catalog
215
+ await catalogClient.registerModule(module);
216
+ ```
217
+ </TabItem>
218
+
219
+ <TabItem label="UI Module">
220
+ ```typescript
221
+ // In a frontend UI
222
+ const module = {
223
+ code: 'habits-ui',
224
+ name: 'Habits UI',
225
+ type: 'UI',
226
+ applicationId: 'habits-app',
227
+ entryPoint: 'http://localhost:8081/main.js',
228
+ containerElement: '#habits-app-container'
229
+ };
230
+
231
+ // Register with catalog
232
+ await catalogClient.registerModule(module);
233
+ ```
234
+ </TabItem>
235
+
236
+ <TabItem label="Documentation Module">
237
+ ```typescript
238
+ // In a documentation service
239
+ const module = {
240
+ code: 'app-documentation',
241
+ name: 'App Documentation',
242
+ type: 'DOCUMENTATION',
243
+ applicationId: 'app-documentation',
244
+ baseUrl: '/app/docs',
245
+ routes: [
246
+ { path: '/habits', method: 'GET' },
247
+ { path: '/habits/:id', method: 'GET' },
248
+ { path: '/habits', method: 'POST' }
249
+ ],
250
+ service: {
251
+ host: "pae-sandbox-documentation",
252
+ port: 80
253
+ },
254
+ dependsOn: [
255
+ "@bluealba/pae-shell-ui"
256
+ ]
257
+ };
258
+
259
+ // Register with catalog
260
+ await catalogClient.registerModule(module);
261
+ ```
262
+ </TabItem>
263
+ </Tabs>
264
+
265
+ ---
266
+
267
+ ## Operations
268
+
269
+ **Operations** represent the most granular level of permissions in the platform. Every action that requires authorization is an Operation.
270
+
271
+ ### What is an Operation?
272
+
273
+ An Operation is:
274
+ - A **specific permission** (e.g., "users.read", "orders.create", "reports.delete")
275
+ - The **smallest unit** of authorization
276
+ - A **building block** for Roles
277
+ - Typically **verb-based** (read, write, update, delete, approve, etc.)
278
+
279
+ ### Operation Naming Convention
280
+
281
+ Operations follow a hierarchical naming pattern using double colons (::):
282
+
283
+ ```
284
+ {domain}::{resource}::{action}[.{modifier}]
285
+
286
+ #### Structure
287
+
288
+ - **domain**: Functional area of the system (e.g., authorization, authentication, documentation)
289
+ - **resource**: Specific entity within the domain (e.g., role, auth-methods, impersonation)
290
+ - **action**: Operation to perform (e.g., delete, manage, read, config)
291
+ - **modifier (optional)**: Additional qualifier to specify scope or context
292
+
293
+ Examples:
294
+ - `authorization::role::delete` - Delete roles from the authorization system
295
+ - `authorization::role::manage-operations` - Manage operations assigned to specific roles
296
+ - `documentation::access` - Access system documentation
297
+
298
+ ### Operation Structure
299
+
300
+ ```typescript
301
+ interface Operation {
302
+ id: string;
303
+ name: string; // e.g., "users::read"
304
+ description: string;
305
+ applicationId: string; // Which app this belongs to
306
+ }
307
+ ```
308
+
309
+ ### Using Operations in Code
310
+
311
+ Operations are checked throughout the platform:
312
+
313
+ <Tabs>
314
+ <TabItem label="Frontend (React)">
315
+ ```typescript
316
+ import { useAuth } from '@bluealba/pae-ui-react-core';
317
+
318
+ function UserManagement() {
319
+ const { hasAccess } = useAuth();
320
+
321
+ const canRead = hasAccess('users.read');
322
+ const canWrite = hasAccess('users.write');
323
+ const canDelete = hasAccess('users.delete');
324
+
325
+ return (
326
+ <div>
327
+ {canRead && <UserList />}
328
+ {canWrite && <CreateUserButton />}
329
+ {canDelete && <DeleteUserButton />}
330
+ </div>
331
+ );
332
+ }
333
+ ```
334
+ </TabItem>
335
+ </Tabs>
336
+
337
+ <Aside>
338
+ **Best Practice**: Define Operations at a granular level. It's easier to combine fine-grained Operations into Roles than to split coarse-grained ones later.
339
+ </Aside>
340
+
341
+ ---
342
+
343
+ ## Roles
344
+
345
+ **Roles** are collections of Operations that define what a user can do in the system.
346
+
347
+ ### What is a Role?
348
+
349
+ A Role is:
350
+ - A **named collection** of Operations
351
+ - A **permission set** assigned to users
352
+ - A **template** for common access patterns
353
+ - **Reusable** across different users and groups
354
+
355
+ ### Role Structure
356
+
357
+ ```typescript
358
+ interface Role {
359
+ id: string;
360
+ name: string; // e.g., "admin", "viewer"
361
+ description: string;
362
+ applicationId: string; // Which app this role applies to
363
+ operations: Operation[]; // Granted operations
364
+ }
365
+ ```
366
+
367
+ ### Common Role Patterns
368
+
369
+ <CardGrid>
370
+ <Card title="Admin Role" icon="star">
371
+ **Operations**: All operations for an application
372
+
373
+ **Use Case**: System administrators who need full access
374
+
375
+ **Example**:
376
+ - `users::*` (all user operations)
377
+ - `orders::*` (all order operations)
378
+ - `settings::*` (all settings operations)
379
+ </Card>
380
+
381
+ <Card title="Viewer Role" icon="open-book">
382
+ **Operations**: Only read operations
383
+
384
+ **Use Case**: Users who need to view data but not modify it
385
+
386
+ **Example**:
387
+ - `users::read`
388
+ - `orders::read`
389
+ - `reports::read`
390
+ </Card>
391
+
392
+ <Card title="Editor Role" icon="pencil">
393
+ **Operations**: Read and write operations (but not delete)
394
+
395
+ **Use Case**: Users who can create and update data
396
+
397
+ **Example**:
398
+ - `users::read`
399
+ - `users::write`
400
+ - `orders::read`
401
+ - `orders::write`
402
+ </Card>
403
+
404
+ <Card title="Custom Role" icon="setting">
405
+ **Operations**: Specific subset for business needs
406
+
407
+ **Use Case**: Specialized roles for unique workflows
408
+
409
+ **Example** (Approver):
410
+ - `orders::read`
411
+ - `orders::approve`
412
+ - `orders::reject`
413
+ </Card>
414
+ </CardGrid>
415
+
416
+ ### Role Assignment
417
+
418
+ Users receive Roles in two ways:
419
+
420
+ 1. **Direct Assignment**: Role assigned directly to a user
421
+ 2. **Group Membership**: User belongs to a Group that has the Role
422
+
423
+ ```typescript
424
+ // Direct role assignment
425
+ await userService.assignRole(userId, roleId);
426
+
427
+ // Group-based assignment
428
+ await groupService.addMember(groupId, userId);
429
+ // User automatically gets all roles assigned to the group
430
+ ```
431
+
432
+ <Aside type="tip">
433
+ **Best Practice**: Use Groups for role assignment rather than direct assignment. This makes managing permissions for many users much easier.
434
+ </Aside>
435
+
436
+ ---
437
+
438
+ ## Rules
439
+
440
+ **Rules** are the mechanism that connects authorization concepts together by associating **Resources** with **Subjects**.
441
+
442
+ ### What is a Rule?
443
+
444
+ A Rule is:
445
+ - The **association** between a Resource and a Subject
446
+ - A **grant or deny** decision for access
447
+ - The **building block** of the authorization system
448
+ - How the platform determines **who can access what**
449
+
450
+ ### Key Concepts
451
+
452
+ #### Resources
453
+
454
+ A **Resource** is anything that can be protected by authorization. In the platform, there are three types of Resources:
455
+
456
+ <CardGrid>
457
+ <Card title="Operations" icon="approve-check">
458
+ The most granular resource - a specific permission or action (e.g., `users::read`, `orders::delete`)
459
+ </Card>
460
+
461
+ <Card title="Roles" icon="seti:config">
462
+ A collection of Operations grouped together (e.g., "admin", "viewer")
463
+ </Card>
464
+
465
+ <Card title="Applications" icon="seti:folder">
466
+ A logical grouping of functionality (e.g., "platform", "customer-portal")
467
+ </Card>
468
+ </CardGrid>
469
+
470
+ <Aside type="note">
471
+ You can grant or deny access to any of these three resource types: **Operations**, **Roles**, or **Applications**.
472
+ </Aside>
473
+
474
+ #### Subjects
475
+
476
+ A **Subject** is the target to which access is granted or denied. There are two types of Subjects:
477
+
478
+ <Tabs>
479
+ <TabItem label="User">
480
+ **User**: A specific individual identified by the Identity Provider
481
+
482
+ ```json
483
+ {
484
+ "subjectType": "user",
485
+ "subject": "john.doe@company.com",
486
+ "resourceType": "operation",
487
+ "resource": "orders::read",
488
+ "denied": false
489
+ }
490
+ ```
491
+
492
+ The `subject` field contains the user's identifier (typically their email from the Identity Provider).
493
+
494
+ **Use Case**: Give John Doe access to read orders
495
+ </TabItem>
496
+
497
+ <TabItem label="Group">
498
+ **Group**: Users belonging to a group from the Identity Provider
499
+
500
+ ```json
501
+ {
502
+ "subjectType": "group",
503
+ "subject": "sales-team",
504
+ "resourceType": "application",
505
+ "resource": "reports-app",
506
+ "denied": false
507
+ }
508
+ ```
509
+
510
+ The `subject` field contains the group identifier from the Identity Provider.
511
+
512
+ **Use Case**: Give all members of the Sales Team group access to the Reports application
513
+ </TabItem>
514
+ </Tabs>
515
+
516
+ ### Rule Structure
517
+
518
+ A Rule has the following structure:
519
+
520
+ ```typescript
521
+ interface Rule {
522
+ // Subject: Who is this rule for?
523
+ subjectType: 'user' | 'group';
524
+ subject: string; // User email or group identifier
525
+
526
+ // Resource: What are they getting access to?
527
+ resourceType: 'operation' | 'role' | 'application';
528
+ resource: string; // Resource identifier
529
+
530
+ // Effect: Grant or deny?
531
+ denied: boolean; // false = ALLOW, true = DENY
532
+
533
+ // Tenant scope
534
+ tenantId?: number; // null = global (applies to all tenants)
535
+ }
536
+ ```
537
+
538
+ **Field Descriptions:**
539
+
540
+ | Field | Type | Description | Example |
541
+ |-------|------|-------------|---------|
542
+ | `subjectType` | `"user"` \| `"group"` | Type of subject | `"user"` |
543
+ | `subject` | `string` | User email or group name | `"juan.bruno@bluealba.com"` |
544
+ | `resourceType` | `"operation"` \| `"role"` \| `"application"` | Type of resource | `"application"` |
545
+ | `resource` | `string` | Resource identifier | `"platform"` |
546
+ | `denied` | `boolean` | `false` = ALLOW, `true` = DENY | `false` |
547
+ | `tenantId` | `number` \| `null` | Tenant scope. `null` = global (all tenants) | `1` |
548
+
549
+ ### Tenant-Scoped vs Global Rules
550
+
551
+ Rules can be either **tenant-scoped** or **global**:
552
+
553
+ - **Tenant-scoped** (`tenantId` is set): The rule only applies within that specific tenant. Rules created from the Admin UI are always scoped to the current tenant.
554
+ - **Global** (`tenantId` is `null`): The rule applies across all tenants. In the Admin UI, these are displayed with a "Global" badge.
555
+
556
+ <Aside type="note">
557
+ When deleting a global rule from the Admin UI, a confirmation dialog warns that the deletion will affect all tenants.
558
+ </Aside>
559
+
560
+ ### How Rules Work
561
+
562
+ Rules create associations between Subjects and Resources:
563
+
564
+ ```
565
+ Subject + Resource + Effect = Rule
566
+
567
+ Examples:
568
+ - User "john@company.com" + Operation "orders::read" + ALLOW
569
+ → John can read orders
570
+
571
+ - Group "admins" + Application "admin-portal" + ALLOW
572
+ → All admin group members can access Admin Portal
573
+
574
+ - User "temp@company.com" + Role "admin" + DENY
575
+ → Temp user explicitly cannot have admin role (even if assigned)
576
+ ```
577
+
578
+ ### Rule Examples
579
+
580
+ <Tabs>
581
+ <TabItem label="User → Operation">
582
+ **Grant a user access to a specific operation**
583
+
584
+ ```json
585
+ {
586
+ "subjectType": "user",
587
+ "subject": "developer@company.com",
588
+ "resourceType": "operation",
589
+ "resource": "users::delete",
590
+ "denied": false
591
+ }
592
+ ```
593
+
594
+ **Result**: User `developer@company.com` can delete users
595
+ </TabItem>
596
+
597
+ <TabItem label="Group → Application">
598
+ **Grant a group access to an application**
599
+
600
+ ```json
601
+ {
602
+ "subjectType": "group",
603
+ "subject": "engineering",
604
+ "resourceType": "application",
605
+ "resource": "developer-portal",
606
+ "denied": false
607
+ }
608
+ ```
609
+
610
+ **Result**: All users in the `engineering` group can access the Developer Portal
611
+ </TabItem>
612
+
613
+ <TabItem label="User → Role">
614
+ **Assign a role to a user**
615
+
616
+ ```json
617
+ {
618
+ "subjectType": "user",
619
+ "subject": "admin@company.com",
620
+ "resourceType": "role",
621
+ "resource": "platform-admin",
622
+ "denied": false
623
+ }
624
+ ```
625
+
626
+ **Result**: User `admin@company.com` gets the `platform-admin` role and all its operations
627
+ </TabItem>
628
+
629
+ <TabItem label="Deny Rule">
630
+ **Explicitly deny access**
631
+
632
+ ```json
633
+ {
634
+ "subjectType": "user",
635
+ "subject": "contractor@company.com",
636
+ "resourceType": "operation",
637
+ "resource": "sensitive::access",
638
+ "denied": true
639
+ }
640
+ ```
641
+
642
+ **Result**: User `contractor@company.com` cannot access sensitive data (even if their role grants it)
643
+ </TabItem>
644
+
645
+ <TabItem label="Group → Role">
646
+ **Assign a role to all members of a group**
647
+
648
+ ```json
649
+ {
650
+ "subjectType": "group",
651
+ "subject": "support-team",
652
+ "resourceType": "role",
653
+ "resource": "customer-support",
654
+ "denied": false
655
+ }
656
+ ```
657
+
658
+ **Result**: All users in the `support-team` group get the `customer-support` role
659
+ </TabItem>
660
+ </Tabs>
661
+
662
+
663
+ ---
664
+
665
+ ## Tenants
666
+
667
+ **Tenants** enable multi-tenancy - running a single instance of the platform for multiple customers or organizations with complete data isolation.
668
+
669
+ ### What is a Tenant?
670
+
671
+ A Tenant is:
672
+ - An **isolated instance** of the platform
673
+ - A **customer or organization** using the platform
674
+ - The **top-level data boundary** for all resources
675
+ - A **context** that flows through every request
676
+
677
+ ### Tenant Structure
678
+
679
+ ```typescript
680
+ interface Tenant {
681
+ id: string;
682
+ code: string; // Unique identifier (e.g., "acme-corp")
683
+ name: string; // Display name
684
+ status: 'ACTIVE' | 'SUSPENDED' | 'DELETED';
685
+
686
+ // Configuration
687
+ settings?: Record<string, any>;
688
+ branding?: {
689
+ logo?: string;
690
+ primaryColor?: string;
691
+ secondaryColor?: string;
692
+ };
693
+
694
+ // Subscription info
695
+ plan?: string;
696
+ subscriptionStartDate?: Date;
697
+ subscriptionEndDate?: Date;
698
+ }
699
+ ```
700
+
701
+ ### Tenant Isolation
702
+
703
+ Every resource in the platform belongs to a tenant:
704
+
705
+ ```typescript
706
+ // Users belong to tenants
707
+ interface User {
708
+ id: string;
709
+ tenantId: string; // Isolates users by tenant
710
+ email: string;
711
+ // ...
712
+ }
713
+
714
+ // Data belongs to tenants
715
+ interface Order {
716
+ id: string;
717
+ tenantId: string; // Isolates orders by tenant
718
+ customerId: string;
719
+ // ...
720
+ }
721
+ ```
722
+
723
+ ### Platform Context
724
+
725
+ The **Platform Context** carries tenant information through every request:
726
+
727
+ ```typescript
728
+ interface PlatformContext {
729
+ tenantId: string; // Current tenant
730
+ userId: string; // Current user
731
+ applicationId?: string; // Current application
732
+ requestId: string; // Trace ID
733
+ }
734
+ ```
735
+
736
+ The gateway extracts the tenant from:
737
+ 1. **JWT token** (for authenticated users)
738
+ 2. **API key** (for service-to-service calls)
739
+ 3. **Subdomain** (e.g., `acme.platform.com`)
740
+ 4. **Custom header** (for development)
741
+
742
+ ### Tenant Isolation in Practice
743
+
744
+ <Tabs>
745
+ <TabItem label="Automatic (Recommended)">
746
+ Use the platform's built-in tenant context:
747
+
748
+ ```typescript
749
+ // Backend service
750
+ @Injectable()
751
+ export class OrdersService {
752
+ async findAll(@PlatformContext() ctx: PlatformContext) {
753
+ // Automatically filters by ctx.tenantId
754
+ return this.ordersRepository.find({
755
+ where: { tenantId: ctx.tenantId }
756
+ });
757
+ }
758
+ }
759
+ ```
760
+ </TabItem>
761
+
762
+ <TabItem label="Manual (Advanced)">
763
+ Explicitly handle tenant filtering:
764
+
765
+ ```typescript
766
+ @Injectable()
767
+ export class OrdersService {
768
+ async findAll(tenantId: string) {
769
+ // Manual tenant filtering
770
+ return this.ordersRepository.find({
771
+ where: { tenantId }
772
+ });
773
+ }
774
+ }
775
+ ```
776
+ </TabItem>
777
+ </Tabs>
778
+
779
+ <Aside type="caution" title="Critical">
780
+ **Always** filter data by `tenantId`. Failing to do so can expose data across tenant boundaries - a serious security issue.
781
+ </Aside>
782
+
783
+ ---
784
+
785
+ ## Catalog
786
+
787
+ The **Catalog** is the platform's dynamic registry of Applications and Modules.
788
+
789
+ ### What is the Catalog?
790
+
791
+ The Catalog is:
792
+ - A **service registry** that tracks all services and UIs
793
+ - A **dynamic routing table** for the gateway
794
+ - A **discovery mechanism** for micro-frontends
795
+ - The **source of truth** for available applications
796
+
797
+ ### How the Catalog Works
798
+
799
+ ```mermaid
800
+ graph LR
801
+ A[Service Starts] --> B[Register with Catalog]
802
+ B --> C[Catalog Stores Metadata]
803
+ C --> D[Gateway Queries Catalog]
804
+ D --> E[Gateway Routes Requests]
805
+ ```
806
+
807
+ 1. **Registration**: Services and UIs register on startup
808
+ 2. **Storage**: Catalog stores module metadata in database
809
+ 3. **Discovery**: Gateway queries catalog for routing
810
+ 4. **Routing**: Gateway proxies requests to appropriate service
811
+
812
+ ### Catalog API
813
+
814
+ The catalog provides APIs for managing modules:
815
+
816
+ ```typescript
817
+ // Register a module
818
+ POST /catalog/modules
819
+ {
820
+ "code": "habits-service",
821
+ "name": "Habits Service",
822
+ "type": "SERVICE",
823
+ "serviceUrl": "http://pae-habits-service:4002",
824
+ "routes": [...]
825
+ }
826
+
827
+ // Get all modules
828
+ GET /catalog/modules
829
+
830
+ // Get modules by application
831
+ GET /catalog/applications/{appId}/modules
832
+
833
+ // Unregister a module
834
+ DELETE /catalog/modules/{moduleId}
835
+ ```
836
+
837
+ ### Benefits of the Catalog
838
+
839
+ <CardGrid>
840
+ <Card title="Zero-Config Gateway" icon="setting">
841
+ Gateway doesn't need configuration files - it learns routes from the catalog
842
+ </Card>
843
+
844
+ <Card title="Flexible Deployment" icon="rocket">
845
+ Add, remove, or update services without redeploying the gateway
846
+ </Card>
847
+
848
+ <Card title="Health Tracking" icon="approve-check">
849
+ Catalog can track service health and availability
850
+ </Card>
851
+ </CardGrid>
852
+
853
+ ---
854
+
855
+ ## Putting It All Together
856
+
857
+ Here's how these concepts work together in a real scenario:
858
+
859
+ ### Example: User Views Their Orders
860
+
861
+ 1. **User** (belongs to **Tenant** "ACME Corp") logs in
862
+ 2. **Gateway** authenticates and extracts **Platform Context** (tenant, user)
863
+ 3. User navigates to the "Orders" **Application** in the Shell UI
864
+ 4. **Catalog** provides the Orders **Module** location to the Shell
865
+ 5. Shell loads the Orders UI **Module** (micro-frontend)
866
+ 6. User clicks "View My Orders"
867
+ 7. UI checks if user has `orders.read` **Operation** (they do via their **Role**)
868
+ 8. UI calls the Orders Service via the **Gateway**
869
+ 9. **Gateway** checks authorization:
870
+ - User has `orders.read` operation
871
+ - **Rules** evaluated: "allow read own orders" passes
872
+ 10. Gateway routes request to Orders **Service Module**
873
+ 11. Service queries database filtered by **Tenant** ID
874
+ 12. Orders returned to UI
875
+
876
+ ### Key Takeaways
877
+
878
+ - **Applications** group related functionality
879
+ - **Modules** are the deployable services and UIs
880
+ - **Operations** are granular permissions
881
+ - **Roles** collect Operations for assignment
882
+ - **Rules** add conditional logic
883
+ - **Tenants** provide multi-tenancy isolation
884
+
885
+ ## Next Steps
886
+
887
+ Now that you understand the core concepts:
888
+
889
+ 1. **[Installation Guide](/_/docs/getting-started/installation/)** - Set up your development environment
890
+ 2. **[Development Workflow](/_/docs/getting-started/development-workflow/)** - Learn the day-to-day development process
891
+ 3. **[Architecture Deep Dive](/_/docs/architecture/overview/)** - Explore the technical architecture
892
+ 4. **[Authorization Guide](/_/docs/guides/authorization/)** - Master the authorization system