@chidchanun/bcp 0.2.10 → 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.
package/README.md CHANGED
@@ -1,54 +1,37 @@
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, background jobs, recurring scheduling, observability, 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, API routes, authentication, authorization, SQL databases, background jobs, scheduling, workflow orchestration, transactional events, observability, uploads, storage and standalone Node.js deployment.
4
4
 
5
- > **Development target:** `0.2.10Durable Jobs Platform`
5
+ > **Development target:** `0.2.12Transactional Outbox & Events`
6
6
  >
7
- > `0.2.10` is an unreleased development target until local validation, RC checks, tagging and npm publication complete.
7
+ > `0.2.12` remains unreleased until local validation, RC checks, tagging and npm publication complete.
8
8
 
9
- ## 0.2 platform
9
+ ## Current 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, `0.2.9` added recurring scheduling, and `0.2.10` adds durable worker leases, DLQ maintenance and Redis-compatible queue/scheduler adapters.
12
-
13
- Machine-readable platform contracts:
14
-
15
- ```text
16
- docs/platform-manifest.json
17
- -> runtime target, capabilities and compatibility
18
-
19
- docs/docs-web-manifest.json
20
- -> documentation navigation, routes and releases
21
-
22
- docs/api-manifest.json
23
- -> public package entrypoints and guide ownership
24
- ```
25
-
26
- ## Current capabilities
11
+ BCP `0.2.x` currently includes:
27
12
 
28
13
  | Area | Capability |
29
14
  | --- | --- |
30
15
  | Application | React SSR, hydration, layouts, metadata and SPA navigation |
31
16
  | Routing | Static, dynamic, catch-all, optional catch-all and route groups |
32
- | Server data | Route `loader.ts`, request-scoped server APIs |
33
- | Mutations | Route-owned `actions.ts` and `<Form>` |
34
- | Authentication | JWT cookie sessions, optional server-side session stores, revocation, logout-all, idle timeout and rotation |
35
- | Authorization | Auth/guest/role/permission route guards, flat permissions and resource-aware policies |
36
- | Request security | Same-origin validation and signed CSRF tokens for unsafe mutations |
17
+ | Server data | Route loaders and request-scoped server APIs |
18
+ | Mutations | Route-owned actions and `<Form>` |
19
+ | Authentication | JWT cookie sessions, optional server-side stores, revocation, logout-all and idle timeout |
20
+ | Authorization | Auth/guest/role/permission guards and resource-aware policies |
21
+ | Security | Same-origin validation and signed CSRF tokens |
37
22
  | Middleware | Middleware System v2 with onion execution |
38
- | Background jobs | Delayed jobs, retries/backoff, cancellation, concurrent workers, visibility leases, heartbeat, stale recovery and DLQ |
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 |
41
- | Observability | Structured logs, counters/gauges/histograms, Prometheus output, request metrics and health/readiness checks |
42
- | Validation | Typed validators and structured validation errors |
43
- | Error handling | HTTP error helpers and consistent error responses |
44
- | Database | Provider-neutral MySQL, PostgreSQL and SQLite adapters, transactions, lifecycle and migrations |
45
- | Uploads | Buffered multipart helpers and production multipart streaming |
46
- | Storage | Local + S3-compatible storage, streaming, list/copy/move, metadata, bulk delete and signed URLs |
23
+ | Database | MySQL, PostgreSQL and SQLite adapters, transactions, lifecycle and migrations |
24
+ | Background jobs | Delay, retry/backoff, cancellation and concurrent workers |
25
+ | Scheduling | Interval/UTC cron schedules and scheduler leases |
26
+ | Durable jobs | Redis-compatible queue/schedule adapters, visibility timeout, heartbeat, stale recovery and DLQ |
27
+ | Workflows | Sequential/parallel steps, retries, persisted delays, compensation and run leases |
28
+ | Events | Transactional outbox, SQL persistence, dispatcher leases, retries, event bus and durable queue handoff |
29
+ | Observability | Structured logs, metrics, Prometheus output and health/readiness checks |
30
+ | Uploads & storage | Multipart streaming, Local/S3-compatible storage and signed URLs |
47
31
  | Caching | Response cache and revalidation primitives |
