@joktec/skills 0.1.3 → 0.1.7

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 (101) hide show
  1. package/README.md +4 -2
  2. package/dist/claude/skills/advanced-typescript-design/SKILL.md +60 -0
  3. package/dist/claude/skills/advanced-typescript-design/agents/openai.yaml +4 -0
  4. package/dist/claude/skills/advanced-typescript-design/references/advanced.md +219 -0
  5. package/dist/claude/skills/advanced-typescript-design/references/simple.md +149 -0
  6. package/dist/claude/skills/joktec-adapter-skill/SKILL.md +1 -0
  7. package/dist/claude/skills/joktec-adapter-skill/references/adapters.md +28 -0
  8. package/dist/claude/skills/joktec-broker-skill/SKILL.md +1 -0
  9. package/dist/claude/skills/joktec-broker-skill/references/brokers.md +29 -0
  10. package/dist/claude/skills/joktec-common-skill/SKILL.md +1 -0
  11. package/dist/claude/skills/joktec-common-skill/references/core.md +56 -0
  12. package/dist/claude/skills/joktec-common-skill/references/utils-cron.md +28 -0
  13. package/dist/claude/skills/joktec-database-extended-skill/SKILL.md +1 -0
  14. package/dist/claude/skills/joktec-database-extended-skill/references/extended-databases.md +24 -0
  15. package/dist/claude/skills/joktec-framework-skill/SKILL.md +1 -0
  16. package/dist/claude/skills/joktec-framework-skill/references/framework-map.md +34 -0
  17. package/dist/claude/skills/joktec-integration-skill/SKILL.md +1 -0
  18. package/dist/claude/skills/joktec-integration-skill/references/integrations.md +29 -0
  19. package/dist/claude/skills/joktec-mongo-skill/SKILL.md +9 -1
  20. package/dist/claude/skills/joktec-mongo-skill/references/repository.md +46 -0
  21. package/dist/claude/skills/joktec-mongo-skill/references/schema-and-plugins.md +65 -0
  22. package/dist/claude/skills/joktec-mysql-skill/SKILL.md +6 -1
  23. package/dist/claude/skills/joktec-mysql-skill/references/entities.md +109 -1
  24. package/dist/claude/skills/joktec-mysql-skill/references/repository.md +63 -0
  25. package/dist/claude/skills/joktec-tool-skill/SKILL.md +1 -0
  26. package/dist/claude/skills/joktec-tool-skill/references/tools.md +36 -0
  27. package/dist/codex/skills/advanced-typescript-design/SKILL.md +60 -0
  28. package/dist/codex/skills/advanced-typescript-design/agents/openai.yaml +4 -0
  29. package/dist/codex/skills/advanced-typescript-design/references/advanced.md +219 -0
  30. package/dist/codex/skills/advanced-typescript-design/references/simple.md +149 -0
  31. package/dist/codex/skills/joktec-adapter-skill/SKILL.md +1 -0
  32. package/dist/codex/skills/joktec-adapter-skill/references/adapters.md +28 -0
  33. package/dist/codex/skills/joktec-broker-skill/SKILL.md +1 -0
  34. package/dist/codex/skills/joktec-broker-skill/references/brokers.md +29 -0
  35. package/dist/codex/skills/joktec-common-skill/SKILL.md +1 -0
  36. package/dist/codex/skills/joktec-common-skill/references/core.md +56 -0
  37. package/dist/codex/skills/joktec-common-skill/references/utils-cron.md +28 -0
  38. package/dist/codex/skills/joktec-database-extended-skill/SKILL.md +1 -0
  39. package/dist/codex/skills/joktec-database-extended-skill/references/extended-databases.md +24 -0
  40. package/dist/codex/skills/joktec-framework-skill/SKILL.md +1 -0
  41. package/dist/codex/skills/joktec-framework-skill/references/framework-map.md +34 -0
  42. package/dist/codex/skills/joktec-integration-skill/SKILL.md +1 -0
  43. package/dist/codex/skills/joktec-integration-skill/references/integrations.md +29 -0
  44. package/dist/codex/skills/joktec-mongo-skill/SKILL.md +9 -1
  45. package/dist/codex/skills/joktec-mongo-skill/references/repository.md +46 -0
  46. package/dist/codex/skills/joktec-mongo-skill/references/schema-and-plugins.md +65 -0
  47. package/dist/codex/skills/joktec-mysql-skill/SKILL.md +6 -1
  48. package/dist/codex/skills/joktec-mysql-skill/references/entities.md +109 -1
  49. package/dist/codex/skills/joktec-mysql-skill/references/repository.md +63 -0
  50. package/dist/codex/skills/joktec-tool-skill/SKILL.md +1 -0
  51. package/dist/codex/skills/joktec-tool-skill/references/tools.md +36 -0
  52. package/dist/copilot/.github/copilot-instructions.md +1003 -3
  53. package/dist/cursor/.cursor/rules/advanced-typescript-design.mdc +437 -0
  54. package/dist/cursor/.cursor/rules/joktec-adapter-skill.mdc +29 -0
  55. package/dist/cursor/.cursor/rules/joktec-broker-skill.mdc +30 -0
  56. package/dist/cursor/.cursor/rules/joktec-common-skill.mdc +85 -0
  57. package/dist/cursor/.cursor/rules/joktec-database-extended-skill.mdc +25 -0
  58. package/dist/cursor/.cursor/rules/joktec-framework-skill.mdc +35 -0
  59. package/dist/cursor/.cursor/rules/joktec-integration-skill.mdc +30 -0
  60. package/dist/cursor/.cursor/rules/joktec-mongo-skill.mdc +120 -1
  61. package/dist/cursor/.cursor/rules/joktec-mysql-skill.mdc +178 -2
  62. package/dist/cursor/.cursor/rules/joktec-tool-skill.mdc +37 -0
  63. package/dist/gemini/GEMINI.md +1005 -3
  64. package/dist/windsurf/.windsurf/rules/advanced-typescript-design.md +433 -0
  65. package/dist/windsurf/.windsurf/rules/joktec-adapter-skill.md +29 -0
  66. package/dist/windsurf/.windsurf/rules/joktec-broker-skill.md +30 -0
  67. package/dist/windsurf/.windsurf/rules/joktec-common-skill.md +85 -0
  68. package/dist/windsurf/.windsurf/rules/joktec-database-extended-skill.md +25 -0
  69. package/dist/windsurf/.windsurf/rules/joktec-framework-skill.md +35 -0
  70. package/dist/windsurf/.windsurf/rules/joktec-integration-skill.md +30 -0
  71. package/dist/windsurf/.windsurf/rules/joktec-mongo-skill.md +120 -1
  72. package/dist/windsurf/.windsurf/rules/joktec-mysql-skill.md +178 -2
  73. package/dist/windsurf/.windsurf/rules/joktec-tool-skill.md +37 -0
  74. package/package.json +6 -3
  75. package/scripts/sync-pack-version.mjs +38 -0
  76. package/skill-pack.json +35 -1
  77. package/skills/advanced-typescript-design/SKILL.md +60 -0
  78. package/skills/advanced-typescript-design/agents/openai.yaml +4 -0
  79. package/skills/advanced-typescript-design/references/advanced.md +219 -0
  80. package/skills/advanced-typescript-design/references/simple.md +149 -0
  81. package/skills/joktec-adapter-skill/SKILL.md +1 -0
  82. package/skills/joktec-adapter-skill/references/adapters.md +28 -0
  83. package/skills/joktec-broker-skill/SKILL.md +1 -0
  84. package/skills/joktec-broker-skill/references/brokers.md +29 -0
  85. package/skills/joktec-common-skill/SKILL.md +1 -0
  86. package/skills/joktec-common-skill/references/core.md +56 -0
  87. package/skills/joktec-common-skill/references/utils-cron.md +28 -0
  88. package/skills/joktec-database-extended-skill/SKILL.md +1 -0
  89. package/skills/joktec-database-extended-skill/references/extended-databases.md +24 -0
  90. package/skills/joktec-framework-skill/SKILL.md +1 -0
  91. package/skills/joktec-framework-skill/references/framework-map.md +34 -0
  92. package/skills/joktec-integration-skill/SKILL.md +1 -0
  93. package/skills/joktec-integration-skill/references/integrations.md +29 -0
  94. package/skills/joktec-mongo-skill/SKILL.md +9 -1
  95. package/skills/joktec-mongo-skill/references/repository.md +46 -0
  96. package/skills/joktec-mongo-skill/references/schema-and-plugins.md +65 -0
  97. package/skills/joktec-mysql-skill/SKILL.md +6 -1
  98. package/skills/joktec-mysql-skill/references/entities.md +109 -1
  99. package/skills/joktec-mysql-skill/references/repository.md +63 -0
  100. package/skills/joktec-tool-skill/SKILL.md +1 -0
  101. package/skills/joktec-tool-skill/references/tools.md +36 -0
@@ -26,6 +26,7 @@ Start here when a task mentions JokTec generally, multiple `@joktec/*` packages,
26
26
  - Prefer config-driven module setup and `conId` when a package supports multiple clients.
27
27
  - Preserve NestJS module boundaries, dependency injection, lifecycle hooks, and exported package APIs.
28
28
  - Do not invent behavior for unfinished or missing packages.
29
+ - If a focused skill is loaded without this entrypoint, still apply source-first lookup before assuming APIs.
29
30
 
30
31
  ## Reference
31
32
 
@@ -37,6 +38,25 @@ Read `references/framework-map.md` when the task needs package selection, depend
37
38
 
38
39
  # JokTec Framework Map
39
40
 
41
+ ## Source-First Operating Protocol
42
+
43
+ Treat this skill pack as curated guidance, not the final implementation truth. When a task is unclear, or when a package API seems different from the skill text:
44
+
45
+ 1. Inspect the consumer project first to understand the package versions and local usage pattern.
46
+ 2. Prefer local framework source at `../joktec-framework` when available.
47
+ 3. Read package `README.md`, nearest `AGENTS.md`, and `src/index.ts` before changing code.
48
+ 4. If local source is unavailable, use `https://github.com/joktec/joktec-framework` as fallback.
49
+ 5. Do not invent behavior that is not visible in framework source or package docs.
50
+ 6. If package docs and source conflict, source code wins and the mismatch should be treated as documentation drift.
51
+
52
+ High-value source files:
53
+
54
+ - `AGENTS.md` and `docs/agents/*` for framework-level architecture and runtime policy.
55
+ - `packages/<family>/AGENTS.md` for family boundaries.
56
+ - `packages/<family>/<package>/README.md` for developer-facing usage.
57
+ - `packages/<family>/<package>/src/index.ts` for public API.
58
+ - Package config/module/service/repository files for real runtime behavior.
59
+
40
60
  ## Package Families
