create-bcp-app 0.2.11 → 0.2.12

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 (3) hide show
  1. package/README.md +87 -198
  2. package/package.json +1 -1
  3. package/template/README.md +75 -200
package/README.md CHANGED
@@ -28,16 +28,6 @@ Generated npm scripts use `bcp` because npm places `node_modules/.bin` on the sc
28
28
  }
29
29
  ```
30
30
 
31
- When Tailwind CSS is selected, the generated packaging script preserves the production CSS step:
32
-
33
- ```json
34
- {
35
- "scripts": {
36
- "package": "npm run css:build:prod && bcp package"
37
- }
38
- }
39
- ```
40
-
41
31
  For direct PowerShell usage, prefer the collision-free local alias:
42
32
 
43
33
  ```powershell
@@ -75,27 +65,21 @@ Select storage provider:
75
65
  Cloudflare R2
76
66
  ```
77
67
 
78
- Equivalent non-interactive flags are available for CI/scaffolding automation.
79
-
80
68
  ## Generated project metadata
81
69
 
82
- New projects include:
70
+ New projects include `bcp.project.json`.
83
71
 
84
- ```text
85
- bcp.project.json
86
- ```
87
-
88
- Example:
72
+ Example for the `0.2.12` target:
89
73
 
90
74
  ```json
