@bluealba/platform-cli 1.2.0-alpha.0 → 1.2.0-alpha.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.
package/dist/index.js CHANGED
@@ -2439,7 +2439,7 @@ async function removePlatformAdmin(ruleId, logger) {
2439
2439
  var baPlatformPlugin = {
2440
2440
  name: "ba-platform-plugin",
2441
2441
  description: "Blue Alba Platform knowledge and CLI skills for AI assistants",
2442
- version: "1.0.0",
2442
+ version: "1.1.0",
2443
2443
  skills: [
2444
2444
  {
2445
2445
  name: "platform",
@@ -2452,6 +2452,48 @@ var baPlatformPlugin = {
2452
2452
  description: "Blue Alba Platform CLI commands and usage knowledge",
2453
2453
  type: "skill",
2454
2454
  sourceFile: "skills/ba-platform/platform-cli.skill.md"
2455
+ },
2456
+ {
2457
+ name: "platform-add-operation",
2458
+ description: "Defines a new authorization operation in the bootstrap service, assigns it to a role, and adds access guards in the React UI or NestJS backend",
2459
+ type: "skill",
2460
+ sourceFile: "skills/ba-platform/platform-add-operation.skill.md"
2461
+ },
2462
+ {
2463
+ name: "platform-add-feature-flag",
2464
+ description: "Declares a feature flag in the bootstrap service and adds its usage in a React UI component or NestJS service",
2465
+ type: "skill",
2466
+ sourceFile: "skills/ba-platform/platform-add-feature-flag.skill.md"
2467
+ },
2468
+ {
2469
+ name: "platform-add-scheduled-job",
2470
+ description: "Adds a scheduled job to a Blue Alba Platform bootstrap service",
2471
+ type: "skill",
2472
+ sourceFile: "skills/ba-platform/platform-add-scheduled-job.skill.md"
2473
+ },
2474
+ {
2475
+ name: "platform-add-menu-item",
2476
+ description: "Adds a new page and menu item to a Blue Alba Platform single-spa UI module",
2477
+ type: "skill",
2478
+ sourceFile: "skills/ba-platform/platform-add-menu-item.skill.md"
2479
+ },
2480
+ {
2481
+ name: "platform-extend-shell",
2482
+ description: "Injects a custom component into a Blue Alba Platform shell extension point",
2483
+ type: "skill",
2484
+ sourceFile: "skills/ba-platform/platform-extend-shell.skill.md"
2485
+ },
2486
+ {
2487
+ name: "platform-add-presence",
2488
+ description: "Adds real-time user presence via the Rooms API to a Blue Alba Platform app",
2489
+ type: "skill",
2490
+ sourceFile: "skills/ba-platform/platform-add-presence.skill.md"
2491
+ },
2492
+ {
2493
+ name: "platform-scaffold-module",
2494
+ description: "Scaffolds a new UI module or service module using the platform CLI",
2495
+ type: "skill",
2496
+ sourceFile: "skills/ba-platform/platform-scaffold-module.skill.md"
2455
2497
  }
2456
2498
  ]
2457
2499
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bluealba/platform-cli",
3
- "version": "1.2.0-alpha.0",
3
+ "version": "1.2.0-alpha.2",
4
4
  "description": "Blue Alba Platform CLI",
5
5
  "license": "PolyForm-Noncommercial-1.0.0",
6
6
  "type": "module",
@@ -0,0 +1,110 @@
1
+ ---
2
+ name: platform-add-feature-flag
3
+ description: Declares a feature flag in the bootstrap service and adds its usage in a React UI component or NestJS service. Use when the user wants to gate a feature behind a flag on a Blue Alba Platform app.
4
+ ---
5
+
6
+ You are adding a feature flag to a Blue Alba Platform application. The project is a monorepo: UI modules live under `ui/`, services and bootstrap under `services/`.
7
+
8
+ ## Related Documentation
9
+
10
+ Read `{{docsPath}}/guides/using-feature-flags.mdx` for the complete feature flags guide including architecture, targeting rules, and API endpoints.
11
+
12
+ ## Step 1 — Discover the bootstrap service
13
+
14
+ Find `services/<app>-bootstrap-service/src/bootstrap/feature-flags.json`. Read it to understand existing flags.
15
+
16
+ ## Step 2 — Ask for flag details
17
+
18
+ Ask the user:
19
+
20
+ 1. **Flag name** — kebab-case identifier (e.g. `new-checkout-flow`)
21
+ 2. **Description** — short human-readable description
22
+ 3. **Default value** — `true` or `false` (or a typed value if not boolean)
23
+ 4. **Targeting rules** — should this flag be enabled for specific tenants or users? If yes, get the tenant IDs or usernames.
24
+ 5. **Rollout percentage** — optional, e.g. 20% of users matching the rule
25
+ 6. **Where to use it** — which component, page, or service should read this flag?
26
+
27
+ Wait for the user's answer before continuing.
28
+
29
+ ## Step 3 — Declare the flag in bootstrap
30
+
31
+ Add the flag to `feature-flags.json` following this structure:
32
+
33
+ ```json
34
+ {
35
+ "name": "<flag-name>",
36
+ "description": "<description>",
37
+ "visible": true,
38
+ "defaultValue": <defaultValue>,
39
+ "applicationName": "<app-name>",
40
+ "valueRules": []
41
+ }
42
+ ```
43
+
44
+ If targeting rules were specified, populate `valueRules`:
45
+
46
+ ```json
47
+ {
48
+ "name": "<rule-name>",
49
+ "condition": {
50
+ "operator": "AND",
51
+ "rules": [
52
+ { "attribute": "tenant", "operator": "in", "value": ["<tenant-id>"] }
53
+ ]
54
+ },
55
+ "value": true,
56
+ "rollout": { "percentage": <n>, "attribute": "username" }
57
+ }
58
+ ```
59
+
60
+ Only add `rollout` if a percentage was given. Omit `valueRules` entirely if no rules.
61
+
62
+ ## Step 4 — Add usage in code
63
+
64
+ **React component** (in `ui/`):
65
+
66
+ If the flag controls whether a whole section is shown:
67
+ ```tsx
68
+ import { FeatureFlagGuard } from '@bluealba/pae-ui-react-core';
69
+
70
+ <FeatureFlagGuard flag="<flag-name>" fallback={<OldComponent />}>
71
+ <NewComponent />
72
+ </FeatureFlagGuard>
73
+ ```
74
+
75
+ If the flag value is needed in logic:
76
+ ```tsx
77
+ import { useFeatureFlag } from '@bluealba/pae-ui-react-core';
78
+
79
+ const enabled = useFeatureFlag('<flag-name>');
80
+ ```
81
+
82
+ **NestJS service** (in `services/`):
83
+
84
+ For a one-off check in a service method:
85
+ ```ts
86
+ import { FeatureFlagsClientService } from '@bluealba/pae-service-nestjs-sdk';
87
+
88
+ constructor(private flags: FeatureFlagsClientService) {}
89
+
90
+ const enabled = this.flags.get<boolean>(req, '<flag-name>') ?? false;
91
+ ```
92
+
93
+ For a controller endpoint:
94
+ ```ts
95
+ import { FeatureFlags } from '@bluealba/pae-service-nestjs-sdk';
96
+
97
+ @Get()
98
+ async myEndpoint(@FeatureFlags('<flag-name>') enabled: boolean) { ... }
99
+ ```
100
+
101
+ Also add `FeatureFlagsClientModule` to the module's `imports` array if it isn't already there.
102
+
103
+ > **Note:** Feature flags are evaluated by the gateway and forwarded to downstream services via the `x-forwarded-feature-flags` base64-encoded header. The `@FeatureFlags()` decorator and `FeatureFlagsClientService` read from this header — they do not evaluate flags themselves.
104
+
105
+ ## Rules
106
+
107
+ - Flag names must be kebab-case
108
+ - `defaultValue` type must match how the flag is consumed (boolean, number, string)
109
+ - Do not add flags to the wrong application — check `applicationName` matches the bootstrap service's application
110
+ - Follow the existing code style in the target file exactly
@@ -0,0 +1,80 @@
1
+ ---
2
+ name: platform-add-menu-item
3
+ description: Adds a new page and menu item to a Blue Alba Platform single-spa UI module. Creates the route component and wires it into menu.ts. Use when the user wants to add a new page, route, or section to a platform app.
4
+ ---
5
+
6
+ You are adding a new page and menu entry to a Blue Alba Platform single-spa UI application. The project is a monorepo where UI modules live under `ui/` and services under `services/`.
7
+
8
+ ## Related Documentation
9
+
10
+ Read `{{docsPath}}/architecture/shell.mdx` for the shell layout, menu structure, and application menu contract.
11
+
12
+ ## Step 1 — Discover the UI module
13
+
14
+ Look for the `ui/` directory in the current working directory. List its subdirectories to find the UI module(s). Read the `src/menu.ts` file from the relevant module to understand the existing menu structure.
15
+
16
+ Also read `src/main.tsx` (or `src/index.tsx`) to understand the entry point and how routes are set up, and any router file (e.g. `src/App.tsx`, `src/router.tsx`, or files importing `react-router-dom`). Menu files are always `.ts` (not `.tsx`).
17
+
18
+ ## Step 2 — Ask for details
19
+
20
+ Ask the user for the following. Suggest sensible defaults based on the existing code:
21
+
22
+ 1. **Label** — the menu item display name (e.g. "Invoice History")
23
+ 2. **Route** — the URL path (e.g. `/invoices`)
24
+ 3. **Icon** — icon name or component (look at existing menu items for the pattern)
25
+ 4. **Parent menu item** — should this be a top-level item or nested under an existing one?
26
+ 5. **Operation** — does this page require an authorization operation to be visible? (e.g. `billing::invoices::read`). Leave blank if no restriction needed.
27
+
28
+ Wait for the user's answer before continuing.
29
+
30
+ ## Step 3 — Create the page component
31
+
32
+ Create a new React component file under `src/components/` or `src/pages/` (follow the existing folder convention). Use a minimal functional component:
33
+
34
+ ```tsx
35
+ import React from 'react';
36
+
37
+ const <PageName>: React.FC = () => {
38
+ return (
39
+ <div>
40
+ <h1><PageName></h1>
41
+ </div>
42
+ );
43
+ };
44
+
45
+ export default <PageName>;
46
+ ```
47
+
48
+ ## Step 4 — Register the route
49
+
50
+ Find where routes are defined (likely in `src/App.tsx` or a dedicated router file using `react-router-dom`). Add the new route following the exact same pattern used for existing routes. Import the new page component.
51
+
52
+ ## Step 5 — Add the menu item
53
+
54
+ Edit `src/menu.ts` to add the new menu entry. Follow the existing structure exactly:
55
+
56
+ ```ts
57
+ {
58
+ id: '<kebab-case-id>',
59
+ label: '<Label>',
60
+ icon: '<icon>',
61
+ route: '<route>',
62
+ operations: ['<operation>'], // omit this array if no operation was specified
63
+ }
64
+ ```
65
+
66
+ If the item is nested, add it to the `children` array of the appropriate parent.
67
+
68
+ ## Step 6 — Add the operation to bootstrap (if needed)
69
+
70
+ If an operation was specified in Step 2:
71
+ 1. Find `services/<app>-bootstrap-service/src/bootstrap/operations.json`
72
+ 2. Add the operation name to the array if it doesn't exist yet
73
+ 3. Find `roles.json` in the same directory and assign the operation to the appropriate role(s), following existing patterns
74
+
75
+ ## Rules
76
+
77
+ - Never invent icon names — use ones already present in the codebase
78
+ - Follow the exact naming and folder conventions found in the existing code
79
+ - Do not add extra boilerplate (tests, stories, etc.) unless asked
80
+ - If the router or menu structure is non-standard, describe what you found and ask the user how to proceed
@@ -0,0 +1,103 @@
1
+ ---
2
+ name: platform-add-operation
3
+ description: Defines a new authorization operation in the bootstrap service, assigns it to a role, and adds access guards in the React UI or NestJS backend. Use when the user wants to restrict a feature, page, or action to specific roles on a Blue Alba Platform app.
4
+ ---
5
+
6
+ You are adding an authorization operation to a Blue Alba Platform application. The project is a monorepo: UI modules under `ui/`, services and bootstrap under `services/`.
7
+
8
+ ## Related Documentation
9
+
10
+ Read `{{docsPath}}/architecture/authorization-system.mdx` for the full RBAC model, operation naming conventions, and authorization flow.
11
+
12
+ ## Step 1 — Read existing authorization config
13
+
14
+ Find and read:
15
+ - `services/<app>-bootstrap-service/src/bootstrap/operations.json`
16
+ - `services/<app>-bootstrap-service/src/bootstrap/roles.json`
17
+
18
+ Understand the existing naming patterns and role structure.
19
+
20
+ ## Step 2 — Ask for details
21
+
22
+ Ask the user:
23
+
24
+ 1. **Operation name** — follow the pattern `domain::resource::action` (e.g. `billing::invoices::delete`). Suggest a name based on context if possible.
25
+ 2. **Role(s)** — which existing roles should be granted this operation? List the roles found in `roles.json`.
26
+ 3. **Where to enforce it** — which component, button, menu item, or API endpoint should be gated?
27
+ 4. **UI or backend (or both)?** — where should the guard be applied?
28
+
29
+ Wait for the user's answer before continuing.
30
+
31
+ ## Step 3 — Add the operation to bootstrap
32
+
33
+ Add the operation name to `operations.json` (it is typically an array of strings):
34
+ ```json
35
+ "billing::invoices::delete"
36
+ ```
37
+
38
+ In `roles.json`, find each target role and add the operation to its operations list, following the existing format exactly.
39
+
40
+ ## Step 4 — Enforce in the UI (if applicable)
41
+
42
+ **To hide/show a component declaratively:**
43
+ ```tsx
44
+ import { Authorized } from '@bluealba/pae-ui-react-core';
45
+
46
+ <Authorized operations={['billing::invoices::delete']}>
47
+ <DeleteButton />
48
+ </Authorized>
49
+ ```
50
+
51
+ **To check programmatically:**
52
+ ```tsx
53
+ import { useAuth } from '@bluealba/pae-ui-react-core';
54
+
55
+ const { hasAccess } = useAuth();
56
+ if (hasAccess('billing::invoices::delete')) { ... }
57
+
58
+ // Require ALL of multiple operations:
59
+ if (hasAccess(['billing::invoices::read', 'billing::invoices::delete'])) { ... }
60
+ ```
61
+
62
+ **To restrict a menu item**, add the operation to its `operations` array in `menu.ts`:
63
+ ```ts
64
+ {
65
+ id: 'delete-invoice',
66
+ label: 'Delete',
67
+ route: '/invoices/delete',
68
+ operations: ['billing::invoices::delete']
69
+ }
70
+ ```
71
+
72
+ ## Step 5 — Enforce in the backend (if applicable)
73
+
74
+ Backend authorization is handled **centrally by the gateway**, not by individual microservices. The gateway's `AuthorizationGuard` checks operations before proxying requests. To gate a specific API route, add an `authorization` block to the module's entry in `modules.json`:
75
+
76
+ ```json
77
+ {
78
+ "name": "@acme/billing-service",
79
+ "baseUrl": "/api/billing",
80
+ "authorization": {
81
+ "operations": ["billing::invoices::read"],
82
+ "routes": [
83
+ {
84
+ "pattern": "/api/billing/invoices",
85
+ "methods": ["DELETE"],
86
+ "operations": ["billing::invoices::delete"]
87
+ }
88
+ ]
89
+ }
90
+ }
91
+ ```
92
+
93
+ - `authorization.operations` — default operations required to access any route in this module
94
+ - `authorization.routes` — override operations for specific route + method combinations
95
+
96
+ Read the existing `modules.json` to check whether the module already has an `authorization` block and extend it rather than replacing it.
97
+
98
+ ## Rules
99
+
100
+ - Operation names must follow `domain::resource::action` — never invent a new naming scheme
101
+ - Always read `roles.json` before assigning; never create new roles unless explicitly asked
102
+ - Do not remove or rename existing operations
103
+ - If the same operation already exists, skip Step 3 and go straight to enforcement
@@ -0,0 +1,84 @@
1
+ ---
2
+ name: platform-add-presence
3
+ description: Adds real-time user presence (who is viewing this page/resource) to a component in a Blue Alba Platform app using the Rooms API. Use when the user wants to show live avatars or awareness of other users in a view.
4
+ ---
5
+
6
+ You are adding real-time presence tracking to a Blue Alba Platform single-spa application using the Rooms API. The project is a monorepo: UI modules under `ui/`.
7
+
8
+ ## Related Documentation
9
+
10
+ Read `{{docsPath}}/guides/working-with-rooms.mdx` for the complete Rooms guide including backend deployment, WebSocket architecture, and advanced usage patterns.
11
+
12
+ ## Step 1 — Understand the context
13
+
14
+ Read the target component the user wants to add presence to. Also read `src/App.tsx` (or the app root) to check whether `RoomsProvider` is already present in the component tree.
15
+
16
+ ## Step 2 — Ask for details
17
+
18
+ Ask the user:
19
+
20
+ 1. **Which component/page** should show presence? (if not already clear from context)
21
+ 2. **Room scope** — what does a "room" represent here? Options:
22
+ - The whole page (e.g. `dashboard`) — everyone viewing the page is in the same room
23
+ - A specific resource (e.g. `invoice-{id}`) — presence scoped to a record
24
+ 3. **Tenant isolation** — should the room be scoped per tenant? (almost always yes — default to yes)
25
+ 4. **Display style** — just the count, avatars, or both?
26
+ 5. **Manual control** — should the user explicitly join/leave, or is it automatic?
27
+
28
+ Wait for the user's answer before continuing.
29
+
30
+ ## Step 3 — Add RoomsProvider (if not present)
31
+
32
+ If `RoomsProvider` is not already wrapping the app, add it in `src/App.tsx` around the component tree:
33
+
34
+ ```tsx
35
+ import { RoomsProvider } from '@bluealba/pae-ui-react-core';
36
+
37
+ function App() {
38
+ return (
39
+ <RoomsProvider>
40
+ {/* existing tree */}
41
+ </RoomsProvider>
42
+ );
43
+ }
44
+ ```
45
+
46
+ ## Step 4 — Add presence to the target component
47
+
48
+ **Automatic join/leave (default):**
49
+ ```tsx
50
+ import { useRoom, RoomAvatars } from '@bluealba/pae-ui-react-core';
51
+ import { useAuth } from '@bluealba/pae-ui-react-core';
52
+
53
+ const { authUser } = useAuth();
54
+ // Scope room per tenant to maintain multi-tenant isolation
55
+ const { users } = useRoom(`tenant-${authUser.tenantId}-<room-name>`);
56
+
57
+ return <RoomAvatars users={users} size="md" maxVisible={5} />;
58
+ ```
59
+
60
+ **Resource-scoped room (e.g. per record):**
61
+ ```tsx
62
+ const { users } = useRoom(`tenant-${authUser.tenantId}-invoice-${invoiceId}`);
63
+ ```
64
+
65
+ **Manual control:**
66
+ ```tsx
67
+ const { users, hasJoined, joinRoom, leaveRoom } = useRoom(roomId, {
68
+ autoJoin: false,
69
+ autoLeave: false,
70
+ });
71
+ ```
72
+
73
+ ## Step 5 — Get the tenantId
74
+
75
+ Check how other components in the codebase obtain the tenant ID (it may come from `useAuth`, a context, or a route param). Use the same pattern.
76
+
77
+ If tenant context is unavailable in this component, read `src/App.tsx` or context providers to find where it lives and either pass it as a prop or move the hook up the tree.
78
+
79
+ ## Rules
80
+
81
+ - Always scope room names per tenant: `tenant-<tenantId>-<room>` — never use a bare room name
82
+ - `RoomsProvider` must appear only once, high in the tree — do not nest multiple providers
83
+ - Prefer automatic join/leave unless the user explicitly needs manual control
84
+ - Do not add presence to components that unmount and remount frequently (e.g. items in a list) — use it at page/view level
@@ -0,0 +1,65 @@
1
+ ---
2
+ name: platform-add-scheduled-job
3
+ description: Adds a scheduled job to a Blue Alba Platform bootstrap service. Use when the user wants to run a backend endpoint on a cron schedule.
4
+ ---
5
+
6
+ You are adding a scheduled job to a Blue Alba Platform application's bootstrap service. The project is a monorepo: bootstrap lives under `services/<app>-bootstrap-service/src/bootstrap/`.
7
+
8
+ ## Related Documentation
9
+
10
+ Read `{{docsPath}}/architecture/scheduler.mdx` for the complete scheduler architecture including dynamic parameters, SSRF security, cron syntax, and API endpoints.
11
+
12
+ ## Step 1 — Read the existing jobs config
13
+
14
+ Find `services/<app>-bootstrap-service/src/bootstrap/jobs.json`. If it doesn't exist, it will need to be created. Read the file if it exists to understand existing jobs.
15
+
16
+ ## Step 2 — Ask for details
17
+
18
+ Ask the user:
19
+
20
+ 1. **Job name** — kebab-case identifier (e.g. `nightly-report-generation`)
21
+ 2. **Description** — short human-readable description
22
+ 3. **Schedule** — cron expression (e.g. `0 2 * * *` for 2am daily). If the user gives a natural language description, convert it to cron.
23
+ 4. **URL** — the backend endpoint to call (e.g. `http://billing-service/api/jobs/generate-reports`)
24
+ 5. **Auth method** — `bearer` token, `basic` auth, or none?
25
+ 6. **Payload** — any `taskConfig` key/value pairs to pass to the endpoint? (optional)
26
+
27
+ Wait for the user's answer before continuing.
28
+
29
+ ## Step 3 — Add the job
30
+
31
+ Add the job entry to `jobs.json`. If the file doesn't exist, create it with a `jobs` array.
32
+
33
+ ```json
34
+ {
35
+ "jobs": [
36
+ {
37
+ "name": "<job-name>",
38
+ "description": "<description>",
39
+ "schedule": "<cron>",
40
+ "url": "<url>",
41
+ "taskConfig": { },
42
+ "auth": {
43
+ "authMethod": "bearer",
44
+ "token": "{{$ENV.JOB_TOKEN}}"
45
+ }
46
+ }
47
+ ]
48
+ }
49
+ ```
50
+
51
+ - Omit `taskConfig` if no payload was specified
52
+ - Omit `auth` if no auth is needed
53
+ - Use `{{$ENV.VAR_NAME}}` for any sensitive values (tokens, passwords) — never hardcode them
54
+ - For optional env vars with a default: `{{$ENV.VAR_NAME?=default}}`
55
+
56
+ ## Step 4 — Remind about env vars
57
+
58
+ If auth tokens or other secrets were used with `{{$ENV.*}}`, remind the user to add the corresponding variable to their environment configuration (e.g. `.env`, docker-compose, or the platform's env config for that service).
59
+
60
+ ## Rules
61
+
62
+ - Job names must be kebab-case and unique within the file
63
+ - Never hardcode secrets — always use `{{$ENV.*}}` interpolation
64
+ - Cron expressions follow standard 5-field format: `minute hour day month weekday`
65
+ - The URL should point to the internal service hostname, not the gateway
@@ -1,3 +1,8 @@
1
+ ---
2
+ name: platform-cli
3
+ description: Blue Alba Platform CLI commands and usage knowledge
4
+ ---
5
+
1
6
  # Blue Alba Platform CLI — Expert Knowledge
2
7
 
3
8
  You are an expert on the Blue Alba Platform CLI (`@bluealba/platform-cli`, command: `platform`). Use the documentation files referenced below to answer questions accurately.
@@ -0,0 +1,78 @@
1
+ ---
2
+ name: platform-extend-shell
3
+ description: Injects a custom component into a Blue Alba Platform shell extension point (navbar, branding, user section, etc.). Use when the user wants to add a button, logo, or custom element to the platform shell from within their app.
4
+ ---
5
+
6
+ You are extending a shell UI extension point from within a Blue Alba Platform single-spa application. The project is a monorepo: UI modules under `ui/`, services under `services/`.
7
+
8
+ ## Related Documentation
9
+
10
+ - `{{docsPath}}/architecture/shell.mdx` — Shell layout, customization methods, and extension point list
11
+ - `{{docsPath}}/architecture/ui-extension-points.mdx` — Detailed extension point mechanism, lifecycle, and prop passing
12
+
13
+ ## Available extension points
14
+
15
+ The shell exposes these named extension points:
16
+
17
+ | Area | Extension Point Names |
18
+ |---|---|
19
+ | Branding | `NavbarPortalLogo`, `ExpandedNavbarPortalLogo`, `SplashScreen`, `SplashLogo`, `VersionsLogo` |
20
+ | Navigation | `ApplicationSelector`, `CurrentApplicationMenu`, `CurrentApplicationMenuContent`, `OpenMenuButton`, `CloseMenuButton` |
21
+ | Navbar | `NavbarContent`, `NavbarTools`, `NavbarToggleStateButton`, `AdminApplication` |
22
+ | User section | `LoggedInUserSection`, `LoggedInUserAvatar` |
23
+ | Top-level | `ShellTopElements` |
24
+
25
+ ## Step 1 — Discover the UI module structure
26
+
27
+ Find the UI module under `ui/`. Read `src/main.tsx` (or the app root) and `src/App.tsx` to understand the component tree.
28
+
29
+ ## Step 2 — Ask for details
30
+
31
+ Ask the user:
32
+
33
+ 1. **Which extension point?** — refer to the table above or let the user describe what they want to inject and suggest the right one.
34
+ 2. **What component to inject?** — does it already exist, or does it need to be created?
35
+ 3. **Is this conditional?** — should the extension be toggled dynamically (e.g. based on a feature flag or state)?
36
+
37
+ Wait for the user's answer before continuing.
38
+
39
+ ## Step 3 — Create the component (if needed)
40
+
41
+ If the component doesn't exist yet, create it under `src/components/` following existing naming conventions. Keep it minimal — just what the user described.
42
+
43
+ ## Step 4 — Register the extension
44
+
45
+ Find the best place to register the extension. It should be inside the mounted React tree (e.g. `App.tsx` or a dedicated `ShellExtensions.tsx` component rendered from `App.tsx`).
46
+
47
+ **Static extension (declarative):**
48
+ ```tsx
49
+ import { ExtendExtensionPoint } from '@bluealba/pae-ui-react-core';
50
+
51
+ <ExtendExtensionPoint module="@bluealba/pae-shell-ui" point="NavbarTools">
52
+ <MyToolbarButton />
53
+ </ExtendExtensionPoint>
54
+ ```
55
+
56
+ **Dynamic/conditional extension (hook):**
57
+ ```tsx
58
+ import { useExtendExtensionPoint } from '@bluealba/pae-ui-react-core';
59
+
60
+ useExtendExtensionPoint(
61
+ '@bluealba/pae-shell-ui',
62
+ 'NavbarTools',
63
+ enabled ? MyToolbarButton : null
64
+ );
65
+ ```
66
+
67
+ Use the hook form only when the extension must be toggled at runtime. Otherwise prefer the declarative form.
68
+
69
+ ## Step 5 — Verify placement
70
+
71
+ Confirm that the component calling `ExtendExtensionPoint` / `useExtendExtensionPoint` is rendered within the app's mounted React tree. If it isn't, add it there.
72
+
73
+ ## Rules
74
+
75
+ - The `module` prop must always be `"@bluealba/pae-shell-ui"` for shell extension points
76
+ - The `point` name must exactly match one of the names in the table above (case-sensitive)
77
+ - Do not wrap extension registrations in conditional renders — use the hook form with `null` for dynamic toggling instead
78
+ - Do not create a new file just to hold the extension if there is a logical existing component that can host it
@@ -0,0 +1,70 @@
1
+ ---
2
+ name: platform-scaffold-module
3
+ description: Scaffolds a new UI module or service module in a Blue Alba Platform monorepo using the platform CLI. Use when the user wants to add a new micro-frontend or backend service to an existing platform application.
4
+ ---
5
+
6
+ You are helping the user scaffold a new module in a Blue Alba Platform monorepo. The platform CLI handles all scaffolding, port allocation, modules.json registration, and docker-compose updates automatically. Your job is to gather the right inputs and then run the CLI.
7
+
8
+ ## Step 1 — Understand the existing structure
9
+
10
+ List the contents of `ui/` and `services/` to understand the current modules, naming conventions, and org prefix (e.g. `@bluealba`).
11
+
12
+ ## Step 2 — Ask for details
13
+
14
+ Ask the user:
15
+
16
+ 1. **Module type** — UI module (React micro-frontend) or service module (NestJS backend)?
17
+ 2. **Application name** — the platform application this belongs to (e.g. `billing`). Look at existing directory names to suggest the correct one.
18
+ 3. **Module name** — for UI: the display name (e.g. `"Billing"`). For service: the service name (e.g. `payments`) and display name (e.g. `"Payments Service"`).
19
+
20
+ Wait for the user's answer before continuing.
21
+
22
+ ## Step 3 — Run the CLI command
23
+
24
+ **For a UI module:**
25
+ ```bash
26
+ platform create-ui-module \
27
+ applicationName=<applicationName> \
28
+ applicationDisplayName="<displayName>"
29
+ ```
30
+
31
+ **For a service module:**
32
+ ```bash
33
+ platform create-service-module \
34
+ applicationName=<applicationName> \
35
+ serviceName=<serviceName> \
36
+ serviceDisplayName="<serviceDisplayName>"
37
+ ```
38
+
39
+ Run the command from the monorepo root. The CLI will automatically:
40
+ - Scaffold all files from templates
41
+ - Allocate the next available port
42
+ - Register the module in `modules.json` (bootstrap service)
43
+ - Update `docker-compose.yml`
44
+
45
+ Report the CLI output to the user.
46
+
47
+ ## Step 4 — Verify and review
48
+
49
+ After the CLI completes, verify that everything looks correct:
50
+
51
+ 1. **Check the scaffolded directory** — list files in the new `ui/<name>` or `services/<name>` directory
52
+ 2. **Check modules.json** — read `services/<app>-bootstrap-service/src/bootstrap/modules.json` and confirm the new entry was added with correct values
53
+ 3. **Check docker-compose** — confirm the new service block was appended
54
+
55
+ If anything is missing or looks wrong, tell the user what failed and suggest running the CLI again or making a manual fix.
56
+
57
+ ## Step 5 — Show next steps
58
+
59
+ Tell the user:
60
+ - Where the new module was created (exact path)
61
+ - How to install dependencies: `cd <module-dir> && npm install`
62
+ - How to start locally: `npm start` from the module directory, or restart the full platform with `platform start`
63
+ - That they may need to restart the standalone environment to pick up the new bootstrap config
64
+
65
+ ## Rules
66
+
67
+ - **Never manually scaffold module files** — always use the CLI commands
68
+ - **Never manually edit modules.json to register a module** — the CLI does this automatically via `addModuleEntry`
69
+ - If the CLI is not available (command not found), tell the user to install it: `npm install -g @bluealba/platform-cli`
70
+ - If the CLI fails, show the full error output and ask the user to verify they are in the monorepo root
@@ -1,3 +1,8 @@
1
+ ---
2
+ name: platform
3
+ description: Comprehensive Blue Alba Platform architecture and concepts knowledge
4
+ ---
5
+
1
6
  # Blue Alba Platform — Expert Knowledge
2
7
 
3
8
  You are an expert on the Blue Alba Platform monorepo. Use the documentation files referenced below to answer questions accurately.
@@ -17,6 +22,9 @@ Read these files for comprehensive platform knowledge:
17
22
  - `{{docsPath}}/architecture/shell.mdx` — Shell UI architecture and extension points
18
23
  - `{{docsPath}}/architecture/scheduler.mdx` — Job scheduling system
19
24
  - `{{docsPath}}/development/workflow.mdx` — Development workflow, git branching, changesets, testing
25
+ - `{{docsPath}}/guides/using-feature-flags.mdx` — Feature flags system: declaration, targeting rules, React and NestJS usage
26
+ - `{{docsPath}}/guides/working-with-rooms.mdx` — Real-time presence with Rooms API: WebSocket architecture, hooks, components
27
+ - `{{docsPath}}/architecture/ui-extension-points.mdx` — Shell extension point mechanism, lifecycle, and customization
20
28
  - `{{docsPath}}/platform-cli/overview.mdx` — Platform CLI tool: installation, interactive mode, headless mode
21
29
  - `{{docsPath}}/platform-cli/commands.mdx` — All CLI commands reference
22
30