41
61
 
42
62
  - `@joktec/core`: bootstrap, config, logger, metrics, guards, base abstractions, transports, pagination, Bull.
@@ -54,6 +74,12 @@ Read `references/framework-map.md` when the task needs package selection, depend
54
74
 
55
75
  Consumer apps depend on concrete `@joktec/*` packages. Concrete packages usually depend on `@joktec/core` and `@joktec/utils`. Keep app-specific schemas, handlers, and business semantics outside reusable packages.
56
76
 
77
+ Do not reverse the dependency direction:
78
+
79
+ - reusable packages must not import from `apps/`
80
+ - `common` packages must not depend on concrete adapters/brokers/databases
81
+ - consumer apps own business workflows, DTO composition, schemas/entities, queue names, topics, and provider credentials
82
+
57
83
  ## Common Consumer App Pattern
58
84
 
59
85
  1. Register package modules in the app module or repository module.
@@ -61,6 +87,15 @@ Consumer apps depend on concrete `@joktec/*` packages. Concrete packages usually
61
87
  3. Extend the package repository base class when the package provides one.
62
88
  4. Use `BaseService`, `BaseController`, or transport helpers from `@joktec/core` when the app follows standard CRUD or message patterns.
63
89
 
90
+ ## Skill Selection
91
+
92
+ - Use `joktec-common-skill` for BaseController/BaseService/config/pagination/client lifecycle/utils/cron.
93
+ - Use `joktec-mongo-skill` when the resource uses Mongo schemas, MongoRepo, Typegoose decorators, plugins, or ObjectId-safe queries.
94
+ - Use `joktec-mysql-skill` when the resource uses TypeORM entities, MysqlRepo, SQL dialect behavior, transactions, or schema-first column decorators.
95
+ - Use broker/adapter/integration/tool skills for provider wiring; keep business semantics in the consumer app.
96
+
97
+ When using the ecosystem `npx skills` installer, install `joktec-framework-skill` and `joktec-common-skill` together with any focused package skill. The current ecosystem installer does not auto-resolve dependencies from frontmatter.
98
+
64
99
  ---
65
100
 
66
101
  ## JokTec Common Skill
@@ -83,6 +118,7 @@ Use this skill for shared framework primitives, low-level helpers, cron utilitie
83
118
  - Use page, offset, or cursor pagination contracts from core; let database packages execute storage-specific pagination.
84
119
  - Use `AbstractClientService` patterns for client packages that need config, lifecycle, retry, and `conId`.
85
120
  - Use `@joktec/utils` for shared helpers instead of duplicating conversion, validation, hashing, or UUID logic.
121
+ - If guidance is insufficient, read this skill's references and inspect `../joktec-framework` package source or GitHub fallback before assuming APIs.
86
122
 
87
123
  ## References
88
124
 
@@ -95,24 +131,80 @@ Use this skill for shared framework primitives, low-level helpers, cron utilitie
95
131
 
96
132
  # Common Core Usage
97
133
 
134
+ ## Source Lookup
135
+
136
+ When blocked, inspect these framework files before guessing:
137
+
138
+ - `packages/common/core/README.md`
139
+ - `packages/common/core/AGENTS.md`
140
+ - `packages/common/core/src/index.ts`
141
+ - `packages/common/core/src/abstractions/*`
142
+ - `packages/common/core/src/models/base.request.ts`
143
+ - `packages/common/core/src/models/base.response.ts`
144
+ - `packages/common/core/src/models/paginations/*`
145
+ - `packages/common/core/src/client/abstract-client.service.ts`
146
+ - `packages/common/core/src/infras/application.ts`
147
+ - `packages/common/core/src/modules/*`
148
+
98
149
  ## Runtime Bootstrap
99
150
 
100
151
  Use the application bootstrap helpers from `@joktec/core` for gateway and microservice runtimes. Keep runtime behavior config-driven.
101
152
 
153
+ Best practice:
154
+
155
+ - Use `Application.bootstrap(AppModule)` instead of hand-rolling Nest bootstrap unless the consumer app has a specific runtime reason.
156
+ - Keep gateway-only behavior in gateway runtime modules and microservice-only behavior in micro runtime modules.
157
+ - Register framework modules through their dynamic module APIs when provided.
158
+ - Do not duplicate config parsing, logger setup, metrics setup, or process lifecycle hooks in consumer apps.
159
+
102
160
  ## CRUD Abstractions
103
161
 
104
162
  - `BaseController` creates standard REST CRUD endpoints for DTO-backed resources.
105
163
  - `BaseService` delegates repository operations through the shared repository contract.
106
164
  - `ClientController` and `ClientService` provide generated microservice CRUD patterns.
107
165
 
166
+ Use BaseController/BaseService when the resource follows standard CRUD. Avoid them when the endpoint has domain-specific command semantics, multi-step transactions, or non-standard authorization that would make the generic abstraction obscure behavior.
167
+
168
+ Controller checklist:
169
+
170
+ - choose the DTO/entity class intentionally
171
+ - set `paginationMode` for the representative Swagger response shape
172
+ - use `customDto.paginationDto` only when the built-in page/offset/cursor response does not represent the API
173
+ - keep auth/guards/interceptors consistent with app conventions
174
+ - avoid putting business branching in controller methods when it belongs in the service
175
+
108
176
  ## Pagination
109
177
 
110
178
  Request priority is cursor, then offset, then page. `BaseController.paginationMode` affects Swagger response shape; runtime selection remains request-driven unless the app service narrows it.
111
179
 
180
+ Best practice:
181
+
182
+ - Use page pagination for admin tables and simple back-office views.
183
+ - Use offset pagination for mobile-style load-more when the data set is moderate and stable enough.
184
+ - Use cursor pagination for feeds, timelines, frequently inserted lists, or large tables.
185
+ - Do not document cursor support for a resource unless the underlying repository package actually supports it.
186
+ - When using cursor mode, ensure the database layer has stable sort keys and tie-breakers.
187
+
112
188
  ## Client Lifecycle
113
189
 
114
190
  Use `ClientConfig`, `AbstractClientService`, and `conId` when building or consuming packages that support multiple client connections.
115
191
 
192
+ Client package checklist:
193
+
194
+ - config class validates all required runtime options
195
+ - service startup fails clearly when the native client cannot initialize
196
+ - shutdown closes native connections only when initialized
197
+ - `conId` is preserved through service/repository calls
198
+ - logs do not leak credentials or full connection strings
199
+ - retries and debug behavior are config-driven
200
+
201
+ ## Do Not
202
+
203
+ - Do not import concrete package or app code into `@joktec/core`.
204
+ - Do not bypass shared pagination contracts with ad-hoc response shapes for standard CRUD.
205
+ - Do not add new public symbols without exporting them through `src/index.ts`.
206
+ - Do not silently swallow bootstrap/client initialization failures.
207
+
116
208
  ### references/utils-cron.md
117
209
 
118
210
  # Utils And Cron Usage
@@ -123,12 +215,40 @@ Use `@joktec/utils` for common generators, validators, converters, hashing helpe
123
215
 
124
216
  Prefer package helpers over app-local reimplementation when behavior should stay consistent across services.
125
217
 
218
+ Source lookup:
219
+
220
+ - `packages/common/utils/README.md`
221
+ - `packages/common/utils/src/index.ts`
222
+ - `packages/common/utils/src/helpers/*`
223
+ - `packages/common/utils/src/validators/*`
224
+ - `packages/common/utils/src/constants/*`
225
+
226
+ Best practice:
227
+
228
+ - Use shared validators from `@joktec/utils` when building schema-first entity/schema decorators.
229
+ - Use shared generators for IDs, tokens, random values, and hashes when consistency matters.
230
+ - Keep utility usage deterministic in tests; mock time/randomness where needed.
231
+ - Do not add framework-level dependencies to `utils`.
232
+
126
233
  ## Cron
127
234
 
128
235
  Use `@joktec/cron` when a consumer app needs scheduled jobs, job worker contracts, or decorator-driven cron registration.
129
236
 
130
237
  Keep job business logic in the consumer app. The package provides scheduling abstractions, not domain behavior.
131
238
 
239
+ Source lookup:
240
+
241
+ - `packages/common/cron/README.md`
242
+ - `packages/common/cron/src/index.ts`
243
+ - cron decorators, models, scheduler services, and worker contracts under `src/`
244
+
245
+ Best practice:
246
+
247
+ - Keep job names, schedules, concurrency, and retry behavior visible in the consumer app.
248
+ - Make cron handlers idempotent.
249
+ - Avoid enabling the same cron owner in multiple processes unless the package/app has explicit locking semantics.
250
+ - Treat cron runtime as infrastructure orchestration; domain writes still belong in app services/repositories.
251
+
132
252
  ## Types
133
253
 
134
254
  Use `@joktec/types` when a consumer workflow needs generated JokTec package config schema/type artifacts. Treat the framework repository as source-of-truth for the generated schema shape.
@@ -147,8 +267,16 @@ Use this skill for MongoDB-backed resources that rely on JokTec's Mongoose/Typeg
147
267
  - Keep schema classes, app repositories, and app-specific queries in the consumer app.
148
268
  - Extend `MongoRepo<T, ID>` for app repositories.
149
269
  - Preserve `conId` when the app has multiple Mongo connections.
150
- - Use schema-first decorators when a schema class should be reused as a DTO source.
270
+ - Use schema-first decorators when a schema class should be reused as a DTO source; wrappers should reduce repeated Typegoose, validator, transformer, and Swagger stacks.
271
+ - Use `RefId<T>` for stored reference id fields and `PopulatedRef<T>` for populated virtual fields.
272
+ - Use `@Schema({ kind: 'embedded' })` for value objects without `_id` or timestamps.
273
+ - Use `@Schema({ kind: 'subdocument' })` for embedded documents that need their own `_id` and timestamps.
274
+ - Use `@Prop({ kind: 'virtual', mode: 'getter' })` for computed getters that need expose/Swagger metadata without persistence.
275
+ - Use `@Prop({ ref: () => Target, foreignField, localField })` for populate-one virtuals when inferred defaults are enough.
276
+ - Use `@Prop({ type: () => [Target], ref: () => Target, foreignField, localField })` for populate-array virtuals.
277
+ - Use `@Prop({ kind: 'map', type: Object })` for map/snapshot payloads that must keep their raw shape.
151
278
  - Treat ObjectId casting and regex behavior as safety-sensitive.
