@chidchanun/bcp 0.1.21 → 0.1.23

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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  BCP Framework is a React full-stack framework with file-based routing, SSR, client navigation, API routes, middleware, metadata, client islands, cache/revalidation, validation, structured errors, authentication, database primitives, security defaults and standalone production builds.
4
4
 
5
- > Current release target: `0.1.21`. BCP is still pre-1.0 and validates each release candidate before the manual npm publish step.
5
+ > Current release target: `0.1.22`. BCP is still pre-1.0 and validates each release candidate before the manual npm publish step.
6
6
 
7
7
  ## Quick start
8
8
 
@@ -110,6 +110,37 @@ Applications should not need to rewrite multiline classes to one line or use `su
110
110
 
111
111
  See [Hydration and deterministic rendering](docs/hydration.md) for the transform pipeline and troubleshooting guidance.
112
112
 
113
+ ## Developer diagnostics
114
+
115
+ BCP 0.1.22 adds dedicated developer tooling for diagnosing application setup without starting the development server.
116
+
117
+ Run a project health check:
118
+
119
+ ```bash
120
+ bcp doctor
121
+ ```
122
+
123
+ The doctor checks the Node.js runtime, project structure, installed BCP/React packages, React and React DOM version parity, duplicate React package roots, environment/config loading, route conflicts and client/server boundaries. Blocking failures produce a non-zero process exit code.
124
+
125
+ Inspect the resolved project inputs BCP sees:
126
+
127
+ ```bash
128
+ bcp inspect
129
+ ```
130
+
131
+ This prints development env filenames, public environment variable names, resolved BCP configuration, dependency versions and discovered page/API routes.
132
+
133
+ Both commands support JSON output:
134
+
135
+ ```bash
136
+ bcp doctor --json
137
+ bcp inspect --json
138
+ ```
139
+
140
+ The duplicate React checks are especially useful when verifying local framework builds. Install packed `.tgz` artifacts for release testing instead of linking `.package/bcp` directly into another project, because a linked staging directory can make the application and SSR renderer resolve different React instances.
141
+
142
+ See [Developer Tools](docs/developer-tools.md) for the complete command reference.
143
+
113
144
  ## Commands
114
145
 
115
146
  ```bash
@@ -117,6 +148,10 @@ bcp dev
117
148
  bcp routes
118
149
  bcp build
119
150
  bcp start
151
+ bcp doctor
152
+ bcp doctor --json
153
+ bcp inspect
154
+ bcp inspect --json
120
155
  bcp update
121
156
  bcp version
122
157
  ```
@@ -141,7 +176,7 @@ bcp update --dry-run
141
176
  Or select a published version/dist-tag explicitly:
142
177
 
143
178
  ```bash
144
- bcp update 0.1.21
179
+ bcp update 0.1.22
145
180
  bcp update next
146
181
  ```
147
182
 
@@ -810,6 +845,7 @@ No real npm publish command is run automatically by the repository.
810
845
  - [Database Migrations](docs/database-migrations.md)
811
846
  - [Middleware](docs/middleware.md)
812
847
  - [Hydration and deterministic rendering](docs/hydration.md)
848
+ - [Developer Tools](docs/developer-tools.md)
813
849
  - [Updating BCP Framework](docs/updating.md)
814
850
  - [Routing](docs/routing.md)
815
851
  - [Configuration](docs/configuration.md)
package/docs/README.md CHANGED
@@ -4,7 +4,7 @@ This directory is the documentation source of truth for the BCP Framework docume
4
4
 
5
5
  The recommended documentation website project name is `bcp-docs`.
6
6
 
7
- > Documentation target: BCP Framework `0.1.21`
7
+ > Documentation target: BCP Framework `0.1.23`
8
8
 
9
9
  ## Purpose
10
10
 
@@ -64,9 +64,10 @@ The website should not invent API behavior that is not documented or tested in t
64
64
  | --- | --- | --- |
65
65
  | `/docs/middleware` | `middleware.md` | Middleware System v2 and v1 compatibility |
66
66
  | `/docs/hydration` | `hydration.md` | SSR/client transform parity, deterministic rendering and Windows line endings |
67
+ | `/docs/developer-tools` | `developer-tools.md` | `bcp doctor`, `bcp inspect` and JSON diagnostics |
68
+ | `/docs/development-logging` | `development-logging.md` | Structured logging, request identity and development observability |
67
69
  | `/docs/caching` | `caching.md` | Cache and revalidation |
68
70
  | `/docs/security` | `security.md` | Framework security defaults |
69
- | `/docs/development-logging` | `development-logging.md` | Development request logging |
70
71
 
71
72
  ### Releases
72
73
 
@@ -75,9 +76,9 @@ Use the files under `docs/releases/` for release pages.
75
76
  Recommended route format:
76
77
 
77
78
  ```text