91
75
  {
92
76
  "schemaVersion": 1,
93
77
  "framework": "bcp",
94
78
  "projectName": "my-app",
95
- "frameworkPackage": "npm:@chidchanun/bcp@0.2.11",
79
+ "frameworkPackage": "npm:@chidchanun/bcp@0.2.12",
96
80
  "createdWith": {
97
81
  "package": "create-bcp-app",
98
- "version": "0.2.11"
82
+ "version": "0.2.12"
99
83
  },
100
84
  "packageManager": "npm",
101
85
  "presets": {
@@ -109,43 +93,9 @@ Example:
109
93
 
110
94
  This manifest records scaffold identity only. It must not contain secrets and should normally be committed to source control.
111
95
 
112
- ## Generated application defaults
113
-
114
- Generated applications include the project-root `@/` alias and TypeScript settings compatible with the BCP bundler.
115
-
116
- Modules that use React client hooks such as `useState` or `useEffect` must declare `"use client"` at the top of the module.
117
-
118
- The generated BCP dependency is pinned to the exact framework release selected by the generator.
119
-
120
- Update later with:
121
-
122
- ```bash
123
- npm run update
124
- ```
125
-
126
- Check without modifying files:
127
-
128
- ```powershell
129
- npm exec -- bcp-framework update --check
130
- ```
131
-
132
- ## Tailwind CSS
133
-
134
- When Tailwind is enabled, the project includes `tailwindcss`, `@tailwindcss/cli`, `concurrently`, `app/globals.css`, `/bcp.css` stylesheet setup and starter utility classes.
135
-
136
- Generated commands include:
137
-
138
- ```text
139
- npm run css:build
140
- npm run css:watch
141
- npm run css:build:prod
142
- ```
143
-
144
- `npm run build` and `npm run package` create the production stylesheet before the BCP production build/package flow.
145
-
146
96
  ## Database presets
147
97
 
148
- The database choice adds starter configuration and the matching driver:
98
+ Database choices add starter configuration and the matching driver:
149
99
 
150
100
  - MySQL: `mysql2`
151
101
  - PostgreSQL: `pg`
@@ -153,71 +103,31 @@ The database choice adds starter configuration and the matching driver:
153
103
  - MongoDB: `mongodb`
154
104
  - None: no database dependency
155
105
 
156
- For **MySQL**, **PostgreSQL** and **SQLite**, generated `lib/database.ts` exposes framework database primitives through `bcp/database`.
157
-
158
- The generator intentionally does not force an ORM.
159
-
160
- ## Storage providers
161
-
162
- Selecting a storage provider creates `lib/storage.ts` and provider-specific environment settings. Supported presets are Local Server, Amazon S3 and Cloudflare R2.
163
-
164
- Storage credentials are server-only. Do not expose them through `BCP_PUBLIC_*` variables.
165
-
166
- ## JWT Cookie authentication
167
-
168
- Selecting `JWT Cookie` creates `lib/auth.ts` and starter `/api/auth/login`, `/logout` and `/me` routes, and adds:
169
-
170
- ```dotenv
171
- BCP_SESSION_SECRET=
172
- ```
173
-
174
- Set this to a cryptographically random secret of at least 32 bytes before real authentication use.
106
+ For MySQL, PostgreSQL and SQLite, generated `lib/database.ts` exposes BCP database primitives through `bcp/database`.
175
107
 
176
- BCP `0.2.5+` can opt into revocable server-side auth state through `AuthSessionStore`.
108
+ ## Authentication and security
177
109
 
178
- ## Authorization & request security 0.2.6+
110
+ The JWT Cookie preset creates `lib/auth.ts` and starter auth routes. BCP `0.2.5+` supports optional revocable server-side auth state, while `0.2.6+` adds permission/policy authorization plus same-origin/CSRF helpers.
179
111
 
180
- Generated applications can use permission guards and resource policies from `bcp/auth`, plus same-origin and CSRF protection from `bcp/server`.
181
-
182
- Authorization and CSRF checks must remain on the server; hiding UI controls in client code is not an authorization boundary.
183
-
184
- ## Observability — 0.2.7+
185
-
186
- Generated projects can opt into process-local metrics and health/readiness without adding another dependency:
112
+ ## Observability
187
113
 
188
114
  ```ts
189
115
  import {
190
116
  createHealthRegistry,
191
117
  createMetricsRegistry,
192
- createRequestMetricsMiddleware,
193
118
  } from "bcp/observability";
194
119
  ```
195
120
 
196
- `bcp/observability` is server-only. Protect metrics and operational health detail with an appropriate network or authorization boundary when needed.
197
-
198
- ## Background jobs — 0.2.8+
199
-
200
- Generated projects can create a server-only background job queue:
121
+ ## Background jobs and scheduling
201
122
 
202
123
  ```ts
203
124
  import {
204
125
  createJobQueue,
126
+ createJobScheduler,
205
127
  } from "bcp/jobs";
206
128
 
207
129
  export const jobs =
208
130
  createJobQueue();
209
- ```
210
-
211
- Workers support concurrency, delayed jobs, retry/backoff and cancellation.
212
-
213
- ## Job scheduling — 0.2.9+
214
-
215
- Recurring schedules use the same `bcp/jobs` entrypoint:
216
-
217
- ```ts
218
- import {
219
- createJobScheduler,
220
- } from "bcp/jobs";
221
131
 
222
132
  export const scheduler =
223
133
  createJobScheduler({
@@ -225,82 +135,23 @@ export const scheduler =
225
135
  });
226
136
  ```
227
137
 
228
- Interval schedule:
229
-
230
- ```ts
231
- await scheduler.schedule(
232
- "cache.cleanup",
233
- {},
234
- {
235
- everyMs: 300_000,
236
- }
237
- );
238
- ```
239
-
240
- UTC cron schedule:
241
-
242
- ```ts
243
- await scheduler.schedule(
244
- "report.weekday",
245
- {},
246
- {
247
- cron: "30 9 * * 1-5",
248
- }
249
- );
250
- ```
251
-
252
- ## Durable jobs — 0.2.10+
253
-
254
- BCP `0.2.10` adds worker visibility leases, heartbeat renewal, stale-running recovery, DLQ/requeue, retention cleanup and queue statistics.
255
-
256
- ```ts
257
- const worker =
258
- jobs.startWorker({
259
- workerId: "worker-a",
260
- concurrency: 4,
261
- visibilityTimeoutMs: 30_000,
262
- heartbeatIntervalMs: 10_000,
263
- });
264
- ```
265
-
266
- BCP intentionally does not install a Redis client library. Applications own the Redis connection and can pass a minimal `RedisCommandClient` to `createRedisJobQueueAdapter()` and `createRedisJobScheduleStore()`.
267
-
268
- `bcp/jobs` is server-only and must not be imported into page/client bundles.
138
+ `0.2.10+` adds visibility leases, heartbeat renewal, stale-running recovery, DLQ/requeue, retention cleanup and Redis-compatible durable adapters.
269
139
 
270
140
  ## Workflow orchestration — 0.2.11+
271
141
 
272
- Generated applications can define persistent backend workflows with the new server-only `bcp/workflow` entrypoint:
273
-
274
142
  ```ts
275
143
  import {
276
144
  createWorkflow,
277
145
  } from "bcp/workflow";
278
146
 
279
147
  export const onboarding =
280
- createWorkflow<{
281
- userId: number;
282
- }>(
148
+ createWorkflow(
283
149
  "user.onboarding",
284
150
  workflow => {
285
151
  workflow.step(
286
152
  "profile",
287
153
  createProfile
288
154
  );
289
-
290
- workflow.parallel(
291
- "initialize",
292
- parallel => {
293
- parallel.step(
294
- "preferences",
295
- createPreferences
296
- );
297
- parallel.step(
298
- "workspace",
299
- createWorkspace
300
- );
301
- }
302
- );
303
-
304
155
  workflow.delay(
305
156
  "cooldown",
306
157
  1_000
@@ -309,45 +160,92 @@ export const onboarding =
309
160
  );
310
161
  ```
311
162
 
312
- Step-level retry and compensation are supported:
163
+ `bcp/workflow` supports sequential/parallel steps, retry, persisted delays, compensation and optional execution through `bcp/jobs`.
164
+
165
+ ## Transactional Outbox & Events — 0.2.12+
166
+
167
+ Applications using the SQL Database Platform can persist integration events in the same transaction as business data:
313
168
 
314
169
  ```ts
315
- workflow.step(
316
- "reserve-stock",
317
- reserveStock,
318
- {
319
- maxAttempts: 3,
320
- retryDelayMs: 1_000,
321
- compensate:
322
- releaseStock,
170
+ import {
171
+ db,
172
+ } from "bcp/database";
173
+
174
+ import {
175
+ createSqlOutboxStore,
176
+ createTransactionalOutbox,
177
+ } from "bcp/events";
178
+
179
+ const outboxStore =
180
+ createSqlOutboxStore({
181
+ database: db,
182
+ driver: "mysql",
183
+ });
184
+
185
+ const outbox =
186
+ createTransactionalOutbox({
187
+ store: outboxStore,
188
+ });
189
+
190
+ await db.transaction(
191
+ async tx => {
192
+ await tx.execute(
193
+ "INSERT INTO orders ..."
194
+ );
195
+
196
+ await outbox.publish(
197
+ tx,
198
+ "order.created",
199
+ {
200
+ orderId: 42,
201
+ }
202
+ );
323
203
  }
324
204
  );
325
205
  ```
326
206
 
327
- For durable queue-backed execution, pass an existing `BackgroundJobQueue` and a durable shared `WorkflowStore`:
207
+ Create migration SQL with:
328
208
 
329
209
  ```ts
330
- const fulfillment =
331
- createWorkflow(
332
- "order.fulfillment",
333
- defineWorkflow,
334
- {
335
- queue: jobs,
336
- store:
337
- workflowStore,
338
- }
210
+ import {
211
+ createOutboxMigrationSql,
212
+ } from "bcp/events";
213
+
214
+ const migrationSql =
215
+ createOutboxMigrationSql(
216
+ "mysql"
339
217
  );
340
218
  ```
341
219
 
342
- The built-in `createMemoryWorkflowStore()` is intended for development/tests. Multi-instance production stores should make `claim()` atomic so only one executor owns a workflow run lease at a time.
220
+ After commit, dispatch to the durable job queue:
343
221
 
344
- External side effects should remain idempotent because durable queue execution is at-least-once.
222
+ ```ts
223
+ import {
224
+ createOutboxDispatcher,
225
+ } from "bcp/events";
345
226
 
346
- `bcp/workflow` is server-only and cannot be imported into page/client bundles.
227
+ const dispatcher =
228
+ createOutboxDispatcher({
229
+ store: outboxStore,
230
+ queue: jobs,
231
+ ownerId: "outbox-a",
232
+ });
233
+
234
+ const runner =
235
+ dispatcher.start();
236
+ ```
347
237
 
348
- ## Application Packaging 0.2.4+
238
+ Event type `order.created` is handed off to queue name `event.order.created`.
349
239
 
350
- Generated projects include:
240
+ The outbox dispatcher supports leases, stale recovery, retry/backoff, custom publishers, a local EventBus, cleanup and statistics.
241
+
242
+ `bcp/events` is server-only. The SQL outbox protects the database-commit/external-publish boundary, but downstream delivery remains at-least-once, so non-repeatable side effects should use idempotency protection.
243
+
244
+ ## Storage providers
245
+
246
+ Supported presets are Local Server, Amazon S3 and Cloudflare R2. Storage credentials are server-only and must not use `BCP_PUBLIC_*` variables.
247
+
248
+ ## Application packaging
351
249
 
352
250
  ```bash
353
251
  npm run package
@@ -355,7 +253,7 @@ npm run package
355
253
 
356
254
  The deployment package excludes application `devDependencies` and project `.env` values. Supply real secrets through the deployment environment.
357
255
 
358
- ## Project generators after creation
256
+ ## Project generators
359
257
 
360
258
  ```bash
361
259
  npm run generate -- page dashboard/users
@@ -364,15 +262,6 @@ npm run generate -- middleware
364
262
  npm run generate -- migration create_users
365
263
  ```
366
264
 
367
- Equivalent direct CLI:
368
-
369
- ```bash
370
- bcp generate page dashboard/users
371
- bcp generate api users
372
- bcp generate middleware
373
- bcp generate migration create_users
374
- ```
375
-
376
265
  ## Options
377
266
 
378
267
  ```text
@@ -387,8 +276,8 @@ bcp generate migration create_users
387
276
  -h, --help Show help
388
277
  ```
389
278
 
390
- The `--bcp` option is mainly for prerelease/local package verification:
279
+ For prerelease/local package verification:
391
280
 
392
281
  ```bash
393
- npx create-bcp-app my-app --bcp file:../chidchanun-bcp-0.2.11.tgz
282
+ npx create-bcp-app my-app --bcp file:../chidchanun-bcp-0.2.12.tgz
394
283
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-bcp-app",
3
- "version": "0.2.11",
3
+ "version": "0.2.12",
4
4
  "description": "Create a new BCP Framework application.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -12,8 +12,6 @@ Open `http://localhost:3000`.
12
12
 
13
13
  ## Project commands
14
14
 
15
- Generated projects use the project-local BCP Framework CLI through npm scripts:
16
-
17
15
  ```bash
18
16
  npm run dev
19
17
  npm run routes
@@ -25,25 +23,17 @@ npm start
25
23
  npm run update
26
24
  ```
27
25
 
28
- The generated scripts call commands such as `bcp dev`, `bcp generate`, `bcp build`, `bcp package` and `bcp start`.
29
-
30
26
  ## Project metadata
31
27
 
32
- Projects created with BCP `0.1.29+` include `bcp.project.json` with non-secret scaffold metadata.
33
-
34
- Commit this file with the project. Do not put passwords, access keys, session secrets or tokens in it.
28
+ Generated projects include `bcp.project.json` with non-secret scaffold metadata. Commit it with the project, but never put passwords, tokens or access keys in it.
35
29
 
36
30
  ## Authentication — BCP 0.2.5+
37
31
 
38
- Projects created with the `JWT Cookie` preset remain stateless by default and use the generated `lib/auth.ts` helpers.
39
-
40
- BCP Authentication Platform v2 can opt into revocable server-side session state with `createAuth()` and `AuthSessionStore`.
32
+ JWT Cookie projects can opt into revocable server-side session state with `createAuth()` and `AuthSessionStore`.
41
33
 
42
34
  ## Authorization & request security — BCP 0.2.6+
43
35
 
44
- Use permission guards and resource policies from `bcp/auth`, and same-origin/CSRF protection from `bcp/server`.
45
-
46
- Authorization must always be enforced server-side. Client UI visibility is not a security boundary.
36
+ Use permission guards/resource policies from `bcp/auth`, and same-origin/CSRF protection from `bcp/server`. Authorization must remain server-side.
47
37
 
48
38
  ## Observability — BCP 0.2.7+
49
39
 
@@ -51,16 +41,11 @@ Authorization must always be enforced server-side. Client UI visibility is not a
51
41
  import {
52
42
  createHealthRegistry,
53
43
  createMetricsRegistry,
54
- createRequestMetricsMiddleware,
55
44
  } from "bcp/observability";
56
45
  ```
57
46
 
58
- Protect operational endpoints when their contents should not be public.
59
-
60
47
  ## Background jobs — BCP 0.2.8+
61
48
 
62
- Create a server-only background queue:
63
-
64
49
  ```ts
65
50
  import {
66
51
  createJobQueue,
@@ -70,21 +55,6 @@ export const jobs =
70
55
  createJobQueue();
71
56
  ```
72
57
 
73
- Register typed work:
74
-
75
- ```ts
76
- jobs.register<{
77
- userId: number;
78
- }>(
79
- "email.welcome",
80
- async ({ payload }) => {
81
- await sendWelcomeEmail(
82
- payload.userId
83
- );
84
- }
85
- );
86
- ```
87
-
88
58
  ## Job scheduling — BCP 0.2.9+
89
59
 
90
60
  ```ts
@@ -98,21 +68,9 @@ export const scheduler =
98
68
  });
99
69
  ```
100
70
 
101
- Example UTC cron schedule:
102
-
103
- ```ts
104
- await scheduler.schedule(
105
- "report.weekday",
106
- {},
107
- {
108
- cron: "30 9 * * 1-5",
109
- }
110
- );
111
- ```
112
-
113
71
  ## Durable jobs — BCP 0.2.10+
114
72
 
115
- Workers can use visibility leases, heartbeat renewal and stale-running recovery:
73
+ Workers can use visibility leases, heartbeat renewal, stale recovery and DLQ/requeue. Redis-compatible adapters are available without forcing a Redis client dependency.
116
74
 
117
75
  ```ts
118
76
  const worker =
@@ -124,132 +82,21 @@ const worker =
124
82
  });