279
+ - For real migrations, inspect `node_modules/@joktec/mongo` first, then installed README or GitHub package docs, then GitHub source before assuming APIs.
152
280
 
153
281
  ## References
154
282
 
@@ -161,14 +289,46 @@ Use this skill for MongoDB-backed resources that rely on JokTec's Mongoose/Typeg
161
289
 
162
290
  # Mongo Repository Usage
163
291
 
292
+ ## Source Lookup
293
+
294
+ When blocked, inspect:
295
+
296
+ - Consumer project first: `node_modules/@joktec/mongo`.
297
+ - Installed docs next: `node_modules/@joktec/mongo/README.md`.
298
+ - GitHub docs next: `https://github.com/joktec/joktec-framework/tree/main/packages/databases/mongo`.
299
+ - GitHub source fallback:
300
+ - `packages/databases/mongo/src/index.ts`
301
+ - `packages/databases/mongo/src/mongo.module.ts`
302
+ - `packages/databases/mongo/src/mongo.service.ts`
303
+ - `packages/databases/mongo/src/mongo.repo.ts`
304
+ - `packages/databases/mongo/src/helpers/mongo.helper.ts`
305
+ - `packages/databases/mongo/src/helpers/mongo.pipeline.ts`
306
+ - `packages/databases/mongo/src/helpers/mongo.utils.ts`
307
+ - `packages/databases/mongo/src/models/*`
308
+
164
309
  ## Module Setup
165
310
 
166
311
  Register schemas with `MongoModule.forRoot({ conId, models: [...] })`. Use the same `conId` in app repositories when using non-default connections.
167
312
 
313
+ Best practice:
314
+
315
+ - Register app schema classes in the consumer app repository module.
316
+ - Use one owner process for index creation in multi-process deployments.
317
+ - Preserve `conId` through service/repo constructors for multi-connection apps.
318
+ - Do not rely on the global mongoose model registry when `MongoService` provides connection-aware resolution.
319
+
168
320
  ## Repository Pattern
169
321
 
170
322
  Extend `MongoRepo` and pass the schema class to the base constructor. Services can then use `BaseService` from `@joktec/core`.
171
323
 
324
+ Repository checklist:
325
+
326
+ - Keep schema-specific query helpers in the app repository, not in controllers.
327
+ - Use repository methods for standard reads so query parsing, soft delete, populate, and pagination stay consistent.
328
+ - Pass transaction/session options through read-modify-write flows when the app uses transactions.
329
+ - Repository read paths should return schema class instances with normalized ObjectId/string values, including populated and deep-populated values.
330
+ - Code that needs raw Mongoose documents should use `MongoService.getModel(...)` or Typegoose/Mongoose APIs directly.
331
+
172
332
  ## Query Safety
173
333
 
174
334
  - Root `id` can act as an API alias for `_id` in query conditions.
@@ -176,30 +336,109 @@ Extend `MongoRepo` and pass the schema class to the base constructor. Services c
176
336
  - `$like`, `$begin`, and `$end` escape regex input by default.
177
337
  - Do not rely on broad conversion when storing raw snapshots, maps, or nested subdocuments.
178
338
 
339
+ Anti-patterns:
340
+
341
+ - Do not convert every nested `id` key into `_id`; only API-facing query aliases should be converted.
342
+ - Do not cast every 24-character hex string into ObjectId; fields like `externalId`, `code`, and `slug` may be strings.
343
+ - Do not inject soft-delete conditions into unknown nested aggregate branches unless the target collection is known.
344
+
179
345
  ## Pagination
180
346
 
181
347
  `MongoRepo.paginate` supports page, offset, and cursor responses. Cursor mode defaults to `_id`; custom `cursorKey` appends `_id` as a tie-breaker.
182
348
 
349
+ Cursor checklist:
350
+
351
+ - Use `_id` for default Mongo cursor ordering.
352
+ - Use `createdAt` or another indexed stable key when the product requires chronological cursor behavior.
353
+ - Append `_id` as a tie-breaker for non-unique cursor keys.
354
+ - Fetch `limit + 1` records and generate `nextCursor` only when another page exists.
355
+ - Treat cursor tokens as opaque; clients should not parse them.
356
+
183
357
  ### references/schema-and-plugins.md
184
358
 
185
359
  # Mongo Schema And Plugins
186
360
 
361
+ ## Source Lookup
362
+
363
+ When blocked, inspect:
364
+
365
+ - Consumer project first: `node_modules/@joktec/mongo`.
366
+ - Package docs next: `node_modules/@joktec/mongo/README.md`.
367
+ - GitHub docs next: `https://github.com/joktec/joktec-framework/tree/main/packages/databases/mongo`.
368
+ - GitHub source fallback:
369
+ - `packages/databases/mongo/src/decorators/schema.decorator.ts`
370
+ - `packages/databases/mongo/src/decorators/schema.options.ts`
371
+ - `packages/databases/mongo/src/decorators/prop.decorator.ts`
372
+ - `packages/databases/mongo/src/decorators/props/*`
373
+ - `packages/databases/mongo/src/models/mongo.ref.ts`
374
+ - `packages/databases/mongo/src/models/object-id.ts`
375
+ - `packages/databases/mongo/src/models/mongo.schema.ts`
376
+ - `packages/databases/mongo/src/plugins/paranoid.plugin.ts`
377
+ - `packages/databases/mongo/src/plugins/strict-reference.plugin.ts`
378
+ - `packages/databases/mongo/src/plugins/transform.plugin.ts`
379
+
187
380
  ## Schema Decorators
188
381
 
189
382
  Use `@Schema` and `@Prop` wrappers from `@joktec/mongo` for Typegoose schema metadata plus validation, transform, and Swagger metadata.
190
383
 
191
384
  Avoid mutating shared option objects across multiple properties.
192
385
 
386
+ Best practice:
387
+
388
+ - Use schema-first decorators when the schema should be reused by DTO mapped types.
389
+ - Keep raw `@prop` or raw Mongoose decorators only when the wrapper cannot express the behavior.
390
+ - Pass custom validators/transforms explicitly rather than adding hidden global behavior.
391
+ - Keep maps, snapshots, and dynamic objects explicit so helper conversion does not alter their shape.
392
+ - Keep app-level reference semantics visible; strict reference plugin checks existence, but the app still owns domain rules.
393
+ - Use `RefId<T>` for persisted id fields and `PopulatedRef<T>` for populated virtual instance fields.
394
+ - Use lazy `type` resolvers such as `type: () => User` or `type: () => [User]` when the wrapper cannot infer the runtime class.
395
+ - Use `@Schema({ kind: 'embedded' })` for value objects without `_id` or timestamps.
396
+ - Use `@Schema({ kind: 'subdocument' })` for embedded documents that need `_id` and timestamps but should not create a collection.
397
+ - Use `@Prop({ kind: 'virtual', mode: 'getter', comment, optional, hidden, expose, swagger })` for computed getters that only need class-transformer and Swagger metadata.
398
+ - Use `@Prop({ ref: () => User, foreignField, localField })` for populate-one virtuals when inferred defaults are enough.
399
+ - Use `@Prop({ type: () => [User], ref: () => User, foreignField, localField })` for populate-array virtuals.
400
+ - Use `@Prop({ kind: 'map', type: Object })` for raw maps/snapshots instead of passing `PropType.MAP` at the call site.
401
+
402
+ Common mappings:
403
+
404
+ | Use case | Preferred shape |
405
+ | --- | --- |
406
+ | Stored single reference id | `fieldId?: RefId<User>` with `@Prop({ type: ObjectId, ref: () => User })` |
407
+ | Stored reference id array | `fieldIds?: RefId<User>[]` with `@Prop({ type: [ObjectId], ref: () => User })` |
408
+ | Embedded value object | `@Schema({ kind: 'embedded' })` on the nested class |
409
+ | Embedded document | `@Schema({ kind: 'subdocument' })` on the nested class |
410
+ | Raw map/snapshot | `@Prop({ kind: 'map', type: Object })` |
411
+ | Populated single virtual | `field?: PopulatedRef<User>` with `@Prop({ ref: () => User, foreignField: '_id', localField: 'fieldId' })` |
412
+ | Populated virtual array | `fields?: PopulatedRef<User>[]` with `@Prop({ type: () => [User], ref: () => User, foreignField: '_id', localField: 'fieldIds' })` |
413
+ | Computed getter | `@Prop({ kind: 'virtual', mode: 'getter', comment: '...' }) get value() { ... }` |
414
+
415
+ Populate inference:
416
+
417
+ - `ref` + `localField` + `foreignField` marks the field as virtual populate.
418
+ - Populate-one can fallback to the same class from `ref`.
419
+ - Populate arrays still need `type: () => [Target]` because runtime reflection only sees `Array`.
420
+ - `justOne` defaults to `true` for non-array populate fields.
421
+ - Swagger examples default to `{}` or `[]` for populated fields unless explicitly overridden.
422
+
193
423
  ## Plugins
194
424
 
195
425
  - Paranoid plugin handles soft delete filtering and must respect aggregate first-stage constraints such as `$geoNear`.
196
426
  - Strict reference plugin validates referenced documents and must resolve models through the active connection.
197
427
  - Transform plugin centralizes common document transformation and should not break Mongo update operators.
198
428
 
429
+ Plugin checklist:
430
+
431
+ - Paranoid aggregate injection must not come before `$geoNear`.
432
+ - Strict reference checks must be connection-aware in multi-connection apps.
433
+ - Transform behavior must preserve update operators such as `$set`, `$inc`, `$push`, and `$addToSet`.
434
+ - Do not treat plugins as a replacement for app authorization or domain validation.
435
+
199
436
  ## Debug Output
200
437
 
201
438
  Use `mongoDebug(collection, method, ...args)` when a Mongoose debug callback should be rendered as a Mongo shell-friendly command.
202
439
 
440
+ Debug output is for developer diagnostics. Do not log credentials or sensitive document payloads in production logs.
441
+
203
442
  ---
204
443
 
205
444
  ## JokTec MySQL Skill
@@ -216,11 +455,16 @@ Use this skill for relational resources backed by JokTec's TypeORM wrapper.
216
455
  - Treat `mysql`, `mariadb`, and `postgres` as the first-class dialects.
