@chidchanun/bcp 0.2.6 → 0.2.7

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
@@ -1,14 +1,14 @@
1
1
  # BCP Framework
2
2
 
3
- BCP Framework is a React full-stack framework for file-based routing, SSR, SPA navigation, server data loading, guarded application flows, API routes, authentication, authorization, database access, validation, uploads, storage and standalone Node.js production deployment.
3
+ BCP Framework is a React full-stack framework for file-based routing, SSR, SPA navigation, server data loading, guarded application flows, API routes, authentication, authorization, database access, observability, validation, uploads, storage and standalone Node.js production deployment.
4
4
 
5
- > **Development target:** `0.2.6Authorization & Security v2`
5
+ > **Development target:** `0.2.7Observability Platform v2`
6
6
  >
7
- > `0.2.6` is an unreleased development target until local validation, RC checks, tagging and npm publication complete.
7
+ > `0.2.7` is an unreleased development target until local validation, RC checks, tagging and npm publication complete.
8
8
 
9
9
  ## 0.2 platform
10
10
 
11
- `0.2.0` established the Framework Platform baseline, `0.2.1` added the Documentation Platform, `0.2.2` added Configuration & Environment v2, `0.2.3` added Database Platform v2, `0.2.4` added Application Packaging, `0.2.5` added Authentication Platform v2, and `0.2.6` adds permission/policy authorization plus CSRF and same-origin request protection without intentionally removing the existing public application model.
11
+ `0.2.0` established the Framework Platform baseline, `0.2.1` added the Documentation Platform, `0.2.2` added Configuration & Environment v2, `0.2.3` added Database Platform v2, `0.2.4` added Application Packaging, `0.2.5` added Authentication Platform v2, `0.2.6` added Authorization & Security v2, and `0.2.7` adds dependency-free metrics, Prometheus exposition, request metrics and health/readiness checks without intentionally changing the existing application model.
12
12
 
13
13
  Machine-readable platform contracts:
14
14
 
@@ -35,10 +35,10 @@ docs/api-manifest.json
35
35
  | Authorization | Auth/guest/role/permission route guards, flat permissions and resource-aware policies |
36
36
  | Request security | Same-origin validation and signed CSRF tokens for unsafe mutations |
37
37
  | Middleware | Middleware System v2 with onion execution |
38
+ | Observability | Structured logs, counters/gauges/histograms, Prometheus output, request metrics and health/readiness checks |
38
39
  | Validation | Typed validators and structured validation errors |
39
40
  | Error handling | HTTP error helpers and consistent error responses |
40
41
  | Database | Provider-neutral MySQL, PostgreSQL and SQLite adapters, transactions, lifecycle and migrations |
41
- | Logging | Structured logger, request logger and request IDs |
42
42
  | Uploads | Buffered multipart helpers and production multipart streaming |
43
43
  | Storage | Local + S3-compatible storage, streaming, list/copy/move, metadata, bulk delete and signed URLs |
44
44
  | Caching | Response cache and revalidation primitives |
@@ -242,8 +242,6 @@ Read more:
242
242
 
243
243
  ## Authorization & Security v2 — 0.2.6
244
244
 
245
- ### Permissions
246
-
247
245
  Use flat permissions directly from `bcp/auth`:
248
246
 
249
247
  ```ts
@@ -268,24 +266,7 @@ await requirePermission(
268
266
  );
269
267
  ```
270
268
 
271
- Route trees can use a permission guard:
272
-
273
- ```ts
274
- import {
275
- createPermissionGuard,
276
- } from "bcp/auth";
277
-
278
- export const guard =
279
- createPermissionGuard(
280
- "admin.access"
281
- );
282
- ```
283
-
284
- The default permission field is `permissions`. Applications can select another field such as `scopes`.
285
-
286
- ### Resource policies
287
-
288
- For ownership, tenant or resource-state rules:
269
+ Resource-aware policies:
289
270
 