48
- | Configuration | Typed `bcp.config.*`, optional `bcp.environment.*`, startup diagnostics and `bcp config check` |
49
- | Developer tools | Generators, Doctor/Inspect v2, updater, route inspection and project metadata |
50
- | Production | Standalone Node.js build, application packaging, production dependency pruning, deployment manifests, Docker starter, hardening and graceful shutdown |
51
- | Documentation | Manifest-driven docs navigation, platform metadata and public API reference |
32
+ | Configuration | Typed config/environment validation and diagnostics |
33
+ | Production | Standalone Node.js build, packaging, dependency pruning, Docker starter and graceful shutdown |
34
+ | Documentation | Manifest-driven docs, platform metadata and API reference |
52
35
 
53
36
  ## Requirements
54
37
 
@@ -56,7 +39,7 @@ docs/api-manifest.json
56
39
  - React `19`
57
40
  - npm
58
41
 
59
- Database drivers are optional and provider-specific:
42
+ Optional SQL drivers:
60
43
 
61
44
  ```text
62
45
  MySQL mysql2
@@ -72,7 +55,7 @@ cd my-app
72
55
  npm run dev
73
56
  ```
74
57
 
75
- Generated projects normally keep one framework dependency key:
58
+ Generated projects normally use one framework dependency:
76
59
 
77
60
  ```json
78
61
  {
@@ -82,55 +65,7 @@ Generated projects normally keep one framework dependency key:
82
65
  }
83
66
  ```
84
67
 
85
- Do not install both `bcp` and a second direct `@chidchanun/bcp` dependency in the same application.
86
-
87
- ## Configuration & environment
88
-
89
- Framework configuration stays in one of:
90
-
91
- ```text
92
- bcp.config.ts
93
- bcp.config.mts
94
- bcp.config.js
95
- bcp.config.mjs
96
- ```
97
-
98
- Application environment validation can be declared in:
99
-
100
- ```text
101
- bcp.environment.ts
102
- bcp.environment.mts
103
- bcp.environment.js
104
- bcp.environment.mjs
105
- ```
106
-
107
- Configuration precedence is:
108
-
109
- ```text
110
- CLI override
111
-
112
- BCP_* environment
113
-
114
- bcp.config.*
115
-
116
- framework defaults
117
- ```
118
-
119
- Validate configuration and declared environment values with:
120
-
121
- ```bash
122
- bcp config check
123
- bcp config check --json
124
- ```
125
-
126
- Variables beginning with `BCP_PUBLIC_` may be embedded in browser output. Never expose application secrets through public-prefixed variables.
127
-
128
- Read more:
129
-
130
- - [Configuration](docs/configuration.md)
131
- - [Environment Validation](docs/environment-validation.md)
132
-
133
- ## Database Platform v2 — 0.2.3
68
+ ## Database Platform
134
69
 
135
70
  ```ts
136
71
  import {
@@ -139,14 +74,6 @@ import {
139
74
  } from "bcp/database";
140
75
  ```
141
76
 
142
- Built-in SQL providers:
143
-
144
- ```text
145
- mysql
146
- postgresql
147
- sqlite
148
- ```
149
-
150
77
  Migration CLI:
151
78
 
152
79
  ```bash
@@ -156,61 +83,17 @@ bcp db status
156
83
  bcp db rollback
157
84
  ```
158
85
 
159
- Read more:
160
-
161
- - [Database](docs/database.md)
162
- - [Database Migrations](docs/database-migrations.md)
163
-
164
- ## Application Packaging — 0.2.4
165
-
166
- Create a fresh production build and deployment package:
167
-
168
- ```bash
169
- bcp package
170
- ```
171
-
172
- Output is written under:
173
-
174
- ```text
175
- .bcp-framework/package/
176
- ```
177
-
178
- Read more:
179
-
180
- - [Application Packaging](docs/application-packaging.md)
181
- - [Deployment](docs/deployment.md)
182
-
183
- ## Authentication Platform v2 — 0.2.5
86
+ ## Authentication & authorization
184
87
 
