@pattern-stack/codegen 0.10.0 → 0.10.1

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.
Files changed (44) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/consumer-skills/events/typed-bus-and-outbox.md +1 -1
  3. package/consumer-skills/subsystems/SKILL.md +56 -0
  4. package/dist/runtime/subsystems/bridge/bridge.module.d.ts +0 -1
  5. package/dist/runtime/subsystems/bridge/bridge.module.js +294 -710
  6. package/dist/runtime/subsystems/bridge/bridge.module.js.map +1 -1
  7. package/dist/runtime/subsystems/bridge/index.d.ts +0 -1
  8. package/dist/runtime/subsystems/bridge/index.js +248 -664
  9. package/dist/runtime/subsystems/bridge/index.js.map +1 -1
  10. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js +18 -10
  11. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js.map +1 -1
  12. package/dist/runtime/subsystems/events/events.module.js +43 -244
  13. package/dist/runtime/subsystems/events/events.module.js.map +1 -1
  14. package/dist/runtime/subsystems/events/index.d.ts +0 -1
  15. package/dist/runtime/subsystems/events/index.js +39 -241
  16. package/dist/runtime/subsystems/events/index.js.map +1 -1
  17. package/dist/runtime/subsystems/index.js +174 -791
  18. package/dist/runtime/subsystems/index.js.map +1 -1
  19. package/dist/runtime/subsystems/jobs/bullmq.config.d.ts +22 -3
  20. package/dist/runtime/subsystems/jobs/bullmq.config.js.map +1 -1
  21. package/dist/runtime/subsystems/jobs/index.d.ts +1 -4
  22. package/dist/runtime/subsystems/jobs/index.js +87 -506
  23. package/dist/runtime/subsystems/jobs/index.js.map +1 -1
  24. package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js.map +1 -1
  25. package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js +3 -0
  26. package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js.map +1 -1
  27. package/dist/runtime/subsystems/jobs/job-worker.module.d.ts +11 -4
  28. package/dist/runtime/subsystems/jobs/job-worker.module.js +248 -664
  29. package/dist/runtime/subsystems/jobs/job-worker.module.js.map +1 -1
  30. package/dist/runtime/subsystems/jobs/jobs-domain.module.d.ts +0 -1
  31. package/dist/runtime/subsystems/jobs/jobs-domain.module.js +89 -391
  32. package/dist/runtime/subsystems/jobs/jobs-domain.module.js.map +1 -1
  33. package/dist/src/cli/index.js +152 -35
  34. package/dist/src/cli/index.js.map +1 -1
  35. package/package.json +1 -1
  36. package/runtime/subsystems/events/event-bus.drizzle-backend.ts +32 -10
  37. package/runtime/subsystems/events/events.module.ts +38 -6
  38. package/runtime/subsystems/events/index.ts +7 -1
  39. package/runtime/subsystems/jobs/bullmq.config.ts +23 -3
  40. package/runtime/subsystems/jobs/index.ts +13 -8
  41. package/runtime/subsystems/jobs/job-worker.bullmq-backend.ts +5 -2
  42. package/runtime/subsystems/jobs/job-worker.module.ts +27 -7
  43. package/runtime/subsystems/jobs/jobs-domain.module.ts +27 -2
  44. package/templates/subsystem/events/domain-events.schema.ejs.t +43 -2