290
271
  ```ts
291
272
  import {
@@ -312,17 +293,6 @@ await authorize(
312
293
  );
313
294
  ```
314
295
 
315
- Available policy helpers:
316
-
317
- ```text
318
- can()
319
- cannot()
320
- authorize()
321
- AuthorizationError
322
- ```
323
-
324
- ### Same-origin and CSRF protection
325
-
326
296
  Request-security helpers are exposed from `bcp/server`:
327
297
 
328
298
  ```ts
@@ -333,43 +303,93 @@ import {
333
303
  } from "bcp/server";
334
304
  ```
335
305
 
336
- Protect an unsafe API/action mutation with origin validation:
306
+ Read more: [Authorization & Security v2](docs/authorization-security.md)
307
+
308
+ ## Observability Platform v2 — 0.2.7
309
+
310
+ Create one application metrics registry:
337
311
 
338
312
  ```ts
339
- await requireSameOriginRequest();
313
+ import {
314
+ createMetricsRegistry,
315
+ } from "bcp/observability";
316
+
317
+ export const metrics =
318
+ createMetricsRegistry();
319
+ ```
320
+
321
+ Supported metric types:
322
+
323
+ ```text
324
+ counter
325
+ gauge
326
+ histogram
340
327
  ```
341
328
 
342
- For signed CSRF protection:
329
+ Expose Prometheus-compatible text:
343
330
 
344
331
  ```ts
345
- const csrfToken =
346
- await createCsrfToken();
332
+ import {
333
+ createMetricsResponse,
334
+ } from "bcp/observability";
347
335
 
348
- // Render/send csrfToken through the trusted application UI.
336
+ export function GET() {
337
+ return createMetricsResponse(
338
+ metrics
339
+ );
340
+ }
341
+ ```
342
+
343
+ Instrument HTTP requests through Middleware System v2:
344
+
345
+ ```ts
346
+ import {
347
+ createRequestMetricsMiddleware,
348
+ } from "bcp/observability";
349
349
 
350
- await requireCsrfRequest({
351
- token: submittedToken,
352
- });
350
+ export const requestMetrics =
351
+ createRequestMetricsMiddleware(
352
+ metrics
353
+ );
353
354
  ```
354
355
 
355
- Default CSRF header/cookie:
356
+ Default request metrics use only bounded labels:
356
357
 
357
358
  ```text
358
- X-BCP-CSRF
359
- bcp_csrf
359
+ bcp_http_requests_total{method,status}
360
+ bcp_http_request_duration_seconds{method,status}
360
361
  ```
361
362
 
362
- Secret resolution:
363
+ Raw paths are not attached by default.
363
364
 
364
- ```text
365
- explicit options.secret
366
-
367
- BCP_CSRF_SECRET
368
-
369
- BCP_SESSION_SECRET
365
+ Health/readiness registry:
366
+
367
+ ```ts
368
+ import {
369
+ createHealthRegistry,
370
+ } from "bcp/observability";
371
+
372
+ export const health =
373
+ createHealthRegistry();
374
+
375
+ health.register(
376
+ "database",
377
+ async () => {
378
+ await db.query("SELECT 1");
379
+ return true;
380
+ }
381
+ );
370
382
  ```
371
383
 
372
- Read more: [Authorization & Security v2](docs/authorization-security.md)
384
+ Use:
385
+
386
+ ```ts
387
+ return health.response();
388
+ ```
389
+
390
+ Health responses return `200` when every check passes and `503` when any registered dependency is unhealthy or times out.
391
+
392
+ Read more: [Observability Platform v2](docs/observability.md)
373
393
 
374
394
  ## Public entrypoints
375
395
 
@@ -384,6 +404,7 @@ bcp/validation
384
404
  bcp/error
385
405
  bcp/database
386
406
  bcp/auth
407
+ bcp/observability
387
408
  bcp/server
388
409
  bcp/server-only
389
410
  bcp/middleware
@@ -446,6 +467,9 @@ Loader / action / API route
446
467
  React SSR
447
468
 
448
469
  Hydration / SPA navigation
470
+
471
+ Operational side channels:
472
+ structured logs + metrics + health/readiness
449
473
  ```
