@joktec/skills 0.1.4 → 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.
- package/README.md +4 -2
- package/dist/claude/skills/advanced-typescript-design/SKILL.md +60 -0
- package/dist/claude/skills/advanced-typescript-design/agents/openai.yaml +4 -0
- package/dist/claude/skills/advanced-typescript-design/references/advanced.md +219 -0
- package/dist/claude/skills/advanced-typescript-design/references/simple.md +149 -0
- package/dist/claude/skills/joktec-mongo-skill/SKILL.md +9 -2
- package/dist/claude/skills/joktec-mongo-skill/references/repository.md +14 -11
- package/dist/claude/skills/joktec-mongo-skill/references/schema-and-plugins.md +43 -7
- package/dist/claude/skills/joktec-mysql-skill/SKILL.md +5 -2
- package/dist/claude/skills/joktec-mysql-skill/references/entities.md +59 -51
- package/dist/claude/skills/joktec-mysql-skill/references/repository.md +15 -1
- package/dist/claude/skills/joktec-tool-skill/references/tools.md +1 -0
- package/dist/codex/skills/advanced-typescript-design/SKILL.md +60 -0
- package/dist/codex/skills/advanced-typescript-design/agents/openai.yaml +4 -0
- package/dist/codex/skills/advanced-typescript-design/references/advanced.md +219 -0
- package/dist/codex/skills/advanced-typescript-design/references/simple.md +149 -0
- package/dist/codex/skills/joktec-mongo-skill/SKILL.md +9 -2
- package/dist/codex/skills/joktec-mongo-skill/references/repository.md +14 -11
- package/dist/codex/skills/joktec-mongo-skill/references/schema-and-plugins.md +43 -7
- package/dist/codex/skills/joktec-mysql-skill/SKILL.md +5 -2
- package/dist/codex/skills/joktec-mysql-skill/references/entities.md +59 -51
- package/dist/codex/skills/joktec-mysql-skill/references/repository.md +15 -1
- package/dist/codex/skills/joktec-tool-skill/references/tools.md +1 -0
- package/dist/copilot/.github/copilot-instructions.md +577 -71
- package/dist/cursor/.cursor/rules/advanced-typescript-design.mdc +437 -0
- package/dist/cursor/.cursor/rules/joktec-mongo-skill.mdc +66 -20
- package/dist/cursor/.cursor/rules/joktec-mysql-skill.mdc +79 -54
- package/dist/cursor/.cursor/rules/joktec-tool-skill.mdc +1 -0
- package/dist/gemini/GEMINI.md +579 -71
- package/dist/windsurf/.windsurf/rules/advanced-typescript-design.md +433 -0
- package/dist/windsurf/.windsurf/rules/joktec-mongo-skill.md +66 -20
- package/dist/windsurf/.windsurf/rules/joktec-mysql-skill.md +79 -54
- package/dist/windsurf/.windsurf/rules/joktec-tool-skill.md +1 -0
- package/package.json +6 -3
- package/scripts/sync-pack-version.mjs +38 -0
- package/skill-pack.json +35 -1
- package/skills/advanced-typescript-design/SKILL.md +60 -0
- package/skills/advanced-typescript-design/agents/openai.yaml +4 -0
- package/skills/advanced-typescript-design/references/advanced.md +219 -0
- package/skills/advanced-typescript-design/references/simple.md +149 -0
- package/skills/joktec-mongo-skill/SKILL.md +9 -2
- package/skills/joktec-mongo-skill/references/repository.md +14 -11
- package/skills/joktec-mongo-skill/references/schema-and-plugins.md +43 -7
- package/skills/joktec-mysql-skill/SKILL.md +5 -2
- package/skills/joktec-mysql-skill/references/entities.md +59 -51
- package/skills/joktec-mysql-skill/references/repository.md +15 -1
- package/skills/joktec-tool-skill/references/tools.md +1 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Simple TypeScript Design Guidance
|
|
2
|
+
|
|
3
|
+
Use this reference for ordinary application and library work where readability, stable APIs, and maintainable TypeScript matter more than type-level cleverness.
|
|
4
|
+
|
|
5
|
+
## Default Practices
|
|
6
|
+
|
|
7
|
+
- Prefer explicit, small interfaces for public boundaries and concrete classes for runtime behavior with lifecycle, dependency injection, or decorators.
|
|
8
|
+
- Use `type` for unions, mapped shapes, conditional aliases, and composition. Use `interface` for object contracts intended to be implemented or extended.
|
|
9
|
+
- Keep primitive aliases meaningful. A `UserId` alias can clarify intent, but it does not add runtime safety unless paired with validation or branding.
|
|
10
|
+
- Model data with plain objects when behavior is absent. Add classes when construction, methods, inheritance hooks, decorators, or framework reflection are required.
|
|
11
|
+
- Keep DTOs, entities, requests, and responses separate when they have different validation, persistence, or transport concerns.
|
|
12
|
+
- Avoid `any` at public boundaries. Use `unknown` for untrusted data, then narrow or validate it.
|
|
13
|
+
- Prefer narrow generic constraints such as `T extends Entity` over unconstrained `T` when the implementation depends on object semantics.
|
|
14
|
+
|
|
15
|
+
## Classes, Interfaces, and OOP
|
|
16
|
+
|
|
17
|
+
- Use abstract classes for shared runtime behavior, protected hooks, and constructor-injected dependencies.
|
|
18
|
+
- Use interfaces for contracts that should not carry runtime behavior.
|
|
19
|
+
- Prefer composition over inheritance when variants differ by collaborator rather than lifecycle.
|
|
20
|
+
- Keep protected hooks purposeful: `afterInit`, `transform`, `validate`, and `map` are good when subclasses are expected to customize one stable step.
|
|
21
|
+
- Avoid deep inheritance chains. If a third level appears, consider Strategy, Adapter, or composition.
|
|
22
|
+
|
|
23
|
+
## Common Data Structures
|
|
24
|
+
|
|
25
|
+
- Use `Record<K, V>` when the key set is known or constrained.
|
|
26
|
+
- Use `{ [key: string]: V }` when the object is truly open-ended.
|
|
27
|
+
- Use `Map<K, V>` when keys are not strings, insertion order matters, or frequent add/remove operations are central.
|
|
28
|
+
- Use arrays for ordered collections and tuples for fixed positional contracts.
|
|
29
|
+
- Use discriminated unions for state or command variants instead of loose booleans.
|
|
30
|
+
- Keep hash-like caches private unless callers need iteration, eviction, or explicit lifecycle.
|
|
31
|
+
|
|
32
|
+
## Basic Types and Utilities
|
|
33
|
+
|
|
34
|
+
- Use union literals for finite options: status, mode, operation, direction.
|
|
35
|
+
- Use `Pick`, `Omit`, `Partial`, `Required`, `Readonly`, `Record`, `Extract`, and `Exclude` before writing custom utilities.
|
|
36
|
+
- Use `keyof` and indexed access types for property-safe APIs.
|
|
37
|
+
- Use overloads sparingly; prefer a single options object when overloads become hard to read.
|
|
38
|
+
- Keep mapped types shallow unless the data is truly nested and the API benefits from deep transformation.
|
|
39
|
+
|
|
40
|
+
## Simple Decorators
|
|
41
|
+
|
|
42
|
+
- Use decorator factories to attach framework metadata or compose existing decorators.
|
|
43
|
+
- Keep decorator options serializable and explicit where possible.
|
|
44
|
+
- Separate metadata collection from runtime execution. A decorator should usually register intent; a loader/service should execute it later.
|
|
45
|
+
- 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.
|
|
46
|
+
- Test decorators at the behavior boundary, not only by checking metadata keys.
|
|
47
|
+
|
|
48
|
+
## Pattern Choices
|
|
49
|
+
|
|
50
|
+
- Use Factory Method or simple factory functions when object creation varies by type or config.
|
|
51
|
+
- Use Builder for stepwise configuration only when partially built objects are common or order matters.
|
|
52
|
+
- Use Adapter to normalize third-party APIs behind project interfaces.
|
|
53
|
+
- Use Facade to simplify a noisy subsystem for callers.
|
|
54
|
+
- Use Decorator when behavior should wrap a method/object without changing its public contract.
|
|
55
|
+
- Use Template Method when a base class owns an algorithm and subclasses fill in specific steps.
|
|
56
|
+
- Use Strategy when an algorithm family changes independently from the caller.
|
|
57
|
+
- Use Observer or Mediator for event-style communication, but keep ownership and error handling explicit.
|
|
58
|
+
|
|
59
|
+
## Symbolic Examples
|
|
60
|
+
|
|
61
|
+
Use examples like these to reason about shape and tradeoffs. Keep final code adapted to the repository style.
|
|
62
|
+
|
|
63
|
+
### Strategy with a Narrow Interface
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
interface PriceStrategy {
|
|
67
|
+
total(items: CartItem[]): number;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
class RetailPrice implements PriceStrategy {
|
|
71
|
+
total(items: CartItem[]) {
|
|
72
|
+
return items.reduce((sum, item) => sum + item.price, 0);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
class WholesalePrice implements PriceStrategy {
|
|
77
|
+
total(items: CartItem[]) {
|
|
78
|
+
return items.reduce((sum, item) => sum + item.price * 0.9, 0);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
class CheckoutService {
|
|
83
|
+
constructor(private readonly strategy: PriceStrategy) {}
|
|
84
|
+
|
|
85
|
+
quote(items: CartItem[]) {
|
|
86
|
+
return this.strategy.total(items);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Use this when the caller should not know which algorithm is active.
|
|
92
|
+
|
|
93
|
+
### Adapter for Third-Party Boundaries
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
interface MessageBus {
|
|
97
|
+
publish(topic: string, payload: unknown): Promise<void>;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
class RabbitBusAdapter implements MessageBus {
|
|
101
|
+
constructor(private readonly rabbit: RabbitClient) {}
|
|
102
|
+
|
|
103
|
+
publish(topic: string, payload: unknown) {
|
|
104
|
+
return this.rabbit.sendToQueue(topic, JSON.stringify(payload));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Use this when external clients have noisy or unstable APIs.
|
|
110
|
+
|
|
111
|
+
### Template Method for Lifecycle Hooks
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
abstract class ManagedClient<TConfig, TClient> {
|
|
115
|
+
async connect(config: TConfig) {
|
|
116
|
+
const client = await this.create(config);
|
|
117
|
+
await this.start(client);
|
|
118
|
+
return client;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
protected abstract create(config: TConfig): Promise<TClient>;
|
|
122
|
+
protected abstract start(client: TClient): Promise<void>;
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Use this when the base class owns lifecycle order and subclasses fill the variable steps.
|
|
127
|
+
|
|
128
|
+
### Simple Decorator Metadata
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
const HANDLER_KEY = "app:handler";
|
|
132
|
+
|
|
133
|
+
function Handler(name: string): MethodDecorator {
|
|
134
|
+
return (_, __, descriptor) => {
|
|
135
|
+
Reflect.defineMetadata(HANDLER_KEY, name, descriptor.value);
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Use this when methods declare intent and another loader executes it later.
|
|
141
|
+
|
|
142
|
+
## Practical Review Checklist
|
|
143
|
+
|
|
144
|
+
- Can a teammate understand the public API without reading private helpers?
|
|
145
|
+
- Does the type design represent real runtime rules?
|
|
146
|
+
- Are names domain-specific enough to explain intent?
|
|
147
|
+
- Is the pattern solving current duplication or variability?
|
|
148
|
+
- Are validation, transformation, persistence, and transport concerns separated?
|
|
149
|
+
- Are tests focused on behavior that the abstraction promises to preserve?
|
|
@@ -17,9 +17,16 @@ Use this skill for MongoDB-backed resources that rely on JokTec's Mongoose/Typeg
|
|
|
17
17
|
- Keep schema classes, app repositories, and app-specific queries in the consumer app.
|
|
18
18
|
- Extend `MongoRepo<T, ID>` for app repositories.
|
|
19
19
|
- Preserve `conId` when the app has multiple Mongo connections.
|
|
20
|
-
- Use schema-first decorators when a schema class should be reused as a DTO source.
|
|
20
|
+
- 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.
|
|
21
|
+
- Use `RefId<T>` for stored reference id fields and `PopulatedRef<T>` for populated virtual fields.
|
|
22
|
+
- Use `@Schema({ kind: 'embedded' })` for value objects without `_id` or timestamps.
|
|
23
|
+
- Use `@Schema({ kind: 'subdocument' })` for embedded documents that need their own `_id` and timestamps.
|
|
24
|
+
- Use `@Prop({ kind: 'virtual', mode: 'getter' })` for computed getters that need expose/Swagger metadata without persistence.
|
|
25
|
+
- Use `@Prop({ ref: () => Target, foreignField, localField })` for populate-one virtuals when inferred defaults are enough.
|
|
26
|
+
- Use `@Prop({ type: () => [Target], ref: () => Target, foreignField, localField })` for populate-array virtuals.
|
|
27
|
+
- Use `@Prop({ kind: 'map', type: Object })` for map/snapshot payloads that must keep their raw shape.
|
|
21
28
|
- Treat ObjectId casting and regex behavior as safety-sensitive.
|
|
22
|
-
-
|
|
29
|
+
- For real migrations, inspect `node_modules/@joktec/mongo` first, then installed README or GitHub package docs, then GitHub source before assuming APIs.
|
|
23
30
|
|
|
24
31
|
## References
|
|
25
32
|
|
|
@@ -4,16 +4,18 @@
|
|
|
4
4
|
|
|
5
5
|
When blocked, inspect:
|
|
6
6
|
|
|
7
|
-
- `
|
|
8
|
-
- `
|
|
9
|
-
- `packages/databases/mongo
|
|
10
|
-
-
|
|
11
|
-
- `packages/databases/mongo/src/
|
|
12
|
-
- `packages/databases/mongo/src/mongo.
|
|
13
|
-
- `packages/databases/mongo/src/
|
|
14
|
-
- `packages/databases/mongo/src/
|
|
15
|
-
- `packages/databases/mongo/src/helpers/mongo.
|
|
16
|
-
- `packages/databases/mongo/src/
|
|
7
|
+
- Consumer project first: `node_modules/@joktec/mongo`.
|
|
8
|
+
- Installed docs next: `node_modules/@joktec/mongo/README.md`.
|
|
9
|
+
- GitHub docs next: `https://github.com/joktec/joktec-framework/tree/main/packages/databases/mongo`.
|
|
10
|
+
- GitHub source fallback:
|
|
11
|
+
- `packages/databases/mongo/src/index.ts`
|
|
12
|
+
- `packages/databases/mongo/src/mongo.module.ts`
|
|
13
|
+
- `packages/databases/mongo/src/mongo.service.ts`
|
|
14
|
+
- `packages/databases/mongo/src/mongo.repo.ts`
|
|
15
|
+
- `packages/databases/mongo/src/helpers/mongo.helper.ts`
|
|
16
|
+
- `packages/databases/mongo/src/helpers/mongo.pipeline.ts`
|
|
17
|
+
- `packages/databases/mongo/src/helpers/mongo.utils.ts`
|
|
18
|
+
- `packages/databases/mongo/src/models/*`
|
|
17
19
|
|
|
18
20
|
## Module Setup
|
|
19
21
|
|
|
@@ -35,7 +37,8 @@ Repository checklist:
|
|
|
35
37
|
- Keep schema-specific query helpers in the app repository, not in controllers.
|
|
36
38
|
- Use repository methods for standard reads so query parsing, soft delete, populate, and pagination stay consistent.
|
|
37
39
|
- Pass transaction/session options through read-modify-write flows when the app uses transactions.
|
|
38
|
-
-
|
|
40
|
+
- Repository read paths should return schema class instances with normalized ObjectId/string values, including populated and deep-populated values.
|
|
41
|
+
- Code that needs raw Mongoose documents should use `MongoService.getModel(...)` or Typegoose/Mongoose APIs directly.
|
|
39
42
|
|
|
40
43
|
## Query Safety
|
|
41
44
|
|
|
@@ -4,13 +4,20 @@
|
|
|
4
4
|
|
|
5
5
|
When blocked, inspect:
|
|
6
6
|
|
|
7
|
-
- `
|
|
8
|
-
- `
|
|
9
|
-
- `packages/databases/mongo
|
|
10
|
-
-
|
|
11
|
-
- `packages/databases/mongo/src/
|
|
12
|
-
- `packages/databases/mongo/src/
|
|
13
|
-
- `packages/databases/mongo/src/
|
|
7
|
+
- Consumer project first: `node_modules/@joktec/mongo`.
|
|
8
|
+
- Package docs next: `node_modules/@joktec/mongo/README.md`.
|
|
9
|
+
- GitHub docs next: `https://github.com/joktec/joktec-framework/tree/main/packages/databases/mongo`.
|
|
10
|
+
- GitHub source fallback:
|
|
11
|
+
- `packages/databases/mongo/src/decorators/schema.decorator.ts`
|
|
12
|
+
- `packages/databases/mongo/src/decorators/schema.options.ts`
|
|
13
|
+
- `packages/databases/mongo/src/decorators/prop.decorator.ts`
|
|
14
|
+
- `packages/databases/mongo/src/decorators/props/*`
|
|
15
|
+
- `packages/databases/mongo/src/models/mongo.ref.ts`
|
|
16
|
+
- `packages/databases/mongo/src/models/object-id.ts`
|
|
17
|
+
- `packages/databases/mongo/src/models/mongo.schema.ts`
|
|
18
|
+
- `packages/databases/mongo/src/plugins/paranoid.plugin.ts`
|
|
19
|
+
- `packages/databases/mongo/src/plugins/strict-reference.plugin.ts`
|
|
20
|
+
- `packages/databases/mongo/src/plugins/transform.plugin.ts`
|
|
14
21
|
|
|
15
22
|
## Schema Decorators
|
|
16
23
|
|
|
@@ -25,6 +32,35 @@ Best practice:
|
|
|
25
32
|
- Pass custom validators/transforms explicitly rather than adding hidden global behavior.
|
|
26
33
|
- Keep maps, snapshots, and dynamic objects explicit so helper conversion does not alter their shape.
|
|
27
34
|
- Keep app-level reference semantics visible; strict reference plugin checks existence, but the app still owns domain rules.
|
|
35
|
+
- Use `RefId<T>` for persisted id fields and `PopulatedRef<T>` for populated virtual instance fields.
|
|
36
|
+
- Use lazy `type` resolvers such as `type: () => User` or `type: () => [User]` when the wrapper cannot infer the runtime class.
|
|
37
|
+
- Use `@Schema({ kind: 'embedded' })` for value objects without `_id` or timestamps.
|
|
38
|
+
- Use `@Schema({ kind: 'subdocument' })` for embedded documents that need `_id` and timestamps but should not create a collection.
|
|
39
|
+
- Use `@Prop({ kind: 'virtual', mode: 'getter', comment, optional, hidden, expose, swagger })` for computed getters that only need class-transformer and Swagger metadata.
|
|
40
|
+
- Use `@Prop({ ref: () => User, foreignField, localField })` for populate-one virtuals when inferred defaults are enough.
|
|
41
|
+
- Use `@Prop({ type: () => [User], ref: () => User, foreignField, localField })` for populate-array virtuals.
|
|
42
|
+
- Use `@Prop({ kind: 'map', type: Object })` for raw maps/snapshots instead of passing `PropType.MAP` at the call site.
|
|
43
|
+
|
|
44
|
+
Common mappings:
|
|
45
|
+
|
|
46
|
+
| Use case | Preferred shape |
|
|
47
|
+
| --- | --- |
|
|
48
|
+
| Stored single reference id | `fieldId?: RefId<User>` with `@Prop({ type: ObjectId, ref: () => User })` |
|
|
49
|
+
| Stored reference id array | `fieldIds?: RefId<User>[]` with `@Prop({ type: [ObjectId], ref: () => User })` |
|
|
50
|
+
| Embedded value object | `@Schema({ kind: 'embedded' })` on the nested class |
|
|
51
|
+
| Embedded document | `@Schema({ kind: 'subdocument' })` on the nested class |
|
|
52
|
+
| Raw map/snapshot | `@Prop({ kind: 'map', type: Object })` |
|
|
53
|
+
| Populated single virtual | `field?: PopulatedRef<User>` with `@Prop({ ref: () => User, foreignField: '_id', localField: 'fieldId' })` |
|
|
54
|
+
| Populated virtual array | `fields?: PopulatedRef<User>[]` with `@Prop({ type: () => [User], ref: () => User, foreignField: '_id', localField: 'fieldIds' })` |
|
|
55
|
+
| Computed getter | `@Prop({ kind: 'virtual', mode: 'getter', comment: '...' }) get value() { ... }` |
|
|
56
|
+
|
|
57
|
+
Populate inference:
|
|
58
|
+
|
|
59
|
+
- `ref` + `localField` + `foreignField` marks the field as virtual populate.
|
|
60
|
+
- Populate-one can fallback to the same class from `ref`.
|
|
61
|
+
- Populate arrays still need `type: () => [Target]` because runtime reflection only sees `Array`.
|
|
62
|
+
- `justOne` defaults to `true` for non-array populate fields.
|
|
63
|
+
- Swagger examples default to `{}` or `[]` for populated fields unless explicitly overridden.
|
|
28
64
|
|
|
29
65
|
## Plugins
|
|
30
66
|
|
|
@@ -19,8 +19,11 @@ Use this skill for relational resources backed by JokTec's TypeORM wrapper.
|
|
|
19
19
|
- Treat `mysql`, `mariadb`, and `postgres` as the first-class dialects.
|
|
20
20
|
- Keep `sync` explicit and normally enabled only by an owner process or development bootstrap.
|
|
21
21
|
- Do not add new behavior to deprecated `MysqlFinder`; use `MysqlRepo.qb()` and `MysqlHelper` paths.
|
|
22
|
-
-
|
|
23
|
-
-
|
|
22
|
+
- Use schema-first `@Column`, `@PrimaryColumn`, and `@TimestampColumn` wrappers when an entity also acts as DTO metadata.
|
|
23
|
+
- Use `@Column({ kind: 'virtual' })` for computed getters that need expose/Swagger metadata without persistence.
|
|
24
|
+
- 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.
|
|
25
|
+
- Do not use `@joktec/mysql` for Mongo/ObjectId columns, even though TypeORM has Mongo-related APIs.
|
|
26
|
+
- 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.
|
|
24
27
|
|
|
25
28
|
## References
|
|
26
29
|
|
|
@@ -2,13 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
## Source Lookup
|
|
4
4
|
|
|
5
|
-
When blocked, inspect:
|
|
5
|
+
When blocked in a consumer project, inspect the installed package first:
|
|
6
|
+
|
|
7
|
+
- `node_modules/@joktec/mysql/README.md`
|
|
8
|
+
- `node_modules/@joktec/mysql/AGENTS.md` when published with the package
|
|
9
|
+
- `node_modules/@joktec/mysql/dist/index.d.ts`
|
|
10
|
+
- `node_modules/@joktec/mysql/dist/decorators/column.decorator.d.ts`
|
|
11
|
+
- `node_modules/@joktec/mysql/dist/decorators/columns/column.type.d.ts`
|
|
12
|
+
- `node_modules/@joktec/mysql/dist/decorators/timestamp.decorator.d.ts`
|
|
13
|
+
|
|
14
|
+
If the installed package is missing enough detail, use the GitHub package docs next:
|
|
15
|
+
|
|
16
|
+
- `https://github.com/joktec/joktec-framework/tree/main/packages/databases/mysql`
|
|
17
|
+
|
|
18
|
+
Use GitHub source only after package docs and installed types are not enough:
|
|
6
19
|
|
|
7
20
|
- `packages/databases/mysql/src/decorators/table.decorator.ts`
|
|
8
21
|
- `packages/databases/mysql/src/decorators/column.decorator.ts`
|
|
9
22
|
- `packages/databases/mysql/src/decorators/columns/column.type.ts`
|
|
10
23
|
- `packages/databases/mysql/src/decorators/columns/column.factory.ts`
|
|
11
24
|
- `packages/databases/mysql/src/decorators/columns/primary.column.ts`
|
|
25
|
+
- `packages/databases/mysql/src/decorators/columns/timestamp.column.ts`
|
|
26
|
+
- `packages/databases/mysql/src/decorators/columns/virtual.column.ts`
|
|
27
|
+
- `packages/databases/mysql/src/decorators/columns/object.column.ts`
|
|
12
28
|
- `packages/databases/mysql/src/decorators/columns/string.column.ts`
|
|
13
29
|
- `packages/databases/mysql/src/decorators/columns/number.column.ts`
|
|
14
30
|
- `packages/databases/mysql/src/decorators/columns/transform.column.ts`
|
|
@@ -16,7 +32,7 @@ When blocked, inspect:
|
|
|
16
32
|
|
|
17
33
|
## Schema-First Entity Pattern
|
|
18
34
|
|
|
19
|
-
Use `@Tables`, `@Column`, and `@
|
|
35
|
+
Use `@Tables`, `@Column`, `@PrimaryColumn`, and `@TimestampColumn` from `@joktec/mysql` when an entity should also act as the source class for mapped DTOs.
|
|
20
36
|
|
|
21
37
|
The new decorators are not thin TypeORM aliases. They are schema-first wrappers that compose:
|
|
22
38
|
|
|
@@ -25,11 +41,18 @@ The new decorators are not thin TypeORM aliases. They are schema-first wrappers
|
|
|
25
41
|
- `class-transformer` expose/exclude behavior.
|
|
26
42
|
- Swagger property metadata.
|
|
27
43
|
|
|
28
|
-
|
|
44
|
+
The wrapper can also represent virtual computed getters and nested JSON/jsonb class payloads. Do not use this package for Mongo/ObjectId columns.
|
|
45
|
+
|
|
46
|
+
Wrapper philosophy:
|
|
29
47
|
|
|
30
|
-
|
|
48
|
+
- prefer one schema declaration that carries persistence, validation, transform, and Swagger metadata
|
|
49
|
+
- use wrapper options before duplicating `@ApiProperty`, `@Expose`, `@Type`, or common validators
|
|
50
|
+
- use raw TypeORM only for advanced cases that the wrapper does not model cleanly
|
|
51
|
+
- keep storage write behavior and API documentation behavior distinct when needed
|
|
31
52
|
|
|
32
|
-
|
|
53
|
+
## Current Decorator Capabilities
|
|
54
|
+
|
|
55
|
+
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.
|
|
33
56
|
|
|
34
57
|
Common mappings:
|
|
35
58
|
|
|
@@ -38,11 +61,21 @@ Common mappings:
|
|
|
38
61
|
| `@PrimaryGeneratedColumn()` | `@PrimaryColumn('increment')` |
|
|
39
62
|
| `@PrimaryGeneratedColumn('uuid')` | `@PrimaryColumn('uuid')` |
|
|
40
63
|
| app-generated ordered UUID id | `@PrimaryColumn('uuidv7')` |
|
|
64
|
+
| `@CreateDateColumn(...)` | `@TimestampColumn('create', ...)` |
|
|
65
|
+
| `@UpdateDateColumn(...)` | `@TimestampColumn('update', ...)` |
|
|
66
|
+
| `@DeleteDateColumn(...)` | `@TimestampColumn('delete', ...)` |
|
|
67
|
+
| TypeORM `@VersionColumn(...)` | `@Column({ kind: 'version', ... })` |
|
|
68
|
+
| TypeORM `@VirtualColumn(...)` | `@Column({ kind: 'virtual', mode: 'sql', query, ... })` |
|
|
69
|
+
| TypeORM `@ViewColumn(...)` | `@Column({ kind: 'view', ... })` |
|
|
41
70
|
| `@Column(...)` | `@Column(...)` from `@joktec/mysql` |
|
|
71
|
+
| `@RelationId(...)` | `@Column({ kind: 'relation-id', relationId })` |
|
|
42
72
|
| `@IsNotEmpty()` | `@Column({ required: true })` |
|
|
43
73
|
| `@IsOptional()` | `@Column({ required: false })` or nullable TypeORM option when storage allows null |
|
|
44
74
|
| `@IsEmail()` | `@Column({ isEmail: true })` |
|
|
45
75
|
| `@IsMobilePhone()` | `@Column({ isPhone: true })` |
|
|
76
|
+
| `@IsInt()` | `@Column({ isInt: true })` or an integer column type |
|
|
77
|
+
| `@IsUUID()` | `@Column({ isUUID: true })` |
|
|
78
|
+
| `@IsObject()` | `@Column({ isObject: true })` or a JSON column |
|
|
46
79
|
| `@IsHexColor()` | `@Column({ isHexColor: true })` |
|
|
47
80
|
| `@IsUrl()` | `@Column({ isUrl: true })` |
|
|
48
81
|
| `@MinLength(n)` | `@Column({ minLength: n })` |
|
|
@@ -53,53 +86,28 @@ Common mappings:
|
|
|
53
86
|
| `@Expose({ groups })` | `@Column({ groups })` |
|
|
54
87
|
| `@Exclude({ toPlainOnly: true })` plus hidden Swagger | `@Column({ hidden: true })` |
|
|
55
88
|
| `@ApiProperty(...)` | `@Column({ swagger: ... })`, or native options such as `example`, `comment`, `deprecated`, `min`, `max`, `minLength`, `maxLength` |
|
|
89
|
+
| `@ValidateNested()` + `@Type(() => Preference)` | `@Column('jsonb', { nested: Preference })` |
|
|
90
|
+
| `@ValidateNested({ each: true })` + `@Type(() => Preference)` | `@Column('jsonb', { nested: Preference, each: true })` |
|
|
91
|
+
| `@Expose()` + `@ApiProperty(...)` on a getter | `@Column({ kind: 'virtual', ... })` |
|
|
92
|
+
| Swagger `readOnly: true` | `@Column({ immutable: true })` or TypeORM `update: false` when ORM updates must also be blocked |
|
|
93
|
+
|
|
94
|
+
## Read-Only Metadata
|
|
95
|
+
|
|
96
|
+
`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:
|
|
97
|
+
|
|
98
|
+
- `immutable` has priority over `update: false`
|
|
99
|
+
- `update: false` implies Swagger `readOnly` only when `immutable` is not set
|
|
100
|
+
- `swagger.readOnly` remains the final explicit override
|
|
101
|
+
|
|
102
|
+
Some field kinds default to API read-only because they are system-managed or computed:
|
|
56
103
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
- Move Swagger examples/descriptions/limits into wrapper options where possible.
|
|
65
|
-
- Preserve custom validators/transforms only through `decorators: [...]`.
|
|
66
|
-
- Keep database-specific options such as `type`, `length`, `nullable`, `unique`, `default`, `enum`, and `comment`.
|
|
67
|
-
- Rebuild and run entity-related tests after migration because DTO metadata and TypeORM metadata both change.
|
|
68
|
-
|
|
69
|
-
Example migration:
|
|
70
|
-
|
|
71
|
-
```ts
|
|
72
|
-
// Before
|
|
73
|
-
@Column({ type: 'varchar', length: 255 })
|
|
74
|
-
@IsEmail()
|
|
75
|
-
@IsNotEmpty()
|
|
76
|
-
@Expose()
|
|
77
|
-
@ApiProperty({ example: 'user@example.com' })
|
|
78
|
-
email!: string;
|
|
79
|
-
|
|
80
|
-
// After
|
|
81
|
-
@Column('varchar', {
|
|
82
|
-
length: 255,
|
|
83
|
-
required: true,
|
|
84
|
-
isEmail: true,
|
|
85
|
-
example: 'user@example.com',
|
|
86
|
-
})
|
|
87
|
-
email!: string;
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
For hidden fields:
|
|
91
|
-
|
|
92
|
-
```ts
|
|
93
|
-
// Before
|
|
94
|
-
@Column({ type: 'varchar', length: 255 })
|
|
95
|
-
@Exclude({ toPlainOnly: true })
|
|
96
|
-
@ApiHideProperty()
|
|
97
|
-
password!: string;
|
|
98
|
-
|
|
99
|
-
// After
|
|
100
|
-
@Column('varchar', { length: 255, hidden: true })
|
|
101
|
-
password!: string;
|
|
102
|
-
```
|
|
104
|
+
- primary keys
|
|
105
|
+
- timestamp columns
|
|
106
|
+
- version columns
|
|
107
|
+
- view columns
|
|
108
|
+
- virtual getter and SQL virtual columns
|
|
109
|
+
- relation-id columns
|
|
110
|
+
- tree level columns
|
|
103
111
|
|
|
104
112
|
## Primary Keys
|
|
105
113
|
|
|
@@ -2,7 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
## Source Lookup
|
|
4
4
|
|
|
5
|
-
When blocked, inspect:
|
|
5
|
+
When blocked in a consumer project, inspect installed package docs and types first:
|
|
6
|
+
|
|
7
|
+
- `node_modules/@joktec/mysql/README.md`
|
|
8
|
+
- `node_modules/@joktec/mysql/AGENTS.md` when published with the package
|
|
9
|
+
- `node_modules/@joktec/mysql/dist/index.d.ts`
|
|
10
|
+
- `node_modules/@joktec/mysql/dist/mysql.module.d.ts`
|
|
11
|
+
- `node_modules/@joktec/mysql/dist/mysql.service.d.ts`
|
|
12
|
+
- `node_modules/@joktec/mysql/dist/mysql.repo.d.ts`
|
|
13
|
+
- `node_modules/@joktec/mysql/dist/models/mysql.request.d.ts`
|
|
14
|
+
|
|
15
|
+
If the installed package is insufficient, read GitHub package docs next:
|
|
16
|
+
|
|
17
|
+
- `https://github.com/joktec/joktec-framework/tree/main/packages/databases/mysql`
|
|
18
|
+
|
|
19
|
+
Use GitHub source only after installed types and package docs are not enough:
|
|
6
20
|
|
|
7
21
|
- `packages/databases/mysql/README.md`
|
|
8
22
|
- `packages/databases/mysql/AGENTS.md`
|
|
@@ -19,6 +19,7 @@ Best practice:
|
|
|
19
19
|
- Use the package service for outbound HTTP so retry/proxy/metrics behavior stays centralized.
|
|
20
20
|
- Keep external endpoint URLs and credentials in runtime config.
|
|
21
21
|
- Be careful with ESM/CommonJS import changes in HTTP/Axios ecosystem packages.
|
|
22
|
+
- `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.
|
|
22
23
|
- Test request behavior with mocks unless the test is an explicit consumer integration scenario.
|
|
23
24
|
|
|
24
25
|
## File
|