@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.
Files changed (52) hide show
  1. package/dist/index.js +278 -15
  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/Dockerfile.development +1 -1
  36. package/templates/bootstrap-service-template/gitignore +57 -0
  37. package/templates/bootstrap-service-template/package.json +1 -1
  38. package/templates/bootstrap-service-template/src/main.ts +6 -16
  39. package/templates/customization-ui-module-template/Dockerfile.development +1 -1
  40. package/templates/customization-ui-module-template/gitignore +73 -0
  41. package/templates/nestjs-service-module-template/Dockerfile.development +1 -1
  42. package/templates/nestjs-service-module-template/gitignore +56 -0
  43. package/templates/platform-init-template/{{platformName}}-core/gitignore +97 -0
  44. package/templates/platform-init-template/{{platformName}}-core/local/.env.example +1 -1
  45. package/templates/platform-init-template/{{platformName}}-core/local/platform-docker-compose.yml +1 -1
  46. package/templates/platform-init-template/{{platformName}}-core/local/{{platformName}}-core-docker-compose.yml +0 -1
  47. package/templates/react-ui-module-template/Dockerfile +1 -1
  48. package/templates/react-ui-module-template/Dockerfile.development +1 -3
  49. package/templates/react-ui-module-template/caddy/Caddyfile +1 -1
  50. package/templates/react-ui-module-template/gitignore +72 -0
  51. package/templates/react-ui-module-template/Dockerfile_nginx +0 -11
  52. package/templates/react-ui-module-template/nginx/default.conf +0 -23