217
456
  - Keep `sync` explicit and normally enabled only by an owner process or development bootstrap.
218
457
  - Do not add new behavior to deprecated `MysqlFinder`; use `MysqlRepo.qb()` and `MysqlHelper` paths.
458
+ - Use schema-first `@Column`, `@PrimaryColumn`, and `@TimestampColumn` wrappers when an entity also acts as DTO metadata.
459
+ - Use `@Column({ kind: 'virtual' })` for computed getters that need expose/Swagger metadata without persistence.
460
+ - Use `immutable` for API read-only metadata; TypeORM `update: false` remains storage write behavior and is also inferred as Swagger read-only when `immutable` is not set.
461
+ - Do not use `@joktec/mysql` for Mongo/ObjectId columns, even though TypeORM has Mongo-related APIs.
462
+ - For real migrations, inspect the installed `@joktec/mysql` source in the consumer project's `node_modules` first. If that is insufficient, read GitHub package docs, then GitHub source. Use the local `../joktec-framework` checkout only when you are working inside the JokTec development workspace.
219
463
 
220
464
  ## References
221
465
 
222
466
  - Read `references/repository.md` for connection lifecycle, repository usage, query safety, transaction, and cursor behavior.
223
- - Read `references/entities.md` for `@Tables`, `@Column`, `@PrimaryColumn`, uuidv7, and dialect guidance.
467
+ - Read `references/entities.md` for `@Tables`, `@Column`, `@PrimaryColumn`, uuidv7, dialect guidance, and legacy decorator migration rules.
224
468
 
225
469
  ## Bundled References
226
470
 
@@ -228,15 +472,123 @@ Use this skill for relational resources backed by JokTec's TypeORM wrapper.
228
472
 
229
473
  # MySQL Entity Decorators
230
474
 
475
+ ## Source Lookup
476
+
477
+ When blocked in a consumer project, inspect the installed package first:
478
+
479
+ - `node_modules/@joktec/mysql/README.md`
480
+ - `node_modules/@joktec/mysql/AGENTS.md` when published with the package
481
+ - `node_modules/@joktec/mysql/dist/index.d.ts`
482
+ - `node_modules/@joktec/mysql/dist/decorators/column.decorator.d.ts`
483
+ - `node_modules/@joktec/mysql/dist/decorators/columns/column.type.d.ts`
484
+ - `node_modules/@joktec/mysql/dist/decorators/timestamp.decorator.d.ts`
485
+
486
+ If the installed package is missing enough detail, use the GitHub package docs next:
487
+
488
+ - `https://github.com/joktec/joktec-framework/tree/main/packages/databases/mysql`
489
+
490
+ Use GitHub source only after package docs and installed types are not enough:
491
+
492
+ - `packages/databases/mysql/src/decorators/table.decorator.ts`
493
+ - `packages/databases/mysql/src/decorators/column.decorator.ts`
494
+ - `packages/databases/mysql/src/decorators/columns/column.type.ts`
495
+ - `packages/databases/mysql/src/decorators/columns/column.factory.ts`
496
+ - `packages/databases/mysql/src/decorators/columns/primary.column.ts`
497
+ - `packages/databases/mysql/src/decorators/columns/timestamp.column.ts`
498
+ - `packages/databases/mysql/src/decorators/columns/virtual.column.ts`
499
+ - `packages/databases/mysql/src/decorators/columns/object.column.ts`
500
+ - `packages/databases/mysql/src/decorators/columns/string.column.ts`
501
+ - `packages/databases/mysql/src/decorators/columns/number.column.ts`
502
+ - `packages/databases/mysql/src/decorators/columns/transform.column.ts`
503
+ - `packages/databases/mysql/src/decorators/columns/swagger.column.ts`
504
+
231
505
  ## Schema-First Entity Pattern
232
506
 
233
- Use `@Tables`, `@Column`, and `@PrimaryColumn` from `@joktec/mysql` when an entity should also act as the source class for mapped DTOs.
507
+ Use `@Tables`, `@Column`, `@PrimaryColumn`, and `@TimestampColumn` from `@joktec/mysql` when an entity should also act as the source class for mapped DTOs.
508
+
509
+ The new decorators are not thin TypeORM aliases. They are schema-first wrappers that compose:
510
+
511
+ - TypeORM column/primary column metadata.
512
+ - `class-validator` behavior through `@joktec/utils` validators.
513
+ - `class-transformer` expose/exclude behavior.
514
+ - Swagger property metadata.
515
+
516
+ The wrapper can also represent virtual computed getters and nested JSON/jsonb class payloads. Do not use this package for Mongo/ObjectId columns.
517
+
518
+ Wrapper philosophy:
519
+
520
+ - prefer one schema declaration that carries persistence, validation, transform, and Swagger metadata
521
+ - use wrapper options before duplicating `@ApiProperty`, `@Expose`, `@Type`, or common validators
522
+ - use raw TypeORM only for advanced cases that the wrapper does not model cleanly
523
+ - keep storage write behavior and API documentation behavior distinct when needed
524
+
525
+ ## Current Decorator Capabilities
526
+
527
+ Use the package README and actual installed source for full migration details. This skill only keeps the common mappings that help an agent recognize old patterns.
528
+
529
+ Common mappings:
530
+
531
+ | Legacy decorators | New decorator shape |
532
+ | --- | --- |
533
+ | `@PrimaryGeneratedColumn()` | `@PrimaryColumn('increment')` |
534
+ | `@PrimaryGeneratedColumn('uuid')` | `@PrimaryColumn('uuid')` |
535
+ | app-generated ordered UUID id | `@PrimaryColumn('uuidv7')` |
536
+ | `@CreateDateColumn(...)` | `@TimestampColumn('create', ...)` |
537
+ | `@UpdateDateColumn(...)` | `@TimestampColumn('update', ...)` |
538
+ | `@DeleteDateColumn(...)` | `@TimestampColumn('delete', ...)` |
539
+ | TypeORM `@VersionColumn(...)` | `@Column({ kind: 'version', ... })` |
540
+ | TypeORM `@VirtualColumn(...)` | `@Column({ kind: 'virtual', mode: 'sql', query, ... })` |
541
+ | TypeORM `@ViewColumn(...)` | `@Column({ kind: 'view', ... })` |
542
+ | `@Column(...)` | `@Column(...)` from `@joktec/mysql` |
543
+ | `@RelationId(...)` | `@Column({ kind: 'relation-id', relationId })` |
544
+ | `@IsNotEmpty()` | `@Column({ required: true })` |
545
+ | `@IsOptional()` | `@Column({ required: false })` or nullable TypeORM option when storage allows null |
546
+ | `@IsEmail()` | `@Column({ isEmail: true })` |
547
+ | `@IsMobilePhone()` | `@Column({ isPhone: true })` |
548
+ | `@IsInt()` | `@Column({ isInt: true })` or an integer column type |
549
+ | `@IsUUID()` | `@Column({ isUUID: true })` |
550
+ | `@IsObject()` | `@Column({ isObject: true })` or a JSON column |
551
+ | `@IsHexColor()` | `@Column({ isHexColor: true })` |
552
+ | `@IsUrl()` | `@Column({ isUrl: true })` |
553
+ | `@MinLength(n)` | `@Column({ minLength: n })` |
554
+ | `@MaxLength(n)` | `@Column({ maxLength: n })` |
555
+ | `@Min(n)` | `@Column({ min: n })` |
556
+ | `@Max(n)` | `@Column({ max: n })` |
557
+ | `@Expose()` | default behavior of `@Column(...)` |
558
+ | `@Expose({ groups })` | `@Column({ groups })` |
559
+ | `@Exclude({ toPlainOnly: true })` plus hidden Swagger | `@Column({ hidden: true })` |
560
+ | `@ApiProperty(...)` | `@Column({ swagger: ... })`, or native options such as `example`, `comment`, `deprecated`, `min`, `max`, `minLength`, `maxLength` |
561
+ | `@ValidateNested()` + `@Type(() => Preference)` | `@Column('jsonb', { nested: Preference })` |
562
+ | `@ValidateNested({ each: true })` + `@Type(() => Preference)` | `@Column('jsonb', { nested: Preference, each: true })` |
563
+ | `@Expose()` + `@ApiProperty(...)` on a getter | `@Column({ kind: 'virtual', ... })` |
564
+ | Swagger `readOnly: true` | `@Column({ immutable: true })` or TypeORM `update: false` when ORM updates must also be blocked |
565
+
566
+ ## Read-Only Metadata
567
+
568
+ `immutable` is the API read-only hint used by the JokTec MySQL wrapper. TypeORM `update: false` is the ORM write behavior. The wrapper maps both to Swagger `readOnly` when appropriate:
569
+
570
+ - `immutable` has priority over `update: false`
571
+ - `update: false` implies Swagger `readOnly` only when `immutable` is not set
572
+ - `swagger.readOnly` remains the final explicit override
573
+
574
+ Some field kinds default to API read-only because they are system-managed or computed:
575
+
576
+ - primary keys
577
+ - timestamp columns
578
+ - version columns
579
+ - view columns
580
+ - virtual getter and SQL virtual columns
581
+ - relation-id columns
582
+ - tree level columns
234
583
 
235
584
  ## Primary Keys
236
585
 
237
586
  - Prefer numeric auto-increment keys for write-heavy MySQL tables.
238
587
  - Use UUIDs when the app needs globally unique or public identifiers.
239
588
  - Prefer `uuidv7` over random UUIDs when the id participates in ordered indexes or cursor-like access.
589
+ - When switching from UUID v4 to uuidv7, verify downstream code does not assume random UUID ordering.
590
+
591
+ Do not blindly convert every primary key to uuidv7. Keep numeric increment keys when the table is internal, write-heavy, and does not need public/global identifiers.
240
592
 
241
593
  ## Dialects
242
594
 
@@ -246,28 +598,91 @@ The stable dialects are MySQL, MariaDB, and Postgres. Dialect capabilities own d
246
598
 
247
599
  # MySQL Repository Usage
248
600
 
