@chidchanun/bcp 0.2.9 → 0.2.10

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,13 +2,13 @@
2
2
 
3
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, background jobs, recurring scheduling, observability, validation, uploads, storage and standalone Node.js production deployment.
4
4
 
5
- > **Development target:** `0.2.9Job Scheduling Platform`
5
+ > **Development target:** `0.2.10Durable Jobs Platform`
6
6
  >
7
- > `0.2.9` is an unreleased development target until local validation, RC checks, tagging and npm publication complete.
7
+ > `0.2.10` 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, `0.2.6` added Authorization & Security v2, `0.2.7` added Observability Platform v2, `0.2.8` added Background Jobs Platform, and `0.2.9` adds recurring interval/UTC-cron scheduling with lease-aware shared-store contracts.
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, `0.2.7` added Observability Platform v2, `0.2.8` added Background Jobs Platform, `0.2.9` added recurring scheduling, and `0.2.10` adds durable worker leases, DLQ maintenance and Redis-compatible queue/scheduler adapters.
12
12
 
13
13
  Machine-readable platform contracts:
14
14
 
@@ -35,8 +35,9 @@ 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
- | Background jobs | Adapter contract, in-memory queue, delayed jobs, retries/backoff, cancellation and concurrent workers |
38
+ | Background jobs | Delayed jobs, retries/backoff, cancellation, concurrent workers, visibility leases, heartbeat, stale recovery and DLQ |
39
39
  | Scheduling | Recurring interval jobs, UTC cron, schedule-store leases and deterministic scheduled run IDs |
40
+ | Durable jobs | Redis-compatible queue/schedule adapters, retention cleanup, requeue and queue statistics |
40
41
  | Observability | Structured logs, counters/gauges/histograms, Prometheus output, request metrics and health/readiness checks |
41
42
  | Validation | Typed validators and structured validation errors |
42
43
  | Error handling | HTTP error helpers and consistent error responses |
@@ -131,8 +132,6 @@ Read more:
131
132
 
132
133
  ## Database Platform v2 — 0.2.3
133
134
 
134
- Application code uses one server-only database entrypoint across supported SQL providers:
135
-
136
135
  ```ts
137
136
  import {
138
137
  db,
@@ -148,16 +147,6 @@ postgresql
148
147
  sqlite
149
148
  ```
150
149
 
151
- Lifecycle control:
152
-
153
- ```ts
154
- await db.connect();
155
-
156
- // application work
157
-
158
- await db.disconnect();
159
- ```
160
-
161
150
  Migration CLI:
162
151
 
163
152
  ```bash
@@ -180,23 +169,10 @@ Create a fresh production build and deployment package:
180
169
  bcp package
181
170
  ```
182
171
 
183
- Output:
172
+ Output is written under:
184
173
 
185
174
  ```text
186
175
  .bcp-framework/package/
187
- ├─ client/
188
- ├─ server/
189
- │ └─ server.mjs
190
- ├─ public/ # when present
191
- ├─ manifest.json
192
- ├─ package.json
193
- ├─ package-lock.json # when a safe npm v3 production lock can be derived
194
- ├─ bcp.package.json
195
- ├─ bcp.deployment.json
196
- ├─ bcp.env.json
197
- ├─ Dockerfile
198
- ├─ .dockerignore
199
- └─ README.md
200
176
  ```
201
177
 
202
178
  Read more:
@@ -206,35 +182,17 @@ Read more:
206
182
 
207
183
  ## Authentication Platform v2 — 0.2.5
208
184
 
209
- Stateless signed JWT-cookie authentication remains supported:
210
-
211
185
  ```ts
212
186
  import {
213
187
  auth,
214
- login,
215
- logout,
216
- } from "bcp/auth";
217
- ```
218
-
219
- Applications that need centralized revocation can add a server-side session store:
220
-
221
- ```ts
222
- import {
223
188
  createAuth,
224
189
  createMemoryAuthSessionStore,
190
+ login,
191
+ logout,
225
192
  } from "bcp/auth";
226
-
227
- const sessionStore =
228
- createMemoryAuthSessionStore();
229
-
230
- export const appAuth =
231
- createAuth({
232
- store: sessionStore,
233
- idleTimeout: 60 * 30,
234
- });
235
193
  ```
236
194
 
237
- With a store configured, authentication requires both a valid signed JWT cookie and an active `sid` record. The built-in memory store is intended for development/tests; production multi-instance deployments should implement `AuthSessionStore` with shared storage.
195
+ Stateless signed JWT-cookie authentication remains supported. Applications that need centralized revocation can configure an `AuthSessionStore`.
238
196
 