@@ -0,0 +1,566 @@
1
+ ---
2
+ title: Working with Rooms
3
+ description: Complete guide to implementing real-time presence tracking using the Blue Alba Platform's rooms system
4
+ ---
5
+
6
+ import { Card, CardGrid, Aside, Tabs, TabItem, Code } from '@astrojs/starlight/components';
7
+ import MermaidDiagram from '~/components/MermaidDiagram.astro';
8
+
9
+ The Blue Alba Platform's rooms system provides real-time presence tracking for users within application contexts. This built-in feature enables you to see who is currently viewing or working in the same space, perfect for implementing collaborative features, live user indicators, and shared presence experiences.
10
+
11
+ ## Overview
12
+
13
+ The rooms system enables you to:
14
+
15
+ - Track which users are currently active in a specific context (room)
16
+ - Display real-time user avatars showing who else is present
17
+ - Build collaborative features without managing WebSocket infrastructure
18
+ - Implement live indicators for shared documents, dashboards, or views
19
+ - Show presence information with minimal code
20
+
21
+ ### Use Cases
22
+
23
+ - **Collaborative Editing**: Show who else is viewing or editing a document
24
+ - **Live Dashboards**: Display users currently viewing a dashboard
25
+ - **Real-time Indicators**: Add "currently viewing" badges to any page
26
+ - **Team Awareness**: Help teams know when colleagues are in the same context
27
+
28
+ ---
29
+
30
+ ## Architecture Overview
31
+
32
+ The rooms system consists of two integrated components:
33
+
34
+ <MermaidDiagram
35
+ title="Rooms System Architecture"
36
+ code={`graph TB
37
+ A[React Application<br/>with RoomsProvider]:::ui --> B[WebSocket Connection]:::ws
38
+ B --> C[pae-rooms-service<br/>WebSocket Gateway]:::service
39
+ C --> D[User Registry<br/>Rooms & Connections]:::data
40
+
41
+ E[Gateway<br/>Authentication]:::gateway --> C
42
+
43
+ F[Catalog Service]:::catalog --> A
44
+
45
+ A -->|joinRoom| C
46
+ A -->|leaveRoom| C
47
+ C -->|user_list broadcast| A
48
+
49
+ classDef ui fill:#87CEEB,color:#333
50
+ classDef ws fill:#FFB6C1,color:#333
51
+ classDef service fill:#90EE90,color:#333
52
+ classDef data fill:#FFD700,color:#333
53
+ classDef gateway fill:#DDA0DD,color:#333
54
+ classDef catalog fill:#F0E68C,color:#333`}
55
+ />
56
+
57
+ ### Backend Service: pae-rooms-service
58
+
59
+ The backend is a NestJS WebSocket gateway that:
60
+ - Manages real-time connections from UI applications
61
+ - Tracks which users are in which rooms
62
+ - Broadcasts user list updates to all connected clients
63
+ - Runs behind the gateway (authentication handled upstream)
64
+
65
+ <Aside type="note" title="Built-in Module">
66
+ The rooms service is a **built-in platform module**, so no bootstrap configuration is needed. Simply deploy the service with the name 'pae-rooms-service'.
67
+ </Aside>
68
+
69
+ ### Frontend Library
70
+
71
+ The frontend components are available in the `@bluealba/pae-ui-react-core` package, providing:
72
+ - `RoomsProvider`: React context provider managing WebSocket connection
73
+ - `useRoom`: Hook for joining rooms and accessing user lists
74
+ - `RoomAvatars`: Pre-built component for displaying user avatars
75
+
76
+ ---
77
+
78
+ ## Backend Deployment
79
+
80
+ The `pae-rooms-service` must be deployed in your infrastructure.
81
+
82
+ ### Docker Compose Example
83
+
84
+ ```yaml
85
+ services:
86
+ pae-rooms-service:
87
+ image: your-registry/pae-rooms-service:latest
88
+ environment:
89
+ - PORT=3000
90
+ - NODE_ENV=production
91
+ ports:
92
+ - "3010:3000"
93
+ networks:
94
+ - platform-network
95
+ ```
96
+
97
+ <Aside type="tip" title="Zero Configuration">
98
+ The rooms service requires no special configuration. Once deployed and accessible, it's ready to use. The gateway handles authentication and forwards user information via headers.
99
+ </Aside>
100
+
101
+ ---
102
+
103
+ ## Frontend Integration
104
+
105
+ This is where you'll spend most of your time - integrating rooms functionality into your React applications.
106
+
107
+ ### Installation
108
+
109
+ The rooms functionality is available in the `@bluealba/pae-ui-react-core` package, which should already be installed in your UI module:
110
+
111
+ ```bash
112
+ npm install @bluealba/pae-ui-react-core
113
+ ```
114
+
115
+ ### Setting Up the RoomsProvider
116
+
117
+ The `RoomsProvider` must wrap any components that need to use rooms functionality. Typically, you'll add it at a high level in your component tree.
118
+
119
+ ```tsx
120
+ import { RoomsProvider } from '@bluealba/pae-ui-react-core';
121
+
122
+ function App() {
123
+ return (
124
+ <RoomsProvider>
125
+ {/* Your application components */}
126
+ <Dashboard />
127
+ <DocumentViewer />
128
+ <WorkspaceArea />
129
+ </RoomsProvider>
130
+ );
131
+ }
132
+
133
+ export default App;
134
+ ```
135
+
136
+ **What the RoomsProvider does:**
137
+ - Automatically establishes a WebSocket connection to the rooms service
138
+ - Retrieves the service URL from the platform's application catalog
139
+ - Manages connection state (loading, connected, closed, error)
140
+ - Handles all WebSocket communication internally
141
+ - Broadcasts user list updates to all consuming components
142
+ - Cleans up the connection when unmounted
143
+
144
+ <Aside type="caution">
145
+ Any component attempting to use `useRoom` outside of a `RoomsProvider` will throw an error. Make sure the provider wraps all components that need rooms functionality.
146
+ </Aside>
147
+
148
+ ### Using the useRoom Hook
149
+
150
+ The `useRoom` hook is your primary interface for working with rooms. It automatically manages room membership and provides the current user list.
151
+
152
+ #### Basic Usage (Automatic Mode)
153
+
154
+ ```tsx
155
+ import { useRoom } from '@bluealba/pae-ui-react-core';
156
+
157
+ function DocumentViewer({ documentId }) {
158
+ const { users, roomId, hasJoined } = useRoom(`document-${documentId}`);
159
+
160
+ return (
161
+ <div>
162
+ <h1>Document Viewer</h1>
163
+ <p>Room: {roomId}</p>
164
+ <p>Status: {hasJoined ? 'Joined' : 'Not in room'}</p>
165
+ <p>Currently viewing: {users.length} user(s)</p>
166
+
167
+ <ul>
168
+ {users.map(user => (
169
+ <li key={user.username}>{user.displayName}</li>
170
+ ))}
171
+ </ul>
172
+ </div>
173
+ );
174
+ }
175
+ ```
176
+
177
+ **Default Hook Behavior:**
178
+ - Automatically joins the specified room when the component mounts
179
+ - Automatically leaves the room when the component unmounts
180
+ - Re-joins if the `roomId` parameter changes
181
+ - Returns the current list of users in that room
182
+ - Updates automatically when users join or leave
183
+
184
+ #### Hook Options
185
+
186
+ The `useRoom` hook accepts an optional second parameter for controlling automatic behavior:
187
+
188
+ ```typescript
189
+ interface UseRoomOptions {
190
+ /**
191
+ * Automatically join the room when the hook is used.
192
+ * Defaults to true.
193
+ */
194
+ autoJoin?: boolean;
195
+ /**
196
+ * Automatically leave the room when the component unmounts.
197
+ * Defaults to true.
198
+ */
199
+ autoLeave?: boolean;
200
+ }
201
+ ```
202
+
203
+ **Default Options:** `{ autoJoin: true, autoLeave: true }` (backward compatible with previous versions)
204
+
205
+ **Return Value:**
206
+ ```typescript
207
+ interface UseRoomReturn {
208
+ users: RoomUser[]; // Array of users currently in the room
209
+ roomId: string; // The current room ID
210
+ hasJoined: boolean; // Whether the authenticated user has joined the room
211
+ joinRoom: () => void; // Function to manually join the room
212
+ leaveRoom: () => void; // Function to manually leave the room
213
+ }
214
+ ```
215
+
216
+ ### Understanding RoomUser Type
217
+
218
+ Each user in the room is represented by a `RoomUser` object:
219
+
220
+ ```typescript
221
+ interface RoomUser {
222
+ username: string; // Unique username from authentication
223
+ displayName: string; // User's display name (human-readable)
224
+ rooms: string[]; // All rooms this user is currently in
225
+ color?: string; // Auto-generated color for avatars
226
+ }
227
+ ```
228
+
229
+ **Key Points:**
230
+ - `username`: Unique identifier, suitable for keys in React lists
231
+ - `displayName`: What you should show to end users
232
+ - `rooms`: Array of all room IDs the user has joined (useful for multi-room scenarios)
233
+ - `color`: Automatically generated consistent color based on username, perfect for avatars
234
+
235
+ ---
236
+
237
+ ## Manual Room Control
238
+
239
+ In some scenarios, you may want full control over when a user joins or leaves a room rather than relying on automatic behavior. The `useRoom` hook supports this through manual mode.
240
+
241
+ <Aside type="tip" title="When to Use Manual Mode">
242
+ Manual room control is useful when:
243
+ - Room joining should be triggered by user action (e.g., clicking "Join Session")
244
+ - You need conditional room participation based on user preferences or permissions
245
+ - You want to implement "preview" mode where users can see the room before joining
246
+ - You need to coordinate room joining with other asynchronous operations
247
+ - You're building chat rooms, live sessions, or collaborative spaces with explicit join/leave actions
248
+ </Aside>
249
+
250
+ ### Enabling Manual Mode
251
+
252
+ Set both `autoJoin` and `autoLeave` to `false` to gain full control:
253
+
254
+ ```tsx
255
+ import { useRoom } from '@bluealba/pae-ui-react-core';
256
+
257
+ function ManualRoomExample({ roomId }) {
258
+ const { users, hasJoined, joinRoom, leaveRoom } = useRoom(roomId, {
259
+ autoJoin: false,
260
+ autoLeave: false,
261
+ });
262
+
263
+ return (
264
+ <div>
265
+ <div>
266
+ <p>Status: {hasJoined ? 'Joined' : 'Not Joined'}</p>
267
+ <p>Participants: {users.length}</p>
268
+ </div>
269
+
270
+ <div>
271
+ <button onClick={joinRoom} disabled={hasJoined}>
272
+ Join Room
273
+ </button>
274
+ <button onClick={leaveRoom} disabled={!hasJoined}>
275
+ Leave Room
276
+ </button>
277
+ </div>
278
+
279
+ {hasJoined && (
280
+ <ul>
281
+ {users.map(user => (
282
+ <li key={user.username}>{user.displayName}</li>
283
+ ))}
284
+ </ul>
285
+ )}
286
+ </div>
287
+ );
288
+ }
289
+ ```
290
+
291
+ ### Manual Control API
292
+
293
+ **`joinRoom()`**: Manually join the room
294
+ - Only works when `autoJoin: false`
295
+ - Calling this when `autoJoin: true` will log a warning and be ignored
296
+ - Safe to call multiple times (no-op if already joined)
297
+
298
+ **`leaveRoom()`**: Manually leave the room
299
+ - Only works when `autoLeave: false`
300
+ - Calling this when `autoLeave: true` will log a warning and be ignored
301
+ - Safe to call multiple times (no-op if not joined)
302
+
303
+ **`hasJoined`**: Boolean indicating if the current user is in the room
304
+ - Returns `true` if the authenticated user appears in the `users` array
305
+ - Updates automatically when join/leave operations complete
306
+ - Useful for conditional rendering and button states
307
+
308
+ ### Advanced Examples
309
+
310
+ <Tabs>
311
+ <TabItem label="Conditional Joining">
312
+ ```tsx
313
+ function ConditionalRoom({ roomId, userHasPermission }) {
314
+ const { users, hasJoined, joinRoom, leaveRoom } = useRoom(roomId, {
315
+ autoJoin: false,
316
+ autoLeave: false,
317
+ });
318
+
319
+ useEffect(() => {
320
+ // Only join if user has permission
321
+ if (userHasPermission && !hasJoined) {
322
+ joinRoom();
323
+ }
324
+ }, [userHasPermission, hasJoined, joinRoom]);
325
+
326
+ useEffect(() => {
327
+ // Leave when component unmounts
328
+ return () => {
329
+ if (hasJoined) {
330
+ leaveRoom();
331
+ }
332
+ };
333
+ }, [hasJoined, leaveRoom]);
334
+
335
+ if (!userHasPermission) {
336
+ return <p>You don't have permission to join this room.</p>;
337
+ }
338
+
339
+ return (
340
+ <div>
341
+ <p>Participants: {users.length}</p>
342
+ {/* ... */}
343
+ </div>
344
+ );
345
+ }
346
+ ```
347
+ Join the room only when specific conditions are met
348
+ </TabItem>
349
+
350
+ <TabItem label="Preview Mode">
351
+ ```tsx
352
+ function RoomPreview({ roomId }) {
353
+ const [mode, setMode] = useState<'preview' | 'active'>('preview');
354
+ const { users, hasJoined, joinRoom, leaveRoom } = useRoom(roomId, {
355
+ autoJoin: false,
356
+ autoLeave: false,
357
+ });
358
+
359
+ useEffect(() => {
360
+ if (mode === 'active' && !hasJoined) {
361
+ joinRoom();
362
+ } else if (mode === 'preview' && hasJoined) {
363
+ leaveRoom();
364
+ }
365
+ }, [mode, hasJoined, joinRoom, leaveRoom]);
366
+
367
+ return (
368
+ <div>
369
+ <div>
370
+ <button onClick={() => setMode('preview')}>Preview</button>
371
+ <button onClick={() => setMode('active')}>Join Active</button>
372
+ </div>
373
+
374
+ <p>Mode: {mode}</p>
375
+ <p>Participants: {users.length}</p>
376
+
377
+ {mode === 'preview' && (
378
+ <p>You are viewing participant count without joining</p>
379
+ )}
380
+
381
+ {mode === 'active' && hasJoined && (
382
+ <ul>
383
+ {users.map(user => (
384
+ <li key={user.username}>{user.displayName}</li>
385
+ ))}
386
+ </ul>
387
+ )}
388
+ </div>
389
+ );
390
+ }
391
+ ```
392
+ Allow users to preview participant count before joining
393
+ </TabItem>
394
+
395
+ <TabItem label="Session Management">
396
+ ```tsx
397
+ function LiveSession({ sessionId }) {
398
+ const [sessionStarted, setSessionStarted] = useState(false);
399
+ const { users, hasJoined, joinRoom, leaveRoom } = useRoom(
400
+ `session-${sessionId}`,
401
+ { autoJoin: false, autoLeave: false }
402
+ );
403
+
404
+ const handleStartSession = async () => {
405
+ // Perform any async setup
406
+ await initializeSession(sessionId);
407
+
408
+ // Then join the room
409
+ joinRoom();
410
+ setSessionStarted(true);
411
+ };
412
+
413
+ const handleEndSession = async () => {
414
+ // Leave the room first
415
+ leaveRoom();
416
+
417
+ // Then cleanup
418
+ await cleanupSession(sessionId);
419
+ setSessionStarted(false);
420
+ };
421
+
422
+ useEffect(() => {
423
+ // Cleanup on unmount
424
+ return () => {
425
+ if (hasJoined) {
426
+ leaveRoom();
427
+ }
428
+ };
429
+ }, [hasJoined, leaveRoom]);
430
+
431
+ return (
432
+ <div>
433
+ {!sessionStarted ? (
434
+ <button onClick={handleStartSession}>
435
+ Start Live Session
436
+ </button>
437
+ ) : (
438
+ <>
439
+ <p>Session Active - {users.length} participants</p>
440
+ <button onClick={handleEndSession}>
441
+ End Session
442
+ </button>
443
+ </>
444
+ )}
445
+ </div>
446
+ );
447
+ }
448
+ ```
449
+ Coordinate room joining with other async operations
450
+ </TabItem>
451
+ </Tabs>
452
+
453
+ <Aside type="caution">
454
+ **Important Behavior Notes:**
455
+ - When `autoJoin: true` (default), calling `joinRoom()` manually will log a warning and be ignored
456
+ - When `autoLeave: true` (default), calling `leaveRoom()` manually will log a warning and be ignored
457
+ - Always check the console for warnings if manual join/leave isn't working as expected
458
+ - The `hasJoined` flag is based on the authenticated user's presence in the `users` array
459
+ </Aside>
460
+
461
+ ### Displaying User Avatars with RoomAvatars
462
+
463
+ The `RoomAvatars` component provides a beautiful, ready-to-use interface for displaying room users:
464
+
465
+ ```tsx
466
+ import { useRoom, RoomAvatars } from '@bluealba/pae-ui-react-core';
467
+
468
+ function DashboardHeader({ dashboardId }) {
469
+ const { users } = useRoom(`dashboard-${dashboardId}`);
470
+
471
+ return (
472
+ <header>
473
+ <h1>Analytics Dashboard</h1>
474
+
475
+ <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
476
+ <span>Currently viewing:</span>
477
+ <RoomAvatars
478
+ users={users}
479
+ size="md"
480
+ maxVisible={5}
481
+ overlap={true}
482
+ />
483
+ </div>
484
+ </header>
485
+ );
486
+ }
487
+ ```
488
+
489
+ **Component Features:**
490
+ - Renders circular avatars with user initials
491
+ - Automatically uses the user's generated color
492
+ - Supports three sizes: `sm` (24px), `md` (32px), `lg` (40px)
493
+ - Can overlap avatars for a compact display
494
+ - Shows overflow count when too many users (e.g., "+3")
495
+ - Includes tooltips showing full display names
496
+ - Optional click handlers for custom interactions
497
+
498
+ **Props:**
499
+
500
+ ```typescript
501
+ interface RoomAvatarsProps {
502
+ users: RoomUser[]; // Array of users to display (required)
503
+ maxVisible?: number; // Max avatars before showing overflow (default: 5)
504
+ size?: 'sm' | 'md' | 'lg'; // Avatar size (default: 'md')
505
+ overlap?: boolean; // Whether avatars overlap (default: true)
506
+ className?: string; // Additional CSS classes
507
+ onUserClick?: (user: RoomUser) => void; // Optional click handler
508
+ }
509
+ ```
510
+
511
+ **Examples:**
512
+
513
+ <Tabs>
514
+ <TabItem label="Compact Display">
515
+ ```tsx
516
+ <RoomAvatars
517
+ users={users}
518
+ size="sm"
519
+ maxVisible={3}
520
+ overlap={true}
521
+ />
522
+ ```
523
+ Perfect for tight spaces, shows 3 overlapping small avatars
524
+ </TabItem>
525
+
526
+ <TabItem label="Spacious List">
527
+ ```tsx
528
+ <RoomAvatars
529
+ users={users}
530
+ size="lg"
531
+ maxVisible={10}
532
+ overlap={false}
533
+ />
534
+ ```
535
+ Larger avatars with no overlap, suitable for prominent displays
536
+ </TabItem>
537
+
538
+ <TabItem label="Interactive">
539
+ ```tsx
540
+ <RoomAvatars
541
+ users={users}
542
+ size="md"
543
+ maxVisible={5}
544
+ onUserClick={(user) => {
545
+ console.log('Clicked user:', user.displayName);
546
+ // Open user profile, start chat, etc.
547
+ }}
548
+ />
549
+ ```
550
+ Adds click interaction to each avatar
551
+ </TabItem>
552
+ </Tabs>
553
+
554
+ ---
555
+
556
+ ## Multi-Tenancy Awareness
557
+
558
+ **Important**: Room IDs are **NOT** automatically scoped by tenant. If you need tenant isolation, you must include the tenant ID as part of the room name:
559
+
560
+ ```tsx
561
+ // ✅ Good: Explicitly scoped by tenant
562
+ const { users } = useRoom(`tenant-${tenantId}-dashboard-main`);
563
+
564
+ // ⚠️ Caution: This is a global room across all tenants
565
+ const { users } = useRoom('dashboard-main');
566
+ ```
package/docs/index.mdx ADDED
@@ -0,0 +1,57 @@
1
+ ---
2
+ title: Blue Alba Platform
3
+ description: a generic and extensible framework and tools for developing customer facing applications from scratch
4
+ template: splash
5
+ hero:
6
+ image:
7
+ alt: Blue Alba Platform Logo
8
+ dark: ~/assets/logo-dark.png
9
+ light: ~/assets/logo-light.png
10
+ tagline: A generic and extensible framework and tools for developing customer facing applications from scratch
11
+ actions:
12
+ - text: Get Started
13
+ link: /_/docs/getting-started/overview/
14
+ icon: right-arrow
15
+ variant: primary
16
+ - text: View Architecture
17
+ link: /_/docs/architecture/overview/
18
+ icon: open-book
19
+ variant: minimal
20
+ ---
21
+
22
+ import { Card, CardGrid } from '@astrojs/starlight/components';
23
+
24
+ ## Key Features
25
+
26
+ <CardGrid stagger>
27
+ <Card title="API Gateway" icon="star">
28
+ Powerful HTTP gateway with application routing, catalog management, HTTP/2 and WebSocket support, and Lambda integration for serverless functions.
29
+ </Card>
30
+
31
+ <Card title="Authentication & Security" icon="approve-check">
32
+ Multi-IDP authentication (Okta, EntraId, OneLogin, Github, Cognito), API keys support, user impersonation, and JWT-based security.
33
+ </Card>
34
+
35
+ <Card title="Authorization & Access Control" icon="approve-check-circle">
36
+ Comprehensive RBAC with permissions, operations, roles, groups management, and fine-grained access control throughout the platform.
37
+ </Card>
38
+
39
+ <Card title="Multi-Tenancy & Provisioning" icon="codeberg">
40
+ Built-in multi-tenant architecture with tenant context management and automated Okta tenant/roles/applications provisioning.
41
+ </Card>
42
+
43
+ <Card title="Micro-Frontend Architecture" icon="puzzle">
44
+ React-based micro-frontends using single-spa with platform Shell UI and Administration UI for independent development and deployment.
45
+ </Card>
46
+
47
+ <Card title="User & State Management" icon="seti:favicon">
48
+ Complete user management with groups, saved views, bookmarks, and user-related data persistence.
49
+ </Card>
50
+
51
+ <Card title="Developer Experience" icon="rocket">
52
+ Comprehensive development tools including templates, conventions, shared libraries, frameworks, and platform bootstrapping utilities.
53
+ </Card>
54
+ </CardGrid>
55
+
56
+
57
+