125
83
  ```
126
84
 
127
- Retry-exhausted jobs are available through the adapter DLQ contract:
128
-
129
- ```ts
130
- const deadLetters =
131
- await jobs.deadLetters();
132
-
133
- await jobs.requeueDeadLetter(
134
- deadLetters[0].id,
135
- {
136
- resetAttempts: true,
137
- }
138
- );
139
- ```
140
-
141
- Operational helpers:
142
-
143
- ```ts
144
- await jobs.recoverStale();
145
- const stats = await jobs.stats();
146
- await jobs.cleanup({
147
- before:
148
- Date.now() -
149
- 7 * 24 * 60 * 60 * 1000,
150
- });
151
- ```
152
-
153
- ### Redis-compatible adapters
154
-
155
- BCP does not install a Redis library. Supply an application-owned command client:
156
-
157
- ```ts
158
- interface RedisCommandClient {
159
- sendCommand(
160
- command: string[]
161
- ): Promise<unknown>;
162
- }
163
- ```
164
-
165
- Create a durable queue:
166
-
167
- ```ts
168
- import {
169
- createJobQueue,
170
- createRedisJobQueueAdapter,
171
- } from "bcp/jobs";
172
-
173
- const adapter =
174
- createRedisJobQueueAdapter({
175
- client: redisCommandClient,
176
- namespace: "my-app:{jobs}",
177
- });
178
-
179
- export const jobs =
180
- createJobQueue({
181
- adapter,
182
- });
183
- ```
184
-
185
- Create a shared schedule store:
186
-
187
- ```ts
188
- import {
189
- createJobScheduler,
190
- createRedisJobScheduleStore,
191
- } from "bcp/jobs";
192
-
193
- const store =
194
- createRedisJobScheduleStore({
195
- client: redisCommandClient,
196
- namespace: "my-app:{jobs}",
197
- });
198
-
199
- export const scheduler =
200
- createJobScheduler({
201
- queue: jobs,
202
- store,
203
- ownerId: "scheduler-a",
204
- });
205
- ```
206
-
207
- A typical deployment may use:
208
-
209
- ```dotenv
210
- REDIS_URL=redis://localhost:6379
211
- ```
212
-
213
- BCP does not read this variable automatically. The application owns Redis connection creation, credentials, TLS/Cluster configuration and shutdown.
214
-
215
- The processing model is at-least-once, so side-effecting job handlers should be idempotent when duplicate execution is unsafe.
216
-
217
- `bcp/jobs` is server-only and cannot be imported into page/client bundles.
218
-
219
85
  ## Workflow orchestration — BCP 0.2.11+
220
86
 
221
- Define persistent server-side workflows through `bcp/workflow`:
222
-
223
87
  ```ts