601
+ ## Source Lookup
602
+
603
+ When blocked in a consumer project, inspect installed package docs and types first:
604
+
605
+ - `node_modules/@joktec/mysql/README.md`
606
+ - `node_modules/@joktec/mysql/AGENTS.md` when published with the package
607
+ - `node_modules/@joktec/mysql/dist/index.d.ts`
608
+ - `node_modules/@joktec/mysql/dist/mysql.module.d.ts`
609
+ - `node_modules/@joktec/mysql/dist/mysql.service.d.ts`
610
+ - `node_modules/@joktec/mysql/dist/mysql.repo.d.ts`
611
+ - `node_modules/@joktec/mysql/dist/models/mysql.request.d.ts`
612
+
613
+ If the installed package is insufficient, read GitHub package docs next:
614
+
615
+ - `https://github.com/joktec/joktec-framework/tree/main/packages/databases/mysql`
616
+
617
+ Use GitHub source only after installed types and package docs are not enough:
618
+
619
+ - `packages/databases/mysql/README.md`
620
+ - `packages/databases/mysql/AGENTS.md`
621
+ - `packages/databases/mysql/src/index.ts`
622
+ - `packages/databases/mysql/src/mysql.module.ts`
623
+ - `packages/databases/mysql/src/mysql.service.ts`
624
+ - `packages/databases/mysql/src/mysql.repo.ts`
625
+ - `packages/databases/mysql/src/helpers/mysql.helper.ts`
626
+ - `packages/databases/mysql/src/helpers/mysql.finder.ts`
627
+ - `packages/databases/mysql/src/services/mysql.dialect.ts`
628
+ - `packages/databases/mysql/src/models/*`
629
+
249
630
  ## Module Setup
250
631
 
251
632
  Register entities with `MysqlModule.forRoot({ conId, models: [...] })`. Use `conId` for multiple DataSources.
252
633
 
634
+ Best practice:
635
+
636
+ - Register consumer app entities in an app repository module.
637
+ - Keep `sync` disabled in request-facing processes unless the app intentionally owns schema sync.
638
+ - Use one controlled owner process for schema sync/migration in multi-process deployments.
639
+ - Preserve `conId` when resolving repositories or transaction-scoped managers.
640
+
253
641
  ## Repository Pattern
254
642
 
255
643
  Extend `MysqlRepo` and pass the entity class to the base constructor. Services can use `BaseService` when CRUD behavior follows the shared contract.
256
644
 
645
+ Repository checklist:
646
+
647
+ - Keep entity-specific SQL helpers in the app repository, not in controllers.
648
+ - Use `MysqlRepo.qb()` and repository methods for standard reads so field validation, relation loading, soft delete, and pagination stay consistent.
649
+ - Do not add new behavior to `MysqlFinder`; it is deprecated compatibility code.
650
+ - Keep read/write operations in the same transaction context when the app passes a manager or query runner.
651
+
257
652
  ## Query Safety
258
653
 
259
654
  - Validate field paths against TypeORM metadata before interpolating SQL identifiers.
260
655
  - Use parameter binding for values.
261
656
  - Keep logical operators such as `$and` and `$or` grouped through QueryBuilder behavior.
262
657
 
658
+ Anti-patterns:
659
+
660
+ - Do not interpolate user-provided field names or relation names into SQL without TypeORM metadata validation.
661
+ - Do not assume MySQL-only syntax when the package supports MySQL, MariaDB, and Postgres.
662
+ - Do not use a relation/populate path unless it maps to entity metadata.
663
+
263
664
  ## Pagination
264
665
 
265
666
  `MysqlRepo.paginate` supports page, offset, and cursor responses. Cursor mode defaults to `createdAt` plus primary key columns. Custom cursor keys must be mapped columns.
266
667
 
668
+ Cursor checklist:
669
+
670
+ - Use `createdAt + primary key` as the default stable cursor.
671
+ - Add primary keys as tie-breakers for non-unique cursor keys.
672
+ - Ensure cursor keys are indexed for hot list endpoints.
673
+ - Validate cursor payload shape before building SQL.
674
+ - Treat cursor tokens as opaque; clients should not parse them.
675
+
267
676
  ## Transactions
268
677
 
269
678
  When using transaction-scoped operations, pass the manager or query runner through repository options so pre-read and write operations use the same context.
270
679
 
680
+ Transaction checklist:
681
+
682
+ - Use one manager/query runner for read-modify-write flows.
683
+ - Rollback tests should prove that both pre-read dependent writes and writes are transaction-scoped.
684
+ - Avoid mixing default repositories and transaction-scoped repositories in one operation.
685
+
271
686
  ---
272
687
 
273
688
  ## JokTec Broker Skill
@@ -289,6 +704,7 @@ Use this skill for message broker packages.
289
704
  - Use broker decorators for transport wiring, not for domain policy.
290
705
  - Preserve config-driven client selection and `conId` when available.
291
706
  - Keep topic, queue, and routing names explicit in app configuration or decorators.
707
+ - If guidance is insufficient, read this skill's references and inspect `../joktec-framework` package source or GitHub fallback before assuming APIs.
292
708
 
293
709
  ## Reference
294
710
 
@@ -300,10 +716,22 @@ Read `references/brokers.md` for setup and package-specific notes.
300
716
 
301
717
  # Broker Usage
302
718
 
719
+ ## Source Lookup
720
+
721
+ When blocked, inspect:
722
+
723
+ - `packages/brokers/README.md`
724
+ - `packages/brokers/AGENTS.md`
725
+ - `packages/brokers/<package>/README.md`
726
+ - `packages/brokers/<package>/src/index.ts`
727
+ - package decorators, loaders, config, and service files under `src/`
728
+
303
729
  ## Runtime Pattern
304
730
 
305
731
  Broker services follow `AbstractClientService` lifecycle. Loader classes discover decorator metadata after module initialization. Apps define producers, consumers, and message semantics.
306
732
 
733
+ Use broker packages for transport wiring, not for business workflow ownership. The consuming app owns event names, payload contracts, idempotency, retry policy, dead-letter behavior, and handler semantics.
734
+
307
735
  ## Package Notes
308
736
 
309
737
  - Kafka: check topic existence and broker advertised listeners in local development.
@@ -311,6 +739,23 @@ Broker services follow `AbstractClientService` lifecycle. Loader classes discove
311
739
  - SQS: local ElasticMQ-style environments may require queues to exist before consumers start.
312
740
  - Redcast: use Redis-backed list, stream, or pub/sub behavior when a lightweight broker is enough.
313
741
 
742
+ ## Best Practices
743
+
744
+ - Start consumers only in processes that should own subscriptions.
745
+ - Keep producer and consumer payload DTOs versionable and explicit.
746
+ - Use config paths or module options for topic/queue names when supported.
747
+ - Make handlers idempotent; brokers may redeliver.
748
+ - Add observable effects for consumer tests rather than asserting log text.
749
+ - Keep broker health/preflight checks separate from business request handling.
750
+ - In local stacks, verify broker-specific infrastructure: Kafka topics, Rabbit exchanges/queues, SQS queues, Redis password/db.
751
+
752
+ ## Anti-Patterns
753
+
754
+ - Do not hide domain workflows inside decorators or broker package services.
755
+ - Do not assume auto-create topic/queue behavior unless the package and local broker support it.
756
+ - Do not run the same consumer group/queue owner in every process by accident.
757
+ - Do not swallow message handling errors without retry/dead-letter visibility.
758
+
314
759
  ---
315
760
 
316
761
  ## JokTec Adapter Skill
@@ -332,6 +777,7 @@ Use this skill for pluggable external capability adapters.
332
777
  - Use validated config and `conId` where supported.
333
778
  - Keep secrets and credentials in app config or runtime environment, never in code.
334
779
  - Prefer adapter services over direct SDK usage in app services.
780
+ - If guidance is insufficient, read this skill's references and inspect `../joktec-framework` package source or GitHub fallback before assuming APIs.
335
781
 
336
782
  ## Reference
337
783
 
@@ -343,10 +789,22 @@ Read `references/adapters.md` for setup and package-specific notes.
343
789
 
344
790
  # Adapter Usage
345
791
 
792
+ ## Source Lookup
793
+
794
+ When blocked, inspect:
795
+
796
+ - `packages/adapters/README.md`
797
+ - `packages/adapters/AGENTS.md`
798
+ - `packages/adapters/<package>/README.md`
799
+ - `packages/adapters/<package>/src/index.ts`
800
+ - package module/config/service files under `src/`
801
+
346
802
  ## Runtime Pattern
347
803
 
348
804
  Adapters are global Nest modules. Services own native client creation and expose package-specific operations.
349
805
 
806
+ Most adapters follow `AbstractClientService`: config is validated, native clients are created by the service, `conId` selects the connection, and shutdown/retry/debug behavior should remain package-owned.
807
+
350
808
  ## Package Notes
351
809
 
352
810
  - Cacher: choose local, Redis, or Memcached stores based on runtime config.
@@ -354,6 +812,22 @@ Adapters are global Nest modules. Services own native client creation and expose
354
812
  - Notifier: keep push provider configuration outside app business logic.
355
813
  - Storage: keep storage metadata and object operations behind the adapter service.
356
814
 
815
+ ## Best Practices
816
+
817
+ - Import adapter modules in the application layer, then inject services into domain services.
818
+ - Keep provider credentials, endpoints, bucket names, SMTP secrets, and push credentials in runtime config.
819
+ - Keep business payload composition in the consuming app. The adapter should send/cache/store, not decide product semantics.
820
+ - Use `conId` for multiple providers or tenants instead of creating ad-hoc service instances.
821
+ - Normalize provider errors at the package/app boundary so controllers do not branch on SDK-specific messages.
822
+ - Mock SDK clients in unit tests; run live provider checks only in explicit integration or consumer harness tests.
823
+
824
+ ## Anti-Patterns
825
+
826
+ - Do not put email template business rules inside `@joktec/mailer`.
827
+ - Do not hardcode S3 buckets, Redis URLs, SMTP credentials, or notification tokens in source.
828
+ - Do not bypass adapter services by importing provider SDK clients directly throughout the app.
829
+ - Do not assume every adapter has identical method names; read each package README/source before calling.
830
+
357
831
  ---
358
832
 
359
833
  ## JokTec Extended Database Skill
@@ -374,6 +848,7 @@ Use this skill for database clients that are not Mongo or MySQL.
374
848
  - Use package services for client lifecycle and connection config.
375
849
  - Do not claim parity with Mongo/MySQL repository behavior unless the package implements it.
376
850
  - Use package README and source as final truth before adding advanced behavior.
851
+ - If guidance is insufficient, read this skill's references and inspect `../joktec-framework` package source or GitHub fallback before assuming APIs.
377
852
 
378
853
  ## Reference
379
854
 
@@ -385,6 +860,16 @@ Read `references/extended-databases.md` for package boundaries and usage notes.
385
860
 