package/CHANGELOG.md CHANGED
@@ -4,6 +4,79 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.10.1] — 2026-05-28
8
+
9
+ Dogfood fixes found wiring `@pattern-stack/codegen@0.10.0` into a second
10
+ consumer (swe-brain): the type-check blockers that forced consumers to exclude
11
+ the vendored subsystem tree from `tsc` are gone. A drizzle-only install now
12
+ type-checks its full tree (`src/shared/subsystems/**` included) with no
13
+ `ioredis`/`bullmq` peer deps.
14
+
15
+ ### Fixed
16
+
17
+ - **`fix(subsystems)` — detection + barrel emission key on `<name>.module.ts`
18
+ (#4, #2).** Installing one subsystem can vendor *protocol stubs* of another
19
+ (e.g. events vendors `bridge/bridge.protocol.ts`); detection used to report
20
+ those stub-only dirs as `installed` and the barrel emitted a phantom
21
+ `BridgeModule` import for a module that was never installed (TS2307).
22
+ Detection now requires the module file; `subsystem list` reports `incomplete`
23
+ for stub-only dirs; the barrel skips them.
24
+ - **`fix(events)` — drizzle backend type-checks against its paired schema
25
+ (#3).** `event-bus.drizzle-backend.ts` read a `tier` column the schema never
26
+ emitted and `tenant_id` columns only present under multi-tenancy. `tier` is
27
+ now always emitted; `tenant_id` access is gated behind `multiTenant`, so the
28
+ backend type-checks under any configuration.
29
+ - **`fix(subsystems)` — installs no longer vendor unselected backends (#6).** A
30
+ `--backend drizzle` install previously vendored the Redis and BullMQ backend
31
+ sources too, dragging `ioredis`/`bullmq` (uninstalled optional peers) into the
32
+ consumer's type-check. The copy filter now prunes `*.redis-backend.ts` /
33
+ `*.bullmq-backend.ts` for non-matching installs; modules lazy-load the chosen
34
+ backend via a non-literal dynamic import; backend-specific classes are no
35
+ longer re-exported from the public barrels; `bullmq.config.ts` is kept on
36
+ every install (peer-dep-free) for its static token references; the BullMQ
37
+ backend is `noImplicitAny`-clean.
38
+ - **`fix(barrel)` — empty-composer output emits the `DynamicModule` import.** A
39
+ generated `subsystems.ts` with no composer calls referenced `DynamicModule`
40
+ without importing it (latent since BULLMQ-1, surfaced by the stricter
41
+ detection above).
42
+
43
+ ### Added
44
+
45
+ - **`feat(cli)` — `codegen subsystem remove` (#5, #7).** Real implementation:
46
+ deletes the vendored subsystem dir, regenerates the barrel, git-safety gated
47
+ with `--force`, and `--yes`/`-y` parity with `install`. Prints the manual
48
+ follow-ups it deliberately does *not* perform (config-block strip,
49
+ `forRoot` un-registration).
50
+ - **`test(smoke)` — `run-smoke-subsystems.ts`.** Exercises an events + jobs +
51
+ bridge drizzle install with a full-tree `tsc` (no subsystem excludes) + a
52
+ programmatic NestJS boot that validates the bridge reserved-pool dependency
53
+ graph. Wired into `just test-all`.
54
+
55
+ ## [0.10.0] — 2026-05-27
56
+
57
+ ### Added
58
+
59
+ - **`feat(cli)` — consumer skill distribution (ADR-035).** A curated
60
+ `consumer-skills/` set (a `codegen` router plus `entities`, `subsystems`,
61
+ `jobs`, `events`, `bridge`, `sync`) is vendored into a consumer's
62
+ `.claude/skills/` via a new `skills` noun (`codegen skills install` / `list`),
63
+ and by `codegen init` by default (`--no-skills` to opt out). Authored fresh
64
+ for a consumer audience; shipped in the npm `files` array.
65
+ - **`feat(cli)` — `codegen update`.** Re-syncs the vendored runtime closure,
66
+ installed subsystems' runtime, and consumer skills to the installed package
67
+ version after a bump. Drift-aware, git-clean gated (`--force`), `--dry-run`;
68
+ never touches consumer-owned files (config, `app.module.ts`, barrels).
69
+ - **`feat(parser)` — recursive YAML discovery.** Entity / relationship /
70
+ junction / event discovery routes through a single `findYamlFiles` helper;
71
+ domain-folder layouts (`entities/crm/account.yaml`) are first-class.
72
+
73
+ ### Changed
74
+
75
+ - **Docs split.** `CONSUMER-SETUP.md` became a hub; the per-subsystem deep dives
76
+ moved to `docs/consumer/{events,bridge,sync,auth,openapi}.md` (progressive
77
+ disclosure), with jobs-API drift (`JobsModule` → `JobsDomainModule` +
78
+ `JobWorkerModule`, `JobHandlerBase`, `concurrency: { key }`) corrected.
79
+
7
80
  ## [0.9.0] — 2026-05-25
8
81
 
9
82
  Bundles four merged PRs (none carried a version bump): the BullMQ backend and
@@ -65,7 +65,7 @@ New code should prefer `TypedEventBus`.
65
65
 
66
66
  ## The outbox table and drain loop
67
67
 
68
- `domain_events` is the outbox. Key columns: `id` (UUID, the idempotency key), `type`, `aggregate_id`, `aggregate_type`, `payload` (jsonb), `occurred_at`, `processed_at`, `status` (`pending | processed | failed`), `error`, `metadata`, and first-class `pool` / `direction` columns (populated from `metadata` at insert so the drain can filter by lane without unpacking JSON).
68
+ `domain_events` is the outbox. Key columns: `id` (UUID, the idempotency key), `type`, `aggregate_id`, `aggregate_type`, `payload` (jsonb), `occurred_at`, `processed_at`, `status` (`pending | processed | failed`), `error`, `metadata`, and first-class `pool` / `direction` / `tier` columns (populated from `metadata` at insert so the drain can filter by lane without unpacking JSON). `tier` (`'domain'` | `'audit'`, default `'domain'`) is always emitted; the `domain_events_tier_routing_check` constraint enforces that `tier='audit'` rows have null `pool`/`direction`. `tenant_id` is the only conditional column — emitted only under `events.multi_tenant: true`.
69
69
 
70
70
  The drain loop (Drizzle backend):
71
71
  1. Claims a batch (default 50) of `pending` rows with `FOR UPDATE SKIP LOCKED`, optionally filtered by pool, ordered by `occurred_at ASC`. `SKIP LOCKED` lets multiple worker processes drain concurrently without double-dispatching.
@@ -87,8 +87,42 @@ pools, and multi-tenancy are in `wiring-and-order.md`.
87
87
  must be registered after them.
88
88
  - **Multi-tenancy is a config flip + a `forRoot` flag + a migration** — never a
89
89
  runtime-only toggle. See `wiring-and-order.md`.
90
+ - **`subsystem list` can report `incomplete`, and that's usually fine.**
91
+ Installing one subsystem may vendor *stub* files of another — e.g. installing
92
+ `events` drops `bridge/bridge.protocol.ts` + `bridge.tokens.ts` because the
93
+ events Drizzle backend imports them. That `bridge/` directory has the protocol
94
+ stubs but no `bridge.module.ts`, so `subsystem list` shows it `incomplete`. It
95
+ is **not** registered in the generated `subsystems.ts` barrel (the barrel only
96
+ emits a `forRoot()` for subsystems whose `<name>.module.ts` exists), so it
97
+ won't break your `tsc`. Run `subsystem install bridge` to promote it to
98
+ `installed` when you actually want the bridge.
90
99
  - **`--backend memory`** is for tests; the scaffolded default is `drizzle`
91
100
  (`local` for storage).
101
+ - **Install vendors only the selected backend.** Alternate-backend source
102
+ files are pruned: a `--backend drizzle` events install does NOT vendor
103
+ `event-bus.redis-backend.ts`, and a drizzle/memory jobs install does NOT
104
+ vendor `job-orchestrator.bullmq-backend.ts`, `job-worker.bullmq-backend.ts`,
105
+ or `bullmq.config.ts`. The module files (`events.module.ts`,
106
+ `jobs-domain.module.ts`, `job-worker.module.ts`) lazy-load the chosen
107
+ backend via dynamic `import()` with a non-literal specifier, so the unused
108
+ backends never drag their peer deps (`ioredis`, `bullmq`) into your `tsc`
109
+ graph. `bullmq` and `ioredis` are declared as **optional peer
110
+ dependencies** — install them ONLY if you actually select that backend.
111
+ **Drizzle installs no longer drag `bullmq` / `ioredis` into your consumer
112
+ peer-deps**; if your `package.json` carries them only as workarounds for
113
+ earlier 0.10.x scaffolds, you can drop them.
114
+ - **Bundler caveat.** The dynamic-import specifier is captured in a variable
115
+ (e.g. `const spec = './event-bus.redis-backend'; await import(spec)`) on
116
+ purpose — that's what makes `tsc` treat it as `any` and skip resolving the
117
+ pruned file. A bundler (webpack / esbuild / rollup) won't static-analyse a
118
+ non-literal specifier either, so it won't include the dynamically-imported
119
+ file in its output bundle. In practice this is fine: when the file isn't
120
+ vendored (drizzle install) there's nothing to bundle; when it IS vendored
121
+ (redis / bullmq install) consumers typically run Node/Bun directly against
122
+ the source tree. If you bundle a redis/bullmq build for deployment, ensure
123
+ your bundler is configured to include the vendored
124
+ `<subsystems-root>/<name>/` tree (e.g. mark it as external + ship alongside)
125
+ or pin the dynamic-import path to a literal in your own wrapper.
92
126
 
93
127
  ## Do not
94
128
 
@@ -103,3 +137,25 @@ pools, and multi-tenancy are in `wiring-and-order.md`.
103
137
  runtime source, not the tenancy-gated Drizzle schema files. If a schema shape
104
138
  changed across versions, re-run `subsystem install <name> --force
105
139
  --force-config`.
140
+
141
+ ## Removing a subsystem
142
+
143
+ `codegen subsystem remove <name>` deletes the vendored
144
+ `<subsystems-root>/<name>/` directory and regenerates
145
+ `src/generated/subsystems.ts` so the removed subsystem drops out of the
146
+ `SUBSYSTEM_MODULES` barrel. Git-safety gated like install (warns on
147
+ uncommitted changes; `--force` overrides). `--yes`/`-y` is accepted for flag
148
+ parity with `install`.
149
+
150
+ What removal does NOT do (intentionally — explicit beats silent rewrites):
151
+
152
+ - It does **not** strip the `<name>:` block from `codegen.config.yaml`.
153
+ - It does **not** remove the `<Name>Module.forRoot(...)` line from
154
+ `app.module.ts`.
155
+ - It does **not** strip shared runtime deps (`src/shared/types/drizzle.ts`,
156
+ `src/shared/constants/tokens.ts`) — other subsystems may still need them.
157
+
158
+ The CLI prints the two follow-up edits on success. `openapi-config` (a
159
+ config-only pseudo-subsystem) and `auth-integrations` (vendored outside the
160
+ subsystems root, alongside the codegen-emitted entity layer) are not
161
+ auto-removable — the command errors with the right manual next-step.
@@ -5,7 +5,6 @@ import '../../types/drizzle.js';
5
5
  import 'drizzle-orm/node-postgres';
6
6
  import '../jobs/jobs-domain.module.js';
7
7
  import '../jobs/bullmq.config.js';
8
- import 'bullmq';
9
8
  import '../jobs/pool-config.loader.js';
10
9
  import '../../../job-orchestrator.protocol-CHOEqBDk.js';
11
10
  import '../events/event-bus.protocol.js';