185
88
  ```ts
186
89
  import {
187
- auth,
188
90
  createAuth,
189
91
  createMemoryAuthSessionStore,
190
- login,
191
- logout,
192
- } from "bcp/auth";
193
- ```
194
-
195
- Stateless signed JWT-cookie authentication remains supported. Applications that need centralized revocation can configure an `AuthSessionStore`.
196
-
197
- Read more:
198
-
199
- - [Authentication](docs/authentication.md)
200
- - [Auth Session Stores](docs/auth-session-store.md)
201
- - [Auth Route Guards](docs/auth-route-guards.md)
202
-
203
- ## Authorization & Security v2 — 0.2.6
204
-
205
- ```ts
206
- import {
207
- authorize,
208
- hasPermission,
209
92
  requirePermission,
210
93
  } from "bcp/auth";
211
94
  ```
212
95
 
213
- Request-security helpers are exposed from `bcp/server`:
96
+ Request security is available from `bcp/server`:
214
97
 
215
98
  ```ts
216
99
  import {
@@ -220,9 +103,7 @@ import {
220
103
  } from "bcp/server";
221
104
  ```
222
105
 
223
- Read more: [Authorization & Security v2](docs/authorization-security.md)
224
-
225
- ## Observability Platform v2 — 0.2.7
106
+ ## Observability
226
107
 
227
108
  ```ts
228
109
  import {
@@ -232,9 +113,7 @@ import {
232
113
  } from "bcp/observability";
233
114
  ```
234
115
 
235
- Read more: [Observability Platform v2](docs/observability.md)
236
-
237
- ## Background Jobs Platform — 0.2.8
116
+ ## Background jobs
238
117
 
239
118
  ```ts
240
119
  import {
@@ -245,7 +124,7 @@ export const jobs =
245
124
  createJobQueue();
246
125
  ```
247
126
 
248
- Register work:
127
+ Register typed work:
249
128
 
250
129
  ```ts
251
130
  jobs.register<{
@@ -260,24 +139,7 @@ jobs.register<{
260
139
  );
261
140
  ```
262
141
 
263
- Enqueue work:
264
-
265
- ```ts
266
- await jobs.enqueue(
267
- "email.welcome",
268
- {
269
- userId: 42,
270
- },
271
- {
272
- delayMs: 5_000,
273
- maxAttempts: 5,
274
- }
275
- );
276
- ```
277
-
278
- Read more: [Background Jobs Platform](docs/background-jobs.md)
279
-
280
- ## Job Scheduling Platform — 0.2.9
142
+ ## Job scheduling
281
143
 
282
144
  ```ts
283
145
  import {
@@ -290,20 +152,7 @@ export const scheduler =
290
152
  });
291
153
  ```
292
154
 
293
- Interval schedule:
294
-
295
- ```ts
296
- await scheduler.schedule(
297
- "cache.cleanup",
298
- {},
299
- {
300
- id: "cache-cleanup",
301
- everyMs: 5 * 60 * 1000,
302
- }
303
- );
304
- ```
305
-
306
- UTC cron schedule:
155
+ UTC cron example:
307
156
 
308
157
  ```ts
309
158
  await scheduler.schedule(
@@ -315,11 +164,9 @@ await scheduler.schedule(
315
164
  );
316
165
  ```
317
166
 
318
- Read more: [Job Scheduling Platform](docs/job-scheduling.md)
319
-
320
167
  ## Durable Jobs Platform — 0.2.10
321
168
 
322
- Workers now support visibility leases, heartbeat renewal and stale-running recovery when the configured adapter implements those capabilities:
169
+ Workers support visibility leases, heartbeat renewal and stale-running recovery:
323
170
 
324
171
  ```ts
325
172
  const worker =
@@ -328,104 +175,202 @@ const worker =
328
175
  concurrency: 4,
329
176
  visibilityTimeoutMs: 30_000,
330
177
  heartbeatIntervalMs: 10_000,
331
- pollIntervalMs: 250,
332
178
  });
333
179
  ```