386
861
  # Extended Database Usage
387
862
 
863
+ ## Source Lookup
864
+
865
+ When blocked, inspect:
866
+
867
+ - `packages/databases/README.md`
868
+ - `packages/databases/AGENTS.md`
869
+ - `packages/databases/<package>/README.md`
870
+ - `packages/databases/<package>/src/index.ts`
871
+ - package config/module/service files under `src/`
872
+
388
873
  ## Package Boundaries
389
874
 
390
875
  Extended database packages expose reusable clients and helpers for specific data systems. They should not contain consumer app schemas or business-specific query policy.
@@ -395,6 +880,20 @@ Extended database packages expose reusable clients and helpers for specific data
395
880
  - Arango and BigQuery are separate client packages; verify the README/source before assuming repository-like CRUD support.
396
881
  - Use local package tests or consumer harnesses only when the target service stack is available.
397
882
 
883
+ ## Best Practices
884
+
885
+ - Treat these packages as client wrappers unless source explicitly exposes a repository abstraction.
886
+ - Keep index names, dataset names, query templates, and domain-specific projections in the consumer app.
887
+ - Validate credentials and endpoints through config; never commit service account data.
888
+ - Keep retries, timeouts, and debug logging visible in config.
889
+ - Use provider-specific tests/mocks for package logic and live stack tests only when credentials/services are intentionally available.
890
+
891
+ ## Anti-Patterns
892
+
893
+ - Do not apply MongoRepo/MysqlRepo assumptions to Elastic/Arango/BigQuery.
894
+ - Do not introduce app schemas or business query policy into reusable database clients.
895
+ - Do not claim support for a provider feature unless the package source or README shows it.
896
+
398
897
  ---
399
898
 
400
899
  ## JokTec Integration Skill
@@ -414,6 +913,7 @@ Use this skill for third-party integration packages.
414
913
  - Use package services instead of direct SDK initialization in app code.
415
914
  - Preserve app-neutral service behavior; consumer apps own domain workflows.
416
915
  - Verify current package README/source before relying on advanced provider features.
916
+ - If guidance is insufficient, read this skill's references and inspect `../joktec-framework` package source or GitHub fallback before assuming APIs.
417
917
 
418
918
  ## Reference
419
919
 
@@ -425,14 +925,43 @@ Read `references/integrations.md` for provider-specific notes.
425
925
 
426
926
  # Integration Usage
427
927
 
928
+ ## Source Lookup
929
+
930
+ When blocked, inspect:
931
+
932
+ - `packages/integrations/README.md`
933
+ - `packages/integrations/AGENTS.md`
934
+ - `packages/integrations/<package>/README.md`
935
+ - `packages/integrations/<package>/src/index.ts`
936
+ - package config/module/service files under `src/`
937
+
428
938
  ## Firebase
429
939
 
430
940
  Use the integration module and service to initialize Firebase Admin clients from validated config. Keep credential files local or environment-provided.
431
941
 
942
+ Best practice:
943
+
944
+ - Keep service account JSON, private keys, and project credentials out of git.
945
+ - Prefer environment-specific config or ignored local credential files.
946
+ - Keep notification/user/storage/product semantics in the consumer app.
947
+ - Mock Firebase Admin SDK in package tests; use live credentials only in explicit integration environments.
948
+
432
949
  ## GPT
433
950
 
434
951
  Use the integration package for reusable GPT client setup. Keep prompt/business policy in the consumer app, not in the generic package.
435
952
 
953
+ Best practice:
954
+
955
+ - Keep prompts, model choice policy, tool schemas, and product safety rules in the consumer app.
956
+ - Keep API keys in secret management or environment config.
957
+ - Verify current package completeness before relying on advanced APIs; `@joktec/gpt` may lag behind provider SDK changes.
958
+
959
+ ## Anti-Patterns
960
+
961
+ - Do not commit real credential files.
962
+ - Do not encode product-specific prompts or notification logic into the reusable integration package.
963
+ - Do not assume provider SDK behavior without checking package source and provider docs when APIs are unstable.
964
+
436
965
  ---
437
966
 
438
967
  ## JokTec Tool Skill
@@ -453,6 +982,7 @@ Use this skill for reusable utility services.
453
982
  - Use config-driven clients instead of direct ad hoc setup in app code.
454
983
  - Preserve retry, metrics, proxy, and upload behavior where the package exposes it.
455
984
  - Keep alert tokens and webhook URLs in runtime config only.
985
+ - If guidance is insufficient, read this skill's references and inspect `../joktec-framework` package source or GitHub fallback before assuming APIs.
456
986
 
457
987
  ## Reference
458
988
 
@@ -464,14 +994,486 @@ Read `references/tools.md` for package-specific usage notes.
464
994
 
465
995
  # Tool Usage
466
996
 
997
+ ## Source Lookup
998
+
999
+ When blocked, inspect:
1000
+
1001
+ - `packages/tools/README.md`
1002
+ - `packages/tools/AGENTS.md`
1003
+ - `packages/tools/<package>/README.md`
1004
+ - `packages/tools/<package>/src/index.ts`
1005
+ - package config/module/service/helper files under `src/`
1006
+
467
1007
  ## HTTP
468
1008
 
469
1009
  Use `@joktec/http` for Axios-backed requests, uploads, proxy agent support, retry config, and metrics where exposed.
470
1010
 
1011
+ Best practice:
1012
+
1013
+ - Use the package service for outbound HTTP so retry/proxy/metrics behavior stays centralized.
1014
+ - Keep external endpoint URLs and credentials in runtime config.
1015
+ - Be careful with ESM/CommonJS import changes in HTTP/Axios ecosystem packages.
1016
+ - `HttpService.buildAgent(proxy, opts)` expects proxy identity in `HttpProxyConfig` and agent tuning in Node `AgentOptions`; inspect the installed source before adapting to proxy-agent major-version changes.
1017
+ - Test request behavior with mocks unless the test is an explicit consumer integration scenario.
1018
+
471
1019
  ## File
472
1020
 
473
1021
  Use `@joktec/file` for shared file helpers and classification behavior instead of duplicating local utility code.
474
1022
 
1023
+ Best practice:
1024
+
1025
+ - Keep filesystem paths and temporary directories environment-specific.
1026
+ - Validate upload/file inputs before passing them into business workflows.
1027
+ - Use package helpers for MIME/classification behavior when consistency matters across services.
1028
+
475
1029
  ## Alert
476
1030
 
477
1031
  Use `@joktec/alert` for Slack-compatible webhook alerts. Keep webhook URLs and credentials out of source control.
