@chidchanun/bcp 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.
package/README.md CHANGED
@@ -1,55 +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, workflow orchestration, 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.11Workflow Orchestration`
5
+ > **Development target:** `0.2.12Transactional Outbox & Events`
6
6
  >
7
- > `0.2.11` 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, `0.2.10` added durable worker leases/DLQ/Redis adapters, and `0.2.11` adds persistent multi-step workflow orchestration.
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
- | Workflows | Sequential/parallel steps, retries, persisted delays, compensation, run leases and optional queue-backed execution |
42
- | Observability | Structured logs, counters/gauges/histograms, Prometheus output, request metrics and health/readiness checks |
43
- | Validation | Typed validators and structured validation errors |
44
- | Error handling | HTTP error helpers and consistent error responses |
45
- | Database | Provider-neutral MySQL, PostgreSQL and SQLite adapters, transactions, lifecycle and migrations |
46
- | Uploads | Buffered multipart helpers and production multipart streaming |
47
- | 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 |
48
31
  | Caching | Response cache and revalidation primitives |
49
- | Configuration | Typed `bcp.config.*`, optional `bcp.environment.*`, startup diagnostics and `bcp config check` |
50
- | Developer tools | Generators, Doctor/Inspect v2, updater, route inspection and project metadata |
51
- | Production | Standalone Node.js build, application packaging, production dependency pruning, deployment manifests, Docker starter, hardening and graceful shutdown |
52
- | 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 |
53
35
 
54
36
  ## Requirements
55
37
 
@@ -57,7 +39,7 @@ docs/api-manifest.json
57
39
  - React `19`
58
40
  - npm
59
41
 
60
- Database drivers are optional and provider-specific:
42
+ Optional SQL drivers:
61
43
 
62
44
  ```text
63
45
  MySQL mysql2
@@ -73,7 +55,7 @@ cd my-app
73
55
  npm run dev
74
56
  ```
75
57
 
76
- Generated projects normally keep one framework dependency key:
58
+ Generated projects normally use one framework dependency:
77
59
 
78
60
  ```json
79
61
  {
@@ -83,55 +65,7 @@ Generated projects normally keep one framework dependency key:
83
65
  }
84
66
  ```
85
67
 
86
- Do not install both `bcp` and a second direct `@chidchanun/bcp` dependency in the same application.
87
-
88
- ## Configuration & environment
89
-
90
- Framework configuration stays in one of:
91
-
92
- ```text
93
- bcp.config.ts
94
- bcp.config.mts
95
- bcp.config.js
96
- bcp.config.mjs
97
- ```
98
-
99
- Application environment validation can be declared in:
100
-
101
- ```text
102
- bcp.environment.ts
103
- bcp.environment.mts
104
- bcp.environment.js
105
- bcp.environment.mjs
106
- ```
107
-
108
- Configuration precedence is:
109
-
110
- ```text
111
- CLI override
112
-
113
- BCP_* environment
114
-
115
- bcp.config.*
116
-
117
- framework defaults
118
- ```
119
-
120
- Validate configuration and declared environment values with:
121
-
122
- ```bash
123
- bcp config check
124
- bcp config check --json
125
- ```
126
-
127
- Variables beginning with `BCP_PUBLIC_` may be embedded in browser output. Never expose application secrets through public-prefixed variables.
128
-
129
- Read more:
130
-
131
- - [Configuration](docs/configuration.md)
132
- - [Environment Validation](docs/environment-validation.md)
133
-
134
- ## Database Platform v2 — 0.2.3
68
+ ## Database Platform
135
69
 
136
70
  ```ts
