@codyswann/lisa 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +867 -0
- package/all/copy-overwrite/.claude/README.md +205 -0
- package/all/copy-overwrite/.claude/agents/agent-architect.md +311 -0
- package/all/copy-overwrite/.claude/agents/codebase-analyzer.md +146 -0
- package/all/copy-overwrite/.claude/agents/codebase-locator.md +125 -0
- package/all/copy-overwrite/.claude/agents/codebase-pattern-finder.md +237 -0
- package/all/copy-overwrite/.claude/agents/git-history-analyzer.md +183 -0
- package/all/copy-overwrite/.claude/agents/hooks-expert.md +74 -0
- package/all/copy-overwrite/.claude/agents/skill-evaluator.md +246 -0
- package/all/copy-overwrite/.claude/agents/slash-command-architect.md +87 -0
- package/all/copy-overwrite/.claude/agents/web-search-researcher.md +112 -0
- package/all/copy-overwrite/.claude/commands/git/commit-and-submit-pr.md +8 -0
- package/all/copy-overwrite/.claude/commands/git/commit.md +44 -0
- package/all/copy-overwrite/.claude/commands/git/prune.md +34 -0
- package/all/copy-overwrite/.claude/commands/git/submit-pr.md +50 -0
- package/all/copy-overwrite/.claude/commands/jira/create.md +50 -0
- package/all/copy-overwrite/.claude/commands/jira/verify.md +34 -0
- package/all/copy-overwrite/.claude/commands/project/archive.md +8 -0
- package/all/copy-overwrite/.claude/commands/project/bootstrap.md +49 -0
- package/all/copy-overwrite/.claude/commands/project/complete-task.md +7 -0
- package/all/copy-overwrite/.claude/commands/project/debrief.md +65 -0
- package/all/copy-overwrite/.claude/commands/project/execute.md +94 -0
- package/all/copy-overwrite/.claude/commands/project/implement.md +42 -0
- package/all/copy-overwrite/.claude/commands/project/local-code-review.md +88 -0
- package/all/copy-overwrite/.claude/commands/project/lower-code-complexity.md +74 -0
- package/all/copy-overwrite/.claude/commands/project/plan.md +314 -0
- package/all/copy-overwrite/.claude/commands/project/research.md +248 -0
- package/all/copy-overwrite/.claude/commands/project/review.md +63 -0
- package/all/copy-overwrite/.claude/commands/project/setup.md +19 -0
- package/all/copy-overwrite/.claude/commands/project/verify.md +38 -0
- package/all/copy-overwrite/.claude/commands/pull-request/review.md +12 -0
- package/all/copy-overwrite/.claude/commands/rules/format-md.md +72 -0
- package/all/copy-overwrite/.claude/commands/sonarqube/check.md +6 -0
- package/all/copy-overwrite/.claude/commands/sonarqube/fix.md +3 -0
- package/all/copy-overwrite/.claude/hooks/README.md +301 -0
- package/all/copy-overwrite/.claude/hooks/notify-ntfy.sh +181 -0
- package/all/copy-overwrite/.claude/settings.json +41 -0
- package/all/copy-overwrite/.claude/settings.local.json.example +14 -0
- package/all/copy-overwrite/.claude/skills/coding-philosophy/SKILL.md +405 -0
- package/all/copy-overwrite/.claude/skills/coding-philosophy/references/function-structure.md +416 -0
- package/all/copy-overwrite/.claude/skills/coding-philosophy/references/immutable-patterns.md +316 -0
- package/all/copy-overwrite/.claude/skills/prompt-complexity-scorer/SKILL.md +118 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/LICENSE.txt +202 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/SKILL.md +210 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/scripts/__pycache__/quick_validate.cpython-312.pyc +0 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/scripts/init_skill.py +303 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/scripts/package_skill.py +110 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/scripts/quick_validate.py +65 -0
- package/all/copy-overwrite/CLAUDE.md +77 -0
- package/all/copy-overwrite/HUMAN.md +17 -0
- package/all/copy-overwrite/specs/.keep +0 -0
- package/all/create-only/PROJECT_RULES.md +0 -0
- package/cdk/merge/package.json +20 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +107 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/prompts.d.ts +45 -0
- package/dist/cli/prompts.d.ts.map +1 -0
- package/dist/cli/prompts.js +58 -0
- package/dist/cli/prompts.js.map +1 -0
- package/dist/core/config.d.ts +73 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +36 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +4 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/lisa.d.ts +81 -0
- package/dist/core/lisa.d.ts.map +1 -0
- package/dist/core/lisa.js +459 -0
- package/dist/core/lisa.js.map +1 -0
- package/dist/core/manifest.d.ts +58 -0
- package/dist/core/manifest.d.ts.map +1 -0
- package/dist/core/manifest.js +104 -0
- package/dist/core/manifest.js.map +1 -0
- package/dist/detection/detector.interface.d.ts +15 -0
- package/dist/detection/detector.interface.d.ts.map +1 -0
- package/dist/detection/detector.interface.js +2 -0
- package/dist/detection/detector.interface.js.map +1 -0
- package/dist/detection/detectors/cdk.d.ts +10 -0
- package/dist/detection/detectors/cdk.d.ts.map +1 -0
- package/dist/detection/detectors/cdk.js +34 -0
- package/dist/detection/detectors/cdk.js.map +1 -0
- package/dist/detection/detectors/expo.d.ts +10 -0
- package/dist/detection/detectors/expo.d.ts.map +1 -0
- package/dist/detection/detectors/expo.js +30 -0
- package/dist/detection/detectors/expo.js.map +1 -0
- package/dist/detection/detectors/nestjs.d.ts +10 -0
- package/dist/detection/detectors/nestjs.d.ts.map +1 -0
- package/dist/detection/detectors/nestjs.js +34 -0
- package/dist/detection/detectors/nestjs.js.map +1 -0
- package/dist/detection/detectors/npm-package.d.ts +13 -0
- package/dist/detection/detectors/npm-package.d.ts.map +1 -0
- package/dist/detection/detectors/npm-package.js +30 -0
- package/dist/detection/detectors/npm-package.js.map +1 -0
- package/dist/detection/detectors/typescript.d.ts +10 -0
- package/dist/detection/detectors/typescript.d.ts.map +1 -0
- package/dist/detection/detectors/typescript.js +25 -0
- package/dist/detection/detectors/typescript.js.map +1 -0
- package/dist/detection/index.d.ts +24 -0
- package/dist/detection/index.d.ts.map +1 -0
- package/dist/detection/index.js +57 -0
- package/dist/detection/index.js.map +1 -0
- package/dist/errors/index.d.ts +69 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +110 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/logging/console-logger.d.ts +12 -0
- package/dist/logging/console-logger.d.ts.map +1 -0
- package/dist/logging/console-logger.js +22 -0
- package/dist/logging/console-logger.js.map +1 -0
- package/dist/logging/index.d.ts +4 -0
- package/dist/logging/index.d.ts.map +1 -0
- package/dist/logging/index.js +3 -0
- package/dist/logging/index.js.map +1 -0
- package/dist/logging/logger.interface.d.ts +20 -0
- package/dist/logging/logger.interface.d.ts.map +1 -0
- package/dist/logging/logger.interface.js +2 -0
- package/dist/logging/logger.interface.js.map +1 -0
- package/dist/logging/silent-logger.d.ts +12 -0
- package/dist/logging/silent-logger.d.ts.map +1 -0
- package/dist/logging/silent-logger.js +21 -0
- package/dist/logging/silent-logger.js.map +1 -0
- package/dist/strategies/copy-contents.d.ts +14 -0
- package/dist/strategies/copy-contents.d.ts.map +1 -0
- package/dist/strategies/copy-contents.js +69 -0
- package/dist/strategies/copy-contents.js.map +1 -0
- package/dist/strategies/copy-overwrite.d.ts +14 -0
- package/dist/strategies/copy-overwrite.d.ts.map +1 -0
- package/dist/strategies/copy-overwrite.js +47 -0
- package/dist/strategies/copy-overwrite.js.map +1 -0
- package/dist/strategies/create-only.d.ts +13 -0
- package/dist/strategies/create-only.d.ts.map +1 -0
- package/dist/strategies/create-only.js +30 -0
- package/dist/strategies/create-only.js.map +1 -0
- package/dist/strategies/index.d.ts +31 -0
- package/dist/strategies/index.d.ts.map +1 -0
- package/dist/strategies/index.js +52 -0
- package/dist/strategies/index.js.map +1 -0
- package/dist/strategies/merge.d.ts +13 -0
- package/dist/strategies/merge.d.ts.map +1 -0
- package/dist/strategies/merge.js +60 -0
- package/dist/strategies/merge.js.map +1 -0
- package/dist/strategies/strategy.interface.d.ts +31 -0
- package/dist/strategies/strategy.interface.d.ts.map +1 -0
- package/dist/strategies/strategy.interface.js +2 -0
- package/dist/strategies/strategy.interface.js.map +1 -0
- package/dist/transaction/backup.d.ts +38 -0
- package/dist/transaction/backup.d.ts.map +1 -0
- package/dist/transaction/backup.js +97 -0
- package/dist/transaction/backup.js.map +1 -0
- package/dist/transaction/index.d.ts +4 -0
- package/dist/transaction/index.d.ts.map +1 -0
- package/dist/transaction/index.js +3 -0
- package/dist/transaction/index.js.map +1 -0
- package/dist/transaction/transaction.d.ts +34 -0
- package/dist/transaction/transaction.d.ts.map +1 -0
- package/dist/transaction/transaction.js +68 -0
- package/dist/transaction/transaction.js.map +1 -0
- package/dist/utils/file-operations.d.ts +29 -0
- package/dist/utils/file-operations.d.ts.map +1 -0
- package/dist/utils/file-operations.js +84 -0
- package/dist/utils/file-operations.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/json-utils.d.ts +22 -0
- package/dist/utils/json-utils.d.ts.map +1 -0
- package/dist/utils/json-utils.js +57 -0
- package/dist/utils/json-utils.js.map +1 -0
- package/dist/utils/path-utils.d.ts +21 -0
- package/dist/utils/path-utils.d.ts.map +1 -0
- package/dist/utils/path-utils.js +35 -0
- package/dist/utils/path-utils.js.map +1 -0
- package/eslint-plugin-code-organization/README.md +149 -0
- package/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +468 -0
- package/eslint-plugin-code-organization/index.js +23 -0
- package/eslint-plugin-code-organization/package.json +10 -0
- package/eslint-plugin-code-organization/rules/enforce-statement-order.js +157 -0
- package/expo/copy-overwrite/.claude/skills/apollo-client/SKILL.md +238 -0
- package/expo/copy-overwrite/.claude/skills/apollo-client/references/mutation-patterns.md +360 -0
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/SKILL.md +360 -0
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/atomic-levels.md +417 -0
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/folder-structure.md +257 -0
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/gluestack-mapping.md +233 -0
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/scripts/validate_atomic_structure.py +327 -0
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/SKILL.md +299 -0
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/references/examples.md +749 -0
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/references/patterns.md +318 -0
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/create_component.py +198 -0
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/validate_component.py +207 -0
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/SKILL.md +268 -0
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/common-issues.md +619 -0
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/file-extensions.md +340 -0
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/platform-api.md +276 -0
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/scripts/validate_cross_platform.py +414 -0
- package/expo/copy-overwrite/.claude/skills/directory-structure/SKILL.md +202 -0
- package/expo/copy-overwrite/.claude/skills/directory-structure/scripts/validate_structure.py +443 -0
- package/expo/copy-overwrite/.claude/skills/expo-env-config/SKILL.md +309 -0
- package/expo/copy-overwrite/.claude/skills/expo-env-config/references/validation-patterns.md +417 -0
- package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/SKILL.md +431 -0
- package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/references/official-docs.md +290 -0
- package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/scripts/generate-route.py +169 -0
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/SKILL.md +411 -0
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/color-tokens.md +343 -0
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/component-mapping.md +307 -0
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/spacing-scale.md +300 -0
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/scripts/validate_styling.py +354 -0
- package/expo/copy-overwrite/.claude/skills/local-state/SKILL.md +362 -0
- package/expo/copy-overwrite/.claude/skills/local-state/references/async-storage.md +505 -0
- package/expo/copy-overwrite/.claude/skills/local-state/references/persistence-patterns.md +711 -0
- package/expo/copy-overwrite/.claude/skills/local-state/references/reactive-variables.md +446 -0
- package/expo/copy-overwrite/.claude/skills/playwright-selectors/SKILL.md +223 -0
- package/expo/copy-overwrite/.claude/skills/testing-library/SKILL.md +319 -0
- package/expo/copy-overwrite/.claude/skills/testing-library/references/async-patterns.md +420 -0
- package/expo/copy-overwrite/.claude/skills/testing-library/references/expo-router-testing.md +556 -0
- package/expo/copy-overwrite/.claude/skills/testing-library/references/mocking-patterns.md +590 -0
- package/expo/copy-overwrite/.claude/skills/testing-library/references/query-priority.md +291 -0
- package/expo/copy-overwrite/.easignore.extra +2 -0
- package/expo/copy-overwrite/.mcp.json +33 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/README.md +234 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/plugin-index.test.js +84 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/require-memo-in-view.test.js +196 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/single-component-per-file.test.js +289 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/index.js +32 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/package.json +10 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/enforce-component-structure.js +230 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/no-return-in-view.js +91 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/require-memo-in-view.js +178 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/single-component-per-file.js +238 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/README.md +260 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/index.js +29 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/package.json +10 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-classname-outside-ui.js +51 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-direct-rn-imports.js +55 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-inline-styles.js +73 -0
- package/expo/copy-overwrite/eslint.config.mjs +560 -0
- package/expo/copy-overwrite/lighthouserc.js +194 -0
- package/expo/create-only/lighthouserc-config.json +28 -0
- package/expo/merge/package.json +132 -0
- package/lisa.sh +35 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/SKILL.md +176 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/advanced-features.md +527 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/project-patterns.md +483 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/quick-start.md +257 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/resolvers-mutations.md +413 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/types-scalars.md +513 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-rules/SKILL.md +536 -0
- package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/SKILL.md +275 -0
- package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/configuration-patterns.md +487 -0
- package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/entity-patterns.md +450 -0
- package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/observability-patterns.md +536 -0
- package/nestjs/merge/package.json +75 -0
- package/package.json +124 -0
- package/typescript/copy-contents/.husky/commit-msg +91 -0
- package/typescript/copy-contents/.husky/pre-commit +96 -0
- package/typescript/copy-contents/.husky/pre-push +211 -0
- package/typescript/copy-overwrite/.claude/hooks/format-on-edit.sh +74 -0
- package/typescript/copy-overwrite/.claude/hooks/install_pkgs.sh +59 -0
- package/typescript/copy-overwrite/.claude/hooks/lint-on-edit.sh +103 -0
- package/typescript/copy-overwrite/.claude/skills/jsdoc-best-practices/SKILL.md +388 -0
- package/typescript/copy-overwrite/.github/README.md +455 -0
- package/typescript/copy-overwrite/.github/dependabot.yml +40 -0
- package/typescript/copy-overwrite/.github/k6/BROWSER_TESTING_NOTE.md +129 -0
- package/typescript/copy-overwrite/.github/k6/INTEGRATION_GUIDE.md +354 -0
- package/typescript/copy-overwrite/.github/k6/README.md +386 -0
- package/typescript/copy-overwrite/.github/k6/SCENARIO_SELECTION_GUIDE.md +264 -0
- package/typescript/copy-overwrite/.github/k6/examples/customer-deploy-integration.yml +115 -0
- package/typescript/copy-overwrite/.github/k6/examples/data-driven-test.js +268 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/load.js +142 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/load.json +27 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/smoke.js +26 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/smoke.json +20 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/soak.js +244 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/soak.json +29 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/spike.js +180 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/spike.json +32 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/stress.js +206 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/stress.json +38 -0
- package/typescript/copy-overwrite/.github/k6/scripts/api-test.js +452 -0
- package/typescript/copy-overwrite/.github/k6/scripts/default-test.js +185 -0
- package/typescript/copy-overwrite/.github/k6/thresholds/normal.json +30 -0
- package/typescript/copy-overwrite/.github/k6/thresholds/relaxed.json +21 -0
- package/typescript/copy-overwrite/.github/k6/thresholds/strict.json +29 -0
- package/typescript/copy-overwrite/.github/workflows/build.yml +72 -0
- package/typescript/copy-overwrite/.github/workflows/ci.yml +49 -0
- package/typescript/copy-overwrite/.github/workflows/claude.yml +51 -0
- package/typescript/copy-overwrite/.github/workflows/create-github-issue-on-failure.yml +113 -0
- package/typescript/copy-overwrite/.github/workflows/create-jira-issue-on-failure.yml +195 -0
- package/typescript/copy-overwrite/.github/workflows/create-sentry-issue-on-failure.yml +267 -0
- package/typescript/copy-overwrite/.github/workflows/deploy.yml +228 -0
- package/typescript/copy-overwrite/.github/workflows/k6-load-test-README.md +230 -0
- package/typescript/copy-overwrite/.github/workflows/lighthouse.yml +68 -0
- package/typescript/copy-overwrite/.github/workflows/load-test.yml +282 -0
- package/typescript/copy-overwrite/.github/workflows/quality.yml +1737 -0
- package/typescript/copy-overwrite/.github/workflows/release.yml +1599 -0
- package/typescript/copy-overwrite/.gitleaksignore +28 -0
- package/typescript/copy-overwrite/.nvmrc +1 -0
- package/typescript/copy-overwrite/.prettierignore +23 -0
- package/typescript/copy-overwrite/.prettierrc.json +22 -0
- package/typescript/copy-overwrite/.versionrc +42 -0
- package/typescript/copy-overwrite/.yamllint +20 -0
- package/typescript/copy-overwrite/commitlint.config.js +11 -0
- package/typescript/copy-overwrite/eslint-plugin-code-organization/README.md +149 -0
- package/typescript/copy-overwrite/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +468 -0
- package/typescript/copy-overwrite/eslint-plugin-code-organization/index.js +23 -0
- package/typescript/copy-overwrite/eslint-plugin-code-organization/package.json +10 -0
- package/typescript/copy-overwrite/eslint-plugin-code-organization/rules/enforce-statement-order.js +157 -0
- package/typescript/copy-overwrite/eslint.config.mjs +390 -0
- package/typescript/copy-overwrite/eslint.ignore.config.json +57 -0
- package/typescript/copy-overwrite/eslint.thresholds.config.json +5 -0
- package/typescript/github-rulesets/base.json +106 -0
- package/typescript/merge/.claude/settings.json +28 -0
- package/typescript/merge/package.json +71 -0
|
@@ -0,0 +1,275 @@
|
|
|
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
|