239
197
  Read more:
240
198
 
@@ -244,37 +202,12 @@ Read more:
244
202
 
245
203
  ## Authorization & Security v2 — 0.2.6
246
204
 
247
- Use flat permissions directly from `bcp/auth`:
248
-
249
205
  ```ts
250
206
  import {
207
+ authorize,
251
208
  hasPermission,
252
209
  requirePermission,
253
210
  } from "bcp/auth";
254
-
255
- hasPermission(
256
- user,
257
- "users.read"
258
- );
259
-
260
- await requirePermission(
261
- [
262
- "users.read",
263
- "users.write",
264
- ],
265
- {
266
- match: "all",
267
- }
268
- );
269
- ```
270
-
271
- Resource-aware policies:
272
-
273
- ```ts
274
- import {
275
- authorize,
276
- defineAuthorizationPolicy,
277
- } from "bcp/auth";
278
211
  ```
279
212
 
280
213
  Request-security helpers are exposed from `bcp/server`:
@@ -303,8 +236,6 @@ Read more: [Observability Platform v2](docs/observability.md)
303
236
 
304
237
  ## Background Jobs Platform — 0.2.8
305
238
 
306
- Create a server-side queue:
307
-
308
239
  ```ts
309
240
  import {
310
241
  createJobQueue,
@@ -314,7 +245,7 @@ export const jobs =
314
245
  createJobQueue();
315
246
  ```
316
247
 
317
- Register a handler:
248
+ Register work:
318
249
 
319
250
  ```ts
320
251
  jobs.register<{
@@ -329,7 +260,7 @@ jobs.register<{
329
260
  );
330
261
  ```
331
262
 
332
- Enqueue immediately or with a delay:
263
+ Enqueue work:
333
264
 
334
265
  ```ts
335
266
  await jobs.enqueue(
@@ -344,24 +275,10 @@ await jobs.enqueue(
344
275
  );
345
276
  ```
346
277
 
347
- Start concurrent workers:
348
-
349
- ```ts
350
- const worker =
351
- jobs.startWorker({
352
- concurrency: 4,
353
- pollIntervalMs: 250,
354
- });
355
- ```
356
-
357
- The default memory adapter is process-local. Durable multi-process deployments should implement `JobQueueAdapter` against shared infrastructure.
358
-
359
278
  Read more: [Background Jobs Platform](docs/background-jobs.md)
360
279
 
361
280
  ## Job Scheduling Platform — 0.2.9
362
281
 
363
- Create a scheduler on top of the same queue:
364
-
365
282
  ```ts
366
283
  import {
367
284
  createJobScheduler,
@@ -398,29 +315,113 @@ await scheduler.schedule(
398
315
  );
399
316
  ```
400
317
 
401
- Supported cron shape:
318
+ Read more: [Job Scheduling Platform](docs/job-scheduling.md)
402
319
 
403
- ```text
404
- minute hour day-of-month month day-of-week
320
+ ## Durable Jobs Platform — 0.2.10
321
+
322
+ Workers now support visibility leases, heartbeat renewal and stale-running recovery when the configured adapter implements those capabilities:
323
+
324
+ ```ts
325
+ const worker =
326
+ jobs.startWorker({
327
+ workerId: "email-worker",
328
+ concurrency: 4,
329
+ visibilityTimeoutMs: 30_000,
330
+ heartbeatIntervalMs: 10_000,
331
+ pollIntervalMs: 250,
332
+ });
333
+ ```
334
+
335
+ Retry-exhausted jobs can be inspected and requeued:
336
+
337
+ ```ts
338
+ const failed =
339
+ await jobs.deadLetters();
340
+
341
+ await jobs.requeueDeadLetter(
342
+ failed[0].id,
343
+ {
344
+ delayMs: 5_000,
345
+ resetAttempts: true,
346
+ }
347
+ );
348
+ ```
349
+
350
+ Operational helpers:
351
+
352
+ ```ts
353
+ await jobs.recoverStale({
354
+ limit: 100,
355
+ });
356
+
357
+ const stats =
358
+ await jobs.stats();
359
+
360
+ await jobs.cleanup({
361
+ before:
362
+ Date.now() -
363
+ 7 * 24 * 60 * 60 * 1000,
364
+ });
365
+ ```
366
+
367
+ ### Redis-compatible durable queue
368
+
369
+ BCP does not install a Redis client library. Supply an application-owned client that implements:
370
+
371
+ ```ts
372
+ interface RedisCommandClient {
373
+ sendCommand(
374
+ command: string[]
375
+ ): Promise<unknown>;
376
+ }
405
377
  ```
406
378
 
407
- The scheduler runner polls due schedules and enqueues normal BCP jobs:
379
+ Then create the adapters:
408
380
 
409
381
  ```ts