450
474
 
451
475
  ## Production build
@@ -491,7 +515,7 @@ npm run test:e2e
491
515
  npm run rc:check
492
516
  ```
493
517
 
494
- `0.2.6` adds Authorization & Security v2 unit and prepared-package smoke checks covering permission matching, policy authorization, permission route guards, same-origin mutation validation and signed CSRF tokens.
518
+ `0.2.7` adds Observability Platform v2 unit and prepared-package smoke checks covering metrics, Prometheus exposition, request timing, cardinality-safe default labels, health/readiness responses and timeout handling.
495
519
 
496
520
  Do not tag or publish until the final release commit passes the complete RC sequence.
497
521
 
@@ -512,12 +536,13 @@ Do not tag or publish until the final release commit passes the complete RC sequ
512
536
  | `0.2.4` | Application Packaging |
513
537
  | `0.2.5` | Authentication Platform v2 |
514
538
  | `0.2.6` | Authorization & Security v2 |
539
+ | `0.2.7` | Observability Platform v2 |
515
540
 
516
541
  ## Roadmap
517
542
 
518
- `0.2.6Authorization & Security v2` establishes the permission/policy and browser-mutation security layer on top of Authentication Platform v2.
543
+ `0.2.7Observability Platform v2` establishes process-level metrics and health/readiness contracts on top of the existing structured logging and Middleware System v2 runtime.
519
544
 
520
- The next `0.2.x` milestone can build on the existing runtime, database, auth, security and packaging contracts. Native `.exe`, desktop and mobile compilation remain later roadmap work.
545
+ Future `0.2.x` work can add distributed tracing or exporter integrations without changing the application metrics/health contract introduced here. Native `.exe`, desktop and mobile compilation remain later roadmap work.
521
546
 
522
547
  ## License
523
548
 
package/docs/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  The `docs/` directory is the documentation source of truth for BCP Framework and is organized for **`bcp-docs-web`**.
4
4
 
5
- > **Documentation target:** BCP Framework `0.2.6Authorization & Security v2`
5
+ > **Documentation target:** BCP Framework `0.2.7Observability Platform v2`
6
6
  >
7
7
  > **Release state:** unreleased development target until RC validation, tagging and npm publication complete.
8
8
 
@@ -52,66 +52,49 @@ Framework source and tests remain authoritative for runtime behavior.
52
52
  | `0.2.4` | Application Packaging |
53
53
  | `0.2.5` | Authentication Platform v2 |
54
54
  | `0.2.6` | Authorization & Security v2 |
55
+ | `0.2.7` | Observability Platform v2 |
55
56
 
56
- ## 0.2.6Authorization & Security v2
57
+ ## 0.2.7Observability Platform v2
57
58
 
58
- `0.2.6` adds server-side permission checks, resource-aware authorization policies, permission route guards, same-origin mutation validation and signed CSRF protection.
59
+ `0.2.7` adds a server-only observability layer without adding third-party runtime dependencies.
59
60
 
60
61
  New/updated documentation sources:
61
62
 
62
63
  | Source | Purpose |
63
64
  | --- | --- |
64
- | `authorization-security.md` | Permissions, policies, permission guards, same-origin validation and CSRF APIs |
65
- | `auth-route-guards.md` | Auth/guest/role/permission route guard guidance |
66
- | `api-reference.md` | Public authorization and request-security exports |
67
- | `platform-manifest.json` | Authorization/security capability flags |
68
- | `api-manifest.json` | `bcp/auth` and `bcp/server` guide ownership |
69
- | `releases/0.2.6.md` | Authorization & Security v2 release notes |
65
+ | `observability.md` | Metrics registry, Prometheus output, request metrics and health/readiness checks |
66
+ | `api-reference.md` | Public `bcp/observability` exports |
67
+ | `platform-manifest.json` | Observability capability flags and new public entrypoint |
68
+ | `api-manifest.json` | `bcp/observability` guide ownership |
69
+ | `docs-web-manifest.json` | Observability navigation and `0.2.7` release route |
70
+ | `releases/0.2.7.md` | Observability Platform v2 release notes |
70
71
 
71
- Primary authorization APIs:
72
+ Primary APIs:
72
73
 
73
74
  ```ts