78
- /releases/0.1.19
79
- /releases/0.1.20
80
79
  /releases/0.1.21
80
+ /releases/0.1.22
81
+ /releases/0.1.23
81
82
  ```
82
83
 
83
84
  The newest release should also be available from `/releases`.
@@ -151,6 +152,16 @@ Recommended feature groups:
151
152
  - Tailwind preset
152
153
  - Database/auth presets
153
154
  - `bcp update`
155
+ - `bcp doctor` project/runtime diagnostics
156
+ - `bcp inspect` environment/config/route inspection
157
+ - JSON developer-tool output for CI/automation
158
+ - Duplicate React and duplicate BCP installation diagnostics
159
+ - `bcp-framework` Windows-safe CLI alias
160
+ - Structured server logger
161
+ - Request-scoped loggers with request identity
162
+ - Pretty and JSON log formats
163
+ - Configurable log levels
164
+ - Structured development HTTP/SSR timing events
154
165
  - Standalone production builds
155
166
  - Critical CSS
156
167
  - Cache/revalidation
@@ -165,7 +176,7 @@ Suggested content, not a required exact copy:
165
176
  BCP Framework
166
177
  A React full-stack framework for building server-rendered applications with routing,
167
178
  data loading, server mutations, authentication, databases, validation, structured errors,
168
- middleware and production tooling.
179
+ middleware, observability and production tooling.
169
180
  ```
170
181
 
171
182
  Primary actions:
@@ -210,17 +221,18 @@ Database
210
221
  Runtime
211
222
  Middleware
212
223
  Hydration
224
+ Developer Tools
225
+ Logging & Observability
213
226
  Caching
214
227
  Security
215
228
 
216
229
  Production
217
230
  Deployment
218
- Development Logging
219
231
 
220
232
  Releases
233
+ 0.1.23
234
+ 0.1.22
221
235
  0.1.21
222
- 0.1.20
223
- 0.1.19
224
236
  ```
225
237
 
226
238
  ## Suggested documentation page layout
@@ -274,6 +286,11 @@ import {
274
286
  unauthorized,
275
287
  } from "bcp/error";
276
288
 
289
+ import {
290
+ logger,
291
+ requestLogger,
292
+ } from "bcp/server";
293
+
277
294
  import {
278
295
  type MiddlewarePipelineHandler,
279
296
  } from "bcp/middleware";
@@ -305,6 +322,10 @@ bcp dev
305
322
  bcp routes
306
323
  bcp build
307
324
  bcp start
325
+ bcp doctor
326
+ bcp doctor --json
327
+ bcp inspect
328
+ bcp inspect --json
308
329
  bcp update
309
330
  bcp version
310
331
 
@@ -314,6 +335,8 @@ bcp db status
314
335
  bcp db rollback
315
336
  ```
316
337
 
338
+ On Windows systems where Microsoft SQL Server owns the `bcp` executable name, document the equivalent collision-free commands with `bcp-framework`.
339
+
317
340
  Project creation:
318
341
 