1032
+
1033
+ Best practice:
1034
+
1035
+ - Treat alert messages as operational notifications, not business workflows.
1036
+ - Do not leak secrets, tokens, connection strings, or personal data into alert payloads.
1037
+ - `@joktec/alert` is present but less complete than core database/client packages; inspect source before depending on advanced behavior.
1038
+
1039
+ ## Anti-Patterns
1040
+
1041
+ - Do not scatter raw Axios instances across the app when `@joktec/http` should own shared behavior.
1042
+ - Do not commit webhook URLs or proxy credentials.
1043
+ - Do not use tool packages as hidden places for app business rules.
1044
+
1045
+ ---
1046
+
1047
+ ## Advanced TypeScript Design
1048
+
1049
+ Packages: TypeScript, NestJS
1050
+
1051
+ ## Overview
1052
+
1053
+ Act as a TypeScript architecture partner. Choose the simplest design that preserves clear boundaries, runtime correctness, and useful compile-time guarantees.
1054
+
1055
+ Use design patterns as vocabulary and pressure tests, not as decoration. Prefer local project conventions, readable APIs, and low-friction extension points before adding type-level machinery.
1056
+
1057
+ ## Architectural Mindset
1058
+
1059
+ - Start from the domain boundary: identify entity, request/response, service, repository, client, decorator, loader, and integration responsibilities.
1060
+ - Keep public APIs narrow and stable. Make extension explicit through interfaces, abstract classes, generic constraints, or composition.
1061
+ - Use classes when lifecycle, inheritance hooks, decorators, or framework reflection matter. Use plain functions/types when behavior is stateless or purely transformational.
1062
+ - Let runtime validation and compile-time types reinforce each other. Do not pretend TypeScript types validate untrusted runtime data.
1063
+ - Do not assume TypeScript generics, interfaces, unions, or array element types exist at runtime through `reflect-metadata`.
1064
+ - Escalate type complexity only when it removes real duplication, prevents invalid states, or makes an API substantially safer.
1065
+ - Check existing code before inventing a new pattern; mirror the repository's style when it already solves the same class of problem.
1066
+
1067
+ ## Public API Compatibility
1068
+
1069
+ - Treat exported types, classes, decorators, config objects, modules, and provider APIs as public contracts.
1070
+ - Prefer additive changes over breaking renames, deleted fields, changed generic parameter order, or narrower accepted input shapes.
1071
+ - Before changing exported generic types, check downstream inference from normal call sites and verify that common extension patterns still compile.
1072
+ - If a breaking type or runtime contract change is unavoidable, report migration impact explicitly and include the smallest migration path.
1073
+
1074
+ ## Pattern Vocabulary
1075
+
1076
+ Use the classic catalog as shared language, including the TypeScript examples catalog from Refactoring.Guru.
1077
+
1078
+ - Creational Patterns: Abstract Factory, Builder, Factory Method, Prototype, Singleton.
1079
+ - Structural Patterns: Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy.
1080
+ - Behavioral Patterns: Chain of Responsibility, Iterator, Memento, State, Template Method, Command, Mediator, Observer, Strategy, Visitor.
1081
+
1082
+ Treat pattern names as a starting point for design discussion. Validate whether the implementation needs the pattern's tradeoffs, or whether a direct function, data object, or interface is enough.
1083
+
1084
+ ## Agent Workflow
1085
+
1086
+ 1. Inspect local code first when working inside a repository. Look for existing abstractions, decorators, DTO types, factory functions, lifecycle hooks, and tests.
1087
+ 2. Classify the task:
1088
+ - Use `references/simple.md` for everyday TypeScript, OOP, data modeling, classes, interfaces, types, records, maps, arrays, simple decorators, and pragmatic refactors.
1089
+ - Use `references/advanced.md` for generic framework code, recursive mapped types, `infer`, distributed/deferred conditional types, reflection metadata, advanced decorators, type-safe builders, plugin architectures, or expert pattern selection.
1090
+ 3. Choose the least complex pattern that solves the force in front of you. Record why a simpler alternative was not enough when choosing advanced machinery.
1091
+ 4. Design the public surface before implementation: inputs, outputs, extension points, error behavior, lifecycle, and type inference experience.
1092
+ 5. Implement incrementally. Keep runtime behavior testable, and add focused type-level checks when exported generic or decorator behavior is subtle.
1093
+ 6. Review for overengineering: remove unused generic parameters, speculative base classes, unnecessary inheritance, and type utilities that do not protect a real API.
1094
+
1095
+ ## Repository Signals
1096
+
1097
+ In JokTec-style TypeScript, expect patterns such as:
1098
+
1099
+ - Generic request/query types with recursive conditions and sort/populate typing.
1100
+ - Factory functions that return decorated NestJS classes.
1101
+ - Abstract services and clients with template methods for lifecycle-specific behavior.
1102
+ - Decorator factories that compose validation, Swagger, transformation, metrics, and integration metadata.
1103
+ - Loader/registry patterns that collect decorator metadata and wire runtime behavior during module initialization.
1104
+
1105
+ ## Bundled References
1106
+
1107
+ ### references/advanced.md
1108
+
1109
+ # Advanced TypeScript Design Guidance
1110
+
1111
+ Use this reference for framework-level TypeScript, generic libraries, decorator infrastructure, metadata-driven loaders, and APIs where compile-time inference is part of the product experience.
1112
+
1113
+ ## Escalation Criteria
1114
+
1115
+ Reach for advanced TypeScript only when at least one is true:
1116
+
1117
+ - The API is reused widely and type inference prevents real misuse.
1118
+ - The runtime model is already generic, recursive, or metadata-driven.
1119
+ - The abstraction eliminates repeated boilerplate across many entities, DTOs, repositories, services, clients, or transports.
1120
+ - The type-level design mirrors a stable domain contract, not a speculative future.
1121
+ - Tests or examples can prove both runtime behavior and developer ergonomics.
1122
+
1123
+ If the advanced type exists only to feel clever, delete it.
1124
+
1125
+ ## Infer, Conditional, and Deferred Types
1126
+
1127
+ - Use `infer` to extract return types, payloads, entity types, DTO shapes, tuple elements, and callback signatures from source contracts.
1128
+ - Control distributive conditional types intentionally. Wrap operands in tuples, such as `[T] extends [U]`, when union distribution is not wanted.
1129
+ - Prefer named intermediate aliases when nested conditionals exceed two branches.
1130
+ - Use `never` as a filter, but verify that it cannot erase useful error information from public APIs.
1131
+ - Treat deferred conditional types and generic inference as public UX: callers should get helpful autocomplete and errors without manual type arguments.
1132
+
1133
+ ## Recursive and Mapped Types
1134
+
1135
+ - Use recursive mapped types for query languages, nested sort/select/populate APIs, deep partials, and entity graph traversal.
1136
+ - Add clear stop conditions for primitives, dates, arrays, functions, and branded values.
1137
+ - Use branded or opaque types for special primitives such as `ObjectId`, `UserId`, tenant IDs, cursors, or external reference IDs when plain strings would blur domain boundaries.
1138
+ - Avoid infinite or overly expensive type recursion. Keep recursion shallow enough for editor performance.
1139
+ - Preserve optionality and readonly modifiers intentionally with `+?`, `-?`, `readonly`, and `-readonly`.
1140
+ - Separate query operator typing from entity typing so the operator model remains testable and reusable.
1141
+
1142
+ ## Reflection and Decorators
1143
+
1144
+ - Use `reflect-metadata` only when runtime type information materially improves the API: schema generation, validation composition, serialization, dependency injection, or loader registration.
1145
+ - Remember that reflected TypeScript types are lossy at runtime. Arrays, unions, generics, and interfaces need explicit options or factories.
1146
+ - Prefer decorator factories that normalize options, resolve type factories, compose framework decorators, and define one clear metadata contract.
1147
+ - Keep advanced decorators thin at the call site and explicit internally: clone options, sanitize runtime-only fields, then compose validators, transformers, docs, and persistence metadata.
1148
+ - For method decorators, preserve `this`, return values, thrown errors, and async behavior unless the decorator explicitly changes them.
1149
+ - Use function source parsing only as a last-resort runtime technique for decorator infrastructure, such as mapping method argument names. Keep it isolated, deterministic, and covered by tests because minification, transpilation, defaults, destructuring, and comments can break it.
1150
+ - Test decorator behavior through a class that uses it, especially for metadata, wrapping behavior, and dependency injection.
1151
+
1152
+ ## Type-Level Verification
1153
+
1154
+ - Add type-level tests when changing exported generic utilities, query DSLs, decorators, builders, or public inference-heavy APIs.
1155
+ - Prefer the project's existing compile/type test setup. If available, use `tsd`, `expect-type`, `vitest`/`jest` type helpers, or a dedicated `tsc --noEmit` fixture.
1156
+ - Include positive inference examples from normal call sites, not only explicit generic arguments.
1157
+ - Include negative examples with `@ts-expect-error` when an invalid state must stay rejected.
1158
+ - Verify runtime tests separately when decorators, reflection metadata, validation, transformation, or loaders are involved.
1159
+
1160
+ ## Expert Pattern Selection
1161
+
1162
+ - Abstract Factory fits families of related clients, repositories, or transport adapters that must be created consistently.
1163
+ - Builder fits fluent configuration with required-step guarantees; type-state builders can enforce completeness but should stay readable.
1164
+ - Factory Method fits framework hooks that create DTOs, pagination wrappers, controllers, or provider instances.
1165
+ - Prototype fits cloning configured objects when construction is expensive or stateful.
1166
+ - Singleton should usually be delegated to the DI container; avoid hand-rolled global state.
1167
+ - Adapter fits third-party client normalization and migration layers.
1168
+ - Bridge fits separating abstraction from implementation, such as transport-agnostic messaging APIs over Rabbit, Kafka, or Redis.
1169
+ - Composite fits tree-shaped filters, pipelines, menu/routes, or nested query conditions.
1170
+ - Decorator fits metrics, retries, circuit breakers, serialization, validation, or publishing side effects around existing behavior.
1171
+ - Facade fits a stable service hiding multiple low-level collaborators.
1172
+ - Flyweight fits large repeated metadata or schema objects only after measuring memory pressure.
1173
+ - Proxy fits lazy clients, caching, access control, retries, and remote boundaries.
1174
+ - Chain of Responsibility fits validation, middleware, parsing, and request pipelines.
1175
+ - Command fits queued work, replayable operations, and undoable actions.
1176
+ - Iterator fits cursor pagination and collection traversal without exposing storage details.
1177
+ - Mediator fits module coordination where direct dependencies would become tangled.
1178
+ - Memento fits snapshots, rollbacks, and state restoration.
1179
+ - Observer fits event streams and pub/sub, with explicit unsubscribe and error policy.
1180
+ - State fits lifecycle-heavy clients, jobs, or connections with mode-specific behavior.
1181
+ - Strategy fits interchangeable algorithms selected by config or runtime context.
1182
+ - Template Method fits abstract base services/clients that own lifecycle while subclasses implement `init`, `start`, `stop`, `validate`, or `transform` steps.
1183
+ - Visitor fits operations over stable object structures when adding new operations is more common than adding new node types.
1184
+
1185
+ ## Symbolic Examples
1186
+
1187
+ Use examples like these as compact templates for thinking. Keep production implementations smaller or larger depending on the actual force.
1188
+
1189
+ ### Type-Safe Event Map
1190
+
1191
+ ```typescript
1192
+ type EventMap = {
1193
+ "user.created": { id: string };
1194
+ "invoice.paid": { invoiceId: string; amount: number };
1195
+ };
1196
+
1197
+ class EventBus<TEvents extends Record<string, unknown>> {
1198
+ on<K extends keyof TEvents>(event: K, handler: (payload: TEvents[K]) => void) {}
1199
+ emit<K extends keyof TEvents>(event: K, payload: TEvents[K]) {}
1200
+ }
1201
+
1202
+ const bus = new EventBus<EventMap>();
1203
+ bus.emit("invoice.paid", { invoiceId: "inv_1", amount: 100 });
1204
+ ```
1205
+
1206
+ Use this for Observer/Mediator-style APIs where event names and payloads must stay coupled.
1207
+
1208
+ ### API Contract Inference
1209
+
1210
+ ```typescript
1211
+ type Endpoint = {
1212
+ "/users/:id": {
1213
+ GET: { params: { id: string }; response: User };
1214
+ PATCH: { params: { id: string }; body: Partial<User>; response: User };
1215
+ };
1216
+ };
1217
+
1218
+ type ResponseOf<T> = T extends { response: infer R } ? R : never;
1219
+
1220
+ class ApiClient<TContract extends Record<string, any>> {
1221
+ request<Path extends keyof TContract, Method extends keyof TContract[Path]>(
1222
+ path: Path,
1223
+ method: Method,
1224
+ ): Promise<ResponseOf<TContract[Path][Method]>> {
1225
+ return null as any;
1226
+ }
1227
+ }
1228
+ ```
1229
+
1230
+ Use this when a contract object should drive call-site inference.
1231
+
1232
+ ### Type-State Builder
1233
+
1234
+ ```typescript
1235
+ type With<K extends string> = Record<K, true>;
1236
+
1237
+ class JobBuilder<State = {}> {
1238
+ queue(name: string): JobBuilder<State & With<"queue">> {
1239
+ return this as any;
1240
+ }
1241
+
1242
+ handler(fn: () => Promise<void>): JobBuilder<State & With<"handler">> {
1243
+ return this as any;
1244
+ }
1245
+
1246
+ build(this: State extends With<"queue"> & With<"handler"> ? JobBuilder<State> : never) {
1247
+ return {};
1248
+ }
1249
+ }
1250
+ ```
1251
+
1252
+ Use this when incomplete configuration is common and worth rejecting at compile time.
1253
+
1254
+ ### Recursive Query Shape
1255
+
1256
+ ```typescript
1257
+ type Primitive = string | number | boolean | Date;
1258
+ type FieldOp<T> = T | { $eq?: T; $in?: T[] };
1259
+ type Brand<T, Name extends string> = T & { readonly __brand: Name };
1260
+ type ObjectId = Brand<string, "ObjectId">;
1261
+
1262
+ type Query<T> = {
1263
+ [K in keyof T]?: T[K] extends Primitive
1264
+ ? FieldOp<T[K]>
1265
+ : T[K] extends Array<infer U>
1266
+ ? Query<U>
1267
+ : Query<T[K]>;
1268
+ } & {
1269
+ $or?: Query<T>[];
1270
+ };
1271
+ ```
1272
+
1273
+ Use this for Composite-style nested filters, but add stop conditions before expanding it.
1274
+
1275
+ ### Opaque ID Boundary
1276
+
1277
+ ```typescript
1278
+ type Brand<T, Name extends string> = T & { readonly __brand: Name };
1279
+ type UserId = Brand<string, "UserId">;
1280
+ type PostId = Brand<string, "PostId">;
1281
+
1282
+ function asUserId(value: string): UserId {
1283
+ return value as UserId;
1284
+ }
1285
+
1286
+ function findUser(id: UserId) {}
1287
+
1288
+ findUser(asUserId("u_1"));
1289
+ // @ts-expect-error raw strings are not accepted here
1290
+ findUser("u_1");
1291
+ ```
1292
+
1293
+ Use this when a domain primitive crosses many generic/query layers and accidental mixing would be costly.
1294
+
1295
+ ### Decorator Wrapper with Preserved Method Contract
1296
+
1297
+ ```typescript
1298
+ function Around(run: (next: () => unknown) => unknown): MethodDecorator {
1299
+ return (_, __, descriptor) => {
1300
+ const original = descriptor.value;
1301
+
1302
+ descriptor.value = function (...args: unknown[]) {
1303
+ return run(() => original.apply(this, args));
1304
+ };
1305
+ };
1306
+ }
1307
+ ```
1308
+
1309
+ Use this for metrics, retry, logging, or publishing side effects; preserve `this`, args, return values, and thrown errors.
1310
+
1311
+ ## JokTec-Style Signals to Reuse
1312
+
1313
+ - Recursive query typing can combine entity properties with operator unions, nested entity traversal, and logical `$or`/`$and` shapes.
1314
+ - Base services and clients commonly use Template Method: the base class owns lifecycle and shared behavior while subclasses provide specific implementation steps.
1315
+ - Controller factories can return decorated classes to avoid repetitive NestJS endpoint scaffolding while preserving DTO-specific metadata.
1316
+ - Decorator infrastructure often composes Swagger, validation, transformation, persistence, and metric behavior from one options object.
1317
+ - Rabbit loaders show a metadata registry plus module-init loader pattern: decorators declare intent; loaders resolve providers and connect runtime consumers.
1318
+
1319
+ ## Advanced Review Checklist
1320
+
1321
+ - Does every generic parameter appear in the public contract or implementation?
1322
+ - Can inference succeed from normal call-site arguments?
1323
+ - Does the type-level model match runtime validation and transformation?
1324
+ - Are metadata keys centralized and collision-resistant?
1325
+ - Are decorator side effects documented by tests?
1326
+ - Is editor performance acceptable after adding recursive or conditional types?
1327
+ - Is there a simpler Strategy, Adapter, or function-based design that would provide the same value?
1328
+
1329
+ ### references/simple.md
1330
+
1331
+ # Simple TypeScript Design Guidance
1332
+
1333
+ Use this reference for ordinary application and library work where readability, stable APIs, and maintainable TypeScript matter more than type-level cleverness.
1334
+
1335
+ ## Default Practices
1336
+
1337
+ - Prefer explicit, small interfaces for public boundaries and concrete classes for runtime behavior with lifecycle, dependency injection, or decorators.
1338
+ - Use `type` for unions, mapped shapes, conditional aliases, and composition. Use `interface` for object contracts intended to be implemented or extended.
1339
+ - Keep primitive aliases meaningful. A `UserId` alias can clarify intent, but it does not add runtime safety unless paired with validation or branding.
1340
+ - Model data with plain objects when behavior is absent. Add classes when construction, methods, inheritance hooks, decorators, or framework reflection are required.
1341
+ - Keep DTOs, entities, requests, and responses separate when they have different validation, persistence, or transport concerns.
1342
+ - Avoid `any` at public boundaries. Use `unknown` for untrusted data, then narrow or validate it.
1343
+ - Prefer narrow generic constraints such as `T extends Entity` over unconstrained `T` when the implementation depends on object semantics.
1344
+
1345
+ ## Classes, Interfaces, and OOP
1346
+
1347
+ - Use abstract classes for shared runtime behavior, protected hooks, and constructor-injected dependencies.
1348
+ - Use interfaces for contracts that should not carry runtime behavior.
1349
+ - Prefer composition over inheritance when variants differ by collaborator rather than lifecycle.
1350
+ - Keep protected hooks purposeful: `afterInit`, `transform`, `validate`, and `map` are good when subclasses are expected to customize one stable step.
1351
+ - Avoid deep inheritance chains. If a third level appears, consider Strategy, Adapter, or composition.
1352
+
1353
+ ## Common Data Structures
1354
+
1355
+ - Use `Record<K, V>` when the key set is known or constrained.
1356
+ - Use `{ [key: string]: V }` when the object is truly open-ended.
1357
+ - Use `Map<K, V>` when keys are not strings, insertion order matters, or frequent add/remove operations are central.
1358
+ - Use arrays for ordered collections and tuples for fixed positional contracts.
1359
+ - Use discriminated unions for state or command variants instead of loose booleans.
1360
+ - Keep hash-like caches private unless callers need iteration, eviction, or explicit lifecycle.
1361
+
1362
+ ## Basic Types and Utilities
1363
+
1364
+ - Use union literals for finite options: status, mode, operation, direction.
1365
+ - Use `Pick`, `Omit`, `Partial`, `Required`, `Readonly`, `Record`, `Extract`, and `Exclude` before writing custom utilities.
1366
+ - Use `keyof` and indexed access types for property-safe APIs.
1367
+ - Use overloads sparingly; prefer a single options object when overloads become hard to read.
1368
+ - Keep mapped types shallow unless the data is truly nested and the API benefits from deep transformation.
1369
+
1370
+ ## Simple Decorators
1371
+
1372
+ - Use decorator factories to attach framework metadata or compose existing decorators.
1373
+ - Keep decorator options serializable and explicit where possible.
1374
+ - Separate metadata collection from runtime execution. A decorator should usually register intent; a loader/service should execute it later.
1375
+ - Avoid parsing function source in ordinary decorators. If runtime argument-name mapping truly requires it, escalate to `advanced.md` and isolate the parser behind tests.
1376
+ - Test decorators at the behavior boundary, not only by checking metadata keys.
1377
+
1378
+ ## Pattern Choices
1379
+
1380
+ - Use Factory Method or simple factory functions when object creation varies by type or config.
1381
+ - Use Builder for stepwise configuration only when partially built objects are common or order matters.
1382
+ - Use Adapter to normalize third-party APIs behind project interfaces.
1383
+ - Use Facade to simplify a noisy subsystem for callers.
1384
+ - Use Decorator when behavior should wrap a method/object without changing its public contract.
1385
+ - Use Template Method when a base class owns an algorithm and subclasses fill in specific steps.
1386
+ - Use Strategy when an algorithm family changes independently from the caller.
1387
+ - Use Observer or Mediator for event-style communication, but keep ownership and error handling explicit.
1388
+
1389
+ ## Symbolic Examples
1390
+
1391
+ Use examples like these to reason about shape and tradeoffs. Keep final code adapted to the repository style.
1392
+
1393
+ ### Strategy with a Narrow Interface
1394
+
1395
+ ```typescript
1396
+ interface PriceStrategy {
1397
+ total(items: CartItem[]): number;
1398
+ }
1399
+
1400
+ class RetailPrice implements PriceStrategy {
1401
+ total(items: CartItem[]) {
1402
+ return items.reduce((sum, item) => sum + item.price, 0);
1403
+ }
1404
+ }
1405
+
1406
+ class WholesalePrice implements PriceStrategy {
1407
+ total(items: CartItem[]) {
1408
+ return items.reduce((sum, item) => sum + item.price * 0.9, 0);
1409
+ }
1410
+ }
1411
+
1412
+ class CheckoutService {
1413
+ constructor(private readonly strategy: PriceStrategy) {}
1414
+
1415
+ quote(items: CartItem[]) {
1416
+ return this.strategy.total(items);
1417
+ }
1418
+ }
1419
+ ```
1420
+
1421
+ Use this when the caller should not know which algorithm is active.
1422
+
1423
+ ### Adapter for Third-Party Boundaries
1424
+
1425
+ ```typescript
1426
+ interface MessageBus {
1427
+ publish(topic: string, payload: unknown): Promise<void>;
1428
+ }
1429
+
1430
+ class RabbitBusAdapter implements MessageBus {
1431
+ constructor(private readonly rabbit: RabbitClient) {}
1432
+
1433
+ publish(topic: string, payload: unknown) {
1434
+ return this.rabbit.sendToQueue(topic, JSON.stringify(payload));
1435
+ }
1436
+ }
1437
+ ```
1438
+
1439
+ Use this when external clients have noisy or unstable APIs.
1440
+
1441
+ ### Template Method for Lifecycle Hooks
1442
+
1443
+ ```typescript
1444
+ abstract class ManagedClient<TConfig, TClient> {
1445
+ async connect(config: TConfig) {
1446
+ const client = await this.create(config);
1447
+ await this.start(client);
1448
+ return client;
1449
+ }
1450
+
1451
+ protected abstract create(config: TConfig): Promise<TClient>;
1452
+ protected abstract start(client: TClient): Promise<void>;
1453
+ }
1454
+ ```
1455
+
1456
+ Use this when the base class owns lifecycle order and subclasses fill the variable steps.
1457
+
1458
+ ### Simple Decorator Metadata
1459
+
1460
+ ```typescript
1461
+ const HANDLER_KEY = "app:handler";
1462
+
1463
+ function Handler(name: string): MethodDecorator {
1464
+ return (_, __, descriptor) => {
1465
+ Reflect.defineMetadata(HANDLER_KEY, name, descriptor.value);
1466
+ };
1467
+ }
1468
+ ```
1469
+
1470
+ Use this when methods declare intent and another loader executes it later.
1471
+
1472
+ ## Practical Review Checklist
1473
+
1474
+ - Can a teammate understand the public API without reading private helpers?
1475
+ - Does the type design represent real runtime rules?
1476
+ - Are names domain-specific enough to explain intent?
1477
+ - Is the pattern solving current duplication or variability?
1478
+ - Are validation, transformation, persistence, and transport concerns separated?
1479
+ - Are tests focused on behavior that the abstraction promises to preserve?