74
75
  import {
75
- authorize,
76
- can,
77
- createPermissionGuard,
78
- defineAuthorizationPolicy,
79
- hasPermission,
80
- requirePermission,
81
- } from "bcp/auth";
76
+ createHealthRegistry,
77
+ createMetricsRegistry,
78
+ createMetricsResponse,
79
+ createRequestMetricsMiddleware,
80
+ } from "bcp/observability";
82
81
  ```
83
82
 
84
- Primary browser-mutation security APIs:
85
-
86
- ```ts
87
- import {
88
- createCsrfToken,
89
- requireCsrfRequest,
90
- requireSameOriginRequest,
91
- } from "bcp/server";
92
- ```
93
-
94
- ## Security model
95
-
96
- The `0.2.6` server model separates concerns:
83
+ Runtime model:
97
84
 
98
85
  ```text
99
- authentication
100
- -> identify a signed/revocable session
101
-
102
- authorization
103
- -> permissions + policies + route guards
104
-
105
- request security
106
- -> Origin/Referer validation + signed CSRF token
107
-
108
- input validation
109
- -> application schema/domain checks
86
+ structured logs
87
+ +
88
+ process-local metrics
89
+ +
90
+ Prometheus exposition
91
+ +
92
+ health/readiness checks
110
93
  ```
111
94
 
112
- All authorization decisions must remain server-side. Client UI permission checks may improve presentation but do not replace route/action/API enforcement.
95
+ The request metrics middleware intentionally uses bounded `method` and `status` labels by default rather than raw paths.
113
96
 
114
- CSRF tokens use `BCP_CSRF_SECRET` when configured and otherwise fall back to `BCP_SESSION_SECRET`. Security secrets must contain at least 32 UTF-8 bytes.
97
+ The built-in metrics registry is process-local; distributed aggregation remains deployment infrastructure or future exporter work.
115
98
 
116
99
  ## Update rule
117
100
 
@@ -150,13 +133,13 @@ Important current routes:
150
133
  | Website route | Markdown source |
151
134
  | --- | --- |
152
135
  | `/docs/authentication` | `authentication.md` |
153
- | `/docs/auth-session-store` | `auth-session-store.md` |
154
- | `/docs/auth-route-guards` | `auth-route-guards.md` |
155
136
  | `/docs/authorization-security` | `authorization-security.md` |
137
+ | `/docs/observability` | `observability.md` |
138
+ | `/docs/development-logging` | `development-logging.md` |
156
139
  | `/docs/application-packaging` | `application-packaging.md` |
157
140
  | `/docs/database` | `database.md` |
158
141
  | `/docs/api-reference` | `api-reference.md` |
159
- | `/releases/0.2.6` | `releases/0.2.6.md` |
142
+ | `/releases/0.2.7` | `releases/0.2.7.md` |
160
143
 
161
144
  Every route/source pair is validated by unit tests.
162
145
 
@@ -196,6 +179,7 @@ bcp/validation
196
179
  bcp/error
197
180
  bcp/database
198
181
  bcp/auth
182
+ bcp/observability
199
183
  bcp/server
200
184
  bcp/server-only
201
185
  bcp/middleware
@@ -235,7 +219,7 @@ synchronize CMS/search/navigation
235
219
 
236
220
  ## Release validation
237
221
 
238
- Before publishing `0.2.6`:
222
+ Before publishing `0.2.7`:
239
223
 
240
224
  ```bash
241
225
  npm run typecheck
@@ -246,16 +230,16 @@ npm run test:e2e
246
230
  npm run rc:check