319
342
  ```bash
@@ -392,11 +415,44 @@ The docs website should make these points clear:
392
415
 
393
416
  See `hydration.md` for the full explanation, transform pipeline and troubleshooting steps.
394
417
 
395
- ## Release roadmap adjustment
418
+ ## Developer Tools documentation priority
419
+
420
+ BCP 0.1.22 adds `bcp doctor` and `bcp inspect` as the first dedicated developer-diagnostics commands.
421
+
422
+ The docs website should surface:
423
+
424
+ - PASS/WARN/FAIL health checks,
425
+ - non-zero exit codes for blocking doctor failures,
426
+ - React / React DOM version and package-root parity,
427
+ - duplicate `bcp` / `@chidchanun/bcp` installation detection,
428
+ - config and development environment inspection,
429
+ - page/API route summaries,
430
+ - `--json` output for CI and automation,
431
+ - the recommendation to verify local releases from packed `.tgz` artifacts installed under the existing `bcp` dependency key rather than linked staging directories.
432
+
433
+ See `developer-tools.md` for the full command reference.
434
+
435
+ ## Logging and observability documentation priority
436
+
437
+ BCP 0.1.23 adds the structured logging foundation through `bcp/server`.
438
+
439
+ The docs website should surface:
440
+
441
+ - `logger.debug/info/warn/error`,
442
+ - `createLogger()` and child loggers,
443
+ - `requestLogger()` and its request ID/method/path bindings,
444
+ - `attachRequestId()` for `X-Request-Id` response propagation,
445
+ - `BCP_LOG_LEVEL`,
446
+ - `BCP_LOG_FORMAT=pretty|json`,
447
+ - JSON-safe `Error`, `bigint` and circular value handling,
448
+ - structured `http.request`, `module.import` and `ssr.render` development events,
449
+ - the existing dev noise filter for framework-internal requests.
450
+
451
+ See `development-logging.md` for the complete API and examples.
396
452
 
397
- `0.1.21` is reserved for the hydration parity hotfix because `0.1.20` was already published before the remaining Babel JSX whitespace mismatch was isolated.
453
+ ## Release roadmap
398
454
 
399
- The previously planned Developer Tools release moves to `0.1.22`, and later roadmap items should shift forward accordingly unless they are regrouped into a larger milestone.
455
+ `0.1.23` is the Logging & Observability milestone. The next planned milestone is `0.1.24` File Upload foundation, followed by Background Jobs, Testing Utilities, Production Build Hardening and Plugin Architecture unless milestones are regrouped.
400
456
 
401
457
  ## Release workflow for documentation
402
458
 
@@ -0,0 +1,166 @@
1
+ # Developer Tools
2
+
3
+ BCP Framework 0.1.22 adds project diagnostics and runtime inspection commands for debugging a BCP application without starting the development server.
4
+
5
+ ## CLI executable names
6
+
7
+ The published BCP package exposes two executable names that point to the same CLI:
8
+
9
+ ```text
10
+ bcp
11
+ bcp-framework
12
+ ```
13
+
14
+ `bcp` remains the primary and backward-compatible command.
15
+
16
+ On Windows, Microsoft SQL Server also installs a native utility named `bcp.exe`. When that executable appears earlier on `PATH`, typing `bcp` in PowerShell can launch the SQL Server utility instead of BCP Framework.
17
+
18
+ Use the Windows-safe alias in that situation:
19
+
20
+ ```powershell
21
+ bcp-framework doctor
22
+ bcp-framework inspect
23
+ bcp-framework dev
24
+ bcp-framework build
25
+ bcp-framework update
26
+ ```
27
+
28
+ You can also explicitly run the project-local executable with npm:
29
+
30
+ ```powershell
31
+ npm exec -- bcp doctor
32
+ ```
33
+
34
+ BCP application npm scripts can continue using `bcp dev`, `bcp build`, and other existing commands because npm places the project's `node_modules/.bin` directory on the script `PATH` before system executables.
35
+
36
+ ## `bcp doctor`
37
+
38
+ Run a health check from the application root:
39
+
40
+ ```bash
41
+ bcp doctor
42
+ ```
43
+
44
+ The command checks:
45
+
46
+ - the current Node.js runtime against BCP's minimum supported version,
47
+ - `package.json` and the `app/` project structure,
48
+ - the declared and installed BCP package,
49
+ - installed `react` and `react-dom` versions,
50
+ - React / React DOM resolution parity between the application and the framework,
51
+ - development environment files,
52
+ - resolved `bcp.config.*` settings,
53
+ - page/API route discovery and conflicts,
54
+ - client/server module boundaries.
55
+
56
+ A successful check is printed as `PASS`, a non-blocking recommendation as `WARN`, and a blocking project/runtime problem as `FAIL`.
57
+
58
+ If one or more checks fail, `bcp doctor` sets a non-zero process exit code. This makes it suitable for local scripts and CI gates.
59
+
60
+ Example:
61
+
62
+ ```text
63
+ BCP Doctor v0.1.22
64
+ Project: D:\apps\my-bcp-app
65
+ Runtime: Node.js 24.15.0 | win32 x64
66
+
67
+ [PASS] Node.js runtime: Node.js 24.15.0 satisfies >=24.11.0.
68
+ [PASS] Project package: package.json is readable.
69
+ [PASS] App directory: app/ is present.
70
+ [PASS] React renderer version parity: react and react-dom both resolve to 19.2.8.
71
+ [PASS] Single React instance: BCP and the application resolve the same React package.
72
+
73
+ Summary: 11 passed, 0 warning(s), 0 failed.
74
+ ```
75
+
76
+ ### Duplicate React detection
77
+
78
+ `bcp doctor` specifically checks the package locations used by the application and by BCP itself.
79
+
80
+ This catches local-development layouts where an application resolves React from one `node_modules` tree while the BCP SSR renderer resolves React DOM from another. That situation commonly produces:
81
+
82
+ ```text
83
+ Invalid hook call. Hooks can only be called inside of the body of a function component.
84
+ ```
85
+
86
+ For local release testing, install the packed `.tgz` artifact instead of linking `.package/bcp` directly into another project. A packed package lets the BCP peer dependencies resolve from the application's normal `node_modules` tree.
87
+
88
+ ### Duplicate BCP package protection
89
+
90
+ A BCP application must not load `node_modules/bcp` and `node_modules/@chidchanun/bcp` as two separate framework copies.
91
+
92
+ The CLI performs a startup preflight. If both package roots exist, runtime commands such as `dev`, `build`, and `start` stop before SSR starts. Two framework copies create separate React contexts, which can make APIs such as `useLoaderData()` incorrectly report missing loader data even when the route loader executed successfully.
93
+
94
+ For local release verification, install the tarball under the existing `bcp` dependency key instead of adding the scoped package beside it:
95
+
96
+ ```powershell
97
+ npm install `
98
+ --no-save `
99
+ --package-lock=false `
100
+ "bcp@file:D:\bcp-framework\.package\artifacts\chidchanun-bcp-0.1.22.tgz"
101
+ ```
102
+
103
+ The installed folder remains `node_modules/bcp` even when the package inside the tarball is published as `@chidchanun/bcp`.
104
+
105
+ ## `bcp inspect`
106
+
107
+ Use `inspect` when you want a deterministic snapshot of the project inputs BCP sees:
108
+
109
+ ```bash
110
+ bcp inspect
111
+ ```
112
+
113
+ It prints:
114
+
115
+ - framework version,
116
+ - Node.js/platform information,
117
+ - development `.env` files that were loaded,
118
+ - names of public `BCP_PUBLIC_*` variables (values are not exposed by the summary),
119
+ - the fully resolved BCP configuration,
120
+ - resolved BCP/React/React DOM package versions,
121
+ - discovered page and API routes.
122
+
123
+ `inspect` validates route conflicts and client boundaries before printing its report. It does not start an HTTP server.
124
+
125
+ ## JSON output
126
+
127
+ Both commands support machine-readable output:
128
+
129
+ ```bash
130
+ bcp doctor --json
131
+ bcp inspect --json
132
+ ```
133
+
134
+ You can also target another project directory:
135
+
136
+ ```bash
137
+ bcp doctor --root ../my-app --json
138
+ bcp inspect --root ../my-app --json
139
+ ```
140
+
141
+ `--json` is intentionally limited to `doctor` and `inspect` so other CLI commands keep their existing human-oriented output contracts.
142
+
143
+ ## Environment and config behavior
144
+
145
+ Developer tools inspect the development environment because they are intended to diagnose `bcp dev` projects.
146
+
147
+ Environment file precedence remains the same as the normal framework environment loader:
148
+
149
+ ```text
150
+ .env
151
+ .env.local
152
+ .env.development
153
+ .env.development.local
154
+ ```
155
+
156
+ Resolved configuration still follows the framework configuration precedence rules. `bcp inspect` displays the final resolved config rather than only the source `bcp.config.*` object.
157
+
158
+ ## CI example
159
+
160
+ A simple project-health gate can use:
161
+
162
+ ```bash
163
+ bcp doctor --json > bcp-doctor.json
164
+ ```
165
+
166
+ The command exits non-zero when blocking checks fail, while the JSON report remains available for CI logs or artifacts.
@@ -1,13 +1,241 @@
1
- # Development request logging
1
+ # Logging and observability
2
2
 