410
- const scheduleRunner =
411
- scheduler.start({
412
- pollIntervalMs: 1_000,
413
- leaseMs: 30_000,
382
+ import {
383
+ createJobQueue,
384
+ createJobScheduler,
385
+ createRedisJobQueueAdapter,
386
+ createRedisJobScheduleStore,
387
+ } from "bcp/jobs";
388
+
389
+ const queueAdapter =
390
+ createRedisJobQueueAdapter({
391
+ client: redisCommandClient,
392
+ namespace: "my-app:{jobs}",
393
+ });
394
+
395
+ export const jobs =
396
+ createJobQueue({
397
+ adapter: queueAdapter,
414
398
  });
415
399
 
416
- // graceful shutdown
417
- await scheduleRunner.stop();
418
- await scheduler.close();
400
+ const scheduleStore =
401
+ createRedisJobScheduleStore({
402
+ client: redisCommandClient,
403
+ namespace: "my-app:{jobs}",
404
+ });
405
+
406
+ export const scheduler =
407
+ createJobScheduler({
408
+ queue: jobs,
409
+ store: scheduleStore,
410
+ ownerId: "scheduler-a",
411
+ });
419
412
  ```
420
413
 
421
- The built-in `createMemoryJobScheduleStore()` is process-local. Multi-instance production deployments should implement a shared `JobScheduleStore` whose `acquireDue()` operation atomically claims schedules with lease ownership/expiry. Scheduled occurrences also use deterministic queue ids for duplicate protection.
414
+ The Redis reference adapters use atomic Lua operations for reservations, visibility leases, heartbeat, stale recovery, DLQ requeue and scheduler leasing. The default namespace is `bcp:{jobs}` so keys share one Redis Cluster hash slot.
422
415
 
423
- Read more: [Job Scheduling Platform](docs/job-scheduling.md)
416
+ A typical application may configure its Redis client with:
417
+
418
+ ```dotenv
419
+ REDIS_URL=redis://localhost:6379
420
+ ```
421
+
422
+ BCP does not read `REDIS_URL` automatically; connection creation, TLS/Cluster settings and credentials remain application-owned.
423
+
424
+ Read more: [Durable Jobs Platform](docs/durable-jobs.md)
424
425
 
425
426
  ## Public entrypoints
426
427
 
@@ -485,27 +486,21 @@ bcp generate middleware
485
486
  bcp generate migration create_users
486
487
  ```
487
488
 
488
- ## Application model
489
+ ## Production model
489
490
 
490
491
  ```text
491
- Browser
492
-
493
- Origin / CSRF / middleware / cache
494
-
495
- Authentication + authorization guard
496
-
497
- Loader / action / API route
498
-
499
- React SSR
500
-
501
- Hydration / SPA navigation
492
+ Browser / API clients
493
+
494
+ security + middleware + auth
495
+
496
+ loaders / actions / API routes
497
+
498
+ SSR / application responses
502
499
 
503
500
  Operational side channels:
504
- background jobs + scheduler + structured logs + metrics + health/readiness
501
+ shared jobs + scheduler + structured logs + metrics + health/readiness
505
502
  ```
506
503
 
507
- ## Production build
508
-
509
504
  Raw standalone build:
510
505
 
511
506
  ```bash
@@ -519,8 +514,6 @@ Deployment package:
519
514
  bcp package
520
515
  ```
521
516
 
522
- Both current targets remain Node.js `standalone-node` applications.
523
-
524
517
  ## Documentation Platform
525
518
 
526
519
  The framework repository is the documentation source of truth.
@@ -547,7 +540,7 @@ npm run test:e2e
547
540
  npm run rc:check
548
541
  ```
549
542
 
550
- `0.2.9` adds Job Scheduling Platform unit and prepared-package smoke checks covering interval schedules, UTC cron parsing, standard day matching, schedule-store leases, deterministic scheduled run ids, retry propagation and lifecycle validation.
543
+ `0.2.10` adds Durable Jobs Platform unit and prepared-package smoke checks covering visibility leases, heartbeat renewal, stale recovery, DLQ/requeue, retention/statistics, Redis queue/scheduler command contracts and the compiled `bcp/jobs` runtime.
551
544
 
552
545
  Do not tag or publish until the final release commit passes the complete RC sequence.
553
546
 
@@ -571,12 +564,13 @@ Do not tag or publish until the final release commit passes the complete RC sequ
571
564
  | `0.2.7` | Observability Platform v2 |
572
565
  | `0.2.8` | Background Jobs Platform |
573
566
  | `0.2.9` | Job Scheduling Platform |
567
+ | `0.2.10` | Durable Jobs Platform |
574
568
 
575
569
  ## Roadmap
576
570
 
577
- `0.2.9Job Scheduling Platform` establishes recurring scheduling and the durable schedule-store contract on top of the provider-neutral queue introduced in `0.2.8`.
571
+ `0.2.10Durable Jobs Platform` establishes shared production queue/scheduler adapters and worker recovery semantics while keeping the provider-neutral `bcp/jobs` contract.
578
572
 
579
- Future work can add first-party durable queue/schedule adapters, dead-letter queues or workflow orchestration without changing the base queue and scheduler contracts. Native `.exe`, desktop and mobile compilation remain later roadmap work.
573
+ Later `0.2.x` work can add workflow orchestration, transactional outbox helpers or additional durable providers without changing the base queue/scheduler model. Native `.exe`, desktop and mobile compilation remain later roadmap work.
580
574
 
581
575
  ## License
582
576
 
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.9Job Scheduling Platform`
5
+ > **Documentation target:** BCP Framework `0.2.10Durable Jobs Platform`
6
6
  >
7
7
  > **Release state:** unreleased development target until RC validation, tagging and npm publication complete.
8
8
 
@@ -37,51 +37,57 @@ Framework source and tests remain authoritative for runtime behavior.
37
37
  | `0.2.7` | Observability Platform v2 |
38
38
  | `0.2.8` | Background Jobs Platform |
39
39
  | `0.2.9` | Job Scheduling Platform |
40
+ | `0.2.10` | Durable Jobs Platform |
40
41
 
41
- ## 0.2.9Job Scheduling Platform
42
+ ## 0.2.10Durable Jobs Platform
42
43
 
43
- `0.2.9` extends `bcp/jobs` with recurring interval jobs, dependency-free UTC cron schedules, scheduler runners, deterministic scheduled occurrence IDs and a lease-aware `JobScheduleStore` contract.
44
+ `0.2.10` makes the queue/scheduler contracts production-oriented without changing the `bcp/jobs` public entrypoint.
44
45
 
45
46
  New/updated documentation sources:
46
47
 
47
48
  | Source | Purpose |
48
49
  | --- | --- |
49
- | `background-jobs.md` | Base queue/worker contract from `0.2.8` |
50
- | `job-scheduling.md` | Interval/cron schedules, leases and durable schedule-store guidance |
51
- | `api-reference.md` | Public queue + scheduler APIs under `bcp/jobs` |
52
- | `platform-manifest.json` | Job Scheduling capability flags |
50
+ | `background-jobs.md` | Base queue/worker contract |
51
+ | `job-scheduling.md` | Interval/cron schedules and scheduler leases |
52
+ | `durable-jobs.md` | Visibility leases, heartbeat recovery, DLQ, retention, statistics and Redis adapters |
53
+ | `api-reference.md` | Current `bcp/jobs` public APIs |
54
+ | `platform-manifest.json` | Durable Jobs capability flags |
53
55
  | `api-manifest.json` | `bcp/jobs` guide ownership |
54
- | `docs-web-manifest.json` | Scheduling navigation and `0.2.9` release route |
55
- | `releases/0.2.9.md` | Job Scheduling Platform release notes |
56
+ | `docs-web-manifest.json` | Durable Jobs navigation and `0.2.10` release route |
57
+ | `releases/0.2.10.md` | Durable Jobs Platform release notes |
56
58
 
57
- Primary scheduling APIs:
59
+ Primary durable APIs:
58
60
 
59
61
  ```ts
60
62
  import {
61
- createJobScheduler,
62
- createMemoryJobScheduleStore,
63
- nextCronTime,
64
- nextScheduleTime,
63
+ createJobQueue,
64
+ createRedisJobQueueAdapter,
65
+ createRedisJobScheduleStore,
65
66
  } from "bcp/jobs";
66
67
  ```
67
68
 
68
69
  Runtime model:
69
70
 
70
71
  ```text
71
- recurring schedule
72
- |
73
- v
74
- JobScheduleStore.acquireDue()
75
- |
76
- | lease + deterministic run id
77
- v
78
- JobQueueAdapter.enqueue()
79
- |
80
- v
81
- queue worker(s)
72
+ web / API / action
73
+ |
74
+ v
75
+ shared JobQueueAdapter
76
+ |
77
+ +--> visibility lease + heartbeat
78
+ +--> retry / stale recovery
79
+ +--> DLQ / requeue
80
+ |
81
+ v
82
+ worker processes
83
+
84
+ scheduler processes
85
+ |
86
+ v
87
+ shared JobScheduleStore lease
82
88
  ```
83
89
 
84
- The built-in schedule store and queue are process-local. Multi-process/container production deployments should implement shared durable `JobScheduleStore` and `JobQueueAdapter` contracts.
90
+ BCP does not bundle a Redis client library. Redis connection creation and shutdown remain application-owned through the minimal `RedisCommandClient` contract and optional close hook.
85
91
 
86
92
  ## Update rule
87
93
 
@@ -98,8 +104,6 @@ When framework behavior or public surface changes:
98
104
 
99
105
  ## Docs-web navigation
100
106
 
101
- `docs/docs-web-manifest.json` is the authoritative ordered navigation contract.
102
-
103
107
  Important current routes:
104
108
 
105
109
  | Website route | Markdown source |
@@ -109,10 +113,11 @@ Important current routes:
109
113
  | `/docs/observability` | `observability.md` |
110
114
  | `/docs/background-jobs` | `background-jobs.md` |
111
115
  | `/docs/job-scheduling` | `job-scheduling.md` |
116
+ | `/docs/durable-jobs` | `durable-jobs.md` |
112
117
  | `/docs/application-packaging` | `application-packaging.md` |
113
118
  | `/docs/database` | `database.md` |
114
119
  | `/docs/api-reference` | `api-reference.md` |
115
- | `/releases/0.2.9` | `releases/0.2.9.md` |
120
+ | `/releases/0.2.10` | `releases/0.2.10.md` |
116
121
 
117
122
  Every route/source pair is validated by unit tests.
118
123
 
@@ -140,7 +145,7 @@ The API-manifest entrypoint set must match the platform public-entrypoint set ex
140
145
 
141
146
  ## Release validation
142
147
 
143
- Before publishing `0.2.9`:
148
+ Before publishing `0.2.10`:
144
149
 
145
150
  ```bash
146
151
  npm run typecheck
@@ -151,17 +156,16 @@ npm run test:e2e
151
156
  npm run rc:check
152
157
  ```
153
158
 
154
- Job Scheduling Platform validation covers:
155
-
156
- - interval scheduling,
157
- - five-field UTC cron parsing,
158
- - standard day-of-month/day-of-week behavior,
159
- - schedule-store leasing,
160
- - deterministic scheduled run IDs,
161
- - retry-limit propagation into queue jobs,
162
- - schedule inspection/removal,
163
- - scheduler configuration validation,
164
- - prepared npm package contents,
159
+ Durable Jobs Platform validation covers:
160
+
161
+ - worker visibility leases and heartbeat renewal,
162
+ - stale-running recovery,
163
+ - retry exhaustion and DLQ indexing,
164
+ - dead-letter requeue,
165
+ - queue statistics,
166
+ - terminal retention cleanup,
167
+ - Redis queue and schedule adapter command contracts,
168
+ - compiled `bcp/jobs` runtime imports,
165
169
  - docs/platform/API version parity.
166
170
 
167
171
  The final release tag must point to the exact commit that passed the complete RC sequence.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "framework": "bcp",
4
- "version": "0.2.9",
4
+ "version": "0.2.10",
5
5
  "releaseState": "unreleased",
6
6
  "coverage": "public-entrypoints",
7
7
  "entrypoints": [
@@ -99,10 +99,11 @@
99
99
  "source": "packages/client/src/jobs.ts",
100
100
  "environment": "server",
101
101
  "route": "/docs/api-reference#bcp-jobs",
102
- "summary": "Background job queues plus recurring interval/cron scheduling, schedule-store leases and worker lifecycle APIs.",
102
+ "summary": "Background queues and schedules with visibility leases, heartbeats, stale recovery, DLQ maintenance and Redis-compatible durable adapters.",
103
103
  "guides": [
104
104
  "/docs/background-jobs",
105
105
  "/docs/job-scheduling",
106
+ "/docs/durable-jobs",
106
107
  "/docs/observability"
107
108
  ]
108
109
  },