@pattern-stack/codegen 0.8.0 → 0.9.0
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/CHANGELOG.md +70 -0
- package/dist/runtime/subsystems/auth/controllers/auth.controller.d.ts +1 -0
- package/dist/runtime/subsystems/auth/index.d.ts +2 -0
- package/dist/runtime/subsystems/auth/index.js +55 -0
- package/dist/runtime/subsystems/auth/index.js.map +1 -1
- package/dist/runtime/subsystems/auth/middleware/requester-context.d.ts +81 -0
- package/dist/runtime/subsystems/auth/middleware/requester-context.js +60 -0
- package/dist/runtime/subsystems/auth/middleware/requester-context.js.map +1 -0
- package/dist/runtime/subsystems/auth/protocols/user-context.d.ts +18 -0
- package/dist/runtime/subsystems/bridge/bridge-delivery-handler.js.map +1 -1
- package/dist/runtime/subsystems/bridge/bridge-outbox-drain-hook.js.map +1 -1
- package/dist/runtime/subsystems/bridge/bridge.module.d.ts +3 -0
- package/dist/runtime/subsystems/bridge/bridge.module.js +930 -275
- package/dist/runtime/subsystems/bridge/bridge.module.js.map +1 -1
- package/dist/runtime/subsystems/bridge/event-flow.service.js.map +1 -1
- package/dist/runtime/subsystems/bridge/index.d.ts +3 -0
- package/dist/runtime/subsystems/bridge/index.js +837 -182
- package/dist/runtime/subsystems/bridge/index.js.map +1 -1
- package/dist/runtime/subsystems/events/event-bus.drizzle-backend.d.ts +3 -1
- package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js +92 -1
- package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js.map +1 -1
- package/dist/runtime/subsystems/events/event-bus.memory-backend.d.ts +3 -1
- package/dist/runtime/subsystems/events/event-bus.memory-backend.js +99 -0
- package/dist/runtime/subsystems/events/event-bus.memory-backend.js.map +1 -1
- package/dist/runtime/subsystems/events/event-bus.redis-backend.js.map +1 -1
- package/dist/runtime/subsystems/events/event-keyset-cursor.d.ts +32 -0
- package/dist/runtime/subsystems/events/event-keyset-cursor.js +38 -0
- package/dist/runtime/subsystems/events/event-keyset-cursor.js.map +1 -0
- package/dist/runtime/subsystems/events/event-read.protocol.d.ts +94 -0
- package/dist/runtime/subsystems/events/event-read.protocol.js +9 -0
- package/dist/runtime/subsystems/events/event-read.protocol.js.map +1 -0
- package/dist/runtime/subsystems/events/events.module.js +177 -3
- package/dist/runtime/subsystems/events/events.module.js.map +1 -1
- package/dist/runtime/subsystems/events/events.tokens.d.ts +16 -1
- package/dist/runtime/subsystems/events/events.tokens.js +2 -0
- package/dist/runtime/subsystems/events/events.tokens.js.map +1 -1
- package/dist/runtime/subsystems/events/generated/bus.js.map +1 -1
- package/dist/runtime/subsystems/events/generated/index.js.map +1 -1
- package/dist/runtime/subsystems/events/index.d.ts +2 -1
- package/dist/runtime/subsystems/events/index.js +178 -3
- package/dist/runtime/subsystems/events/index.js.map +1 -1
- package/dist/runtime/subsystems/index.d.ts +2 -0
- package/dist/runtime/subsystems/index.js +1198 -264
- package/dist/runtime/subsystems/index.js.map +1 -1
- package/dist/runtime/subsystems/jobs/bullmq.config.d.ts +98 -0
- package/dist/runtime/subsystems/jobs/bullmq.config.js +143 -0
- package/dist/runtime/subsystems/jobs/bullmq.config.js.map +1 -0
- package/dist/runtime/subsystems/jobs/index.d.ts +6 -2
- package/dist/runtime/subsystems/jobs/index.js +861 -201
- package/dist/runtime/subsystems/jobs/index.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.d.ts +107 -0
- package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js +922 -0
- package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js.map +1 -0
- package/dist/runtime/subsystems/jobs/job-run-keyset-cursor.d.ts +52 -0
- package/dist/runtime/subsystems/jobs/job-run-keyset-cursor.js +57 -0
- package/dist/runtime/subsystems/jobs/job-run-keyset-cursor.js.map +1 -0
- package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.d.ts +2 -1
- package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.js +81 -1
- package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.d.ts +2 -1
- package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.js +81 -0
- package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-run-service.protocol.d.ts +74 -1
- package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.d.ts +48 -0
- package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js +374 -0
- package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js.map +1 -0
- package/dist/runtime/subsystems/jobs/job-worker.module.d.ts +42 -4
- package/dist/runtime/subsystems/jobs/job-worker.module.js +832 -178
- package/dist/runtime/subsystems/jobs/job-worker.module.js.map +1 -1
- package/dist/runtime/subsystems/jobs/jobs-domain.module.d.ts +10 -1
- package/dist/runtime/subsystems/jobs/jobs-domain.module.js +519 -20
- package/dist/runtime/subsystems/jobs/jobs-domain.module.js.map +1 -1
- package/dist/runtime/subsystems/jobs/pool-config.loader.d.ts +9 -1
- package/dist/runtime/subsystems/jobs/pool-config.loader.js +4 -0
- package/dist/runtime/subsystems/jobs/pool-config.loader.js.map +1 -1
- package/dist/runtime/subsystems/observability/index.d.ts +4 -3
- package/dist/runtime/subsystems/observability/index.js +109 -2
- package/dist/runtime/subsystems/observability/index.js.map +1 -1
- package/dist/runtime/subsystems/observability/observability.module.js +109 -2
- package/dist/runtime/subsystems/observability/observability.module.js.map +1 -1
- package/dist/runtime/subsystems/observability/observability.protocol.d.ts +63 -2
- package/dist/runtime/subsystems/observability/observability.service.d.ts +21 -3
- package/dist/runtime/subsystems/observability/observability.service.js +109 -2
- package/dist/runtime/subsystems/observability/observability.service.js.map +1 -1
- package/dist/runtime/subsystems/observability/reporters/bridge-metrics.reporter.d.ts +1 -0
- package/dist/runtime/subsystems/observability/reporters/index.d.ts +1 -0
- package/dist/src/cli/index.js +43 -7
- package/dist/src/cli/index.js.map +1 -1
- package/package.json +1 -1
- package/runtime/subsystems/auth/index.ts +8 -0
- package/runtime/subsystems/auth/middleware/requester-context.ts +141 -0
- package/runtime/subsystems/auth/protocols/user-context.ts +17 -0
- package/runtime/subsystems/bridge/bridge.module.ts +5 -0
- package/runtime/subsystems/events/event-bus.drizzle-backend.ts +109 -3
- package/runtime/subsystems/events/event-bus.memory-backend.ts +103 -1
- package/runtime/subsystems/events/event-keyset-cursor.ts +59 -0
- package/runtime/subsystems/events/event-read.protocol.ts +97 -0
- package/runtime/subsystems/events/events.module.ts +18 -2
- package/runtime/subsystems/events/events.tokens.ts +16 -0
- package/runtime/subsystems/events/index.ts +7 -0
- package/runtime/subsystems/jobs/bullmq.config.ts +125 -0
- package/runtime/subsystems/jobs/index.ts +22 -0
- package/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.ts +381 -0
- package/runtime/subsystems/jobs/job-run-keyset-cursor.ts +88 -0
- package/runtime/subsystems/jobs/job-run-service.drizzle-backend.ts +59 -1
- package/runtime/subsystems/jobs/job-run-service.memory-backend.ts +53 -0
- package/runtime/subsystems/jobs/job-run-service.protocol.ts +77 -0
- package/runtime/subsystems/jobs/job-worker.bullmq-backend.ts +311 -0
- package/runtime/subsystems/jobs/job-worker.module.ts +124 -10
- package/runtime/subsystems/jobs/jobs-domain.module.ts +40 -21
- package/runtime/subsystems/jobs/pool-config.loader.ts +11 -0
- package/runtime/subsystems/observability/index.ts +8 -0
- package/runtime/subsystems/observability/observability.protocol.ts +76 -0
- package/runtime/subsystems/observability/observability.service.ts +148 -1
- package/templates/entity/new/clean-lite-ps/prompt-extension.js +14 -12
- package/templates/relationship/new/prompt.js +8 -5
- package/templates/subsystem/jobs/worker.ejs.t +30 -7
- package/templates/subsystem/sync/sync-audit.schema.ejs.t +12 -16
|
@@ -203,10 +203,13 @@ function processFields(fields) {
|
|
|
203
203
|
function zodChainForCreate(field) {
|
|
204
204
|
const { type, nullable, required, hasDefault, hasChoices, choices } = field;
|
|
205
205
|
|
|
206
|
+
// Nullability and optionality are independent — see the clean-lite-ps copy of
|
|
207
|
+
// this function for the rationale (nullable-and-optional fields must get both
|
|
208
|
+
// `.nullable()` and `.optional()`, not just `.nullable()`).
|
|
206
209
|
if (hasChoices) {
|
|
207
|
-
|
|
208
|
-
if (
|
|
209
|
-
if (
|
|
210
|
+
let base = `z.enum([${choices.map((c) => `'${c}'`).join(", ")}])`;
|
|
211
|
+
if (nullable) base += ".nullable()";
|
|
212
|
+
if (!required) base += ".optional()";
|
|
210
213
|
return base;
|
|
211
214
|
}
|
|
212
215
|
|
|
@@ -215,8 +218,8 @@ function zodChainForCreate(field) {
|
|
|
215
218
|
base += `.default(${field.default ?? false})`;
|
|
216
219
|
return base;
|
|
217
220
|
}
|
|
218
|
-
if (nullable)
|
|
219
|
-
if (!required)
|
|
221
|
+
if (nullable) base += ".nullable()";
|
|
222
|
+
if (!required) base += ".optional()";
|
|
220
223
|
return base;
|
|
221
224
|
}
|
|
222
225
|
|
|
@@ -5,13 +5,30 @@ unless_exists: true
|
|
|
5
5
|
/**
|
|
6
6
|
* Standalone job worker entrypoint — emitted by `codegen subsystem install jobs`.
|
|
7
7
|
*
|
|
8
|
-
* Boots a Nest application context (NO HTTP listener) wiring the
|
|
9
|
-
*
|
|
8
|
+
* Boots a Nest application context (NO HTTP listener) wiring the full
|
|
9
|
+
* subsystem barrel (`SUBSYSTEM_MODULES` — events + jobs + bridge + sync, in
|
|
10
|
+
* dependency order) plus `JobWorkerModule.forRoot({ mode: 'standalone',
|
|
11
|
+
* allPools: true })`. Run with:
|
|
10
12
|
*
|
|
11
13
|
* bun worker.ts
|
|
12
14
|
*
|
|
15
|
+
* Why the barrel + `allPools`:
|
|
16
|
+
* - The events subsystem's outbox drain and the bridge's fanout wrappers
|
|
17
|
+
* run as `job_run` rows in the RESERVED `events_*` pools. A worker that
|
|
18
|
+
* only polls the non-reserved pools (`interactive`, `batch`, …) leaves
|
|
19
|
+
* those lanes stranded — `BridgeDeliveryHandler` never fires and durable
|
|
20
|
+
* event→job fanout silently stops.
|
|
21
|
+
* - `allPools: true` activates every pool in the resolved config, reserved
|
|
22
|
+
* lanes included, so this single standalone process drains both user work
|
|
23
|
+
* and the framework's reserved lanes.
|
|
24
|
+
* - Importing `SUBSYSTEM_MODULES` (rather than `JobsDomainModule` alone)
|
|
25
|
+
* registers `EVENT_BUS` / `JOB_ORCHESTRATOR` / `BRIDGE_*` so the
|
|
26
|
+
* framework `@framework/bridge_delivery` handler resolves its DI deps.
|
|
27
|
+
* `BridgeModule`'s reserved-pool guard short-circuits to pass because
|
|
28
|
+
* `allPools` is set.
|
|
29
|
+
*
|
|
13
30
|
* Embedded mode (single-process) is configured by importing
|
|
14
|
-
* JobWorkerModule.forRoot({ mode: 'embedded' }) inside AppModule instead —
|
|
31
|
+
* `JobWorkerModule.forRoot({ mode: 'embedded' })` inside AppModule instead —
|
|
15
32
|
* see the commented guidance injected into `src/main.ts`.
|
|
16
33
|
*
|
|
17
34
|
* SIGTERM triggers graceful shutdown bounded by SHUTDOWN_TIMEOUT_MS; after the
|
|
@@ -23,16 +40,22 @@ import { Logger, Module } from '@nestjs/common';
|
|
|
23
40
|
import { NestFactory } from '@nestjs/core';
|
|
24
41
|
|
|
25
42
|
import { DatabaseModule } from '@shared/database/database.module';
|
|
26
|
-
import { JobsDomainModule } from '@shared/subsystems/jobs/jobs-domain.module';
|
|
27
43
|
import { JobWorkerModule } from '@shared/subsystems/jobs/job-worker.module';
|
|
44
|
+
import { SUBSYSTEM_MODULES } from '@generated/subsystems';
|
|
28
45
|
|
|
29
46
|
const SHUTDOWN_TIMEOUT_MS = 30_000;
|
|
30
47
|
|
|
31
48
|
@Module({
|
|
32
49
|
imports: [
|
|
33
50
|
DatabaseModule,
|
|
34
|
-
|
|
35
|
-
|
|
51
|
+
// Events + Jobs + Bridge + Sync (dependency-ordered) from the generated
|
|
52
|
+
// barrel. This is the same composition AppModule imports — keeping the
|
|
53
|
+
// worker's DI graph identical to the HTTP app's so handlers resolve the
|
|
54
|
+
// same way in both processes.
|
|
55
|
+
...SUBSYSTEM_MODULES,
|
|
56
|
+
// `allPools: true` drains the reserved `events_*` lanes (events outbox +
|
|
57
|
+
// bridge wrappers) alongside the user pools.
|
|
58
|
+
JobWorkerModule.forRoot({ mode: 'standalone', allPools: true }),
|
|
36
59
|
],
|
|
37
60
|
})
|
|
38
61
|
class WorkerAppModule {}
|
|
@@ -72,7 +95,7 @@ async function bootstrap(): Promise<void> {
|
|
|
72
95
|
void shutdown('SIGINT');
|
|
73
96
|
});
|
|
74
97
|
|
|
75
|
-
logger.log('job worker started (standalone mode)');
|
|
98
|
+
logger.log('job worker started (standalone mode, all pools)');
|
|
76
99
|
}
|
|
77
100
|
|
|
78
101
|
bootstrap().catch((err) => {
|
|
@@ -19,14 +19,16 @@ force: true
|
|
|
19
19
|
* is owned by the sync subsystem's runtime protocol
|
|
20
20
|
* (`sync-field-diff.protocol.ts` from SYNC-2).
|
|
21
21
|
*
|
|
22
|
-
* ## `tenant_id` columns —
|
|
22
|
+
* ## `tenant_id` columns — always emitted
|
|
23
23
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
24
|
+
* `tenant_id` is emitted as a nullable text column on all three tables
|
|
25
|
+
* REGARDLESS of `sync.multi_tenant` — the runtime sync code (cursor store +
|
|
26
|
+
* run recorder) references `tenant_id` unconditionally, so a `multi_tenant:
|
|
27
|
+
* false` consumer that omitted the column failed to type-check (the column
|
|
28
|
+
* was referenced but absent). The `SYNC_MULTI_TENANT` DI flag (SYNC-6) gates
|
|
29
|
+
* non-null *enforcement* at runtime; it does not gate the column's existence
|
|
30
|
+
* (mirrors the jobs subsystem). Under `multi_tenant: false` the column simply
|
|
31
|
+
* stays null.
|
|
30
32
|
*
|
|
31
33
|
* See SYNC-1 / SYNC-6 in epic #60 for the decision rationale.
|
|
32
34
|
*/
|
|
@@ -98,9 +100,7 @@ export const syncSubscriptions = pgTable(
|
|
|
98
100
|
config: jsonb('config').notNull().default({}).$type<Record<string, unknown>>(),
|
|
99
101
|
cursor: jsonb('cursor').$type<unknown>(),
|
|
100
102
|
lastSyncAt: timestamp('last_sync_at', { withTimezone: true }),
|
|
101
|
-
|
|
102
|
-
tenantId: text('tenant_id'), // scaffold-time conditional — see sync.multi_tenant
|
|
103
|
-
<% } -%>
|
|
103
|
+
tenantId: text('tenant_id'), // always emitted — the runtime sync code (cursor store + run recorder) references tenant_id unconditionally; SYNC_MULTI_TENANT gates enforcement, not the column's existence (mirrors jobs)
|
|
104
104
|
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
|
105
105
|
updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
|
|
106
106
|
},
|
|
@@ -141,9 +141,7 @@ export const syncRuns = pgTable(
|
|
|
141
141
|
.notNull()
|
|
142
142
|
.defaultNow(),
|
|
143
143
|
completedAt: timestamp('completed_at', { withTimezone: true }),
|
|
144
|
-
|
|
145
|
-
tenantId: text('tenant_id'), // scaffold-time conditional — see sync.multi_tenant
|
|
146
|
-
<% } -%>
|
|
144
|
+
tenantId: text('tenant_id'), // always emitted — the runtime sync code (cursor store + run recorder) references tenant_id unconditionally; SYNC_MULTI_TENANT gates enforcement, not the column's existence (mirrors jobs)
|
|
147
145
|
},
|
|
148
146
|
(t) => ({
|
|
149
147
|
idxSyncRunsSubscriptionStartedAt: index(
|
|
@@ -178,9 +176,7 @@ export const syncRunItems = pgTable(
|
|
|
178
176
|
createdAt: timestamp('created_at', { withTimezone: true })
|
|
179
177
|
.notNull()
|
|
180
178
|
.defaultNow(),
|
|
181
|
-
|
|
182
|
-
tenantId: text('tenant_id'), // scaffold-time conditional — see sync.multi_tenant
|
|
183
|
-
<% } -%>
|
|
179
|
+
tenantId: text('tenant_id'), // always emitted — the runtime sync code (cursor store + run recorder) references tenant_id unconditionally; SYNC_MULTI_TENANT gates enforcement, not the column's existence (mirrors jobs)
|
|
184
180
|
},
|
|
185
181
|
(t) => ({
|
|
186
182
|
idxSyncRunItemsRunCreatedAt: index('idx_sync_run_items_run_created_at').on(
|