3
- BCP keeps development request output focused on application API traffic.
3
+ BCP Framework 0.1.23 adds a structured server logger and upgrades development request timing output while keeping framework-internal browser/bootstrap traffic quiet by default.
4
4
 
5
- By default, request-style console lines are shown for application API routes such as:
5
+ ## Server logger
6
+
7
+ Import logging APIs from the server-only `bcp/server` entry:
8
+
9
+ ```ts
10
+ import {
11
+ logger,
12
+ } from "bcp/server";
13
+
14
+ logger.info(
15
+ "Application started",
16
+ {
17
+ service: "catalog",
18
+ }
19
+ );
20
+ ```
21
+
22
+ Available levels are:
23
+
24
+ ```text
25
+ debug
26
+ info
27
+ warn
28
+ error
29
+ silent
30
+ ```
31
+
32
+ The default level is `info`.
33
+
34
+ Structured fields can contain strings, numbers, booleans, objects, arrays, `Error` values and `bigint` values. Circular references are replaced with `[Circular]` rather than crashing the logger.
35
+
36
+ ## Request-scoped logging
37
+
38
+ Use `requestLogger()` while handling an API route, loader, guard or form action:
39
+
40
+ ```ts
41
+ import {
42
+ requestLogger,
43
+ } from "bcp/server";
44
+
45
+ export async function loader() {
46
+ const log =
47
+ await requestLogger({
48
+ feature: "categories",
49
+ });
50
+
51
+ log.info(
52
+ "Loading categories"
53
+ );
54
+
55
+ return {
56
+ items: [],
57
+ };
58
+ }
59
+ ```
60
+
61
+ The returned child logger automatically binds the current request identity:
62
+
63
+ ```text
64
+ requestId
65
+ method
66
+ path
67
+ ```
68
+
69
+ `requestId` uses the same request-scoped value exposed by `requestId()`: a valid incoming `X-Request-Id` is reused, otherwise BCP creates a UUID for the request.
70
+
71
+ ## Response request ID
72
+
73
+ When an application wants to return the request identity to a caller, wrap a response with `attachRequestId()`:
74
+
75
+ ```ts
76
+ import {
77
+ attachRequestId,
78
+ json,
79
+ } from "bcp/server";
80
+
81
+ export async function GET() {
82
+ return attachRequestId(
83
+ json({
84
+ ok: true,
85
+ })
86
+ );
87
+ }
88
+ ```
89
+
90
+ The returned response includes:
6
91
 