224
88
  import {
225
89
  createWorkflow,
226
90
  } from "bcp/workflow";
227
91
 
228
92
  export const onboarding =
229
- createWorkflow<{
230
- userId: number;
231
- }>(
93
+ createWorkflow(
232
94
  "user.onboarding",
233
95
  workflow => {
234
96
  workflow.step(
235
97
  "profile",
236
98
  createProfile
237
99
  );
238
-
239
- workflow.parallel(
240
- "initialize",
241
- parallel => {
242
- parallel.step(
243
- "preferences",
244
- createPreferences
245
- );
246
- parallel.step(
247
- "workspace",
248
- createWorkspace
249
- );
250
- }
251
- );
252
-
253
100
  workflow.delay(
254
101
  "cooldown",
255
102
  1_000
@@ -258,41 +105,86 @@ export const onboarding =
258
105
  );
259
106
  ```
260
107
 
261
- Step retry and compensation:
108
+ Workflows support sequential/parallel steps, retries, persisted delays, compensation, run leases and optional durable queue execution.
109
+
110
+ ## Transactional Outbox & Events — BCP 0.2.12+
111
+
112
+ Use `bcp/events` when application data and an integration event must commit atomically in the same SQL transaction.
262
113
 
263
114
  ```ts
264
- workflow.step(
265
- "reserve-stock",
266
- reserveStock,
267
- {
268
- maxAttempts: 3,
269
- retryDelayMs: 1_000,
270
- compensate:
271
- releaseStock,
115
+ import {
116
+ db,
117
+ } from "bcp/database";
118
+
119
+ import {
120
+ createSqlOutboxStore,
121
+ createTransactionalOutbox,
122
+ } from "bcp/events";
123
+
124
+ const outboxStore =
125
+ createSqlOutboxStore({
126
+ database: db,
127
+ driver: "mysql",
128
+ });
129
+
130
+ const outbox =
131
+ createTransactionalOutbox({
132
+ store: outboxStore,
133
+ });
134
+
135
+ await db.transaction(
136
+ async tx => {
137
+ await tx.execute(
138
+ "INSERT INTO orders ..."
139
+ );
140
+
141
+ await outbox.publish(
142
+ tx,
143
+ "order.created",
144
+ {
145
+ orderId: 42,
146
+ }
147
+ );
272
148
  }
273
149
  );
274
150
  ```
275
151
 
276
- For queue-backed execution:
152
+ Generate the required table SQL:
277
153
 
278
154
  ```ts
279
- const fulfillment =
280
- createWorkflow(
281
- "order.fulfillment",
282
- defineWorkflow,
283
- {
284
- queue: jobs,
285
- store:
286
- workflowStore,
287
- }
155
+ import {
156
+ createOutboxMigrationSql,
157
+ } from "bcp/events";
158
+
159
+ const sql =
160
+ createOutboxMigrationSql(
161
+ "mysql"
288
162
  );
289
163
  ```
290
164
 
291
- The default `createMemoryWorkflowStore()` is for local development/tests. Multi-instance production deployments should implement a shared durable `WorkflowStore` with atomic `claim()` behavior.
165
+ Dispatch committed events to the durable queue:
166
+
167
+ ```ts
168
+ import {
169
+ createOutboxDispatcher,
170
+ } from "bcp/events";
171
+
172
+ const dispatcher =
173
+ createOutboxDispatcher({
174
+ store: outboxStore,
175
+ queue: jobs,
176
+ ownerId: "outbox-a",
177
+ });
178
+
179
+ const runner =
180
+ dispatcher.start();
181
+ ```
182
+
183
+ Event `order.created` is queued as `event.order.created`.
292
184
 
293
- Workflow handlers that perform external side effects should be idempotent because durable job execution is at-least-once.
185
+ The dispatcher supports leases, stale recovery, retry/backoff, custom publishers, local EventBus delivery, retention cleanup and statistics.
294
186
 
295
- `bcp/workflow` is server-only and cannot be imported into page/client bundles.
187
+ `bcp/events` is server-only. Outbox delivery remains at-least-once, so non-repeatable downstream side effects should use idempotency protection.
296
188
 
297
189
  ## Generate framework files
298
190
 
@@ -303,22 +195,9 @@ npm run generate -- middleware
303
195
  npm run generate -- migration create_users
304
196
  ```
305
197
 
306
- Equivalent direct commands:
307
-
308
- ```bash
309
- bcp generate page dashboard/users
310
- bcp generate api users
311
- bcp generate middleware
312
- bcp generate migration create_users
313
- ```
314
-
315
- Existing page/API/middleware targets are not replaced unless `--force` is supplied explicitly.
316
-
317
198
  ## Direct CLI usage
318
199
 
319
- BCP Framework is installed as a project-local dependency.
320
-
321
- For PowerShell direct usage:
200
+ For PowerShell:
322
201
 
323
202
  ```powershell
324
203
  npm exec -- bcp-framework --version
@@ -330,8 +209,6 @@ npm exec -- bcp-framework build
330
209
  npm exec -- bcp-framework package
331
210
  ```
332
211
 
333
- Microsoft SQL Server can install another Windows executable named `bcp.exe`, so the `bcp-framework` alias avoids that command-name collision.
334
-
335
212
  ## Production build
336
213
 
337
214
  ```bash
@@ -339,12 +216,10 @@ npm run build
339
216
  npm start
340
217
  ```
341
218
 
342
- ## Deployment package — BCP 0.2.4+
219
+ ## Deployment package
343
220
 
344
221
  ```bash
345
222
  npm run package
346
223
  ```
347
224
 
348
- The output is written to `.bcp-framework/package/` and contains standalone output, production dependency metadata, deployment/environment manifests, integrity hashes and a starter Dockerfile.
349
-
350
- BCP intentionally excludes project `.env` files and application `devDependencies` from the deployment package. Provide secrets through your deployment environment.
225
+ BCP excludes project `.env` files and application `devDependencies` from the deployment package. Supply secrets through the deployment environment.