247
231
  ```
248
232
 
249
- Authorization & Security v2 validation covers:
233
+ Observability Platform v2 validation covers:
250
234
 
251
- - permission normalization and any/all matching,
252
- - permission route guards,
253
- - sync/async authorization policies,
254
- - `AuthorizationError` denial behavior,
255
- - same-origin mutation checks,
256
- - signed CSRF tokens,
257
- - malformed/cross-origin rejection,
258
- - public `bcp/auth` and `bcp/server` exports,
235
+ - counter/gauge/histogram behavior,
236
+ - Prometheus exposition,
237
+ - metric definition validation,
238
+ - request count and duration middleware,
239
+ - cardinality-safe default request labels,
240
+ - health/readiness response semantics,
241
+ - health check timeout handling,
242
+ - public `bcp/observability` exports,
259
243
  - prepared npm package contents,
260
244
  - docs/platform/API version parity.
261
245
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "framework": "bcp",
4
- "version": "0.2.6",
4
+ "version": "0.2.7",
5
5
  "releaseState": "unreleased",
6
6
  "coverage": "public-entrypoints",
7
7
  "entrypoints": [
@@ -94,6 +94,17 @@
94
94
  "/docs/session-auth"
95
95
  ]
96
96
  },
97
+ {
98
+ "package": "bcp/observability",
99
+ "source": "packages/client/src/observability.ts",
100
+ "environment": "server",
101
+ "route": "/docs/api-reference#bcp-observability",
102
+ "summary": "In-process metrics, Prometheus exposition, request metrics middleware and health/readiness checks.",
103
+ "guides": [
104
+ "/docs/observability",
105
+ "/docs/development-logging"
106
+ ]
107
+ },
97
108
  {
98
109
  "package": "bcp/server",
99
110
  "source": "packages/client/src/server.ts",
@@ -226,6 +226,42 @@ Authorization & Security v2 adds permission checks, permission route guards and
226
226
 
227
227
  Related guides: [Authentication](authentication.md), [Auth Session Stores](auth-session-store.md), [Auth Route Guards](auth-route-guards.md), [Authorization & Security v2](authorization-security.md), [JWT Sessions](session-auth.md).
228
228
 
229
+ ## `bcp/observability`
230
+
231
+ Server-only Observability Platform v2 APIs.
232
+
233
+ ```ts
234
+ import {
235
+ createHealthRegistry,
236
+ createMetricsRegistry,
237
+ createMetricsResponse,
238
+ createRequestMetricsMiddleware,
239
+ type CounterMetric,
240
+ type GaugeMetric,
241
+ type HealthCheck,
242
+ type HealthCheckOptions,
243
+ type HealthCheckReportItem,
244
+ type HealthCheckResult,
245
+ type HealthRegistry,
246
+ type HealthReport,
247
+ type HistogramMetric,
248
+ type HistogramOptions,
249
+ type MetricDefinitionOptions,
250
+ type MetricLabels,
251
+ type MetricLabelValue,
252
+ type MetricsRegistry,
253
+ type RequestMetricsOptions,
254
+ } from "bcp/observability";
255
+ ```
256
+
257
+ `createMetricsRegistry()` provides process-local counters, gauges and histograms. `createMetricsResponse()` renders Prometheus-compatible text exposition. `createRequestMetricsMiddleware()` measures HTTP request counts and duration using bounded `method` / `status` labels by default and intentionally does not label by raw path.
258
+
259
+ `createHealthRegistry()` registers synchronous or asynchronous liveness/readiness checks, applies per-check timeouts and produces JSON health responses with HTTP `200` when all checks pass or `503` when any check fails.
260
+
261
+ The built-in registry is process-local. Multi-instance deployments should scrape each process/container or aggregate through external monitoring infrastructure.
262
+
263
+ Related guides: [Observability Platform v2](observability.md), [Logging](development-logging.md).
264
+
229
265
  ## `bcp/server`
230
266
 
231
267
  Server request/runtime APIs.
@@ -1,6 +1,21 @@
1
1
  # Logging and observability
2
2
 
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.
3
+ BCP Framework 0.1.23 added the structured server logger and development request timing output. BCP Framework `0.2.7` complements that logging layer with process-local metrics and health/readiness primitives through `bcp/observability`.
4
+
5
+ Use these layers together:
6
+
7
+ ```text
8
+ bcp/server
9
+ -> structured event/request logs
10
+
11
+ bcp/observability
12
+ -> counters, gauges, histograms
13
+ -> Prometheus exposition
14
+ -> request metrics middleware
15
+ -> health/readiness checks
16
+ ```
17
+
18
+ See [Observability Platform v2](observability.md) for the `0.2.7` metrics and health APIs.
4
19
 
5
20
  ## Server logger
6
21
 
@@ -205,6 +220,34 @@ ssr.render
205
220
 
206
221
  They are therefore visible when `BCP_LOG_LEVEL=debug` and stay out of normal `info` output.
207
222
 
223
+ ## Metrics vs logs
224
+
225
+ Logs and metrics serve different purposes.
226
+
227
+ Use structured logs when you need per-event context:
228
+
229
+ ```text
230
+ request ID
231
+ operation
232
+ error stack
233
+ resource identity
234
+ diagnostic fields
235
+ ```
236
+
237
+ Use metrics when you need aggregate trends:
238
+
239
+ ```text
240
+ request count
241
+ status distribution
242
+ latency buckets
243
+ queue depth
244
+ worker count
245
+ ```
246
+
247
+ Avoid copying high-cardinality log fields such as request IDs, user IDs or raw paths into metric labels.
248
+
249
+ The `0.2.7` request metrics middleware follows this rule by using `method` and `status` labels by default.
250
+
208
251
  ## Errors
209
252
 
210
253
  Pass an `Error` as a structured field:
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "framework": "bcp",
4
- "versionTarget": "0.2.6",
4
+ "versionTarget": "0.2.7",
5
5
  "releaseState": "unreleased",
6
6
  "sections": [
7
7
  {
@@ -57,11 +57,12 @@
57
57
  {
58
58
  "id": "runtime",
59
59
  "title": "Runtime & Infrastructure",
60
- "description": "Middleware, hydration, logging, caching, security and production hardening.",
60
+ "description": "Middleware, observability, logging, caching, security and production hardening.",
61
61
  "pages": [
62
62
  { "route": "/docs/middleware", "source": "middleware.md", "title": "Middleware" },
63
63
  { "route": "/docs/hydration", "source": "hydration.md", "title": "Hydration" },
64
- { "route": "/docs/development-logging", "source": "development-logging.md", "title": "Logging & Observability" },
64
+ { "route": "/docs/development-logging", "source": "development-logging.md", "title": "Logging" },
65
+ { "route": "/docs/observability", "source": "observability.md", "title": "Observability Platform v2" },
65
66
  { "route": "/docs/caching", "source": "caching.md", "title": "Caching" },
66
67
  { "route": "/docs/security", "source": "security.md", "title": "Security" },
67
68
  { "route": "/docs/production-hardening", "source": "production-hardening.md", "title": "Production Hardening" }
@@ -107,7 +108,8 @@
107
108
  }
108
109
  ],
109
110
  "releases": [
110
- { "route": "/releases/0.2.6", "source": "releases/0.2.6.md", "version": "0.2.6", "state": "unreleased" },
111
+ { "route": "/releases/0.2.7", "source": "releases/0.2.7.md", "version": "0.2.7", "state": "unreleased" },
112
+ { "route": "/releases/0.2.6", "source": "releases/0.2.6.md", "version": "0.2.6" },
111
113
  { "route": "/releases/0.2.5", "source": "releases/0.2.5.md", "version": "0.2.5" },
112
114
  { "route": "/releases/0.2.4", "source": "releases/0.2.4.md", "version": "0.2.4" },
113
115
  { "route": "/releases/0.2.3", "source": "releases/0.2.3.md", "version": "0.2.3" },