@bluealba/platform-cli 1.1.0 → 1.2.0-alpha.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.
@@ -0,0 +1,415 @@
1
+ ---
2
+ title: Standalone Mode
3
+ description: Run a single application with a fully functional platform infrastructure without setting up a full product repository
4
+ ---
5
+
6
+ import { Aside, Steps, Tabs, TabItem, Card, CardGrid } from '@astrojs/starlight/components';
7
+
8
+ Standalone mode lets you run a single application with a fully functional platform infrastructure — gateway, database, and bootstrap service — without needing a full product repository. It is designed for rapid application development and testing in isolation.
9
+
10
+ <CardGrid>
11
+ <Card title="No product repo required">
12
+ Work entirely within your application monorepo. The CLI scaffolds a temporary platform core on demand.
13
+ </Card>
14
+ <Card title="Persistent configuration">
15
+ IDP and admin user settings are stored in `~/.ba-platform/standalone.json` and reused across all your standalone applications.
16
+ </Card>
17
+ <Card title="Foreground or detached">
18
+ Run with live output and Ctrl+C teardown, or use `--detach` for background execution.
19
+ </Card>
20
+ <Card title="First-run auto-detection">
21
+ The CLI reads your bootstrap service to detect platform and application identifiers automatically, so you rarely need to type them manually.
22
+ </Card>
23
+ </CardGrid>
24
+
25
+ ---
26
+
27
+ ## When to use standalone mode
28
+
29
+ Use standalone mode when you want to:
30
+
31
+ - Develop or test a single application in isolation, without standing up an entire platform product repository
32
+ - Iterate quickly on a new application before integrating it into a shared environment
33
+ - Run integration tests against a real gateway with a real database from a CI job
34
+
35
+ Use a full platform setup (via `platform init`) when you need to run multiple applications together or when you are working on the platform core itself.
36
+
37
+ ---
38
+
39
+ ## Prerequisites
40
+
41
+ | Requirement | Notes |
42
+ |-------------|-------|
43
+ | Node.js >= 22 | Required by the platform services |
44
+ | Docker with Compose plugin | Used to run the gateway and database |
45
+ | An application monorepo | Created by `platform create-application` (either inside or outside an existing platform). Must have `docker-compose.yml` and `package.json` at the root. |
46
+
47
+ <Aside type="note">
48
+ Standalone mode is unavailable inside a directory that already contains an initialized platform (a `*-core/product.manifest.json` file). Run it from within the application monorepo directory itself, not the product repository root.
49
+ </Aside>
50
+
51
+ ---
52
+
53
+ ## Creating a standalone application
54
+
55
+ If you are starting from scratch, use `create-application` to scaffold an application monorepo that is ready for standalone mode. The command works the same whether you are inside a platform repository or not — the only difference is that outside a platform you must also supply `platformName` and `organizationName`:
56
+
57
+ ```bash
58
+ platform create-application \
59
+ platformName=myplatform \
60
+ organizationName=myorg \
61
+ applicationName=billing \
62
+ applicationDisplayName="Billing" \
63
+ applicationDescription="Invoice and payment management" \
64
+ hasUserInterface=yes \
65
+ hasBackendService=yes
66
+ ```
67
+
68
+ This creates a `myplatform-billing/` directory with:
69
+
70
+ ```
71
+ myplatform-billing/
72
+ ├── package.json
73
+ ├── docker-compose.yml ← Compose file for this app's services
74
+ ├── services/
75
+ │ ├── myplatform-billing-bootstrap-service/
76
+ │ │ └── ... ← Bootstrap NestJS service (registers the app)
77
+ │ └── myplatform-billing-service/ ← NestJS backend service (if requested)
78
+ │ └── ...
79
+ └── ui/
80
+ └── myplatform-billing-ui/ ← React micro-frontend module (if requested)
81
+ └── ...
82
+ ```
83
+
84
+ It also writes initial configuration to `~/.ba-platform/standalone.json`.
85
+
86
+ The scaffolded `package.json` includes convenience scripts so you can use npm instead of invoking the CLI directly:
87
+
88
+ | npm script | Equivalent CLI command |
89
+ |------------|----------------------|
90
+ | `npm run standalone` | `platform standalone` |
91
+ | `npm run standalone:stop` | `platform standalone-stop` |
92
+
93
+ If you created your application with `platform create-application` inside a full platform, the resulting application monorepo is already compatible with standalone mode. Copy or clone it anywhere and run `platform standalone` from its root.
94
+
95
+ ---
96
+
97
+ ## Running standalone mode
98
+
99
+ <Steps>
100
+
101
+ 1. **Navigate to the application monorepo root:**
102
+
103
+ ```bash
104
+ cd myplatform-billing
105
+ ```
106
+
107
+ 2. **Start the standalone platform:**
108
+
109
+ ```bash
110
+ platform standalone
111
+ ```
112
+
113
+ Or use the npm script included in the scaffolded `package.json`:
114
+
115
+ ```bash
116
+ npm run standalone
117
+ ```
118
+
119
+ 3. **Follow the first-time setup wizard** (if no config exists yet — see [First-time setup](#first-time-setup) below).
120
+
121
+ 4. **Wait for the gateway to become healthy.** The CLI logs progress:
122
+
123
+ ```
124
+ Scaffolding temporary platform core...
125
+ Installing dependencies...
126
+ Building...
127
+ Starting containers...
128
+ Waiting for gateway to be healthy...
129
+ Gateway is healthy.
130
+ IDP provider "My Okta" configured successfully.
131
+ Admin user "you@example.com" configured successfully.
132
+
133
+ Platform is running. Press Ctrl+C to stop and clean up.
134
+ ```
135
+
136
+ 5. **Access the platform.** The gateway is available at `https://localhost:443` by default (self-signed certificate).
137
+
138
+ 6. **Press Ctrl+C** to stop containers and remove the temporary platform core.
139
+
140
+ </Steps>
141
+
142
+ <Aside type="note" title="Temporary platform core location">
143
+ The CLI scaffolds a real platform core in `/tmp/platform-standalone-{platformName}/`. This directory is created fresh on every run and deleted on shutdown. All persistent application data lives in Docker volumes, which are also reset on each run to avoid database credential mismatches between runs.
144
+ </Aside>
145
+
146
+ ---
147
+
148
+ ## First-time setup
149
+
150
+ When no standalone configuration is found for the current application, the CLI launches a setup wizard before starting.
151
+
152
+ **Auto-detection**: The CLI first scans your bootstrap service's `application.json` to detect the platform name, application name, and display name. It also looks in `~/.ba-platform/standalone.json` for existing defaults (from previous apps). Any detected values are pre-filled as prompt defaults.
153
+
154
+ **What the wizard prompts:**
155
+
156
+ | Prompt | Auto-detected from | Pre-filled from defaults if |
157
+ |--------|--------------------|------------------------------|
158
+ | Platform name | Bootstrap service directory name | `defaults.platformName` already set |
159
+ | Organization name | — | `defaults.organizationName` already set |
160
+ | Application name | `application.json` | — |
161
+ | Application display name | `application.json` | — |
162
+ | IDP configuration | — | `defaults.idp` already set (asked to confirm reuse) |
163
+ | Admin users | `git config user.email` (first user) | `defaults.adminUsers` already set (asked to confirm reuse) |
164
+
165
+ After the wizard, the CLI asks whether to run in detached mode.
166
+
167
+ **Subsequent runs**: If config exists in `~/.ba-platform/standalone.json` for the detected `platformName/applicationName` key, the wizard is skipped entirely. The platform starts immediately.
168
+
169
+ ---
170
+
171
+ ## Detached mode
172
+
173
+ By default, `platform standalone` runs in the foreground. Logs stream to the terminal and Ctrl+C stops and cleans up everything.
174
+
175
+ Use detached mode when you want the platform to keep running in the background:
176
+
177
+ <Tabs>
178
+ <TabItem label="Interactive">
179
+ ```bash
180
+ platform standalone
181
+ # When prompted "Run in detached mode (background)?", answer yes
182
+ ```
183
+ </TabItem>
184
+ <TabItem label="Headless">
185
+ ```bash
186
+ platform standalone detach=true
187
+ # or
188
+ platform standalone d=true
189
+ ```
190
+ </TabItem>
191
+ </Tabs>
192
+
193
+ In detached mode, the CLI prints a confirmation and exits. To stop a detached platform:
194
+
195
+ ```bash
196
+ platform standalone-stop
197
+ # or
198
+ npm run standalone:stop
199
+ ```
200
+
201
+ <Aside type="caution" title="One standalone platform at a time">
202
+ Only one standalone platform can run at a time, regardless of detach mode. If you attempt to start a second one while another is running, the CLI will print an error and exit. Run `platform standalone-stop` first.
203
+ </Aside>
204
+
205
+ ---
206
+
207
+ ## Centralized configuration
208
+
209
+ All standalone configuration is stored in `~/.ba-platform/standalone.json`. This file is owned by you (mode `0600`) and is never committed to any repository.
210
+
211
+ ### File structure
212
+
213
+ ```json
214
+ {
215
+ "defaults": {
216
+ "platformName": "myplatform",
217
+ "organizationName": "myorg",
218
+ "idp": {
219
+ "provider": "okta",
220
+ "name": "My Okta",
221
+ "issuer": "https://myorg.okta.com/oauth2/default",
222
+ "clientId": "0oa...",
223
+ "clientSecret": "..."
224
+ },
225
+ "adminUsers": ["you@example.com"]
226
+ },
227
+ "apps": {
228
+ "myplatform/billing": {
229
+ "applicationName": "billing",
230
+ "applicationDisplayName": "Billing"
231
+ },
232
+ "myplatform/hr": {
233
+ "applicationName": "hr",
234
+ "applicationDisplayName": "HR",
235
+ "adminUsers": ["hr-admin@example.com"]
236
+ }
237
+ }
238
+ }
239
+ ```
240
+
241
+ **`defaults`** holds values shared across all applications: platform name, organization name, IDP credentials, and admin users. You only need to enter IDP credentials once — they are reused every time you start standalone mode for any application.
242
+
243
+ **`apps`** holds per-application entries keyed by `platformName/applicationName`. Each entry requires `applicationName` and `applicationDisplayName`. Any field present in an app entry overrides the corresponding default for that application only — useful when a specific app needs a different IDP or different admin users.
244
+
245
+ ### Resolution order
246
+
247
+ When starting standalone mode, the CLI merges the two sections:
248
+
249
+ ```
250
+ resolved = defaults + app override
251
+ ```
252
+
253
+ Fields in the app entry take precedence over fields in defaults. Fields absent from the app entry fall back to defaults.
254
+
255
+ ---
256
+
257
+ ## Configuration management commands
258
+
259
+ ### standalone-config-show
260
+
261
+ Shows the resolved configuration for the current application (auto-detected from the current directory), or the full contents of `~/.ba-platform/standalone.json` if run outside an app monorepo.
262
+
263
+ <Tabs>
264
+ <TabItem label="Interactive">
265
+ ```bash
266
+ platform standalone-config-show
267
+ ```
268
+ </TabItem>
269
+ <TabItem label="Headless — current app">
270
+ ```bash
271
+ platform standalone-config-show
272
+ # Auto-detects app from cwd
273
+ ```
274
+ </TabItem>
275
+ <TabItem label="Headless — specific app">
276
+ ```bash
277
+ platform standalone-config-show app=myplatform/billing
278
+ ```
279
+ </TabItem>
280
+ </Tabs>
281
+
282
+ ### standalone-config-set
283
+
284
+ Edits defaults or app-specific overrides.
285
+
286
+ <Tabs>
287
+ <TabItem label="Interactive">
288
+ ```bash
289
+ platform standalone-config-set
290
+ # Select "Defaults" or "App-specific config" and follow prompts
291
+ ```
292
+ </TabItem>
293
+ <TabItem label="Headless — edit defaults">
294
+ ```bash
295
+ platform standalone-config-set defaults=true platformName=myplatform organizationName=myorg
296
+ ```
297
+ </TabItem>
298
+ <TabItem label="Headless — edit app">
299
+ ```bash
300
+ platform standalone-config-set app=myplatform/billing applicationDisplayName="Billing v2"
301
+ # Auto-detects app from cwd if 'app' is omitted
302
+ ```
303
+ </TabItem>
304
+ </Tabs>
305
+
306
+ <Aside type="note">
307
+ IDP and admin user configuration cannot be set via headless arguments for `standalone-config-set`. Use interactive mode to configure or update IDP credentials and admin user lists, as these fields contain sensitive information that should not appear in shell history.
308
+ </Aside>
309
+
310
+ ### standalone-config-delete
311
+
312
+ Removes a saved app config entry from `~/.ba-platform/standalone.json`. Defaults are not affected.
313
+
314
+ <Tabs>
315
+ <TabItem label="Interactive">
316
+ ```bash
317
+ platform standalone-config-delete
318
+ # Select from list, confirm deletion
319
+ ```
320
+ </TabItem>
321
+ <TabItem label="Headless">
322
+ ```bash
323
+ platform standalone-config-delete app=myplatform/billing
324
+ ```
325
+ </TabItem>
326
+ </Tabs>
327
+
328
+ ### standalone-config-list
329
+
330
+ Lists all configured applications with their resolved settings.
331
+
332
+ ```bash
333
+ platform standalone-config-list
334
+ ```
335
+
336
+ Example output:
337
+
338
+ ```
339
+ Config file: /Users/you/.ba-platform/standalone.json
340
+
341
+ Defaults:
342
+ Platform: myplatform
343
+ Organization: myorg
344
+ IDP: okta (My Okta)
345
+ Admin Users: you@example.com
346
+
347
+ Apps:
348
+ myplatform/billing — Billing [IDP: yes, Admins: 1]
349
+ myplatform/hr — HR [IDP: no, Admins: 1]
350
+ ```
351
+
352
+ ---
353
+
354
+ ## Legacy migration
355
+
356
+ If your application monorepo contains a `standalone.json` file at its root (from an earlier version of the CLI), the standalone wizard detects it automatically and migrates the contents to `~/.ba-platform/standalone.json`. Shared fields (platform name, organization name, IDP, admin users) move to `defaults`; app-specific fields move to the `apps` section. You are prompted to delete the old file after migration.
357
+
358
+ ---
359
+
360
+ ## Troubleshooting
361
+
362
+ ### Gateway does not become healthy
363
+
364
+ The CLI waits up to 120 seconds for the gateway's `/health` endpoint to respond. If it times out:
365
+
366
+ 1. Check the gateway container logs:
367
+ ```bash
368
+ docker compose -p myplatform-platform logs pae-nestjs-gateway-service
369
+ ```
370
+ 2. Check that all containers are running:
371
+ ```bash
372
+ docker ps
373
+ ```
374
+ 3. If you see a PostgreSQL authentication error, a stale Docker volume from a previous standalone run may be using an old password. The standalone orchestrator resets volumes automatically on each start, but if the volume was created by a non-standalone platform run with the same name, you may need to remove it manually:
375
+ ```bash
376
+ docker volume ls | grep myplatform
377
+ docker volume rm <volume-name>
378
+ ```
379
+
380
+ ### IDP not configured
381
+
382
+ If you skipped IDP setup during the wizard, users will not be able to log in. Configure IDP interactively:
383
+
384
+ ```bash
385
+ platform standalone-config-set
386
+ # Choose "Defaults (shared across all apps)" and configure an IDP
387
+ ```
388
+
389
+ Then restart standalone mode.
390
+
391
+ ### Platform already running error
392
+
393
+ Only one standalone platform can run at a time. If the CLI reports another instance is running but you do not have one:
394
+
395
+ 1. Check for a stale marker file:
396
+ ```bash
397
+ ls /tmp/platform-standalone-*/
398
+ ```
399
+ 2. Stop it cleanly (if containers are actually running):
400
+ ```bash
401
+ platform standalone-stop
402
+ ```
403
+ 3. Or remove the directory manually if no containers are running:
404
+ ```bash
405
+ rm -rf /tmp/platform-standalone-myplatform/
406
+ ```
407
+
408
+ ### Changes to application services not reflected
409
+
410
+ The temporary platform core is scaffolded fresh on every run, but your application's Docker image is rebuilt using the existing built artifacts. If you make source code changes, rebuild before running standalone:
411
+
412
+ ```bash
413
+ npm run build
414
+ platform standalone
415
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bluealba/platform-cli",
3
- "version": "1.1.0",
3
+ "version": "1.2.0-alpha.0",
4
4
  "description": "Blue Alba Platform CLI",
5
5
  "license": "PolyForm-Noncommercial-1.0.0",
6
6
  "type": "module",
@@ -10,7 +10,9 @@
10
10
  "lint": "turbo run lint",
11
11
  "changeset": "changeset",
12
12
  "check-deps": "syncpack list-mismatches",
13
- "fix-deps": "syncpack fix-mismatches"
13
+ "fix-deps": "syncpack fix-mismatches",
14
+ "standalone": "platform standalone",
15
+ "standalone:stop": "platform standalone-stop"
14
16
  },
15
17
  "packageManager": "npm@10.8.2",
16
18
  "keywords": [],