7
92
  ```text
8
- GET /api/users 200 1.24ms
93
+ X-Request-Id: <current request id>
94
+ ```
95
+
96
+ This helper preserves the original response status, status text, body and headers.
97
+
98
+ ## Child loggers
99
+
100
+ Bind shared fields once with `child()`:
101
+
102
+ ```ts
103
+ import {
104
+ logger,
105
+ } from "bcp/server";
106
+
107
+ const dbLog =
108
+ logger.child({
109
+ component: "database",
110
+ });
111
+
112
+ dbLog.debug(
113
+ "Executing query",
114
+ {
115
+ operation: "users.list",
116
+ }
117
+ );
9
118
  ```
10
119
 
11
- BCP suppresses framework and browser bootstrap traffic such as `/_bcp/*`, page/document requests, public static assets, and the generated Tailwind stylesheet endpoint `/api/bcp-styles`.
120
+ Child bindings are inherited by further child loggers.
121
+
122
+ ## Log level
123
+
124
+ Set the minimum log level with:
125
+
126
+ ```bash
127
+ BCP_LOG_LEVEL=debug
128
+ ```
129
+
130
+ Supported values:
131
+
132
+ ```text
133
+ debug
134
+ info
135
+ warn
136
+ error
137
+ silent
138
+ ```
139
+
140
+ Invalid or missing values fall back to `info`.
141
+
142
+ Use `debug` during framework/application diagnostics to see development SSR and module-import timing events.
143
+
144
+ ## Log format
12
145
 
