@codyswann/lisa 1.47.1 → 1.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. package/all/copy-overwrite/.claude/rules/lisa.md +23 -10
  2. package/all/copy-overwrite/.claude/settings.json +10 -252
  3. package/all/deletions.json +67 -1
  4. package/cdk/copy-overwrite/.claude/settings.json +80 -0
  5. package/cdk/create-only/.github/workflows/ci.yml +1 -1
  6. package/cdk/create-only/.github/workflows/deploy.yml +1 -1
  7. package/dist/core/lisa.d.ts +14 -0
  8. package/dist/core/lisa.d.ts.map +1 -1
  9. package/dist/core/lisa.js +47 -0
  10. package/dist/core/lisa.js.map +1 -1
  11. package/expo/copy-overwrite/.claude/settings.json +80 -0
  12. package/expo/copy-overwrite/eslint.expo.ts +2 -2
  13. package/expo/create-only/.github/workflows/ci.yml +1 -1
  14. package/expo/create-only/.github/workflows/deploy.yml +1 -1
  15. package/expo/deletions.json +33 -0
  16. package/expo/package-lisa/package.lisa.json +2 -2
  17. package/nestjs/copy-overwrite/.claude/settings.json +80 -0
  18. package/nestjs/create-only/.github/workflows/ci.yml +1 -1
  19. package/nestjs/create-only/.github/workflows/deploy.yml +1 -1
  20. package/nestjs/deletions.json +8 -0
  21. package/package.json +8 -4
  22. package/rails/copy-overwrite/.claude/settings.json +80 -0
  23. package/rails/create-only/.github/workflows/ci.yml +1 -1
  24. package/rails/deletions.json +11 -1
  25. package/typescript/copy-overwrite/.claude/settings.json +13 -253
  26. package/typescript/copy-overwrite/eslint.typescript.ts +1 -1
  27. package/typescript/create-only/.github/workflows/ci.yml +1 -1
  28. package/typescript/deletions.json +12 -1
  29. package/typescript/package-lisa/package.lisa.json +1 -1
  30. package/all/copy-overwrite/.claude/agents/agent-architect.md +0 -310
  31. package/all/copy-overwrite/.claude/agents/architecture-specialist.md +0 -53
  32. package/all/copy-overwrite/.claude/agents/debug-specialist.md +0 -204
  33. package/all/copy-overwrite/.claude/agents/git-history-analyzer.md +0 -183
  34. package/all/copy-overwrite/.claude/agents/hooks-expert.md +0 -74
  35. package/all/copy-overwrite/.claude/agents/implementer.md +0 -54
  36. package/all/copy-overwrite/.claude/agents/learner.md +0 -44
  37. package/all/copy-overwrite/.claude/agents/performance-specialist.md +0 -95
  38. package/all/copy-overwrite/.claude/agents/product-specialist.md +0 -72
  39. package/all/copy-overwrite/.claude/agents/quality-specialist.md +0 -55
  40. package/all/copy-overwrite/.claude/agents/security-specialist.md +0 -58
  41. package/all/copy-overwrite/.claude/agents/skill-evaluator.md +0 -246
  42. package/all/copy-overwrite/.claude/agents/slash-command-architect.md +0 -87
  43. package/all/copy-overwrite/.claude/agents/test-specialist.md +0 -64
  44. package/all/copy-overwrite/.claude/agents/verification-specialist.md +0 -189
  45. package/all/copy-overwrite/.claude/agents/web-search-researcher.md +0 -112
  46. package/all/copy-overwrite/.claude/commands/git/commit-and-submit-pr.md +0 -7
  47. package/all/copy-overwrite/.claude/commands/git/commit-submit-pr-and-verify.md +0 -7
  48. package/all/copy-overwrite/.claude/commands/git/commit-submit-pr-deploy-and-verify.md +0 -7
  49. package/all/copy-overwrite/.claude/commands/git/commit.md +0 -7
  50. package/all/copy-overwrite/.claude/commands/git/prune.md +0 -6
  51. package/all/copy-overwrite/.claude/commands/git/submit-pr.md +0 -7
  52. package/all/copy-overwrite/.claude/commands/jira/create.md +0 -7
  53. package/all/copy-overwrite/.claude/commands/jira/sync.md +0 -7
  54. package/all/copy-overwrite/.claude/commands/jira/verify.md +0 -7
  55. package/all/copy-overwrite/.claude/commands/lisa/review-implementation.md +0 -7
  56. package/all/copy-overwrite/.claude/commands/plan/add-test-coverage.md +0 -7
  57. package/all/copy-overwrite/.claude/commands/plan/create.md +0 -6
  58. package/all/copy-overwrite/.claude/commands/plan/execute.md +0 -7
  59. package/all/copy-overwrite/.claude/commands/plan/fix-linter-error.md +0 -7
  60. package/all/copy-overwrite/.claude/commands/plan/local-code-review.md +0 -6
  61. package/all/copy-overwrite/.claude/commands/plan/lower-code-complexity.md +0 -6
  62. package/all/copy-overwrite/.claude/commands/plan/reduce-max-lines-per-function.md +0 -7
  63. package/all/copy-overwrite/.claude/commands/plan/reduce-max-lines.md +0 -7
  64. package/all/copy-overwrite/.claude/commands/pull-request/review.md +0 -7
  65. package/all/copy-overwrite/.claude/commands/security/zap-scan.md +0 -6
  66. package/all/copy-overwrite/.claude/commands/sonarqube/check.md +0 -6
  67. package/all/copy-overwrite/.claude/commands/sonarqube/fix.md +0 -6
  68. package/all/copy-overwrite/.claude/commands/tasks/load.md +0 -7
  69. package/all/copy-overwrite/.claude/commands/tasks/sync.md +0 -7
  70. package/all/copy-overwrite/.claude/hooks/check-tired-boss.sh +0 -61
  71. package/all/copy-overwrite/.claude/hooks/debug-hook.sh +0 -47
  72. package/all/copy-overwrite/.claude/hooks/enforce-plan-rules.sh +0 -15
  73. package/all/copy-overwrite/.claude/hooks/notify-ntfy.sh +0 -183
  74. package/all/copy-overwrite/.claude/hooks/setup-jira-cli.sh +0 -52
  75. package/all/copy-overwrite/.claude/hooks/sync-tasks.sh +0 -107
  76. package/all/copy-overwrite/.claude/hooks/ticket-sync-reminder.sh +0 -23
  77. package/all/copy-overwrite/.claude/hooks/track-plan-sessions.sh +0 -164
  78. package/all/copy-overwrite/.claude/hooks/verify-completion.sh +0 -77
  79. package/all/copy-overwrite/.claude/rules/coding-philosophy.md +0 -428
  80. package/all/copy-overwrite/.claude/rules/verfication.md +0 -596
  81. package/all/copy-overwrite/.claude/skills/agent-design-best-practices/SKILL.md +0 -219
  82. package/all/copy-overwrite/.claude/skills/git-commit/SKILL.md +0 -48
  83. package/all/copy-overwrite/.claude/skills/git-commit-and-submit-pr/SKILL.md +0 -8
  84. package/all/copy-overwrite/.claude/skills/git-commit-submit-pr-and-verify/SKILL.md +0 -7
  85. package/all/copy-overwrite/.claude/skills/git-commit-submit-pr-deploy-and-verify/SKILL.md +0 -7
  86. package/all/copy-overwrite/.claude/skills/git-prune/SKILL.md +0 -35
  87. package/all/copy-overwrite/.claude/skills/git-submit-pr/SKILL.md +0 -44
  88. package/all/copy-overwrite/.claude/skills/jira-create/SKILL.md +0 -41
  89. package/all/copy-overwrite/.claude/skills/jira-sync/SKILL.md +0 -63
  90. package/all/copy-overwrite/.claude/skills/jira-verify/SKILL.md +0 -29
  91. package/all/copy-overwrite/.claude/skills/lisa-review-implementation/SKILL.md +0 -209
  92. package/all/copy-overwrite/.claude/skills/plan-add-test-coverage/SKILL.md +0 -44
  93. package/all/copy-overwrite/.claude/skills/plan-execute/SKILL.md +0 -89
  94. package/all/copy-overwrite/.claude/skills/plan-fix-linter-error/SKILL.md +0 -45
  95. package/all/copy-overwrite/.claude/skills/plan-local-code-review/SKILL.md +0 -88
  96. package/all/copy-overwrite/.claude/skills/plan-lower-code-complexity/SKILL.md +0 -44
  97. package/all/copy-overwrite/.claude/skills/plan-reduce-max-lines/SKILL.md +0 -45
  98. package/all/copy-overwrite/.claude/skills/plan-reduce-max-lines-per-function/SKILL.md +0 -46
  99. package/all/copy-overwrite/.claude/skills/pull-request-review/SKILL.md +0 -68
  100. package/all/copy-overwrite/.claude/skills/security-zap-scan/SKILL.md +0 -33
  101. package/all/copy-overwrite/.claude/skills/skill-creator/LICENSE.txt +0 -202
  102. package/all/copy-overwrite/.claude/skills/skill-creator/SKILL.md +0 -210
  103. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/__pycache__/quick_validate.cpython-312.pyc +0 -0
  104. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/init_skill.py +0 -305
  105. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/package_skill.py +0 -112
  106. package/all/copy-overwrite/.claude/skills/skill-creator/scripts/quick_validate.py +0 -67
  107. package/all/copy-overwrite/.claude/skills/sonarqube-check/SKILL.md +0 -11
  108. package/all/copy-overwrite/.claude/skills/sonarqube-fix/SKILL.md +0 -8
  109. package/all/copy-overwrite/.claude/skills/tasks-load/SKILL.md +0 -88
  110. package/all/copy-overwrite/.claude/skills/tasks-sync/SKILL.md +0 -108
  111. package/eslint-plugin-code-organization/README.md +0 -149
  112. package/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +0 -473
  113. package/eslint-plugin-code-organization/index.js +0 -28
  114. package/eslint-plugin-code-organization/package.json +0 -10
  115. package/eslint-plugin-code-organization/rules/enforce-statement-order.js +0 -162
  116. package/expo/copy-overwrite/.claude/agents/ops-specialist.md +0 -124
  117. package/expo/copy-overwrite/.claude/rules/expo-verification.md +0 -261
  118. package/expo/copy-overwrite/.claude/skills/apollo-client/SKILL.md +0 -238
  119. package/expo/copy-overwrite/.claude/skills/apollo-client/references/mutation-patterns.md +0 -360
  120. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/SKILL.md +0 -360
  121. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/atomic-levels.md +0 -417
  122. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/folder-structure.md +0 -257
  123. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/gluestack-mapping.md +0 -233
  124. package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/scripts/validate_atomic_structure.py +0 -329
  125. package/expo/copy-overwrite/.claude/skills/container-view-pattern/SKILL.md +0 -299
  126. package/expo/copy-overwrite/.claude/skills/container-view-pattern/references/examples.md +0 -749
  127. package/expo/copy-overwrite/.claude/skills/container-view-pattern/references/patterns.md +0 -318
  128. package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/create_component.py +0 -200
  129. package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/validate_component.py +0 -209
  130. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/SKILL.md +0 -268
  131. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/common-issues.md +0 -619
  132. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/file-extensions.md +0 -340
  133. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/platform-api.md +0 -276
  134. package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/scripts/validate_cross_platform.py +0 -416
  135. package/expo/copy-overwrite/.claude/skills/directory-structure/SKILL.md +0 -202
  136. package/expo/copy-overwrite/.claude/skills/directory-structure/scripts/validate_structure.py +0 -445
  137. package/expo/copy-overwrite/.claude/skills/expo-env-config/SKILL.md +0 -309
  138. package/expo/copy-overwrite/.claude/skills/expo-env-config/references/validation-patterns.md +0 -417
  139. package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/SKILL.md +0 -431
  140. package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/references/official-docs.md +0 -290
  141. package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/scripts/generate-route.py +0 -171
  142. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/SKILL.md +0 -411
  143. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/color-tokens.md +0 -343
  144. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/component-mapping.md +0 -307
  145. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/spacing-scale.md +0 -300
  146. package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/scripts/validate_styling.py +0 -315
  147. package/expo/copy-overwrite/.claude/skills/local-state/SKILL.md +0 -362
  148. package/expo/copy-overwrite/.claude/skills/local-state/references/async-storage.md +0 -505
  149. package/expo/copy-overwrite/.claude/skills/local-state/references/persistence-patterns.md +0 -711
  150. package/expo/copy-overwrite/.claude/skills/local-state/references/reactive-variables.md +0 -446
  151. package/expo/copy-overwrite/.claude/skills/ops-browser-uat/SKILL.md +0 -124
  152. package/expo/copy-overwrite/.claude/skills/ops-check-logs/SKILL.md +0 -211
  153. package/expo/copy-overwrite/.claude/skills/ops-db-ops/SKILL.md +0 -119
  154. package/expo/copy-overwrite/.claude/skills/ops-deploy/SKILL.md +0 -119
  155. package/expo/copy-overwrite/.claude/skills/ops-monitor-errors/SKILL.md +0 -99
  156. package/expo/copy-overwrite/.claude/skills/ops-performance/SKILL.md +0 -165
  157. package/expo/copy-overwrite/.claude/skills/ops-run-local/SKILL.md +0 -166
  158. package/expo/copy-overwrite/.claude/skills/ops-verify-health/SKILL.md +0 -101
  159. package/expo/copy-overwrite/.claude/skills/owasp-zap/SKILL.md +0 -56
  160. package/expo/copy-overwrite/.claude/skills/playwright-selectors/SKILL.md +0 -223
  161. package/expo/copy-overwrite/.claude/skills/testing-library/SKILL.md +0 -314
  162. package/expo/copy-overwrite/.claude/skills/testing-library/references/async-patterns.md +0 -420
  163. package/expo/copy-overwrite/.claude/skills/testing-library/references/expo-router-testing.md +0 -556
  164. package/expo/copy-overwrite/.claude/skills/testing-library/references/mocking-patterns.md +0 -590
  165. package/expo/copy-overwrite/.claude/skills/testing-library/references/query-priority.md +0 -291
  166. package/expo/copy-overwrite/eslint-plugin-component-structure/README.md +0 -234
  167. package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/plugin-index.test.js +0 -89
  168. package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/require-memo-in-view.test.js +0 -201
  169. package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/single-component-per-file.test.js +0 -294
  170. package/expo/copy-overwrite/eslint-plugin-component-structure/index.js +0 -37
  171. package/expo/copy-overwrite/eslint-plugin-component-structure/package.json +0 -10
  172. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/enforce-component-structure.js +0 -235
  173. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/no-return-in-view.js +0 -96
  174. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/require-memo-in-view.js +0 -183
  175. package/expo/copy-overwrite/eslint-plugin-component-structure/rules/single-component-per-file.js +0 -243
  176. package/expo/copy-overwrite/eslint-plugin-ui-standards/README.md +0 -192
  177. package/expo/copy-overwrite/eslint-plugin-ui-standards/index.js +0 -31
  178. package/expo/copy-overwrite/eslint-plugin-ui-standards/package.json +0 -10
  179. package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-classname-outside-ui.js +0 -56
  180. package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-direct-rn-imports.js +0 -60
  181. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/SKILL.md +0 -176
  182. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/advanced-features.md +0 -527
  183. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/project-patterns.md +0 -483
  184. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/quick-start.md +0 -257
  185. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/resolvers-mutations.md +0 -413
  186. package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/types-scalars.md +0 -513
  187. package/nestjs/copy-overwrite/.claude/skills/nestjs-rules/SKILL.md +0 -536
  188. package/nestjs/copy-overwrite/.claude/skills/security-zap-scan/SKILL.md +0 -33
  189. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/SKILL.md +0 -275
  190. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/configuration-patterns.md +0 -487
  191. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/entity-patterns.md +0 -450
  192. package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/observability-patterns.md +0 -536
  193. package/rails/copy-overwrite/.claude/skills/action-controller-best-practices/SKILL.md +0 -374
  194. package/rails/copy-overwrite/.claude/skills/action-view-best-practices/SKILL.md +0 -335
  195. package/rails/copy-overwrite/.claude/skills/active-record-model-best-practices/SKILL.md +0 -166
  196. package/rails/copy-overwrite/.claude/skills/plan-add-test-coverage/SKILL.md +0 -45
  197. package/rails/copy-overwrite/.claude/skills/plan-fix-linter-error/SKILL.md +0 -45
  198. package/rails/copy-overwrite/.claude/skills/plan-lower-code-complexity/SKILL.md +0 -48
  199. package/rails/copy-overwrite/.claude/skills/plan-reduce-max-lines/SKILL.md +0 -46
  200. package/rails/copy-overwrite/.claude/skills/plan-reduce-max-lines-per-function/SKILL.md +0 -46
  201. package/typescript/copy-overwrite/.claude/hooks/format-on-edit.sh +0 -76
  202. package/typescript/copy-overwrite/.claude/hooks/install-pkgs.sh +0 -64
  203. package/typescript/copy-overwrite/.claude/hooks/lint-on-edit.sh +0 -81
  204. package/typescript/copy-overwrite/.claude/hooks/sg-scan-on-edit.sh +0 -68
  205. package/typescript/copy-overwrite/.claude/skills/jsdoc-best-practices/SKILL.md +0 -432
  206. package/typescript/copy-overwrite/eslint-plugin-code-organization/README.md +0 -149
  207. package/typescript/copy-overwrite/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +0 -473
  208. package/typescript/copy-overwrite/eslint-plugin-code-organization/index.js +0 -28
  209. package/typescript/copy-overwrite/eslint-plugin-code-organization/package.json +0 -10
  210. package/typescript/copy-overwrite/eslint-plugin-code-organization/rules/enforce-statement-order.js +0 -162