334
180
 
335
- Retry-exhausted jobs can be inspected and requeued:
181
+ Redis-compatible adapters are available from `bcp/jobs`. BCP does not install or own the Redis client; applications provide a command client and manage credentials/TLS/Cluster/lifecycle themselves.
182
+
183
+ ## Workflow Orchestration — 0.2.11
336
184
 
337
185
  ```ts
338
- const failed =
339
- await jobs.deadLetters();
186
+ import {
187
+ createWorkflow,
188
+ } from "bcp/workflow";
189
+
190
+ export const onboarding =
191
+ createWorkflow<{
192
+ userId: number;
193
+ }>(
194
+ "user.onboarding",
195
+ workflow => {
196
+ workflow.step(
197
+ "profile",
198
+ createProfile
199
+ );
200
+
201
+ workflow.parallel(
202
+ "initialize",
203
+ parallel => {
204
+ parallel.step(
205
+ "preferences",
206
+ createPreferences
207
+ );
208
+ parallel.step(
209
+ "workspace",
210
+ createWorkspace
211
+ );
212
+ }
213
+ );
214
+
215
+ workflow.delay(
216
+ "cooldown",
217
+ 1_000
218
+ );
219
+ }
220
+ );
221
+ ```
222
+
223
+ Workflows support retries, compensation and optional execution through the durable job queue.
224
+
225
+ ## Transactional Outbox & Events — 0.2.12
226
+
227
+ `0.2.12` adds the server-only `bcp/events` entrypoint.
228
+
229
+ The problem it solves:
340
230
 