137
71
  import {
@@ -140,14 +74,6 @@ import {
140
74
  } from "bcp/database";
141
75
  ```
142
76
 
143
- Built-in SQL providers:
144
-
145
- ```text
146
- mysql
147
- postgresql
148
- sqlite
149
- ```
150
-
151
77
  Migration CLI:
152
78
 
153
79
  ```bash
@@ -157,61 +83,17 @@ bcp db status
157
83
  bcp db rollback
158
84
  ```
159
85
 
160
- Read more:
161
-
162
- - [Database](docs/database.md)
163
- - [Database Migrations](docs/database-migrations.md)
164
-
165
- ## Application Packaging — 0.2.4
166
-
167
- Create a fresh production build and deployment package:
168
-
169
- ```bash
170
- bcp package
171
- ```
172
-
173
- Output is written under:
174
-
175
- ```text
176
- .bcp-framework/package/
177
- ```
178
-
179
- Read more:
180
-
181
- - [Application Packaging](docs/application-packaging.md)
182
- - [Deployment](docs/deployment.md)
183
-
184
- ## Authentication Platform v2 — 0.2.5
86
+ ## Authentication & authorization
185
87
 
186
88
  ```ts
187
89
  import {
188
- auth,
189
90
  createAuth,
190
91
  createMemoryAuthSessionStore,
191
- login,
192
- logout,
193
- } from "bcp/auth";
194
- ```
195
-
196
- Stateless signed JWT-cookie authentication remains supported. Applications that need centralized revocation can configure an `AuthSessionStore`.
197
-
198
- Read more:
199
-
200
- - [Authentication](docs/authentication.md)
201
- - [Auth Session Stores](docs/auth-session-store.md)
202
- - [Auth Route Guards](docs/auth-route-guards.md)
203
-
204
- ## Authorization & Security v2 — 0.2.6
205
-
206
- ```ts
207
- import {
208
- authorize,
209
- hasPermission,
210
92
  requirePermission,
211
93
  } from "bcp/auth";
212
94
  ```
213
95
 
214
- Request-security helpers are exposed from `bcp/server`:
96
+ Request security is available from `bcp/server`:
215
97
 
216
98
  ```ts
217
99
  import {
@@ -221,9 +103,7 @@ import {
221
103
  } from "bcp/server";
222
104
  ```
223
105
 
224
- Read more: [Authorization & Security v2](docs/authorization-security.md)
225
-
226
- ## Observability Platform v2 — 0.2.7
106
+ ## Observability
227
107
 
228
108
  ```ts
229
109
  import {
@@ -233,9 +113,7 @@ import {
233
113
  } from "bcp/observability";
234
114
  ```
235
115
 
236
- Read more: [Observability Platform v2](docs/observability.md)
237
-
238
- ## Background Jobs Platform — 0.2.8
116
+ ## Background jobs
239
117
 
240
118
  ```ts
241
119
  import {
@@ -246,7 +124,7 @@ export const jobs =
246
124
  createJobQueue();
247
125
  ```
248
126
 
249
- Register work:
127
+ Register typed work:
250
128
 
251
129
  ```ts
252
130
  jobs.register<{
@@ -261,24 +139,7 @@ jobs.register<{
261
139
  );
262
140
  ```
263
141
 
264
- Enqueue work:
265
-
266
- ```ts
267
- await jobs.enqueue(
268
- "email.welcome",
269
- {
270
- userId: 42,
271
- },
272
- {
273
- delayMs: 5_000,
274
- maxAttempts: 5,
275
- }
276
- );
277
- ```
278
-
279
- Read more: [Background Jobs Platform](docs/background-jobs.md)
280
-
281
- ## Job Scheduling Platform — 0.2.9
142
+ ## Job scheduling
282
143
 
283
144
  ```ts
284
145
  import {
@@ -291,20 +152,7 @@ export const scheduler =
291
152
  });
292
153
  ```
293
154
 
294
- Interval schedule:
295
-
296
- ```ts
297
- await scheduler.schedule(
298
- "cache.cleanup",
299
- {},
300
- {
301
- id: "cache-cleanup",
302
- everyMs: 5 * 60 * 1000,
303
- }
304
- );
305
- ```
306
-
307
- UTC cron schedule:
155
+ UTC cron example:
308
156
 
309
157
  ```ts
310
158
  await scheduler.schedule(
@@ -316,11 +164,9 @@ await scheduler.schedule(
316
164
  );
317
165
  ```
318
166
 
319
- Read more: [Job Scheduling Platform](docs/job-scheduling.md)
320
-
321
167
  ## Durable Jobs Platform — 0.2.10
322
168
 
323
- Workers 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:
324
170
 
325
171
  ```ts
326
172
  const worker =
@@ -329,68 +175,13 @@ const worker =
329
175
  concurrency: 4,
330
176
  visibilityTimeoutMs: 30_000,
331
177
  heartbeatIntervalMs: 10_000,
332
- pollIntervalMs: 250,
333
- });
334
- ```
335
-
336
- Retry-exhausted jobs can be inspected and requeued:
337
-
338
- ```ts
339
- const failed =
340
- await jobs.deadLetters();
341
-
342
- await jobs.requeueDeadLetter(
343
- failed[0].id,
344
- {
345
- delayMs: 5_000,
346
- resetAttempts: true,
347
- }
348
- );
349
- ```
350
-
351
- Redis-compatible durable adapters:
352
-
353
- ```ts
354
- import {
355
- createJobQueue,
356
- createJobScheduler,
357
- createRedisJobQueueAdapter,
358
- createRedisJobScheduleStore,
359
- } from "bcp/jobs";
360
-
361
- const queueAdapter =
362
- createRedisJobQueueAdapter({
363
- client: redisCommandClient,
364
- namespace: "my-app:{jobs}",
365
- });
366
-
367
- export const jobs =
368
- createJobQueue({
369
- adapter: queueAdapter,
370
- });
371
-
372
- const scheduleStore =
373
- createRedisJobScheduleStore({
374
- client: redisCommandClient,
375
- namespace: "my-app:{jobs}",
376
- });
377
-
378
- export const scheduler =
379
- createJobScheduler({
380
- queue: jobs,
381
- store: scheduleStore,
382
- ownerId: "scheduler-a",
383
178
  });
384
179
  ```
385
180
 
386
- BCP does not read `REDIS_URL` or own the Redis client connection lifecycle automatically.
387
-
388
- Read more: [Durable Jobs Platform](docs/durable-jobs.md)
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.
389
182
 
390
183
  ## Workflow Orchestration — 0.2.11
391
184
 
392
- Create a server-only workflow with typed input:
393
-
394
185
  ```ts
395
186
  import {
396
187
  createWorkflow,
@@ -404,11 +195,7 @@ export const onboarding =
404
195
  workflow => {
405
196
  workflow.step(
406
197
  "profile",
407
- async ({ input }) => {
408
- await createProfile(
409
- input.userId
410
- );
411
- }
198
+ createProfile
412
199
  );
413
200
 
414
201
  workflow.parallel(
@@ -433,66 +220,157 @@ export const onboarding =
433
220
  );
434
221
  ```
435
222
 
436
- Per-step retries:
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:
230
+
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:
437
240
 
438
241
  ```ts
439
- workflow.step(
440
- "charge-card",
441
- chargeCard,
442
- {
443
- maxAttempts: 3,
444
- retryDelayMs:
445
- attempt =>
446
- attempt * 1_000,
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
+ );
447
279
  }
448
280
  );
449
281
  ```
450
282
 
451
- Saga-style compensation:
283
+ Generate the outbox table migration for the configured provider:
452
284
 
453
285
  ```ts
454
- workflow.step(
455
- "reserve-stock",
456
- reserveStock,
457
- {
458
- compensate:
459
- releaseStock,
460
- }
461
- );
286
+ import {
287
+ createOutboxMigrationSql,
288
+ } from "bcp/events";
289
+
290
+ const sql =
291
+ createOutboxMigrationSql(
292
+ "postgresql"
293
+ );
462
294
  ```
463
295
 
464
- A failed run can be compensated in reverse completion order:
296
+ Supported providers:
297
+
298
+ ```text
299
+ mysql
300
+ postgresql
301
+ sqlite
302
+ ```
303
+
304
+ ### Dispatcher
305
+
306
+ After the SQL transaction commits, a dispatcher claims due events and delivers them:
465
307
 
466
308
  ```ts
467
- await onboarding.compensate(
468
- runId
469
- );
309
+ import {
310
+ createOutboxDispatcher,
311
+ } from "bcp/events";
312
+
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,
321
+ });
322
+
323
+ const runner =
324
+ dispatcher.start();
325
+ ```
326
+
327
+ With `queue: jobs`, event type:
328
+
329
+ ```text
330
+ order.created
331
+ ```
332
+
333
+ is handed off as:
334
+
335
+ ```text
336
+ event.order.created
470
337
  ```
471
338
 
472
- For durable execution, supply an existing BCP job queue and a shared workflow store:
339
+ Register its durable consumer:
473
340
 
474
341
  ```ts
475
- export const fulfillment =
476
- createWorkflow(
477
- "order.fulfillment",
478
- defineWorkflow,
479
- {
480
- queue: jobs,
481
- store:
482
- workflowStore,
483
- }
484
- );
342
+ jobs.register(
343
+ "event.order.created",
344
+ async ({ payload }) => {
345
+ await handleOrderCreated(
346
+ payload
347
+ );
348
+ }
349
+ );
485
350
  ```
486
351
 
487
- With a queue configured, `start()`, `retry()`, `resume()` and delay continuations execute through `bcp/jobs`. `WorkflowStore.claim()` is the atomic run-level concurrency boundary for multi-instance deployments.
352
+ Dispatcher features include:
488
353
 
489
- The built-in `createMemoryWorkflowStore()` is intended for local development and tests. External side effects should remain idempotent because durable job delivery is at-least-once.
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.
490
364
 
491
- Read more: [Workflow Orchestration](docs/workflow-orchestration.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)
492
370
 
493
371
  ## Public entrypoints
494
372
 
495
- The current `0.2.x` platform contract recognizes:
373
+ The current documented platform surface is:
496
374
 
497
375
  ```text
498
376
  bcp
@@ -505,24 +383,17 @@ bcp/database
505
383
  bcp/auth
506
384
  bcp/jobs
507
385
  bcp/workflow
386
+ bcp/events
508
387
  bcp/observability
509
388
  bcp/server
510
389
  bcp/server-only
511
390
  bcp/middleware
512
391
  ```
513
392
 
514
- Application code should use public entrypoints instead of importing framework internals under `packages/`.
515
-
516
- See:
517
-
518
- - [API Reference](docs/api-reference.md)
519
- - [Platform Manifest](docs/platform-manifest.json)
520
- - [API Manifest](docs/api-manifest.json)
393
+ Application code should use public entrypoints instead of importing private `packages/*` implementation files.
521
394
 
522
395
  ## CLI
523
396
 
524
- Core commands:
525
-
526
397
  ```bash
527
398
  bcp dev
528
399
  bcp build
@@ -536,16 +407,7 @@ bcp inspect
536
407
  bcp version
537
408
  ```
538
409
 
539
- Database migrations:
540
-
541
- ```bash
542
- bcp db create create_users
543
- bcp db migrate
544
- bcp db status
545
- bcp db rollback
546
- ```
547
-
548
- Project generators:
410
+ Generators:
549
411
 
550
412
  ```bash
551
413
  bcp generate page dashboard/users
@@ -557,27 +419,35 @@ bcp generate migration create_users
557
419
  ## Production model
558
420
 
559
421
  ```text
560
- Browser / API clients
561
-
562
- security + middleware + auth
563
-
422
+ Browser / API
423
+ |
424
+ security + auth + middleware
425
+ |
564
426
  loaders / actions / API routes
565
-
566
- SSR / application responses
567
-
568
- Operational side channels:
569
- workflow orchestration
570
-
571
- shared jobs + scheduler
572
-
573
- workers + structured logs + metrics + health/readiness
427
+ |
428
+ Database transaction
429
+ |\
430
+ | +--> transactional outbox
431
+ | |
432
+ | dispatcher
433
+ | |
434
+ | durable jobs
435
+ | |
436
+ | workers
437
+ |
438
+ SSR / response
439
+
440
+ Workflow + scheduler + logs + metrics + health
441
+ operate alongside the request path.
574
442
  ```
575
443
 
576
- Raw standalone build:
444
+ ## Packaging
445
+
446
+ Raw production build:
577
447
 
578
448
  ```bash
579
449
  npm run build
580
- npm run start
450
+ npm start
581
451
  ```
582
452
 
583
453
  Deployment package:
@@ -590,31 +460,30 @@ bcp package
590
460
 
591
461
  The framework repository is the documentation source of truth.
592
462
 
593
- `bcp-docs-web` consumes:
463
+ Machine-readable contracts:
594
464
 
595
465
  ```text
596
- docs/docs-web-manifest.json
597
466
  docs/platform-manifest.json
467
+ docs/docs-web-manifest.json
598
468
  docs/api-manifest.json
599
469
  ```
600
470
 
601
471
  ## Release validation
602
472
 
603
- Framework releases must pass:
473
+ Before publishing `0.2.12`:
604
474
 
605
475
  ```bash
606
- npm install
607
476
  npm run typecheck
608
477
  npm run test:unit
609
478
  npm run test:integration
610
- npm run test:package
611
479
  npm run test:e2e
480
+ npm run test:package
612
481
  npm run rc:check
613
482
  ```
614
483
 
615
- `0.2.11` adds Workflow Orchestration unit and prepared-package smoke checks covering sequential/parallel execution, retries, persisted delay/resume behavior, compensation, queue-backed continuation, run leases, browser boundary enforcement and the compiled `bcp/workflow` 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.
616
485
 
617
- 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.
618
487
 
619
488
  ## Release history
620
489
 
@@ -638,12 +507,15 @@ Do not tag or publish until the final release commit passes the complete RC sequ
638
507
  | `0.2.9` | Job Scheduling Platform |
639
508
  | `0.2.10` | Durable Jobs Platform |
640
509
  | `0.2.11` | Workflow Orchestration |
510
+ | `0.2.12` | Transactional Outbox & Events |
641
511
 
642
512
  ## Roadmap
643
513
 
644
- `0.2.11 Workflow Orchestration` establishes persistent multi-step backend workflows on top of the provider-neutral jobs foundation.
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.
645
517
 
646
- The next logical `0.2.x` milestone is transactional outbox/event delivery so a database change and later asynchronous workflow/job publication can be coordinated without pretending a Redis publish is part of the database transaction. Realtime, testing, plugin/module and broader deployment work remain later roadmap items. Native `.exe`, desktop and mobile compilation remain later roadmap work.
518
+ Native desktop/mobile compilation remains later roadmap work.
647
519
 
648
520
  ## License
649
521