@@ -1,275 +0,0 @@
1
- ---
2
- name: typeorm-patterns
3
- description: Enforces TypeORM implementation patterns for this NestJS backend project. This skill should be used when creating or modifying TypeORM entities, repositories, database configuration, migrations, or any database-related code. It covers configuration patterns (TypeOrmModule.forRootAsync, replication, naming strategy), entity patterns (base entity, comments, indexes), and observability (X-Ray logging).
4
- ---
5
-
6
- # TypeORM Patterns
7
-
8
- ## Overview
9
-
10
- This skill enforces TypeORM implementation patterns for the NestJS backend project. It ensures consistent database configuration, entity design, repository patterns, and observability across the codebase.
11
-
12
- ## Core Requirements
13
-
14
- ### Configuration Requirements
15
-
16
- | Requirement | Details |
17
- |-------------|---------|
18
- | **Module Pattern** | `TypeOrmModule.forRootAsync()` with `dataSourceFactory` |
19
- | **Naming Strategy** | `SnakeNamingStrategy` from `typeorm-naming-strategies` |
20
- | **Synchronize** | Always `false` - migrations only, no auto-sync |
21
- | **Entity Loading** | Explicit entity exports via index.ts (esbuild compatibility) |
22
- | **Database** | PostgreSQL (local Docker, AWS Aurora Serverless v2 production) |
23
-
24
- ### Environment-Based Configuration
25
-
26
- | Environment | Connection Type | Authentication |
27
- |-------------|-----------------|----------------|
28
- | **Local** | Direct connection | Environment variables |
29
- | **Production** | Read-write replication | AWS RDS Signer (IAM) |
30
-
31
- ### Entity Requirements
32
-
33
- | Requirement | Details |
34
- |-------------|---------|
35
- | **Abstract Base** | All entities extend `TimestampedEntity` (NOT TypeORM's `BaseEntity`) |
36
- | **Primary Key** | UUID via `@PrimaryGeneratedColumn("uuid")` |
37
- | **Column Comments** | Required on all columns via `@Column({ comment: "..." })` |
38
- | **Foreign Keys** | Must be indexed via `@Index()` decorator |
39
- | **Cascade Deletes** | Use `orphanedRowAction: "delete"` on OneToMany relations |
40
-
41
- **Note**: We use `TimestampedEntity` to avoid confusion with TypeORM's built-in `BaseEntity` class which provides Active Record pattern methods. Our abstract class only provides column inheritance.
42
-
43
- ### Observability Requirements
44
-
45
- | Requirement | Details |
46
- |-------------|---------|
47
- | **Logger** | Custom `TypeOrmXRayLogger` for distributed tracing |
48
- | **Graceful Degradation** | Logger must work locally without X-Ray SDK |
49
- | **Query Tracking** | Extract query type and table name for metrics |
50
-
51
- ## Quick Reference
52
-
53
- ### Database Module Setup
54
-
55
- Use the standard NestJS `TypeOrmModule.forRootAsync()` with `dataSourceFactory` for full control:
56
-
57
- ```typescript
58
- import { Module } from "@nestjs/common";
59
- import { TypeOrmModule } from "@nestjs/typeorm";
60
- import { DataSource } from "typeorm";
61
- import { createTypeOrmOptions } from "./database.config";
62
-
63
- /**
64
- * Database module using official NestJS TypeORM integration.
65
- *
66
- * @remarks
67
- * Uses forRootAsync with dataSourceFactory for:
68
- * - Async configuration (environment-based)
69
- * - Custom DataSource initialization
70
- * - Replication support with dynamic passwords
71
- */
72
- @Module({
73
- imports: [
74
- TypeOrmModule.forRootAsync({
75
- useFactory: createTypeOrmOptions,
76
- dataSourceFactory: async (options) => {
77
- const dataSource = new DataSource(options);
78
- return dataSource.initialize();
79
- },
80
- }),
81
- ],
82
- })
83
- export class DatabaseModule {}
84
- ```
85
-
86
- ### Creating a New Entity
87
-
88
- ```typescript
89
- import { Column, Entity, Index, JoinColumn, ManyToOne, OneToMany } from "typeorm";
90
- import { TimestampedEntity } from "./timestamped.entity";
91
-
92
- /**
93
- * Represents a user in the system.
94
- *
95
- * @remarks
96
- * Users belong to organizations and can have multiple watchlists.
97
- */
98
- @Entity({ comment: "Application users with organization membership" })
99
- export class User extends TimestampedEntity {
100
- @Column({ comment: "User email address for authentication" })
101
- @Index()
102
- email: string;
103
-
104
- @Column({ comment: "User display name", nullable: true })
105
- name: string | null;
106
-
107
- @Column({ comment: "Foreign key to organization", type: "uuid" })
108
- @Index()
109
- organizationId: string;
110
-
111
- @ManyToOne(() => Organization, { onDelete: "SET NULL", nullable: true })
112
- @JoinColumn()
113
- organization: Organization;
114
-
115
- @OneToMany(() => Watchlist, w => w.user, { orphanedRowAction: "delete" })
116
- watchlists: Watchlist[];
117
- }
118
- ```
119
-
120
- **Important**: The abstract `TimestampedEntity` does NOT have an `@Entity()` decorator - only concrete child entities get this decorator.
121
-
122
- ### Adding Entity to Exports
123
-
124
- After creating any entity, add it to `src/database/entities/index.ts`:
125
-
126
- ```typescript
127
- export { User } from "./user.entity";
128
- export { Organization } from "./organization.entity";
129
- // Add new entity here
130
- ```
131
-
132
- ### Using Repository Injection
133
-
134
- With `TypeOrmModule`, use `@InjectRepository()` for standard repository access:
135
-
136
- ```typescript
137
- import { Injectable } from "@nestjs/common";
138
- import { InjectRepository } from "@nestjs/typeorm";
139
- import { Repository } from "typeorm";
140
- import { User } from "../entities/user.entity";
141
-
142
- @Injectable()
143
- export class UserService {
144
- constructor(
145
- @InjectRepository(User)
146
- private readonly userRepository: Repository<User>
147
- ) {}
148
-
149
- async findByEmail(email: string): Promise<User | null> {
150
- return this.userRepository.findOne({ where: { email } });
151
- }
152
- }
153
- ```
154
-
155
- ### Creating a Custom Repository (When Needed)
156
-
157
- Only create custom repositories when you need reusable query methods:
158
-
159
- ```typescript
160
- import { Injectable } from "@nestjs/common";
161
- import { DataSource, Repository } from "typeorm";
162
- import { User } from "../entities/user.entity";
163
-
164
- /**
165
- * Custom repository for complex User queries.
166
- */
167
- @Injectable()
168
- export class UserRepository extends Repository<User> {
169
- constructor(private readonly dataSource: DataSource) {
170
- super(User, dataSource.createEntityManager());
171
- }
172
-
173
- /**
174
- * Find users with full-text search.
175
- */
176
- async searchByName(query: string): Promise<User[]> {
177
- return this.createQueryBuilder("user")
178
- .where("user.name ILIKE :query", { query: `%${query}%` })
179
- .getMany();
180
- }
181
- }
182
- ```
183
-
184
- ### Custom Repositories in Transactions
185
-
186
- **Critical**: Class-based repositories extending `Repository<T>` do NOT work correctly inside transactions. Per [TypeORM documentation](https://typeorm.io/docs/working-with-entity-manager/custom-repository/), you must use `withRepository()`:
187
-
188
- ```typescript
189
- // WRONG - repository uses wrong EntityManager, won't be transactional
190
- async transferFunds(fromId: string, toId: string, amount: number): Promise<void> {
191
- await this.dataSource.transaction(async manager => {
192
- const from = await this.accountRepository.findOne({ where: { id: fromId } });
193
- // This query runs OUTSIDE the transaction!
194
- });
195
- }
196
-
197
- // CORRECT - use withRepository() for transactional operations
198
- async transferFunds(fromId: string, toId: string, amount: number): Promise<void> {
199
- await this.dataSource.transaction(async manager => {
200
- const accountRepo = manager.withRepository(this.accountRepository);
201
- const from = await accountRepo.findOne({ where: { id: fromId } });
202
- // This query runs INSIDE the transaction
203
- });
204
- }
205
- ```
206
-
207
- ## Read-Write Routing
208
-
209
- TypeORM automatically routes queries based on operation type when replication is configured:
210
-
211
- | Operation | Endpoint | Method Examples |
212
- |-----------|----------|-----------------|
213
- | **Read** | Slave (read replica) | `find()`, `findOne()`, `query()` with SELECT |
214
- | **Write** | Master | `save()`, `insert()`, `update()`, `delete()` |
215
-
216
- To force a specific connection:
217
-
218
- ```typescript
219
- // Force master for reads (when consistency required)
220
- await this.userRepository.manager.transaction(async manager => {
221
- const user = await manager.findOne(User, { where: { id } });
222
- // This read uses master connection
223
- });
224
-
225
- // QueryRunner for explicit control
226
- const queryRunner = dataSource.createQueryRunner("master");
227
- try {
228
- await queryRunner.query("SELECT * FROM users WHERE id = $1", [id]);
229
- } finally {
230
- await queryRunner.release();
231
- }
232
- ```
233
-
234
- ## Migration Workflow
235
-
236
- Always use the migration scripts - never modify migration files directly:
237
-
238
- ```bash
239
- # Generate migration from entity changes
240
- bun migration:generate --name=AddUserEmailIndex
241
-
242
- # Run pending migrations
243
- bun migration:run
244
-
245
- # Revert last migration
246
- bun migration:revert
247
- ```
248
-
249
- ## File Structure
250
-
251
- ```
252
- src/database/
253
- ├── database.module.ts # NestJS module with TypeOrmModule.forRootAsync
254
- ├── database.config.ts # Configuration factory
255
- ├── typeorm-xray-logger.ts # Custom X-Ray logger
256
- ├── entities/
257
- │ ├── index.ts # Explicit entity exports
258
- │ ├── timestamped.entity.ts # Abstract base entity (no @Entity decorator)
259
- │ ├── user.entity.ts
260
- │ └── ...
261
- ├── repositories/ # Only if custom repositories needed
262
- │ ├── index.ts
263
- │ ├── user.repository.ts
264
- │ └── ...
265
- └── migrations/
266
- └── {timestamp}-{name}.ts
267
- ```
268
-
269
- ## Detailed References
270
-
271
- For comprehensive implementation details, see:
272
-
273
- - **[references/configuration-patterns.md](references/configuration-patterns.md)** - TypeOrmModule setup, replication, environment configuration
274
- - **[references/entity-patterns.md](references/entity-patterns.md)** - Base entity, relationships, indexes, enums, views
275
- - **[references/observability-patterns.md](references/observability-patterns.md)** - X-Ray logger implementation with graceful degradation