341
- await jobs.requeueDeadLetter(
342
- failed[0].id,
343
- {
344
- delayMs: 5_000,
345
- resetAttempts: true,
231
+ ```text
232
+ DB commit succeeds
233
+ +
234
+ external publish fails
235
+ =
236
+ missing integration event
237
+ ```
238
+
239
+ The outbox writes the event in the **same SQL transaction** as the business data:
240
+
241
+ ```ts
242
+ import {
243
+ db,
244
+ } from "bcp/database";
245
+
246
+ import {
247
+ createSqlOutboxStore,
248
+ createTransactionalOutbox,
249
+ } from "bcp/events";
250
+
251
+ const outboxStore =
252
+ createSqlOutboxStore({
253
+ database: db,
254
+ driver: "postgresql",
255
+ });
256
+
257
+ const outbox =
258
+ createTransactionalOutbox({
259
+ store: outboxStore,
260
+ });
261
+
262
+ await db.transaction(
263
+ async tx => {
264
+ await tx.execute(
265
+ "INSERT INTO orders ..."
266
+ );
267
+
268
+ await outbox.publish(
269
+ tx,
270
+ "order.created",
271
+ {
272
+ orderId: 42,
273
+ },
274
+ {
275
+ aggregateId: "42",
276
+ correlationId: requestId,
277
+ }
278
+ );
346
279
  }
347
280
  );
348
281
  ```
349
282
 
350
- Operational helpers:
283
+ Generate the outbox table migration for the configured provider:
351
284
 
352
285
  ```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
- ```
286
+ import {
287
+ createOutboxMigrationSql,
288
+ } from "bcp/events";
366
289
 
367
- ### Redis-compatible durable queue
290
+ const sql =
291
+ createOutboxMigrationSql(
292
+ "postgresql"
293
+ );
294
+ ```
368
295
 
369
- BCP does not install a Redis client library. Supply an application-owned client that implements:
296
+ Supported providers:
370
297
 
371
- ```ts
372
- interface RedisCommandClient {
373
- sendCommand(
374
- command: string[]
375
- ): Promise<unknown>;
376
- }
298
+ ```text
299
+ mysql
300
+ postgresql
301
+ sqlite
377
302
  ```
378
303
 
379
- Then create the adapters:
304
+ ### Dispatcher
305
+
306
+ After the SQL transaction commits, a dispatcher claims due events and delivers them:
380
307
 
381
308
  ```ts
382
309
  import {
383
- createJobQueue,
384
- createJobScheduler,
385
- createRedisJobQueueAdapter,
386
- createRedisJobScheduleStore,
387
- } from "bcp/jobs";
310
+ createOutboxDispatcher,
311
+ } from "bcp/events";
388
312
 
389
- const queueAdapter =
390
- createRedisJobQueueAdapter({
391
- client: redisCommandClient,
392
- namespace: "my-app:{jobs}",
313
+ export const dispatcher =
314
+ createOutboxDispatcher({
315
+ store: outboxStore,
316
+ queue: jobs,
317
+ ownerId: "outbox-a",
318
+ leaseMs: 30_000,
319
+ batchSize: 100,
320
+ pollIntervalMs: 1_000,
393
321
  });
394
322
 
395
- export const jobs =
396
- createJobQueue({
397
- adapter: queueAdapter,
398
- });
323
+ const runner =
324
+ dispatcher.start();
325
+ ```
399
326
 
400
- const scheduleStore =
401
- createRedisJobScheduleStore({
402
- client: redisCommandClient,
403
- namespace: "my-app:{jobs}",
404
- });
327
+ With `queue: jobs`, event type:
405
328
 
406
- export const scheduler =
407
- createJobScheduler({
408
- queue: jobs,
409
- store: scheduleStore,
410
- ownerId: "scheduler-a",
411
- });
329
+ ```text
330
+ order.created
412
331
  ```
413
332
 
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.
333
+ is handed off as:
415
334
 
416
- A typical application may configure its Redis client with:
335
+ ```text
336
+ event.order.created
337
+ ```
338
+
339
+ Register its durable consumer:
417
340
 
418
- ```dotenv
419
- REDIS_URL=redis://localhost:6379
341
+ ```ts
342
+ jobs.register(
343
+ "event.order.created",
344
+ async ({ payload }) => {
345
+ await handleOrderCreated(
346
+ payload
347
+ );
348
+ }
349
+ );
420
350
  ```
421
351
 
422
- BCP does not read `REDIS_URL` automatically; connection creation, TLS/Cluster settings and credentials remain application-owned.
352
+ Dispatcher features include:
353
+
354
+ - batched claims,
355
+ - lease ownership,
356
+ - stale lease recovery,
357
+ - retry/backoff,
358
+ - terminal failed state,
359
+ - queue delivery,
360
+ - custom publisher callbacks,
361
+ - local `EventBus`,
362
+ - retention cleanup,
363
+ - outbox statistics.
423
364
 
424
- Read more: [Durable Jobs Platform](docs/durable-jobs.md)
365
+ `published` means the configured destination accepted the event. For queue delivery, it means enqueue succeeded; it does not mean the downstream job handler has completed.
366
+
367
+ Delivery remains **at-least-once**, so consumers that perform non-idempotent side effects should use stable event IDs/idempotency controls.
368
+
369
+ Read more: [Transactional Outbox & Events](docs/transactional-outbox-events.md)
425
370
 
426
371
  ## Public entrypoints
427
372
 
428
- The current `0.2.x` platform contract recognizes:
373
+ The current documented platform surface is:
429
374
 
430
375
  ```text
431
376
  bcp
@@ -437,24 +382,18 @@ bcp/error
437
382
  bcp/database
438
383
  bcp/auth
439
384
  bcp/jobs
385
+ bcp/workflow
386
+ bcp/events
440
387
  bcp/observability
441
388
  bcp/server
442
389
  bcp/server-only
443
390
  bcp/middleware
444
391
  ```
445
392
 
446
- Application code should use public entrypoints instead of importing framework internals under `packages/`.
447
-
448
- See:
449
-
450
- - [API Reference](docs/api-reference.md)
451
- - [Platform Manifest](docs/platform-manifest.json)
452
- - [API Manifest](docs/api-manifest.json)
393
+ Application code should use public entrypoints instead of importing private `packages/*` implementation files.
453
394
 
454
395
  ## CLI
455
396
 
456
- Core commands:
457
-
458
397
  ```bash
459
398
  bcp dev
460
399
  bcp build
@@ -468,16 +407,7 @@ bcp inspect
468
407
  bcp version
469
408
  ```
470
409
 
471
- Database migrations:
472
-
473
- ```bash
474
- bcp db create create_users
475
- bcp db migrate
476
- bcp db status
477
- bcp db rollback
478
- ```
479
-
480
- Project generators:
410
+ Generators:
481
411
 
482
412
  ```bash
483
413
  bcp generate page dashboard/users
@@ -489,23 +419,35 @@ bcp generate migration create_users
489
419
  ## Production model
490
420
 
491
421
  ```text
492
- Browser / API clients
493
-
494
- security + middleware + auth
495
-
422
+ Browser / API
423
+ |
424
+ security + auth + middleware
425
+ |
496
426
  loaders / actions / API routes
497
-
498
- SSR / application responses
427
+ |
428
+ Database transaction
429
+ |\
430
+ | +--> transactional outbox
431
+ | |
432
+ | dispatcher
433
+ | |
434
+ | durable jobs
435
+ | |
436
+ | workers
437
+ |
438
+ SSR / response
499
439
 
500
- Operational side channels:
501
- shared jobs + scheduler + structured logs + metrics + health/readiness
440
+ Workflow + scheduler + logs + metrics + health
441
+ operate alongside the request path.
502
442
  ```
503
443
 
504
- Raw standalone build:
444
+ ## Packaging
445
+
446
+ Raw production build:
505
447
 
506
448
  ```bash
507
449
  npm run build
508
- npm run start
450
+ npm start
509
451
  ```
510
452
 
511
453
  Deployment package:
@@ -518,31 +460,30 @@ bcp package
518
460
 
519
461
  The framework repository is the documentation source of truth.
520
462
 
521
- `bcp-docs-web` consumes:
463
+ Machine-readable contracts:
522
464
 
523
465
  ```text
524
- docs/docs-web-manifest.json
525
466
  docs/platform-manifest.json
467
+ docs/docs-web-manifest.json
526
468
  docs/api-manifest.json
527
469
  ```
528
470
 
529
471
  ## Release validation
530
472
 
531
- Framework releases must pass:
473
+ Before publishing `0.2.12`:
532
474
 
533
475
  ```bash
534
- npm install
535
476
  npm run typecheck
536
477
  npm run test:unit
537
478
  npm run test:integration
538
- npm run test:package
539
479
  npm run test:e2e
480
+ npm run test:package
540
481
  npm run rc:check
541
482
  ```
542
483
 
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.
484
+ `0.2.12` adds unit and prepared-package smoke coverage for transaction-bound outbox writes, dispatcher queue handoff, retry/failure behavior, stale lease recovery, SQL migration generation, public export/runtime compilation and browser boundary enforcement.
544
485
 
545
- Do not tag or publish until the final release commit passes the complete RC sequence.
486
+ Do not tag or publish until the exact final release commit passes the full RC sequence.
546
487
 
547
488
  ## Release history
548
489
 
@@ -565,12 +506,16 @@ Do not tag or publish until the final release commit passes the complete RC sequ
565
506
  | `0.2.8` | Background Jobs Platform |
566
507
  | `0.2.9` | Job Scheduling Platform |
567
508
  | `0.2.10` | Durable Jobs Platform |
509
+ | `0.2.11` | Workflow Orchestration |
510
+ | `0.2.12` | Transactional Outbox & Events |
568
511
 
569
512
  ## Roadmap
570
513
 
571
- `0.2.10 Durable Jobs Platform` establishes shared production queue/scheduler adapters and worker recovery semantics while keeping the provider-neutral `bcp/jobs` contract.
514
+ `0.2.12` closes the database-commit / external-publish gap and establishes a provider-neutral event-delivery boundary on top of Database + Durable Jobs.
515
+
516
+ The next logical milestone is **`0.2.13 — Realtime Platform`**, adding WebSocket/SSE channels, rooms/presence, authenticated realtime connections and live delivery for workflow/job/event progress without changing the current outbox/job contracts.
572
517
 
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.
518
+ Native desktop/mobile compilation remains later roadmap work.
574
519
 
575
520
  ## License
576
521