@wazir-dev/cli 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/AGENTS.md +111 -0
- package/CHANGELOG.md +14 -0
- package/CONTRIBUTING.md +101 -0
- package/LICENSE +21 -0
- package/README.md +314 -0
- package/assets/composition-engine.mmd +34 -0
- package/assets/demo-script.sh +17 -0
- package/assets/logo-dark.svg +14 -0
- package/assets/logo.svg +14 -0
- package/assets/pipeline.mmd +39 -0
- package/assets/record-demo.sh +51 -0
- package/docs/README.md +51 -0
- package/docs/adapters/context-mode.md +60 -0
- package/docs/concepts/architecture.md +87 -0
- package/docs/concepts/artifact-model.md +60 -0
- package/docs/concepts/composition-engine.md +36 -0
- package/docs/concepts/indexing-and-recall.md +160 -0
- package/docs/concepts/observability.md +41 -0
- package/docs/concepts/roles-and-workflows.md +59 -0
- package/docs/concepts/terminology-policy.md +27 -0
- package/docs/getting-started/01-installation.md +78 -0
- package/docs/getting-started/02-first-run.md +102 -0
- package/docs/getting-started/03-adding-to-project.md +15 -0
- package/docs/getting-started/04-host-setup.md +15 -0
- package/docs/guides/ci-integration.md +15 -0
- package/docs/guides/creating-skills.md +15 -0
- package/docs/guides/expertise-module-authoring.md +15 -0
- package/docs/guides/hook-development.md +15 -0
- package/docs/guides/memory-and-learnings.md +34 -0
- package/docs/guides/multi-host-export.md +15 -0
- package/docs/guides/troubleshooting.md +101 -0
- package/docs/guides/writing-custom-roles.md +15 -0
- package/docs/plans/2026-03-15-cli-pipeline-integration-design.md +592 -0
- package/docs/plans/2026-03-15-cli-pipeline-integration-plan.md +598 -0
- package/docs/plans/2026-03-15-docs-enforcement-plan.md +238 -0
- package/docs/readmes/INDEX.md +99 -0
- package/docs/readmes/features/expertise/README.md +171 -0
- package/docs/readmes/features/exports/README.md +222 -0
- package/docs/readmes/features/hooks/README.md +103 -0
- package/docs/readmes/features/hooks/loop-cap-guard.md +133 -0
- package/docs/readmes/features/hooks/post-tool-capture.md +121 -0
- package/docs/readmes/features/hooks/post-tool-lint.md +130 -0
- package/docs/readmes/features/hooks/pre-compact-summary.md +122 -0
- package/docs/readmes/features/hooks/pre-tool-capture-route.md +100 -0
- package/docs/readmes/features/hooks/protected-path-write-guard.md +128 -0
- package/docs/readmes/features/hooks/session-start.md +119 -0
- package/docs/readmes/features/hooks/stop-handoff-harvest.md +125 -0
- package/docs/readmes/features/roles/README.md +157 -0
- package/docs/readmes/features/roles/clarifier.md +152 -0
- package/docs/readmes/features/roles/content-author.md +190 -0
- package/docs/readmes/features/roles/designer.md +193 -0
- package/docs/readmes/features/roles/executor.md +184 -0
- package/docs/readmes/features/roles/learner.md +210 -0
- package/docs/readmes/features/roles/planner.md +182 -0
- package/docs/readmes/features/roles/researcher.md +164 -0
- package/docs/readmes/features/roles/reviewer.md +184 -0
- package/docs/readmes/features/roles/specifier.md +162 -0
- package/docs/readmes/features/roles/verifier.md +215 -0
- package/docs/readmes/features/schemas/README.md +178 -0
- package/docs/readmes/features/skills/README.md +63 -0
- package/docs/readmes/features/skills/brainstorming.md +96 -0
- package/docs/readmes/features/skills/debugging.md +148 -0
- package/docs/readmes/features/skills/design.md +120 -0
- package/docs/readmes/features/skills/prepare-next.md +109 -0
- package/docs/readmes/features/skills/run-audit.md +159 -0
- package/docs/readmes/features/skills/scan-project.md +109 -0
- package/docs/readmes/features/skills/self-audit.md +176 -0
- package/docs/readmes/features/skills/tdd.md +137 -0
- package/docs/readmes/features/skills/using-skills.md +92 -0
- package/docs/readmes/features/skills/verification.md +120 -0
- package/docs/readmes/features/skills/writing-plans.md +104 -0
- package/docs/readmes/features/tooling/README.md +320 -0
- package/docs/readmes/features/workflows/README.md +186 -0
- package/docs/readmes/features/workflows/author.md +181 -0
- package/docs/readmes/features/workflows/clarify.md +154 -0
- package/docs/readmes/features/workflows/design-review.md +171 -0
- package/docs/readmes/features/workflows/design.md +169 -0
- package/docs/readmes/features/workflows/discover.md +162 -0
- package/docs/readmes/features/workflows/execute.md +173 -0
- package/docs/readmes/features/workflows/learn.md +167 -0
- package/docs/readmes/features/workflows/plan-review.md +165 -0
- package/docs/readmes/features/workflows/plan.md +170 -0
- package/docs/readmes/features/workflows/prepare-next.md +167 -0
- package/docs/readmes/features/workflows/review.md +169 -0
- package/docs/readmes/features/workflows/run-audit.md +191 -0
- package/docs/readmes/features/workflows/spec-challenge.md +159 -0
- package/docs/readmes/features/workflows/specify.md +160 -0
- package/docs/readmes/features/workflows/verify.md +177 -0
- package/docs/readmes/packages/README.md +50 -0
- package/docs/readmes/packages/ajv.md +117 -0
- package/docs/readmes/packages/context-mode.md +118 -0
- package/docs/readmes/packages/gray-matter.md +116 -0
- package/docs/readmes/packages/node-test.md +137 -0
- package/docs/readmes/packages/yaml.md +112 -0
- package/docs/reference/configuration-reference.md +159 -0
- package/docs/reference/expertise-index.md +52 -0
- package/docs/reference/git-flow.md +43 -0
- package/docs/reference/hooks.md +87 -0
- package/docs/reference/host-exports.md +50 -0
- package/docs/reference/launch-checklist.md +172 -0
- package/docs/reference/marketplace-listings.md +76 -0
- package/docs/reference/release-process.md +34 -0
- package/docs/reference/roles-reference.md +77 -0
- package/docs/reference/skills.md +33 -0
- package/docs/reference/templates.md +29 -0
- package/docs/reference/tooling-cli.md +94 -0
- package/docs/truth-claims.yaml +222 -0
- package/expertise/PROGRESS.md +63 -0
- package/expertise/README.md +18 -0
- package/expertise/antipatterns/PROGRESS.md +56 -0
- package/expertise/antipatterns/backend/api-design-antipatterns.md +1271 -0
- package/expertise/antipatterns/backend/auth-antipatterns.md +1195 -0
- package/expertise/antipatterns/backend/caching-antipatterns.md +622 -0
- package/expertise/antipatterns/backend/database-antipatterns.md +1038 -0
- package/expertise/antipatterns/backend/index.md +24 -0
- package/expertise/antipatterns/backend/microservices-antipatterns.md +850 -0
- package/expertise/antipatterns/code/architecture-antipatterns.md +919 -0
- package/expertise/antipatterns/code/async-antipatterns.md +622 -0
- package/expertise/antipatterns/code/code-smells.md +1186 -0
- package/expertise/antipatterns/code/dependency-antipatterns.md +1209 -0
- package/expertise/antipatterns/code/error-handling-antipatterns.md +1360 -0
- package/expertise/antipatterns/code/index.md +27 -0
- package/expertise/antipatterns/code/naming-and-abstraction.md +1118 -0
- package/expertise/antipatterns/code/state-management-antipatterns.md +1076 -0
- package/expertise/antipatterns/code/testing-antipatterns.md +1053 -0
- package/expertise/antipatterns/design/accessibility-antipatterns.md +1136 -0
- package/expertise/antipatterns/design/dark-patterns.md +1121 -0
- package/expertise/antipatterns/design/index.md +22 -0
- package/expertise/antipatterns/design/ui-antipatterns.md +1202 -0
- package/expertise/antipatterns/design/ux-antipatterns.md +680 -0
- package/expertise/antipatterns/frontend/css-layout-antipatterns.md +691 -0
- package/expertise/antipatterns/frontend/flutter-antipatterns.md +1827 -0
- package/expertise/antipatterns/frontend/index.md +23 -0
- package/expertise/antipatterns/frontend/mobile-antipatterns.md +573 -0
- package/expertise/antipatterns/frontend/react-antipatterns.md +1128 -0
- package/expertise/antipatterns/frontend/spa-antipatterns.md +1235 -0
- package/expertise/antipatterns/index.md +31 -0
- package/expertise/antipatterns/performance/index.md +20 -0
- package/expertise/antipatterns/performance/performance-antipatterns.md +1013 -0
- package/expertise/antipatterns/performance/premature-optimization.md +623 -0
- package/expertise/antipatterns/performance/scaling-antipatterns.md +785 -0
- package/expertise/antipatterns/process/ai-coding-antipatterns.md +853 -0
- package/expertise/antipatterns/process/code-review-antipatterns.md +656 -0
- package/expertise/antipatterns/process/deployment-antipatterns.md +920 -0
- package/expertise/antipatterns/process/index.md +23 -0
- package/expertise/antipatterns/process/technical-debt-antipatterns.md +647 -0
- package/expertise/antipatterns/security/index.md +20 -0
- package/expertise/antipatterns/security/secrets-antipatterns.md +849 -0
- package/expertise/antipatterns/security/security-theater.md +843 -0
- package/expertise/antipatterns/security/vulnerability-patterns.md +801 -0
- package/expertise/architecture/PROGRESS.md +70 -0
- package/expertise/architecture/data/caching-architecture.md +671 -0
- package/expertise/architecture/data/data-consistency.md +574 -0
- package/expertise/architecture/data/data-modeling.md +536 -0
- package/expertise/architecture/data/event-streams-and-queues.md +634 -0
- package/expertise/architecture/data/index.md +25 -0
- package/expertise/architecture/data/search-architecture.md +663 -0
- package/expertise/architecture/data/sql-vs-nosql.md +708 -0
- package/expertise/architecture/decisions/architecture-decision-records.md +640 -0
- package/expertise/architecture/decisions/build-vs-buy.md +616 -0
- package/expertise/architecture/decisions/index.md +23 -0
- package/expertise/architecture/decisions/monolith-to-microservices.md +790 -0
- package/expertise/architecture/decisions/technology-selection.md +616 -0
- package/expertise/architecture/distributed/cap-theorem-and-tradeoffs.md +800 -0
- package/expertise/architecture/distributed/circuit-breaker-bulkhead.md +741 -0
- package/expertise/architecture/distributed/consensus-and-coordination.md +796 -0
- package/expertise/architecture/distributed/distributed-systems-fundamentals.md +564 -0
- package/expertise/architecture/distributed/idempotency-and-retry.md +796 -0
- package/expertise/architecture/distributed/index.md +25 -0
- package/expertise/architecture/distributed/saga-pattern.md +797 -0
- package/expertise/architecture/foundations/architectural-thinking.md +460 -0
- package/expertise/architecture/foundations/coupling-and-cohesion.md +770 -0
- package/expertise/architecture/foundations/design-principles-solid.md +649 -0
- package/expertise/architecture/foundations/domain-driven-design.md +719 -0
- package/expertise/architecture/foundations/index.md +25 -0
- package/expertise/architecture/foundations/separation-of-concerns.md +472 -0
- package/expertise/architecture/foundations/twelve-factor-app.md +797 -0
- package/expertise/architecture/index.md +34 -0
- package/expertise/architecture/integration/api-design-graphql.md +638 -0
- package/expertise/architecture/integration/api-design-grpc.md +804 -0
- package/expertise/architecture/integration/api-design-rest.md +892 -0
- package/expertise/architecture/integration/index.md +25 -0
- package/expertise/architecture/integration/third-party-integration.md +795 -0
- package/expertise/architecture/integration/webhooks-and-callbacks.md +1152 -0
- package/expertise/architecture/integration/websockets-realtime.md +791 -0
- package/expertise/architecture/mobile-architecture/index.md +22 -0
- package/expertise/architecture/mobile-architecture/mobile-app-architecture.md +780 -0
- package/expertise/architecture/mobile-architecture/mobile-backend-for-frontend.md +670 -0
- package/expertise/architecture/mobile-architecture/offline-first.md +719 -0
- package/expertise/architecture/mobile-architecture/push-and-sync.md +782 -0
- package/expertise/architecture/patterns/cqrs-event-sourcing.md +717 -0
- package/expertise/architecture/patterns/event-driven.md +797 -0
- package/expertise/architecture/patterns/hexagonal-clean-architecture.md +870 -0
- package/expertise/architecture/patterns/index.md +27 -0
- package/expertise/architecture/patterns/layered-architecture.md +736 -0
- package/expertise/architecture/patterns/microservices.md +753 -0
- package/expertise/architecture/patterns/modular-monolith.md +692 -0
- package/expertise/architecture/patterns/monolith.md +626 -0
- package/expertise/architecture/patterns/plugin-architecture.md +735 -0
- package/expertise/architecture/patterns/serverless.md +780 -0
- package/expertise/architecture/scaling/database-scaling.md +615 -0
- package/expertise/architecture/scaling/feature-flags-and-rollouts.md +757 -0
- package/expertise/architecture/scaling/horizontal-vs-vertical.md +606 -0
- package/expertise/architecture/scaling/index.md +24 -0
- package/expertise/architecture/scaling/multi-tenancy.md +800 -0
- package/expertise/architecture/scaling/stateless-design.md +787 -0
- package/expertise/backend/embedded-firmware.md +625 -0
- package/expertise/backend/go.md +853 -0
- package/expertise/backend/index.md +24 -0
- package/expertise/backend/java-spring.md +448 -0
- package/expertise/backend/node-typescript.md +625 -0
- package/expertise/backend/python-fastapi.md +724 -0
- package/expertise/backend/rust.md +458 -0
- package/expertise/backend/solidity.md +711 -0
- package/expertise/composition-map.yaml +443 -0
- package/expertise/content/foundations/content-modeling.md +395 -0
- package/expertise/content/foundations/editorial-standards.md +449 -0
- package/expertise/content/foundations/index.md +24 -0
- package/expertise/content/foundations/microcopy.md +455 -0
- package/expertise/content/foundations/terminology-governance.md +509 -0
- package/expertise/content/index.md +34 -0
- package/expertise/content/patterns/accessibility-copy.md +518 -0
- package/expertise/content/patterns/index.md +24 -0
- package/expertise/content/patterns/notification-content.md +433 -0
- package/expertise/content/patterns/sample-content.md +486 -0
- package/expertise/content/patterns/state-copy.md +439 -0
- package/expertise/design/PROGRESS.md +58 -0
- package/expertise/design/disciplines/dark-mode-theming.md +577 -0
- package/expertise/design/disciplines/design-systems.md +595 -0
- package/expertise/design/disciplines/index.md +25 -0
- package/expertise/design/disciplines/information-architecture.md +800 -0
- package/expertise/design/disciplines/interaction-design.md +788 -0
- package/expertise/design/disciplines/responsive-design.md +552 -0
- package/expertise/design/disciplines/usability-testing.md +516 -0
- package/expertise/design/disciplines/user-research.md +792 -0
- package/expertise/design/foundations/accessibility-design.md +796 -0
- package/expertise/design/foundations/color-theory.md +797 -0
- package/expertise/design/foundations/iconography.md +795 -0
- package/expertise/design/foundations/index.md +26 -0
- package/expertise/design/foundations/motion-and-animation.md +653 -0
- package/expertise/design/foundations/rtl-design.md +585 -0
- package/expertise/design/foundations/spacing-and-layout.md +607 -0
- package/expertise/design/foundations/typography.md +800 -0
- package/expertise/design/foundations/visual-hierarchy.md +761 -0
- package/expertise/design/index.md +32 -0
- package/expertise/design/patterns/authentication-flows.md +474 -0
- package/expertise/design/patterns/content-consumption.md +789 -0
- package/expertise/design/patterns/data-display.md +618 -0
- package/expertise/design/patterns/e-commerce.md +1494 -0
- package/expertise/design/patterns/feedback-and-states.md +642 -0
- package/expertise/design/patterns/forms-and-input.md +819 -0
- package/expertise/design/patterns/gamification.md +801 -0
- package/expertise/design/patterns/index.md +31 -0
- package/expertise/design/patterns/microinteractions.md +449 -0
- package/expertise/design/patterns/navigation.md +800 -0
- package/expertise/design/patterns/notifications.md +705 -0
- package/expertise/design/patterns/onboarding.md +700 -0
- package/expertise/design/patterns/search-and-filter.md +601 -0
- package/expertise/design/patterns/settings-and-preferences.md +768 -0
- package/expertise/design/patterns/social-and-community.md +748 -0
- package/expertise/design/platforms/desktop-native.md +612 -0
- package/expertise/design/platforms/index.md +25 -0
- package/expertise/design/platforms/mobile-android.md +825 -0
- package/expertise/design/platforms/mobile-cross-platform.md +983 -0
- package/expertise/design/platforms/mobile-ios.md +699 -0
- package/expertise/design/platforms/tablet.md +794 -0
- package/expertise/design/platforms/web-dashboard.md +790 -0
- package/expertise/design/platforms/web-responsive.md +550 -0
- package/expertise/design/psychology/behavioral-nudges.md +449 -0
- package/expertise/design/psychology/cognitive-load.md +1191 -0
- package/expertise/design/psychology/error-psychology.md +778 -0
- package/expertise/design/psychology/index.md +22 -0
- package/expertise/design/psychology/persuasive-design.md +736 -0
- package/expertise/design/psychology/user-mental-models.md +623 -0
- package/expertise/design/tooling/open-pencil.md +266 -0
- package/expertise/frontend/angular.md +1073 -0
- package/expertise/frontend/desktop-electron.md +546 -0
- package/expertise/frontend/flutter.md +782 -0
- package/expertise/frontend/index.md +27 -0
- package/expertise/frontend/native-android.md +409 -0
- package/expertise/frontend/native-ios.md +490 -0
- package/expertise/frontend/react-native.md +1160 -0
- package/expertise/frontend/react.md +808 -0
- package/expertise/frontend/vue.md +1089 -0
- package/expertise/humanize/domain-rules-code.md +79 -0
- package/expertise/humanize/domain-rules-content.md +67 -0
- package/expertise/humanize/domain-rules-technical-docs.md +56 -0
- package/expertise/humanize/index.md +35 -0
- package/expertise/humanize/self-audit-checklist.md +87 -0
- package/expertise/humanize/sentence-patterns.md +218 -0
- package/expertise/humanize/vocabulary-blacklist.md +105 -0
- package/expertise/i18n/PROGRESS.md +65 -0
- package/expertise/i18n/advanced/accessibility-and-i18n.md +28 -0
- package/expertise/i18n/advanced/bidirectional-text-algorithm.md +38 -0
- package/expertise/i18n/advanced/complex-scripts.md +30 -0
- package/expertise/i18n/advanced/performance-and-i18n.md +27 -0
- package/expertise/i18n/advanced/testing-i18n.md +28 -0
- package/expertise/i18n/content/content-adaptation.md +23 -0
- package/expertise/i18n/content/locale-specific-formatting.md +23 -0
- package/expertise/i18n/content/machine-translation-integration.md +28 -0
- package/expertise/i18n/content/translation-management.md +29 -0
- package/expertise/i18n/foundations/date-time-calendars.md +67 -0
- package/expertise/i18n/foundations/i18n-architecture.md +272 -0
- package/expertise/i18n/foundations/locale-and-language-tags.md +79 -0
- package/expertise/i18n/foundations/numbers-currency-units.md +61 -0
- package/expertise/i18n/foundations/pluralization-and-gender.md +109 -0
- package/expertise/i18n/foundations/string-externalization.md +236 -0
- package/expertise/i18n/foundations/text-direction-bidi.md +241 -0
- package/expertise/i18n/foundations/unicode-and-encoding.md +86 -0
- package/expertise/i18n/index.md +38 -0
- package/expertise/i18n/platform/backend-i18n.md +31 -0
- package/expertise/i18n/platform/flutter-i18n.md +148 -0
- package/expertise/i18n/platform/native-android-i18n.md +36 -0
- package/expertise/i18n/platform/native-ios-i18n.md +36 -0
- package/expertise/i18n/platform/react-i18n.md +103 -0
- package/expertise/i18n/platform/web-css-i18n.md +81 -0
- package/expertise/i18n/rtl/arabic-specific.md +175 -0
- package/expertise/i18n/rtl/hebrew-specific.md +149 -0
- package/expertise/i18n/rtl/rtl-animations-and-transitions.md +111 -0
- package/expertise/i18n/rtl/rtl-forms-and-input.md +161 -0
- package/expertise/i18n/rtl/rtl-fundamentals.md +211 -0
- package/expertise/i18n/rtl/rtl-icons-and-images.md +181 -0
- package/expertise/i18n/rtl/rtl-layout-mirroring.md +252 -0
- package/expertise/i18n/rtl/rtl-navigation-and-gestures.md +107 -0
- package/expertise/i18n/rtl/rtl-testing-and-qa.md +147 -0
- package/expertise/i18n/rtl/rtl-typography.md +160 -0
- package/expertise/index.md +113 -0
- package/expertise/index.yaml +216 -0
- package/expertise/infrastructure/cloud-aws.md +597 -0
- package/expertise/infrastructure/cloud-gcp.md +599 -0
- package/expertise/infrastructure/cybersecurity.md +816 -0
- package/expertise/infrastructure/database-mongodb.md +447 -0
- package/expertise/infrastructure/database-postgres.md +400 -0
- package/expertise/infrastructure/devops-cicd.md +787 -0
- package/expertise/infrastructure/index.md +27 -0
- package/expertise/performance/PROGRESS.md +50 -0
- package/expertise/performance/backend/api-latency.md +1204 -0
- package/expertise/performance/backend/background-jobs.md +506 -0
- package/expertise/performance/backend/connection-pooling.md +1209 -0
- package/expertise/performance/backend/database-query-optimization.md +515 -0
- package/expertise/performance/backend/index.md +23 -0
- package/expertise/performance/backend/rate-limiting-and-throttling.md +971 -0
- package/expertise/performance/foundations/algorithmic-complexity.md +954 -0
- package/expertise/performance/foundations/caching-strategies.md +489 -0
- package/expertise/performance/foundations/concurrency-and-parallelism.md +847 -0
- package/expertise/performance/foundations/index.md +24 -0
- package/expertise/performance/foundations/measuring-and-profiling.md +440 -0
- package/expertise/performance/foundations/memory-management.md +964 -0
- package/expertise/performance/foundations/performance-budgets.md +1314 -0
- package/expertise/performance/index.md +31 -0
- package/expertise/performance/infrastructure/auto-scaling.md +1059 -0
- package/expertise/performance/infrastructure/cdn-and-edge.md +1081 -0
- package/expertise/performance/infrastructure/index.md +22 -0
- package/expertise/performance/infrastructure/load-balancing.md +1081 -0
- package/expertise/performance/infrastructure/observability.md +1079 -0
- package/expertise/performance/mobile/index.md +23 -0
- package/expertise/performance/mobile/mobile-animations.md +544 -0
- package/expertise/performance/mobile/mobile-memory-battery.md +416 -0
- package/expertise/performance/mobile/mobile-network.md +452 -0
- package/expertise/performance/mobile/mobile-rendering.md +599 -0
- package/expertise/performance/mobile/mobile-startup-time.md +505 -0
- package/expertise/performance/platform-specific/flutter-performance.md +647 -0
- package/expertise/performance/platform-specific/index.md +22 -0
- package/expertise/performance/platform-specific/node-performance.md +1307 -0
- package/expertise/performance/platform-specific/postgres-performance.md +1366 -0
- package/expertise/performance/platform-specific/react-performance.md +1403 -0
- package/expertise/performance/web/bundle-optimization.md +1239 -0
- package/expertise/performance/web/image-and-media.md +636 -0
- package/expertise/performance/web/index.md +24 -0
- package/expertise/performance/web/network-optimization.md +1133 -0
- package/expertise/performance/web/rendering-performance.md +1098 -0
- package/expertise/performance/web/ssr-and-hydration.md +918 -0
- package/expertise/performance/web/web-vitals.md +1374 -0
- package/expertise/quality/accessibility.md +985 -0
- package/expertise/quality/evidence-based-verification.md +499 -0
- package/expertise/quality/index.md +24 -0
- package/expertise/quality/ml-model-audit.md +614 -0
- package/expertise/quality/performance.md +600 -0
- package/expertise/quality/testing-api.md +891 -0
- package/expertise/quality/testing-mobile.md +496 -0
- package/expertise/quality/testing-web.md +849 -0
- package/expertise/security/PROGRESS.md +54 -0
- package/expertise/security/agentic-identity.md +540 -0
- package/expertise/security/compliance-frameworks.md +601 -0
- package/expertise/security/data/data-encryption.md +364 -0
- package/expertise/security/data/data-privacy-gdpr.md +692 -0
- package/expertise/security/data/database-security.md +1171 -0
- package/expertise/security/data/index.md +22 -0
- package/expertise/security/data/pii-handling.md +531 -0
- package/expertise/security/foundations/authentication.md +1041 -0
- package/expertise/security/foundations/authorization.md +603 -0
- package/expertise/security/foundations/cryptography.md +1001 -0
- package/expertise/security/foundations/index.md +25 -0
- package/expertise/security/foundations/owasp-top-10.md +1354 -0
- package/expertise/security/foundations/secrets-management.md +1217 -0
- package/expertise/security/foundations/secure-sdlc.md +700 -0
- package/expertise/security/foundations/supply-chain-security.md +698 -0
- package/expertise/security/index.md +31 -0
- package/expertise/security/infrastructure/cloud-security-aws.md +1296 -0
- package/expertise/security/infrastructure/cloud-security-gcp.md +1376 -0
- package/expertise/security/infrastructure/container-security.md +721 -0
- package/expertise/security/infrastructure/incident-response.md +1295 -0
- package/expertise/security/infrastructure/index.md +24 -0
- package/expertise/security/infrastructure/logging-and-monitoring.md +1618 -0
- package/expertise/security/infrastructure/network-security.md +1337 -0
- package/expertise/security/mobile/index.md +23 -0
- package/expertise/security/mobile/mobile-android-security.md +1218 -0
- package/expertise/security/mobile/mobile-binary-protection.md +1229 -0
- package/expertise/security/mobile/mobile-data-storage.md +1265 -0
- package/expertise/security/mobile/mobile-ios-security.md +1401 -0
- package/expertise/security/mobile/mobile-network-security.md +1520 -0
- package/expertise/security/smart-contract-security.md +594 -0
- package/expertise/security/testing/index.md +22 -0
- package/expertise/security/testing/penetration-testing.md +1258 -0
- package/expertise/security/testing/security-code-review.md +1765 -0
- package/expertise/security/testing/threat-modeling.md +1074 -0
- package/expertise/security/testing/vulnerability-scanning.md +1062 -0
- package/expertise/security/web/api-security.md +586 -0
- package/expertise/security/web/cors-and-headers.md +433 -0
- package/expertise/security/web/csrf.md +562 -0
- package/expertise/security/web/file-upload.md +1477 -0
- package/expertise/security/web/index.md +25 -0
- package/expertise/security/web/injection.md +1375 -0
- package/expertise/security/web/session-management.md +1101 -0
- package/expertise/security/web/xss.md +1158 -0
- package/exports/README.md +17 -0
- package/exports/hosts/claude/.claude/agents/clarifier.md +42 -0
- package/exports/hosts/claude/.claude/agents/content-author.md +63 -0
- package/exports/hosts/claude/.claude/agents/designer.md +55 -0
- package/exports/hosts/claude/.claude/agents/executor.md +55 -0
- package/exports/hosts/claude/.claude/agents/learner.md +51 -0
- package/exports/hosts/claude/.claude/agents/planner.md +53 -0
- package/exports/hosts/claude/.claude/agents/researcher.md +43 -0
- package/exports/hosts/claude/.claude/agents/reviewer.md +54 -0
- package/exports/hosts/claude/.claude/agents/specifier.md +47 -0
- package/exports/hosts/claude/.claude/agents/verifier.md +71 -0
- package/exports/hosts/claude/.claude/commands/author.md +42 -0
- package/exports/hosts/claude/.claude/commands/clarify.md +38 -0
- package/exports/hosts/claude/.claude/commands/design-review.md +46 -0
- package/exports/hosts/claude/.claude/commands/design.md +44 -0
- package/exports/hosts/claude/.claude/commands/discover.md +37 -0
- package/exports/hosts/claude/.claude/commands/execute.md +48 -0
- package/exports/hosts/claude/.claude/commands/learn.md +38 -0
- package/exports/hosts/claude/.claude/commands/plan-review.md +42 -0
- package/exports/hosts/claude/.claude/commands/plan.md +39 -0
- package/exports/hosts/claude/.claude/commands/prepare-next.md +37 -0
- package/exports/hosts/claude/.claude/commands/review.md +40 -0
- package/exports/hosts/claude/.claude/commands/run-audit.md +41 -0
- package/exports/hosts/claude/.claude/commands/spec-challenge.md +41 -0
- package/exports/hosts/claude/.claude/commands/specify.md +38 -0
- package/exports/hosts/claude/.claude/commands/verify.md +37 -0
- package/exports/hosts/claude/.claude/settings.json +34 -0
- package/exports/hosts/claude/CLAUDE.md +19 -0
- package/exports/hosts/claude/export.manifest.json +38 -0
- package/exports/hosts/claude/host-package.json +67 -0
- package/exports/hosts/codex/AGENTS.md +19 -0
- package/exports/hosts/codex/export.manifest.json +38 -0
- package/exports/hosts/codex/host-package.json +41 -0
- package/exports/hosts/cursor/.cursor/hooks.json +16 -0
- package/exports/hosts/cursor/.cursor/rules/wazir-core.mdc +19 -0
- package/exports/hosts/cursor/export.manifest.json +38 -0
- package/exports/hosts/cursor/host-package.json +42 -0
- package/exports/hosts/gemini/GEMINI.md +19 -0
- package/exports/hosts/gemini/export.manifest.json +38 -0
- package/exports/hosts/gemini/host-package.json +41 -0
- package/hooks/README.md +18 -0
- package/hooks/definitions/loop_cap_guard.yaml +21 -0
- package/hooks/definitions/post_tool_capture.yaml +24 -0
- package/hooks/definitions/pre_compact_summary.yaml +19 -0
- package/hooks/definitions/pre_tool_capture_route.yaml +19 -0
- package/hooks/definitions/protected_path_write_guard.yaml +19 -0
- package/hooks/definitions/session_start.yaml +19 -0
- package/hooks/definitions/stop_handoff_harvest.yaml +20 -0
- package/hooks/loop-cap-guard +17 -0
- package/hooks/post-tool-lint +36 -0
- package/hooks/protected-path-write-guard +17 -0
- package/hooks/session-start +41 -0
- package/llms-full.txt +2355 -0
- package/llms.txt +43 -0
- package/package.json +79 -0
- package/roles/README.md +20 -0
- package/roles/clarifier.md +42 -0
- package/roles/content-author.md +63 -0
- package/roles/designer.md +55 -0
- package/roles/executor.md +55 -0
- package/roles/learner.md +51 -0
- package/roles/planner.md +53 -0
- package/roles/researcher.md +43 -0
- package/roles/reviewer.md +54 -0
- package/roles/specifier.md +47 -0
- package/roles/verifier.md +71 -0
- package/schemas/README.md +24 -0
- package/schemas/accepted-learning.schema.json +20 -0
- package/schemas/author-artifact.schema.json +156 -0
- package/schemas/clarification.schema.json +19 -0
- package/schemas/design-artifact.schema.json +80 -0
- package/schemas/docs-claim.schema.json +18 -0
- package/schemas/export-manifest.schema.json +20 -0
- package/schemas/hook.schema.json +67 -0
- package/schemas/host-export-package.schema.json +18 -0
- package/schemas/implementation-plan.schema.json +19 -0
- package/schemas/proposed-learning.schema.json +19 -0
- package/schemas/research.schema.json +18 -0
- package/schemas/review.schema.json +29 -0
- package/schemas/run-manifest.schema.json +18 -0
- package/schemas/spec-challenge.schema.json +18 -0
- package/schemas/spec.schema.json +20 -0
- package/schemas/usage.schema.json +102 -0
- package/schemas/verification-proof.schema.json +29 -0
- package/schemas/wazir-manifest.schema.json +173 -0
- package/skills/README.md +40 -0
- package/skills/brainstorming/SKILL.md +77 -0
- package/skills/debugging/SKILL.md +50 -0
- package/skills/design/SKILL.md +61 -0
- package/skills/dispatching-parallel-agents/SKILL.md +128 -0
- package/skills/executing-plans/SKILL.md +70 -0
- package/skills/finishing-a-development-branch/SKILL.md +169 -0
- package/skills/humanize/SKILL.md +123 -0
- package/skills/init-pipeline/SKILL.md +124 -0
- package/skills/prepare-next/SKILL.md +20 -0
- package/skills/receiving-code-review/SKILL.md +123 -0
- package/skills/requesting-code-review/SKILL.md +105 -0
- package/skills/requesting-code-review/code-reviewer.md +108 -0
- package/skills/run-audit/SKILL.md +197 -0
- package/skills/scan-project/SKILL.md +41 -0
- package/skills/self-audit/SKILL.md +153 -0
- package/skills/subagent-driven-development/SKILL.md +154 -0
- package/skills/subagent-driven-development/code-quality-reviewer-prompt.md +26 -0
- package/skills/subagent-driven-development/implementer-prompt.md +102 -0
- package/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -0
- package/skills/tdd/SKILL.md +23 -0
- package/skills/using-git-worktrees/SKILL.md +163 -0
- package/skills/using-skills/SKILL.md +95 -0
- package/skills/verification/SKILL.md +22 -0
- package/skills/wazir/SKILL.md +463 -0
- package/skills/writing-plans/SKILL.md +30 -0
- package/skills/writing-skills/SKILL.md +157 -0
- package/skills/writing-skills/anthropic-best-practices.md +122 -0
- package/skills/writing-skills/persuasion-principles.md +50 -0
- package/templates/README.md +20 -0
- package/templates/artifacts/README.md +10 -0
- package/templates/artifacts/accepted-learning.md +19 -0
- package/templates/artifacts/accepted-learning.template.json +12 -0
- package/templates/artifacts/author.md +74 -0
- package/templates/artifacts/author.template.json +19 -0
- package/templates/artifacts/clarification.md +21 -0
- package/templates/artifacts/clarification.template.json +12 -0
- package/templates/artifacts/execute-notes.md +19 -0
- package/templates/artifacts/implementation-plan.md +21 -0
- package/templates/artifacts/implementation-plan.template.json +11 -0
- package/templates/artifacts/learning-proposal.md +19 -0
- package/templates/artifacts/next-run-handoff.md +21 -0
- package/templates/artifacts/plan-review.md +19 -0
- package/templates/artifacts/proposed-learning.template.json +12 -0
- package/templates/artifacts/research.md +21 -0
- package/templates/artifacts/research.template.json +12 -0
- package/templates/artifacts/review-findings.md +19 -0
- package/templates/artifacts/review.template.json +11 -0
- package/templates/artifacts/run-manifest.template.json +8 -0
- package/templates/artifacts/spec-challenge.md +19 -0
- package/templates/artifacts/spec-challenge.template.json +11 -0
- package/templates/artifacts/spec.md +21 -0
- package/templates/artifacts/spec.template.json +12 -0
- package/templates/artifacts/verification-proof.md +19 -0
- package/templates/artifacts/verification-proof.template.json +11 -0
- package/templates/examples/accepted-learning.example.json +14 -0
- package/templates/examples/author.example.json +152 -0
- package/templates/examples/clarification.example.json +15 -0
- package/templates/examples/docs-claim.example.json +8 -0
- package/templates/examples/export-manifest.example.json +7 -0
- package/templates/examples/host-export-package.example.json +11 -0
- package/templates/examples/implementation-plan.example.json +17 -0
- package/templates/examples/proposed-learning.example.json +13 -0
- package/templates/examples/research.example.json +15 -0
- package/templates/examples/research.example.md +6 -0
- package/templates/examples/review.example.json +17 -0
- package/templates/examples/run-manifest.example.json +9 -0
- package/templates/examples/spec-challenge.example.json +14 -0
- package/templates/examples/spec.example.json +21 -0
- package/templates/examples/verification-proof.example.json +21 -0
- package/templates/examples/wazir-manifest.example.yaml +65 -0
- package/templates/task-definition-schema.md +99 -0
- package/tooling/README.md +20 -0
- package/tooling/src/adapters/context-mode.js +50 -0
- package/tooling/src/capture/command.js +376 -0
- package/tooling/src/capture/store.js +99 -0
- package/tooling/src/capture/usage.js +270 -0
- package/tooling/src/checks/branches.js +50 -0
- package/tooling/src/checks/brand-truth.js +110 -0
- package/tooling/src/checks/changelog.js +231 -0
- package/tooling/src/checks/command-registry.js +36 -0
- package/tooling/src/checks/commits.js +102 -0
- package/tooling/src/checks/docs-drift.js +103 -0
- package/tooling/src/checks/docs-truth.js +201 -0
- package/tooling/src/checks/runtime-surface.js +156 -0
- package/tooling/src/cli.js +116 -0
- package/tooling/src/command-options.js +56 -0
- package/tooling/src/commands/validate.js +320 -0
- package/tooling/src/doctor/command.js +91 -0
- package/tooling/src/export/command.js +77 -0
- package/tooling/src/export/compiler.js +498 -0
- package/tooling/src/guards/loop-cap-guard.js +52 -0
- package/tooling/src/guards/protected-path-write-guard.js +67 -0
- package/tooling/src/index/command.js +152 -0
- package/tooling/src/index/storage.js +1061 -0
- package/tooling/src/index/summarizers.js +261 -0
- package/tooling/src/loaders.js +18 -0
- package/tooling/src/project-root.js +22 -0
- package/tooling/src/recall/command.js +225 -0
- package/tooling/src/schema-validator.js +30 -0
- package/tooling/src/state-root.js +40 -0
- package/tooling/src/status/command.js +71 -0
- package/wazir.manifest.yaml +135 -0
- package/workflows/README.md +19 -0
- package/workflows/author.md +42 -0
- package/workflows/clarify.md +38 -0
- package/workflows/design-review.md +46 -0
- package/workflows/design.md +44 -0
- package/workflows/discover.md +37 -0
- package/workflows/execute.md +48 -0
- package/workflows/learn.md +38 -0
- package/workflows/plan-review.md +42 -0
- package/workflows/plan.md +39 -0
- package/workflows/prepare-next.md +37 -0
- package/workflows/review.md +40 -0
- package/workflows/run-audit.md +41 -0
- package/workflows/spec-challenge.md +41 -0
- package/workflows/specify.md +38 -0
- package/workflows/verify.md +37 -0
|
@@ -0,0 +1,625 @@
|
|
|
1
|
+
# Node.js + TypeScript -- Expertise Module
|
|
2
|
+
|
|
3
|
+
> A Node.js/TypeScript backend specialist designs, builds, and maintains server-side applications
|
|
4
|
+
> using Node.js (v22+) with TypeScript (5.x+). Scope spans API design, data layer integration,
|
|
5
|
+
> authentication, background jobs, observability, and production deployment of performant, type-safe services.
|
|
6
|
+
|
|
7
|
+
## Core Patterns & Conventions
|
|
8
|
+
|
|
9
|
+
### Project Structure
|
|
10
|
+
|
|
11
|
+
**Monorepo (Turborepo or Nx):**
|
|
12
|
+
```
|
|
13
|
+
apps/
|
|
14
|
+
api/ # Main HTTP service
|
|
15
|
+
worker/ # Background job processor
|
|
16
|
+
packages/
|
|
17
|
+
shared/ # Shared types, utils, validation schemas
|
|
18
|
+
db/ # Database client, migrations, seed
|
|
19
|
+
turbo.json
|
|
20
|
+
tsconfig.base.json
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**Feature-based single service:**
|
|
24
|
+
```
|
|
25
|
+
src/
|
|
26
|
+
modules/
|
|
27
|
+
users/
|
|
28
|
+
users.controller.ts
|
|
29
|
+
users.service.ts
|
|
30
|
+
users.repository.ts
|
|
31
|
+
users.schema.ts # Zod schemas
|
|
32
|
+
users.test.ts
|
|
33
|
+
common/middleware/ errors/ guards/
|
|
34
|
+
infrastructure/database/ cache/ queue/
|
|
35
|
+
app.ts
|
|
36
|
+
server.ts
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- Co-locate tests with source files. Keep barrel files minimal. Use `@/modules/*` path aliases.
|
|
40
|
+
|
|
41
|
+
### Module System
|
|
42
|
+
|
|
43
|
+
ESM is the default in 2025-2026. Use `"type": "module"` in `package.json`, `"module": "NodeNext"` and `"moduleResolution": "NodeNext"` in `tsconfig.json`. Use `.js` extensions in imports.
|
|
44
|
+
|
|
45
|
+
### Naming Conventions
|
|
46
|
+
|
|
47
|
+
- **Files:** kebab-case with role suffix (`user-auth.service.ts`)
|
|
48
|
+
- **Classes:** PascalCase. **Functions/vars:** camelCase. **Constants:** UPPER_SNAKE_CASE
|
|
49
|
+
- **Types/Interfaces:** PascalCase, no `I` prefix. Prefer `as const` objects over enums
|
|
50
|
+
- **Tooling:** ESLint flat config (`eslint.config.js`) with `@typescript-eslint` v8+ and Prettier. Enforce via lint-staged + husky pre-commit hooks
|
|
51
|
+
|
|
52
|
+
### Architecture
|
|
53
|
+
|
|
54
|
+
**Clean Architecture / Hexagonal:**
|
|
55
|
+
```
|
|
56
|
+
Controller (HTTP) --> Service (business logic) --> Repository (data access)
|
|
57
|
+
|
|
|
58
|
+
Domain models (pure TS, no framework deps)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
- Controllers: parse request, call service, format response. Services: business logic, depend on repository interfaces. Repositories: encapsulate data access. Domain models: plain TypeScript.
|
|
62
|
+
- **DI:** NestJS built-in; otherwise `tsyringe`, `awilix`, or manual constructor injection.
|
|
63
|
+
|
|
64
|
+
### Framework Selection
|
|
65
|
+
|
|
66
|
+
| Framework | Best For | Key Trait |
|
|
67
|
+
|-----------|----------|-----------|
|
|
68
|
+
| **Express** | General purpose, max ecosystem | Middleware-based, massive plugin library |
|
|
69
|
+
| **Fastify** | Performance-sensitive APIs | JSON schema validation, plugin architecture |
|
|
70
|
+
| **NestJS** | Enterprise, large teams (10+) | Opinionated, DI, decorators, modules |
|
|
71
|
+
| **Hono** | Edge/serverless, multi-runtime | Ultra-light (~14kb), Workers/Deno/Bun/Node |
|
|
72
|
+
|
|
73
|
+
### Data Flow
|
|
74
|
+
|
|
75
|
+
**Express/Fastify:** Request --> Auth middleware --> Validation --> Route handler --> Error middleware --> Response
|
|
76
|
+
|
|
77
|
+
**NestJS:** Request --> Guards (auth) --> Interceptors (logging) --> Pipes (validation) --> Controller --> Interceptors (transform) --> Response
|
|
78
|
+
|
|
79
|
+
### Error Handling
|
|
80
|
+
|
|
81
|
+
Create custom error class hierarchies with `statusCode` and `isOperational` fields. Central error middleware converts operational `AppError` subclasses to structured JSON; non-operational errors log full stack and return generic 500.
|
|
82
|
+
|
|
83
|
+
### Logging & Observability
|
|
84
|
+
|
|
85
|
+
**Pino** -- 5x faster than Winston. Use structured JSON, `pino-pretty` in dev, `redact` for secrets. **OpenTelemetry** for distributed tracing: `@opentelemetry/sdk-node` with auto-instrumentation, correlate logs via `@opentelemetry/instrumentation-pino`. One OTel SDK per service. Use sampling in production (`TraceIdRatioBasedSampler(0.1)`).
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Production Patterns
|
|
90
|
+
|
|
91
|
+
### Express.js Security Middleware Stack
|
|
92
|
+
|
|
93
|
+
Apply security middleware early in the stack — before any route handlers. Order matters: helmet first (headers on every response), then rate limiting (reject abusers before doing work), then CORS (reject disallowed origins).
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
import helmet from 'helmet';
|
|
97
|
+
import rateLimit from 'express-rate-limit';
|
|
98
|
+
import cors from 'cors';
|
|
99
|
+
|
|
100
|
+
// Security headers — sets CSP, HSTS, X-Frame-Options, etc.
|
|
101
|
+
app.use(helmet({
|
|
102
|
+
contentSecurityPolicy: {
|
|
103
|
+
directives: {
|
|
104
|
+
defaultSrc: ["'self'"],
|
|
105
|
+
scriptSrc: ["'self'"],
|
|
106
|
+
styleSrc: ["'self'", "'unsafe-inline'"],
|
|
107
|
+
imgSrc: ["'self'", 'data:', 'https:'],
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
hsts: { maxAge: 31536000, includeSubDomains: true, preload: true },
|
|
111
|
+
}));
|
|
112
|
+
|
|
113
|
+
// Rate limiting — per-IP, sliding window
|
|
114
|
+
app.use(rateLimit({
|
|
115
|
+
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
116
|
+
max: 100, // 100 requests per window per IP
|
|
117
|
+
standardHeaders: true, // RateLimit-* headers (draft-6)
|
|
118
|
+
legacyHeaders: false, // Disable X-RateLimit-* headers
|
|
119
|
+
message: { error: 'Too many requests, try again later' },
|
|
120
|
+
}));
|
|
121
|
+
|
|
122
|
+
// CORS — explicit origin whitelist from env
|
|
123
|
+
app.use(cors({
|
|
124
|
+
origin: process.env.ALLOWED_ORIGINS?.split(',') ?? [],
|
|
125
|
+
credentials: true,
|
|
126
|
+
maxAge: 86400, // Preflight cache 24h
|
|
127
|
+
}));
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Key decisions:**
|
|
131
|
+
- `ALLOWED_ORIGINS` from env — never hardcode origins in source
|
|
132
|
+
- `credentials: true` requires explicit origin list (not `*`)
|
|
133
|
+
- `legacyHeaders: false` — only emit the standardized `RateLimit-*` headers
|
|
134
|
+
- Layer auth-specific rate limits separately (e.g., 10/min on `/auth/login`)
|
|
135
|
+
|
|
136
|
+
### PostgreSQL Schema Patterns
|
|
137
|
+
|
|
138
|
+
Index design is the highest-leverage performance optimization. These patterns cover the most common production needs.
|
|
139
|
+
|
|
140
|
+
```sql
|
|
141
|
+
-- Partial index: only index rows that match a condition
|
|
142
|
+
-- Saves space and speeds up queries that always filter by status
|
|
143
|
+
CREATE INDEX idx_orders_pending ON orders (created_at)
|
|
144
|
+
WHERE status = 'pending';
|
|
145
|
+
|
|
146
|
+
-- GIN index for full-text search with weighted ranking
|
|
147
|
+
ALTER TABLE products ADD COLUMN search_vector tsvector
|
|
148
|
+
GENERATED ALWAYS AS (
|
|
149
|
+
setweight(to_tsvector('english', coalesce(name, '')), 'A') ||
|
|
150
|
+
setweight(to_tsvector('english', coalesce(description, '')), 'B')
|
|
151
|
+
) STORED;
|
|
152
|
+
CREATE INDEX idx_products_search ON products USING GIN (search_vector);
|
|
153
|
+
|
|
154
|
+
-- Covering index (INCLUDE avoids table lookup for frequently selected columns)
|
|
155
|
+
CREATE INDEX idx_users_email ON users (email) INCLUDE (name, role, status);
|
|
156
|
+
|
|
157
|
+
-- Expression index for case-insensitive lookups
|
|
158
|
+
-- Pair with WHERE lower(email) = lower($1) in queries
|
|
159
|
+
CREATE INDEX idx_users_email_lower ON users (lower(email));
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**When to use each:**
|
|
163
|
+
- **Partial index:** Queries always filter on a known condition (status, soft-delete flag, tenant)
|
|
164
|
+
- **GIN + tsvector:** Full-text search without ElasticSearch — sufficient for <10M rows
|
|
165
|
+
- **Covering index:** High-read endpoints that SELECT a small subset of columns
|
|
166
|
+
- **Expression index:** Case-insensitive email lookup, JSONB field extraction
|
|
167
|
+
|
|
168
|
+
### Graceful Shutdown Pattern
|
|
169
|
+
|
|
170
|
+
Production servers must drain in-flight requests before exiting. Without this, deployments drop active connections and corrupt long-running operations.
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
import net from 'node:net';
|
|
174
|
+
|
|
175
|
+
const server = app.listen(port);
|
|
176
|
+
const connections = new Set<net.Socket>();
|
|
177
|
+
|
|
178
|
+
// Track all open connections
|
|
179
|
+
server.on('connection', (conn) => {
|
|
180
|
+
connections.add(conn);
|
|
181
|
+
conn.on('close', () => connections.delete(conn));
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
async function shutdown(signal: string) {
|
|
185
|
+
console.log(`${signal} received, starting graceful shutdown`);
|
|
186
|
+
|
|
187
|
+
// Stop accepting new connections
|
|
188
|
+
server.close();
|
|
189
|
+
|
|
190
|
+
// Give existing requests time to complete, then force-close
|
|
191
|
+
setTimeout(() => {
|
|
192
|
+
connections.forEach((conn) => conn.destroy());
|
|
193
|
+
process.exit(0);
|
|
194
|
+
}, 10_000);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
198
|
+
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**Production checklist:**
|
|
202
|
+
- Close DB connection pools and Redis clients inside `server.close()` callback
|
|
203
|
+
- Set the force-exit timeout shorter than your orchestrator's kill grace period (e.g., 10s app vs 30s Kubernetes `terminationGracePeriodSeconds`)
|
|
204
|
+
- Add a `shuttingDown` flag to reject new work in queue consumers during drain
|
|
205
|
+
- Use `.unref()` on the timeout to prevent it from keeping the process alive if all connections close early
|
|
206
|
+
|
|
207
|
+
### Request ID Correlation
|
|
208
|
+
|
|
209
|
+
Attach a unique ID to every request for end-to-end tracing across logs, error reports, and downstream services.
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
import { randomUUID } from 'node:crypto';
|
|
213
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
214
|
+
|
|
215
|
+
const requestContext = new AsyncLocalStorage<{ requestId: string }>();
|
|
216
|
+
|
|
217
|
+
app.use((req, _res, next) => {
|
|
218
|
+
const requestId = req.headers['x-request-id'] as string ?? randomUUID();
|
|
219
|
+
req.headers['x-request-id'] = requestId;
|
|
220
|
+
requestContext.run({ requestId }, next);
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// In any downstream code:
|
|
224
|
+
export function getRequestId(): string | undefined {
|
|
225
|
+
return requestContext.getStore()?.requestId;
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**Why `AsyncLocalStorage`:** Unlike attaching data to `req`, this works in service/repository layers that do not (and should not) have access to the HTTP request object. Pino's `mixin` option can call `getRequestId()` to include it in every log line automatically.
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## Anti-Patterns & Pitfalls
|
|
234
|
+
|
|
235
|
+
### 1. Using `any` to Silence the Compiler
|
|
236
|
+
**Why:** Defeats type safety, spreads virally to downstream types, allows runtime errors TypeScript should catch.
|
|
237
|
+
**Fix:** Use `unknown` + type guards. Parse untrusted data with Zod. Enable `noImplicitAny`.
|
|
238
|
+
|
|
239
|
+
### 2. Blocking the Event Loop
|
|
240
|
+
**Why:** Node.js is single-threaded. A 50ms sync file read blocks ALL concurrent requests.
|
|
241
|
+
**Fix:** Use `fs.promises`, stream large payloads, offload CPU work to worker threads or BullMQ.
|
|
242
|
+
|
|
243
|
+
### 3. Swallowing Errors in `catch` Blocks
|
|
244
|
+
**Why:** Silent failures make debugging impossible. System enters inconsistent state.
|
|
245
|
+
**Fix:** Always log or re-throw. Use `catch (error: unknown)` and narrow. Add process-level unhandled rejection handlers.
|
|
246
|
+
|
|
247
|
+
### 4. No Runtime Validation of External Input
|
|
248
|
+
**Why:** TS types vanish at runtime. API bodies, env vars, queue messages are `unknown` regardless of annotations.
|
|
249
|
+
**Fix:** Validate at trust boundaries with Zod `safeParse`. Validate env vars at startup.
|
|
250
|
+
|
|
251
|
+
### 5. Fat Controllers
|
|
252
|
+
**Why:** Business logic in route handlers is untestable without HTTP, violates SRP, couples logic to transport.
|
|
253
|
+
**Fix:** Controllers parse/format only. Business logic in services, unit-tested in isolation.
|
|
254
|
+
|
|
255
|
+
### 6. N+1 Query Patterns
|
|
256
|
+
**Why:** 100 users + 1 query each = 101 DB round-trips. Latency scales linearly.
|
|
257
|
+
**Fix:** Eager loading (`include` in Prisma, `with` in Drizzle), DataLoader for GraphQL, explicit JOINs.
|
|
258
|
+
|
|
259
|
+
### 7. Leaking DB Models Through API Responses
|
|
260
|
+
**Why:** Internal columns, sensitive fields (password hashes) leak. Schema changes break API contracts.
|
|
261
|
+
**Fix:** Map to DTOs/response schemas. Use Zod `.pick()`/`.omit()`. Never `res.json(ormModel)`.
|
|
262
|
+
|
|
263
|
+
### 8. Type Assertions (`as`) Instead of Type Guards
|
|
264
|
+
**Why:** `as` performs zero runtime checks. Errors surface far from the assertion site.
|
|
265
|
+
**Fix:** Discriminated unions, `instanceof`, user-defined type guards, or Zod `.parse()`.
|
|
266
|
+
|
|
267
|
+
### 9. No Graceful Shutdown
|
|
268
|
+
**Why:** Drops in-flight requests, leaks DB connections, loses queued jobs, can corrupt data.
|
|
269
|
+
**Fix:** `SIGTERM`/`SIGINT` listeners, stop accepting connections, drain requests, close pools, force-exit timeout.
|
|
270
|
+
|
|
271
|
+
### 10. Secrets in Git
|
|
272
|
+
**Why:** Secrets in version control persist forever in history. Anyone with repo access gets prod credentials.
|
|
273
|
+
**Fix:** `.env` in `.gitignore` for local dev. Production: AWS Secrets Manager, Vault, Doppler.
|
|
274
|
+
|
|
275
|
+
### 11. Unstructured Error Responses
|
|
276
|
+
**Why:** Clients cannot distinguish error types programmatically. Frontend resorts to string-matching.
|
|
277
|
+
**Fix:** Structured errors: `{ code: "VALIDATION_ERROR", message: "...", details: [...] }`.
|
|
278
|
+
|
|
279
|
+
### 12. Over-Wrapping API Responses
|
|
280
|
+
**Why:** `{ success: true, data: ... }` restates HTTP status codes, creates `data.data` nesting.
|
|
281
|
+
**Fix:** Use HTTP status codes semantically. Return resources directly. Error envelope only for errors.
|
|
282
|
+
|
|
283
|
+
### 13. Lax TypeScript Config
|
|
284
|
+
**Why:** Without `strict: true`, implicit `any` and unchecked `null` undermine type safety.
|
|
285
|
+
**Fix:** Enable `strict`, `noUncheckedIndexedAccess`, `exactOptionalPropertyTypes`.
|
|
286
|
+
|
|
287
|
+
### 14. Global Mutable State
|
|
288
|
+
**Why:** Race conditions across requests, non-deterministic tests, breaks horizontal scaling.
|
|
289
|
+
**Fix:** `AsyncLocalStorage` for request context, DI, Redis/DB for shared state.
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## Testing Strategy
|
|
294
|
+
|
|
295
|
+
| Layer | Tool | Scope | Speed |
|
|
296
|
+
|-------|------|-------|-------|
|
|
297
|
+
| Unit | Vitest | Single function/class, mocked deps | ~1ms/test |
|
|
298
|
+
| Integration | Vitest + Testcontainers | Service + real DB/queue | ~100ms/test |
|
|
299
|
+
| E2E/API | Vitest + Supertest | Full HTTP request cycle | ~500ms/test |
|
|
300
|
+
|
|
301
|
+
**Vitest over Jest** for new projects (2025-2026): native ESM/TS, 30-70% faster, compatible API, built-in coverage. Reserve Jest for React Native or legacy codebases.
|
|
302
|
+
|
|
303
|
+
**Mocking:** Constructor injection (swap deps in tests), `vi.mock()` for third-party SDKs, MSW for outbound HTTP. Prefer real dependencies via Testcontainers over heavy mocking.
|
|
304
|
+
|
|
305
|
+
**Coverage:** 80%+ for services, 90%+ for shared libs. Enforce in CI. Diminishing returns past ~90%.
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## Performance Considerations
|
|
310
|
+
|
|
311
|
+
### Event Loop
|
|
312
|
+
Never block it. `JSON.parse()` on 50MB, sync crypto, CPU loops all block. Use `setImmediate()` to yield. Monitor lag with `monitorEventLoopDelay` from `perf_hooks`; alert if p99 > 100ms.
|
|
313
|
+
|
|
314
|
+
### Memory Leaks
|
|
315
|
+
Common sources: unbounded caches (no TTL/LRU), closures capturing large objects, undestroyed streams, per-request globals. Detect with `--inspect` + Chrome DevTools heap snapshots, `clinic.js heapprofile`, or Prometheus gauge on `process.memoryUsage().heapUsed`.
|
|
316
|
+
|
|
317
|
+
### Connection Pooling
|
|
318
|
+
DB: always pool (Prisma/Drizzle auto-manage; raw `pg` set `max: 20`). Redis: single `ioredis` client (multiplexes). HTTP: reuse agents with keep-alive (default in Node 22).
|
|
319
|
+
|
|
320
|
+
### Profiling Tools
|
|
321
|
+
|
|
322
|
+
| Tool | Purpose |
|
|
323
|
+
|------|---------|
|
|
324
|
+
| `node --inspect` + DevTools | CPU profiling, heap snapshots |
|
|
325
|
+
| `clinic.js doctor/flame` | Auto-detect issues, flamegraphs |
|
|
326
|
+
| `0x` | Lightweight flamegraph |
|
|
327
|
+
| `autocannon` | HTTP load testing |
|
|
328
|
+
|
|
329
|
+
### Scaling
|
|
330
|
+
**Cluster mode:** PM2 or `cluster` module for multi-core. **Worker threads:** `piscina` pool for CPU-bound tasks. **Job queues:** BullMQ for async processing.
|
|
331
|
+
|
|
332
|
+
### Thresholds
|
|
333
|
+
|
|
334
|
+
| Metric | Target | Alert |
|
|
335
|
+
|--------|--------|-------|
|
|
336
|
+
| p50 latency | < 50ms | > 200ms |
|
|
337
|
+
| p99 latency | < 500ms | > 2s |
|
|
338
|
+
| Event loop lag p99 | < 50ms | > 100ms |
|
|
339
|
+
| Heap usage | < 70% max | > 85% |
|
|
340
|
+
| Error rate | < 0.1% | > 1% |
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## Security Considerations
|
|
345
|
+
|
|
346
|
+
### OWASP Top Risks for Node.js
|
|
347
|
+
1. **Injection:** Parameterized queries only. Never interpolate user input into SQL or shell commands.
|
|
348
|
+
2. **Broken Auth:** Use Lucia/Auth.js or SaaS (Clerk, Auth0). Hash with `bcrypt`/`argon2`. Enforce MFA.
|
|
349
|
+
3. **Data Exposure:** Redact secrets from logs. Minimal API responses. HTTPS everywhere.
|
|
350
|
+
4. **Broken Access Control:** RBAC/ABAC at service layer. Check ownership on every resource access.
|
|
351
|
+
5. **Misconfiguration:** `helmet` for headers. Disable `X-Powered-By`. Strict CORS.
|
|
352
|
+
6. **XSS:** `dompurify` for HTML. Content-Security-Policy headers.
|
|
353
|
+
7. **SSRF:** Whitelist outbound URLs. Block internal IPs (169.254.x.x, 10.x.x.x).
|
|
354
|
+
8. **Insecure Deps:** `npm audit` in CI. Snyk/Socket.dev for supply chain. Pin versions with lockfiles.
|
|
355
|
+
|
|
356
|
+
### Input Validation
|
|
357
|
+
Validate ALL external input with **Zod** at boundaries. Use `safeParse` in production. Infer TS types from schemas (`z.infer<typeof Schema>`). Validate env vars at startup (crash early).
|
|
358
|
+
|
|
359
|
+
### Authentication
|
|
360
|
+
- **JWT:** 15-min access tokens, 7-30 day refresh tokens in httpOnly cookies. Rotate on use. Use `jose` library.
|
|
361
|
+
- **Sessions:** Server-side store (Redis) + cookies -- most battle-tested for web apps.
|
|
362
|
+
- **OAuth2:** Passport.js or Auth.js. Validate ID tokens server-side.
|
|
363
|
+
|
|
364
|
+
### Rate Limiting
|
|
365
|
+
`express-rate-limit` with layered limits: global 1000/min/IP, auth endpoints 10/min/IP. Redis-backed store for distributed setups.
|
|
366
|
+
|
|
367
|
+
### Secrets
|
|
368
|
+
Dev: `.env` (`.gitignore`d). Production: AWS Secrets Manager / Vault / Doppler. Never log secrets (Pino `redact`). Type-safe via `@t3-oss/env-core` or Zod.
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## Integration Patterns
|
|
373
|
+
|
|
374
|
+
### Database ORMs
|
|
375
|
+
|
|
376
|
+
| ORM | Approach | Strength | Trade-off |
|
|
377
|
+
|-----|----------|----------|-----------|
|
|
378
|
+
| **Prisma v6+** | Schema-first, codegen | Best migrations, DX, editor support | Generated client size |
|
|
379
|
+
| **Drizzle v0.38+** | Code-first, TS schemas | ~7kb, zero deps, SQL-like API | Manual migration review |
|
|
380
|
+
| **TypeORM** | Decorators, Active Record | NestJS integration | Losing ground to above |
|
|
381
|
+
|
|
382
|
+
### Message Queues
|
|
383
|
+
- **BullMQ** (Redis): First choice for Node.js. TS-native. Delayed/repeatable/priority jobs, parent-child flows, rate limiting.
|
|
384
|
+
- **RabbitMQ** (AMQP): Cross-language, complex routing, guaranteed delivery. Use for polyglot systems.
|
|
385
|
+
|
|
386
|
+
### API Design
|
|
387
|
+
- **REST:** Public APIs, multi-language clients. Resource-oriented URLs. Consistent pagination envelope.
|
|
388
|
+
- **GraphQL (Pothos/Apollo):** Flexible querying for multiple clients. DataLoader for N+1. Enable complexity/depth limits.
|
|
389
|
+
- **tRPC v11+:** End-to-end type safety in TS monorepos. NOT for public APIs or polyglot clients.
|
|
390
|
+
|
|
391
|
+
### File Handling
|
|
392
|
+
Use streams for large files. `pipeline()` from `stream/promises` for safe chaining. Stream to S3 via `@aws-sdk/lib-storage`. Set `Content-Length` limits.
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## DevOps & Deployment
|
|
397
|
+
|
|
398
|
+
### Build Tools
|
|
399
|
+
|
|
400
|
+
| Tool | Speed vs tsc | Notes |
|
|
401
|
+
|------|-------------|-------|
|
|
402
|
+
| `tsc` | 1x (baseline) | Only tool that type-checks. Use `tsc --noEmit` in CI. |
|
|
403
|
+
| `tsup` | ~40x | Built on esbuild. Best for libraries (CJS + ESM + .d.ts). |
|
|
404
|
+
| `esbuild` | ~45x | Go-based. No type checking. Great for app builds. |
|
|
405
|
+
| `SWC` | ~20x | Rust-based. Used by Next.js. |
|
|
406
|
+
|
|
407
|
+
**Pipeline:** `tsc --noEmit` for type checking, then `tsup src/server.ts --format esm --target node22 --minify` for production bundle.
|
|
408
|
+
|
|
409
|
+
### Docker (Multi-Stage)
|
|
410
|
+
|
|
411
|
+
```dockerfile
|
|
412
|
+
FROM node:22-alpine AS deps
|
|
413
|
+
WORKDIR /app
|
|
414
|
+
COPY package.json pnpm-lock.yaml ./
|
|
415
|
+
RUN corepack enable && pnpm install --frozen-lockfile
|
|
416
|
+
|
|
417
|
+
FROM deps AS build
|
|
418
|
+
COPY . .
|
|
419
|
+
RUN pnpm run build
|
|
420
|
+
|
|
421
|
+
FROM node:22-alpine AS production
|
|
422
|
+
WORKDIR /app
|
|
423
|
+
RUN addgroup -g 1001 app && adduser -u 1001 -G app -s /bin/sh -D app
|
|
424
|
+
COPY --from=deps /app/node_modules ./node_modules
|
|
425
|
+
COPY --from=build /app/dist ./dist
|
|
426
|
+
COPY package.json ./
|
|
427
|
+
USER app
|
|
428
|
+
EXPOSE 3000
|
|
429
|
+
HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://localhost:3000/health || exit 1
|
|
430
|
+
CMD ["node", "dist/server.js"]
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
Alpine base (60-80% smaller), non-root user, HEALTHCHECK, `.dockerignore`, pinned versions.
|
|
434
|
+
|
|
435
|
+
### CI/CD (GitHub Actions)
|
|
436
|
+
|
|
437
|
+
```yaml
|
|
438
|
+
name: CI
|
|
439
|
+
on: [push, pull_request]
|
|
440
|
+
jobs:
|
|
441
|
+
check:
|
|
442
|
+
runs-on: ubuntu-latest
|
|
443
|
+
services:
|
|
444
|
+
postgres: { image: 'postgres:16-alpine', env: { POSTGRES_PASSWORD: test }, ports: ['5432:5432'] }
|
|
445
|
+
steps:
|
|
446
|
+
- uses: actions/checkout@v4
|
|
447
|
+
- uses: pnpm/action-setup@v4
|
|
448
|
+
- uses: actions/setup-node@v4
|
|
449
|
+
with: { node-version: 22, cache: pnpm }
|
|
450
|
+
- run: pnpm install --frozen-lockfile
|
|
451
|
+
- run: pnpm lint && pnpm typecheck && pnpm test && pnpm build
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### Environment Config
|
|
455
|
+
Validate env vars at startup with Zod. Crash immediately on misconfiguration -- not at 3am when a code path reads it.
|
|
456
|
+
|
|
457
|
+
### Process Management
|
|
458
|
+
Dev: `tsx watch src/server.ts`. Production (containers): `node dist/server.js` directly (container runtime handles restarts). Bare metal: PM2 cluster mode. Always implement graceful shutdown.
|
|
459
|
+
|
|
460
|
+
---
|
|
461
|
+
|
|
462
|
+
## Decision Trees
|
|
463
|
+
|
|
464
|
+
### Which Framework?
|
|
465
|
+
```
|
|
466
|
+
Team > 10 or enterprise compliance? --> NestJS
|
|
467
|
+
|NO
|
|
468
|
+
Edge/serverless (Workers, Deno Deploy)? --> Hono
|
|
469
|
+
|NO
|
|
470
|
+
Need max ecosystem & middleware? --> Express
|
|
471
|
+
|NO
|
|
472
|
+
Default modern choice --> Fastify
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
### Which ORM?
|
|
476
|
+
```
|
|
477
|
+
Serverless/edge, cold start matters? --> Drizzle
|
|
478
|
+
|NO
|
|
479
|
+
Team prefers SQL, wants query control? --> Drizzle
|
|
480
|
+
|NO
|
|
481
|
+
Want best migration tooling & DX? --> Prisma
|
|
482
|
+
|NO
|
|
483
|
+
Existing NestJS with decorators? --> TypeORM (or migrate)
|
|
484
|
+
|NO
|
|
485
|
+
Safe default --> Prisma
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
### Monolith vs. Microservices?
|
|
489
|
+
```
|
|
490
|
+
Team < 8 AND no proven PMF? --> Monolith
|
|
491
|
+
|NO
|
|
492
|
+
Components have vastly different scaling needs? --> Extract ONLY divergent component
|
|
493
|
+
|NO
|
|
494
|
+
50+ engineers OR >1M req/day with clear boundaries?
|
|
495
|
+
YES --> Microservices (REQUIRES: K8s, tracing, centralized logging, per-service CI/CD)
|
|
496
|
+
NO --> Modular monolith (extract later when pain emerges)
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
---
|
|
500
|
+
|
|
501
|
+
## Code Examples
|
|
502
|
+
|
|
503
|
+
### 1. Graceful Shutdown
|
|
504
|
+
|
|
505
|
+
```typescript
|
|
506
|
+
import { Server } from 'node:http';
|
|
507
|
+
|
|
508
|
+
function setupGracefulShutdown(server: Server, cleanup: () => Promise<void>): void {
|
|
509
|
+
let shuttingDown = false;
|
|
510
|
+
const shutdown = async (signal: string) => {
|
|
511
|
+
if (shuttingDown) return;
|
|
512
|
+
shuttingDown = true;
|
|
513
|
+
logger.info({ signal }, 'Draining connections...');
|
|
514
|
+
server.close(async () => {
|
|
515
|
+
await cleanup(); // close DB pools, Redis, queues
|
|
516
|
+
process.exit(0);
|
|
517
|
+
});
|
|
518
|
+
setTimeout(() => process.exit(1), 15_000).unref(); // force exit
|
|
519
|
+
};
|
|
520
|
+
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
521
|
+
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
522
|
+
}
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
### 2. Zod Validation Middleware (Express)
|
|
526
|
+
|
|
527
|
+
```typescript
|
|
528
|
+
import { z, ZodSchema } from 'zod';
|
|
529
|
+
import { Request, Response, NextFunction } from 'express';
|
|
530
|
+
|
|
531
|
+
function validate<T extends ZodSchema>(schema: T) {
|
|
532
|
+
return (req: Request, res: Response, next: NextFunction) => {
|
|
533
|
+
const result = schema.safeParse(req.body);
|
|
534
|
+
if (!result.success) {
|
|
535
|
+
return res.status(400).json({
|
|
536
|
+
code: 'VALIDATION_ERROR',
|
|
537
|
+
errors: result.error.issues.map((i) => ({ path: i.path.join('.'), message: i.message })),
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
req.body = result.data;
|
|
541
|
+
next();
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// Usage:
|
|
546
|
+
app.post('/orders', validate(z.object({
|
|
547
|
+
productId: z.string().uuid(),
|
|
548
|
+
quantity: z.number().int().positive().max(100),
|
|
549
|
+
})), orderController.create);
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
### 3. Repository Pattern (Drizzle)
|
|
553
|
+
|
|
554
|
+
```typescript
|
|
555
|
+
import { eq } from 'drizzle-orm';
|
|
556
|
+
import { db } from '../infrastructure/database';
|
|
557
|
+
import { users } from '../infrastructure/schema';
|
|
558
|
+
|
|
559
|
+
export interface UserRepository {
|
|
560
|
+
findById(id: string): Promise<User | null>;
|
|
561
|
+
create(data: NewUser): Promise<User>;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
export function createUserRepository(): UserRepository {
|
|
565
|
+
return {
|
|
566
|
+
async findById(id) {
|
|
567
|
+
const [user] = await db.select().from(users).where(eq(users.id, id)).limit(1);
|
|
568
|
+
return user ?? null;
|
|
569
|
+
},
|
|
570
|
+
async create(data) {
|
|
571
|
+
const [user] = await db.insert(users).values(data).returning();
|
|
572
|
+
return user;
|
|
573
|
+
},
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
### 4. Type-Safe Env Config
|
|
579
|
+
|
|
580
|
+
```typescript
|
|
581
|
+
import { z } from 'zod';
|
|
582
|
+
import 'dotenv/config';
|
|
583
|
+
|
|
584
|
+
const envSchema = z.object({
|
|
585
|
+
NODE_ENV: z.enum(['development', 'production', 'test']),
|
|
586
|
+
PORT: z.coerce.number().min(1).max(65535).default(3000),
|
|
587
|
+
DATABASE_URL: z.string().url(),
|
|
588
|
+
JWT_SECRET: z.string().min(32),
|
|
589
|
+
CORS_ORIGINS: z.string().transform((s) => s.split(',')),
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
const parsed = envSchema.safeParse(process.env);
|
|
593
|
+
if (!parsed.success) {
|
|
594
|
+
console.error('Invalid env vars:', parsed.error.flatten().fieldErrors);
|
|
595
|
+
process.exit(1);
|
|
596
|
+
}
|
|
597
|
+
export const env = Object.freeze(parsed.data);
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
### 5. Structured Error Middleware
|
|
601
|
+
|
|
602
|
+
```typescript
|
|
603
|
+
class AppError extends Error {
|
|
604
|
+
constructor(public code: string, public statusCode: number, message: string, public details?: unknown) {
|
|
605
|
+
super(message);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
function errorHandler(err: unknown, _req: Request, res: Response, _next: NextFunction): void {
|
|
610
|
+
if (err instanceof AppError) {
|
|
611
|
+
res.status(err.statusCode).json({ code: err.code, message: err.message, ...(err.details && { details: err.details }) });
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
if (err instanceof ZodError) {
|
|
615
|
+
res.status(400).json({ code: 'VALIDATION_ERROR', message: 'Invalid data', details: err.issues });
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
logger.error({ err }, 'Unhandled error');
|
|
619
|
+
res.status(500).json({ code: 'INTERNAL_ERROR', message: 'An unexpected error occurred' });
|
|
620
|
+
}
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
---
|
|
624
|
+
|
|
625
|
+
*Researched: 2026-03-07 | Sources: [Encore -- Best TS Backend Frameworks 2026](https://encore.dev/articles/best-typescript-backend-frameworks), [DEV -- Modern Node.js + TS Setup 2025](https://dev.to/woovi/a-modern-nodejs-typescript-setup-for-2025-nlk), [OWASP Node.js Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Nodejs_Security_Cheat_Sheet.html), [OneUptime -- Node.js API Security OWASP](https://oneuptime.com/blog/post/2026-01-06-nodejs-api-security-owasp-top-10/view), [Better Stack -- Drizzle vs Prisma](https://betterstack.com/community/guides/scaling-nodejs/drizzle-vs-prisma/), [Bytebase -- Drizzle vs Prisma 2026](https://www.bytebase.com/blog/drizzle-vs-prisma/), [DevTools Watch -- Vitest vs Jest 2026](https://devtoolswatch.com/en/vitest-vs-jest-2026), [SD Times -- tRPC vs GraphQL vs REST](https://sdtimes.com/graphql/trpc-vs-graphql-vs-rest-choosing-the-right-api-design-for-modern-web-applications/), [DEV -- REST vs GraphQL vs tRPC 2026](https://dev.to/pockit_tools/rest-vs-graphql-vs-trpc-vs-grpc-in-2026-the-definitive-guide-to-choosing-your-api-layer-1j8m), [DZone -- OpenTelemetry + Pino](https://dzone.com/articles/observability-nodejs-opentelemetry-pino), [SigNoz -- Pino Logger 2026](https://signoz.io/guides/pino-logger/), [Medium -- ESBuild SWC TSC 2026](https://medium.com/@mernstackdevbykevin/esbuild-swc-and-tsc-which-compiler-should-you-use-in-2026-a2df3c783ad2), [BullMQ Docs](https://docs.bullmq.io/), [AgileSoft -- Monolith vs Microservices 2026](https://www.agilesoftlabs.com/blog/2026/02/monolith-vs-microservices-decision), [Better Stack -- Node.js Memory Leaks](https://betterstack.com/community/guides/scaling-nodejs/high-performance-nodejs/nodejs-memory-leaks/), [Dash0 -- Production Logging with Pino](https://www.dash0.com/guides/logging-in-node-js-with-pino), [Docker Docs -- Containerize Node.js](https://docs.docker.com/guides/nodejs/containerize/)*
|