13
- Build, SSR, Fast Refresh, watcher and error diagnostics are not affected by this filter.
146
+ Human-readable output is the default:
147
+
148
+ ```bash
149
+ BCP_LOG_FORMAT=pretty
150
+ ```
151
+
152
+ Example:
153
+
154
+ ```text
155
+ [2026-08-27T10:00:00.000Z] [INFO] [bcp] User loaded userId=42
156
+ ```
157
+
158
+ For containers, log collectors and CI systems use JSON lines:
159
+
160
+ ```bash
161
+ BCP_LOG_FORMAT=json
162
+ ```
163
+
164
+ Example:
165
+
166
+ ```json
167
+ {"timestamp":"2026-08-27T10:00:00.000Z","level":"info","logger":"bcp","message":"User loaded","userId":42}
168
+ ```
169
+
170
+ Each log call emits exactly one line.
171
+
172
+ ## Development HTTP logging
173
+
174
+ Development request output remains focused on application API traffic. BCP suppresses request-style logs for framework and browser bootstrap traffic such as:
175
+
176
+ ```text
177
+ /_bcp/*
178
+ /api/bcp-styles
179
+ page/document requests
180
+ public static assets
181
+ ```
182
+
183
+ An application API request is converted into the structured logger format. With pretty output it resembles:
184
+
185
+ ```text
186
+ [2026-08-27T10:00:00.000Z] [INFO] [bcp-dev] HTTP request event=http.request method=GET path=/api/users status=200 durationMs=1.24
187
+ ```
188
+
189
+ With `BCP_LOG_FORMAT=json` the same event is emitted as one JSON object containing:
190
+
191
+ ```text
192
+ event=http.request
193
+ method
194
+ path
195
+ status
196
+ durationMs
197
+ ```
198
+
199
+ Existing development `Import: ...ms` and `SSR: ...ms` measurements are converted into `debug` events:
200
+
201
+ ```text
202
+ module.import
203
+ ssr.render
204
+ ```
205
+
206
+ They are therefore visible when `BCP_LOG_LEVEL=debug` and stay out of normal `info` output.
207
+
208
+ ## Errors
209
+
210
+ Pass an `Error` as a structured field:
211
+
212
+ ```ts
213
+ try {
214
+ // ...
215
+ } catch (error) {
216
+ logger.error(
217
+ "Operation failed",
218
+ {
219
+ error,
220
+ }
221
+ );
222
+ }
223
+ ```
224
+
225
+ `Error` values are serialized with their name, message, stack and cause when available.
226
+
227
+ ## Environment example
228
+
229
+ A development `.env.local` can use:
230
+
231
+ ```text
232
+ BCP_LOG_LEVEL=debug
233
+ BCP_LOG_FORMAT=pretty
234
+ ```
235
+
236
+ A production/container environment can use:
237
+
238
+ ```text
239
+ BCP_LOG_LEVEL=info
240
+ BCP_LOG_FORMAT=json
241
+ ```