@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.
Files changed (629) hide show
  1. package/AGENTS.md +111 -0
  2. package/CHANGELOG.md +14 -0
  3. package/CONTRIBUTING.md +101 -0
  4. package/LICENSE +21 -0
  5. package/README.md +314 -0
  6. package/assets/composition-engine.mmd +34 -0
  7. package/assets/demo-script.sh +17 -0
  8. package/assets/logo-dark.svg +14 -0
  9. package/assets/logo.svg +14 -0
  10. package/assets/pipeline.mmd +39 -0
  11. package/assets/record-demo.sh +51 -0
  12. package/docs/README.md +51 -0
  13. package/docs/adapters/context-mode.md +60 -0
  14. package/docs/concepts/architecture.md +87 -0
  15. package/docs/concepts/artifact-model.md +60 -0
  16. package/docs/concepts/composition-engine.md +36 -0
  17. package/docs/concepts/indexing-and-recall.md +160 -0
  18. package/docs/concepts/observability.md +41 -0
  19. package/docs/concepts/roles-and-workflows.md +59 -0
  20. package/docs/concepts/terminology-policy.md +27 -0
  21. package/docs/getting-started/01-installation.md +78 -0
  22. package/docs/getting-started/02-first-run.md +102 -0
  23. package/docs/getting-started/03-adding-to-project.md +15 -0
  24. package/docs/getting-started/04-host-setup.md +15 -0
  25. package/docs/guides/ci-integration.md +15 -0
  26. package/docs/guides/creating-skills.md +15 -0
  27. package/docs/guides/expertise-module-authoring.md +15 -0
  28. package/docs/guides/hook-development.md +15 -0
  29. package/docs/guides/memory-and-learnings.md +34 -0
  30. package/docs/guides/multi-host-export.md +15 -0
  31. package/docs/guides/troubleshooting.md +101 -0
  32. package/docs/guides/writing-custom-roles.md +15 -0
  33. package/docs/plans/2026-03-15-cli-pipeline-integration-design.md +592 -0
  34. package/docs/plans/2026-03-15-cli-pipeline-integration-plan.md +598 -0
  35. package/docs/plans/2026-03-15-docs-enforcement-plan.md +238 -0
  36. package/docs/readmes/INDEX.md +99 -0
  37. package/docs/readmes/features/expertise/README.md +171 -0
  38. package/docs/readmes/features/exports/README.md +222 -0
  39. package/docs/readmes/features/hooks/README.md +103 -0
  40. package/docs/readmes/features/hooks/loop-cap-guard.md +133 -0
  41. package/docs/readmes/features/hooks/post-tool-capture.md +121 -0
  42. package/docs/readmes/features/hooks/post-tool-lint.md +130 -0
  43. package/docs/readmes/features/hooks/pre-compact-summary.md +122 -0
  44. package/docs/readmes/features/hooks/pre-tool-capture-route.md +100 -0
  45. package/docs/readmes/features/hooks/protected-path-write-guard.md +128 -0
  46. package/docs/readmes/features/hooks/session-start.md +119 -0
  47. package/docs/readmes/features/hooks/stop-handoff-harvest.md +125 -0
  48. package/docs/readmes/features/roles/README.md +157 -0
  49. package/docs/readmes/features/roles/clarifier.md +152 -0
  50. package/docs/readmes/features/roles/content-author.md +190 -0
  51. package/docs/readmes/features/roles/designer.md +193 -0
  52. package/docs/readmes/features/roles/executor.md +184 -0
  53. package/docs/readmes/features/roles/learner.md +210 -0
  54. package/docs/readmes/features/roles/planner.md +182 -0
  55. package/docs/readmes/features/roles/researcher.md +164 -0
  56. package/docs/readmes/features/roles/reviewer.md +184 -0
  57. package/docs/readmes/features/roles/specifier.md +162 -0
  58. package/docs/readmes/features/roles/verifier.md +215 -0
  59. package/docs/readmes/features/schemas/README.md +178 -0
  60. package/docs/readmes/features/skills/README.md +63 -0
  61. package/docs/readmes/features/skills/brainstorming.md +96 -0
  62. package/docs/readmes/features/skills/debugging.md +148 -0
  63. package/docs/readmes/features/skills/design.md +120 -0
  64. package/docs/readmes/features/skills/prepare-next.md +109 -0
  65. package/docs/readmes/features/skills/run-audit.md +159 -0
  66. package/docs/readmes/features/skills/scan-project.md +109 -0
  67. package/docs/readmes/features/skills/self-audit.md +176 -0
  68. package/docs/readmes/features/skills/tdd.md +137 -0
  69. package/docs/readmes/features/skills/using-skills.md +92 -0
  70. package/docs/readmes/features/skills/verification.md +120 -0
  71. package/docs/readmes/features/skills/writing-plans.md +104 -0
  72. package/docs/readmes/features/tooling/README.md +320 -0
  73. package/docs/readmes/features/workflows/README.md +186 -0
  74. package/docs/readmes/features/workflows/author.md +181 -0
  75. package/docs/readmes/features/workflows/clarify.md +154 -0
  76. package/docs/readmes/features/workflows/design-review.md +171 -0
  77. package/docs/readmes/features/workflows/design.md +169 -0
  78. package/docs/readmes/features/workflows/discover.md +162 -0
  79. package/docs/readmes/features/workflows/execute.md +173 -0
  80. package/docs/readmes/features/workflows/learn.md +167 -0
  81. package/docs/readmes/features/workflows/plan-review.md +165 -0
  82. package/docs/readmes/features/workflows/plan.md +170 -0
  83. package/docs/readmes/features/workflows/prepare-next.md +167 -0
  84. package/docs/readmes/features/workflows/review.md +169 -0
  85. package/docs/readmes/features/workflows/run-audit.md +191 -0
  86. package/docs/readmes/features/workflows/spec-challenge.md +159 -0
  87. package/docs/readmes/features/workflows/specify.md +160 -0
  88. package/docs/readmes/features/workflows/verify.md +177 -0
  89. package/docs/readmes/packages/README.md +50 -0
  90. package/docs/readmes/packages/ajv.md +117 -0
  91. package/docs/readmes/packages/context-mode.md +118 -0
  92. package/docs/readmes/packages/gray-matter.md +116 -0
  93. package/docs/readmes/packages/node-test.md +137 -0
  94. package/docs/readmes/packages/yaml.md +112 -0
  95. package/docs/reference/configuration-reference.md +159 -0
  96. package/docs/reference/expertise-index.md +52 -0
  97. package/docs/reference/git-flow.md +43 -0
  98. package/docs/reference/hooks.md +87 -0
  99. package/docs/reference/host-exports.md +50 -0
  100. package/docs/reference/launch-checklist.md +172 -0
  101. package/docs/reference/marketplace-listings.md +76 -0
  102. package/docs/reference/release-process.md +34 -0
  103. package/docs/reference/roles-reference.md +77 -0
  104. package/docs/reference/skills.md +33 -0
  105. package/docs/reference/templates.md +29 -0
  106. package/docs/reference/tooling-cli.md +94 -0
  107. package/docs/truth-claims.yaml +222 -0
  108. package/expertise/PROGRESS.md +63 -0
  109. package/expertise/README.md +18 -0
  110. package/expertise/antipatterns/PROGRESS.md +56 -0
  111. package/expertise/antipatterns/backend/api-design-antipatterns.md +1271 -0
  112. package/expertise/antipatterns/backend/auth-antipatterns.md +1195 -0
  113. package/expertise/antipatterns/backend/caching-antipatterns.md +622 -0
  114. package/expertise/antipatterns/backend/database-antipatterns.md +1038 -0
  115. package/expertise/antipatterns/backend/index.md +24 -0
  116. package/expertise/antipatterns/backend/microservices-antipatterns.md +850 -0
  117. package/expertise/antipatterns/code/architecture-antipatterns.md +919 -0
  118. package/expertise/antipatterns/code/async-antipatterns.md +622 -0
  119. package/expertise/antipatterns/code/code-smells.md +1186 -0
  120. package/expertise/antipatterns/code/dependency-antipatterns.md +1209 -0
  121. package/expertise/antipatterns/code/error-handling-antipatterns.md +1360 -0
  122. package/expertise/antipatterns/code/index.md +27 -0
  123. package/expertise/antipatterns/code/naming-and-abstraction.md +1118 -0
  124. package/expertise/antipatterns/code/state-management-antipatterns.md +1076 -0
  125. package/expertise/antipatterns/code/testing-antipatterns.md +1053 -0
  126. package/expertise/antipatterns/design/accessibility-antipatterns.md +1136 -0
  127. package/expertise/antipatterns/design/dark-patterns.md +1121 -0
  128. package/expertise/antipatterns/design/index.md +22 -0
  129. package/expertise/antipatterns/design/ui-antipatterns.md +1202 -0
  130. package/expertise/antipatterns/design/ux-antipatterns.md +680 -0
  131. package/expertise/antipatterns/frontend/css-layout-antipatterns.md +691 -0
  132. package/expertise/antipatterns/frontend/flutter-antipatterns.md +1827 -0
  133. package/expertise/antipatterns/frontend/index.md +23 -0
  134. package/expertise/antipatterns/frontend/mobile-antipatterns.md +573 -0
  135. package/expertise/antipatterns/frontend/react-antipatterns.md +1128 -0
  136. package/expertise/antipatterns/frontend/spa-antipatterns.md +1235 -0
  137. package/expertise/antipatterns/index.md +31 -0
  138. package/expertise/antipatterns/performance/index.md +20 -0
  139. package/expertise/antipatterns/performance/performance-antipatterns.md +1013 -0
  140. package/expertise/antipatterns/performance/premature-optimization.md +623 -0
  141. package/expertise/antipatterns/performance/scaling-antipatterns.md +785 -0
  142. package/expertise/antipatterns/process/ai-coding-antipatterns.md +853 -0
  143. package/expertise/antipatterns/process/code-review-antipatterns.md +656 -0
  144. package/expertise/antipatterns/process/deployment-antipatterns.md +920 -0
  145. package/expertise/antipatterns/process/index.md +23 -0
  146. package/expertise/antipatterns/process/technical-debt-antipatterns.md +647 -0
  147. package/expertise/antipatterns/security/index.md +20 -0
  148. package/expertise/antipatterns/security/secrets-antipatterns.md +849 -0
  149. package/expertise/antipatterns/security/security-theater.md +843 -0
  150. package/expertise/antipatterns/security/vulnerability-patterns.md +801 -0
  151. package/expertise/architecture/PROGRESS.md +70 -0
  152. package/expertise/architecture/data/caching-architecture.md +671 -0
  153. package/expertise/architecture/data/data-consistency.md +574 -0
  154. package/expertise/architecture/data/data-modeling.md +536 -0
  155. package/expertise/architecture/data/event-streams-and-queues.md +634 -0
  156. package/expertise/architecture/data/index.md +25 -0
  157. package/expertise/architecture/data/search-architecture.md +663 -0
  158. package/expertise/architecture/data/sql-vs-nosql.md +708 -0
  159. package/expertise/architecture/decisions/architecture-decision-records.md +640 -0
  160. package/expertise/architecture/decisions/build-vs-buy.md +616 -0
  161. package/expertise/architecture/decisions/index.md +23 -0
  162. package/expertise/architecture/decisions/monolith-to-microservices.md +790 -0
  163. package/expertise/architecture/decisions/technology-selection.md +616 -0
  164. package/expertise/architecture/distributed/cap-theorem-and-tradeoffs.md +800 -0
  165. package/expertise/architecture/distributed/circuit-breaker-bulkhead.md +741 -0
  166. package/expertise/architecture/distributed/consensus-and-coordination.md +796 -0
  167. package/expertise/architecture/distributed/distributed-systems-fundamentals.md +564 -0
  168. package/expertise/architecture/distributed/idempotency-and-retry.md +796 -0
  169. package/expertise/architecture/distributed/index.md +25 -0
  170. package/expertise/architecture/distributed/saga-pattern.md +797 -0
  171. package/expertise/architecture/foundations/architectural-thinking.md +460 -0
  172. package/expertise/architecture/foundations/coupling-and-cohesion.md +770 -0
  173. package/expertise/architecture/foundations/design-principles-solid.md +649 -0
  174. package/expertise/architecture/foundations/domain-driven-design.md +719 -0
  175. package/expertise/architecture/foundations/index.md +25 -0
  176. package/expertise/architecture/foundations/separation-of-concerns.md +472 -0
  177. package/expertise/architecture/foundations/twelve-factor-app.md +797 -0
  178. package/expertise/architecture/index.md +34 -0
  179. package/expertise/architecture/integration/api-design-graphql.md +638 -0
  180. package/expertise/architecture/integration/api-design-grpc.md +804 -0
  181. package/expertise/architecture/integration/api-design-rest.md +892 -0
  182. package/expertise/architecture/integration/index.md +25 -0
  183. package/expertise/architecture/integration/third-party-integration.md +795 -0
  184. package/expertise/architecture/integration/webhooks-and-callbacks.md +1152 -0
  185. package/expertise/architecture/integration/websockets-realtime.md +791 -0
  186. package/expertise/architecture/mobile-architecture/index.md +22 -0
  187. package/expertise/architecture/mobile-architecture/mobile-app-architecture.md +780 -0
  188. package/expertise/architecture/mobile-architecture/mobile-backend-for-frontend.md +670 -0
  189. package/expertise/architecture/mobile-architecture/offline-first.md +719 -0
  190. package/expertise/architecture/mobile-architecture/push-and-sync.md +782 -0
  191. package/expertise/architecture/patterns/cqrs-event-sourcing.md +717 -0
  192. package/expertise/architecture/patterns/event-driven.md +797 -0
  193. package/expertise/architecture/patterns/hexagonal-clean-architecture.md +870 -0
  194. package/expertise/architecture/patterns/index.md +27 -0
  195. package/expertise/architecture/patterns/layered-architecture.md +736 -0
  196. package/expertise/architecture/patterns/microservices.md +753 -0
  197. package/expertise/architecture/patterns/modular-monolith.md +692 -0
  198. package/expertise/architecture/patterns/monolith.md +626 -0
  199. package/expertise/architecture/patterns/plugin-architecture.md +735 -0
  200. package/expertise/architecture/patterns/serverless.md +780 -0
  201. package/expertise/architecture/scaling/database-scaling.md +615 -0
  202. package/expertise/architecture/scaling/feature-flags-and-rollouts.md +757 -0
  203. package/expertise/architecture/scaling/horizontal-vs-vertical.md +606 -0
  204. package/expertise/architecture/scaling/index.md +24 -0
  205. package/expertise/architecture/scaling/multi-tenancy.md +800 -0
  206. package/expertise/architecture/scaling/stateless-design.md +787 -0
  207. package/expertise/backend/embedded-firmware.md +625 -0
  208. package/expertise/backend/go.md +853 -0
  209. package/expertise/backend/index.md +24 -0
  210. package/expertise/backend/java-spring.md +448 -0
  211. package/expertise/backend/node-typescript.md +625 -0
  212. package/expertise/backend/python-fastapi.md +724 -0
  213. package/expertise/backend/rust.md +458 -0
  214. package/expertise/backend/solidity.md +711 -0
  215. package/expertise/composition-map.yaml +443 -0
  216. package/expertise/content/foundations/content-modeling.md +395 -0
  217. package/expertise/content/foundations/editorial-standards.md +449 -0
  218. package/expertise/content/foundations/index.md +24 -0
  219. package/expertise/content/foundations/microcopy.md +455 -0
  220. package/expertise/content/foundations/terminology-governance.md +509 -0
  221. package/expertise/content/index.md +34 -0
  222. package/expertise/content/patterns/accessibility-copy.md +518 -0
  223. package/expertise/content/patterns/index.md +24 -0
  224. package/expertise/content/patterns/notification-content.md +433 -0
  225. package/expertise/content/patterns/sample-content.md +486 -0
  226. package/expertise/content/patterns/state-copy.md +439 -0
  227. package/expertise/design/PROGRESS.md +58 -0
  228. package/expertise/design/disciplines/dark-mode-theming.md +577 -0
  229. package/expertise/design/disciplines/design-systems.md +595 -0
  230. package/expertise/design/disciplines/index.md +25 -0
  231. package/expertise/design/disciplines/information-architecture.md +800 -0
  232. package/expertise/design/disciplines/interaction-design.md +788 -0
  233. package/expertise/design/disciplines/responsive-design.md +552 -0
  234. package/expertise/design/disciplines/usability-testing.md +516 -0
  235. package/expertise/design/disciplines/user-research.md +792 -0
  236. package/expertise/design/foundations/accessibility-design.md +796 -0
  237. package/expertise/design/foundations/color-theory.md +797 -0
  238. package/expertise/design/foundations/iconography.md +795 -0
  239. package/expertise/design/foundations/index.md +26 -0
  240. package/expertise/design/foundations/motion-and-animation.md +653 -0
  241. package/expertise/design/foundations/rtl-design.md +585 -0
  242. package/expertise/design/foundations/spacing-and-layout.md +607 -0
  243. package/expertise/design/foundations/typography.md +800 -0
  244. package/expertise/design/foundations/visual-hierarchy.md +761 -0
  245. package/expertise/design/index.md +32 -0
  246. package/expertise/design/patterns/authentication-flows.md +474 -0
  247. package/expertise/design/patterns/content-consumption.md +789 -0
  248. package/expertise/design/patterns/data-display.md +618 -0
  249. package/expertise/design/patterns/e-commerce.md +1494 -0
  250. package/expertise/design/patterns/feedback-and-states.md +642 -0
  251. package/expertise/design/patterns/forms-and-input.md +819 -0
  252. package/expertise/design/patterns/gamification.md +801 -0
  253. package/expertise/design/patterns/index.md +31 -0
  254. package/expertise/design/patterns/microinteractions.md +449 -0
  255. package/expertise/design/patterns/navigation.md +800 -0
  256. package/expertise/design/patterns/notifications.md +705 -0
  257. package/expertise/design/patterns/onboarding.md +700 -0
  258. package/expertise/design/patterns/search-and-filter.md +601 -0
  259. package/expertise/design/patterns/settings-and-preferences.md +768 -0
  260. package/expertise/design/patterns/social-and-community.md +748 -0
  261. package/expertise/design/platforms/desktop-native.md +612 -0
  262. package/expertise/design/platforms/index.md +25 -0
  263. package/expertise/design/platforms/mobile-android.md +825 -0
  264. package/expertise/design/platforms/mobile-cross-platform.md +983 -0
  265. package/expertise/design/platforms/mobile-ios.md +699 -0
  266. package/expertise/design/platforms/tablet.md +794 -0
  267. package/expertise/design/platforms/web-dashboard.md +790 -0
  268. package/expertise/design/platforms/web-responsive.md +550 -0
  269. package/expertise/design/psychology/behavioral-nudges.md +449 -0
  270. package/expertise/design/psychology/cognitive-load.md +1191 -0
  271. package/expertise/design/psychology/error-psychology.md +778 -0
  272. package/expertise/design/psychology/index.md +22 -0
  273. package/expertise/design/psychology/persuasive-design.md +736 -0
  274. package/expertise/design/psychology/user-mental-models.md +623 -0
  275. package/expertise/design/tooling/open-pencil.md +266 -0
  276. package/expertise/frontend/angular.md +1073 -0
  277. package/expertise/frontend/desktop-electron.md +546 -0
  278. package/expertise/frontend/flutter.md +782 -0
  279. package/expertise/frontend/index.md +27 -0
  280. package/expertise/frontend/native-android.md +409 -0
  281. package/expertise/frontend/native-ios.md +490 -0
  282. package/expertise/frontend/react-native.md +1160 -0
  283. package/expertise/frontend/react.md +808 -0
  284. package/expertise/frontend/vue.md +1089 -0
  285. package/expertise/humanize/domain-rules-code.md +79 -0
  286. package/expertise/humanize/domain-rules-content.md +67 -0
  287. package/expertise/humanize/domain-rules-technical-docs.md +56 -0
  288. package/expertise/humanize/index.md +35 -0
  289. package/expertise/humanize/self-audit-checklist.md +87 -0
  290. package/expertise/humanize/sentence-patterns.md +218 -0
  291. package/expertise/humanize/vocabulary-blacklist.md +105 -0
  292. package/expertise/i18n/PROGRESS.md +65 -0
  293. package/expertise/i18n/advanced/accessibility-and-i18n.md +28 -0
  294. package/expertise/i18n/advanced/bidirectional-text-algorithm.md +38 -0
  295. package/expertise/i18n/advanced/complex-scripts.md +30 -0
  296. package/expertise/i18n/advanced/performance-and-i18n.md +27 -0
  297. package/expertise/i18n/advanced/testing-i18n.md +28 -0
  298. package/expertise/i18n/content/content-adaptation.md +23 -0
  299. package/expertise/i18n/content/locale-specific-formatting.md +23 -0
  300. package/expertise/i18n/content/machine-translation-integration.md +28 -0
  301. package/expertise/i18n/content/translation-management.md +29 -0
  302. package/expertise/i18n/foundations/date-time-calendars.md +67 -0
  303. package/expertise/i18n/foundations/i18n-architecture.md +272 -0
  304. package/expertise/i18n/foundations/locale-and-language-tags.md +79 -0
  305. package/expertise/i18n/foundations/numbers-currency-units.md +61 -0
  306. package/expertise/i18n/foundations/pluralization-and-gender.md +109 -0
  307. package/expertise/i18n/foundations/string-externalization.md +236 -0
  308. package/expertise/i18n/foundations/text-direction-bidi.md +241 -0
  309. package/expertise/i18n/foundations/unicode-and-encoding.md +86 -0
  310. package/expertise/i18n/index.md +38 -0
  311. package/expertise/i18n/platform/backend-i18n.md +31 -0
  312. package/expertise/i18n/platform/flutter-i18n.md +148 -0
  313. package/expertise/i18n/platform/native-android-i18n.md +36 -0
  314. package/expertise/i18n/platform/native-ios-i18n.md +36 -0
  315. package/expertise/i18n/platform/react-i18n.md +103 -0
  316. package/expertise/i18n/platform/web-css-i18n.md +81 -0
  317. package/expertise/i18n/rtl/arabic-specific.md +175 -0
  318. package/expertise/i18n/rtl/hebrew-specific.md +149 -0
  319. package/expertise/i18n/rtl/rtl-animations-and-transitions.md +111 -0
  320. package/expertise/i18n/rtl/rtl-forms-and-input.md +161 -0
  321. package/expertise/i18n/rtl/rtl-fundamentals.md +211 -0
  322. package/expertise/i18n/rtl/rtl-icons-and-images.md +181 -0
  323. package/expertise/i18n/rtl/rtl-layout-mirroring.md +252 -0
  324. package/expertise/i18n/rtl/rtl-navigation-and-gestures.md +107 -0
  325. package/expertise/i18n/rtl/rtl-testing-and-qa.md +147 -0
  326. package/expertise/i18n/rtl/rtl-typography.md +160 -0
  327. package/expertise/index.md +113 -0
  328. package/expertise/index.yaml +216 -0
  329. package/expertise/infrastructure/cloud-aws.md +597 -0
  330. package/expertise/infrastructure/cloud-gcp.md +599 -0
  331. package/expertise/infrastructure/cybersecurity.md +816 -0
  332. package/expertise/infrastructure/database-mongodb.md +447 -0
  333. package/expertise/infrastructure/database-postgres.md +400 -0
  334. package/expertise/infrastructure/devops-cicd.md +787 -0
  335. package/expertise/infrastructure/index.md +27 -0
  336. package/expertise/performance/PROGRESS.md +50 -0
  337. package/expertise/performance/backend/api-latency.md +1204 -0
  338. package/expertise/performance/backend/background-jobs.md +506 -0
  339. package/expertise/performance/backend/connection-pooling.md +1209 -0
  340. package/expertise/performance/backend/database-query-optimization.md +515 -0
  341. package/expertise/performance/backend/index.md +23 -0
  342. package/expertise/performance/backend/rate-limiting-and-throttling.md +971 -0
  343. package/expertise/performance/foundations/algorithmic-complexity.md +954 -0
  344. package/expertise/performance/foundations/caching-strategies.md +489 -0
  345. package/expertise/performance/foundations/concurrency-and-parallelism.md +847 -0
  346. package/expertise/performance/foundations/index.md +24 -0
  347. package/expertise/performance/foundations/measuring-and-profiling.md +440 -0
  348. package/expertise/performance/foundations/memory-management.md +964 -0
  349. package/expertise/performance/foundations/performance-budgets.md +1314 -0
  350. package/expertise/performance/index.md +31 -0
  351. package/expertise/performance/infrastructure/auto-scaling.md +1059 -0
  352. package/expertise/performance/infrastructure/cdn-and-edge.md +1081 -0
  353. package/expertise/performance/infrastructure/index.md +22 -0
  354. package/expertise/performance/infrastructure/load-balancing.md +1081 -0
  355. package/expertise/performance/infrastructure/observability.md +1079 -0
  356. package/expertise/performance/mobile/index.md +23 -0
  357. package/expertise/performance/mobile/mobile-animations.md +544 -0
  358. package/expertise/performance/mobile/mobile-memory-battery.md +416 -0
  359. package/expertise/performance/mobile/mobile-network.md +452 -0
  360. package/expertise/performance/mobile/mobile-rendering.md +599 -0
  361. package/expertise/performance/mobile/mobile-startup-time.md +505 -0
  362. package/expertise/performance/platform-specific/flutter-performance.md +647 -0
  363. package/expertise/performance/platform-specific/index.md +22 -0
  364. package/expertise/performance/platform-specific/node-performance.md +1307 -0
  365. package/expertise/performance/platform-specific/postgres-performance.md +1366 -0
  366. package/expertise/performance/platform-specific/react-performance.md +1403 -0
  367. package/expertise/performance/web/bundle-optimization.md +1239 -0
  368. package/expertise/performance/web/image-and-media.md +636 -0
  369. package/expertise/performance/web/index.md +24 -0
  370. package/expertise/performance/web/network-optimization.md +1133 -0
  371. package/expertise/performance/web/rendering-performance.md +1098 -0
  372. package/expertise/performance/web/ssr-and-hydration.md +918 -0
  373. package/expertise/performance/web/web-vitals.md +1374 -0
  374. package/expertise/quality/accessibility.md +985 -0
  375. package/expertise/quality/evidence-based-verification.md +499 -0
  376. package/expertise/quality/index.md +24 -0
  377. package/expertise/quality/ml-model-audit.md +614 -0
  378. package/expertise/quality/performance.md +600 -0
  379. package/expertise/quality/testing-api.md +891 -0
  380. package/expertise/quality/testing-mobile.md +496 -0
  381. package/expertise/quality/testing-web.md +849 -0
  382. package/expertise/security/PROGRESS.md +54 -0
  383. package/expertise/security/agentic-identity.md +540 -0
  384. package/expertise/security/compliance-frameworks.md +601 -0
  385. package/expertise/security/data/data-encryption.md +364 -0
  386. package/expertise/security/data/data-privacy-gdpr.md +692 -0
  387. package/expertise/security/data/database-security.md +1171 -0
  388. package/expertise/security/data/index.md +22 -0
  389. package/expertise/security/data/pii-handling.md +531 -0
  390. package/expertise/security/foundations/authentication.md +1041 -0
  391. package/expertise/security/foundations/authorization.md +603 -0
  392. package/expertise/security/foundations/cryptography.md +1001 -0
  393. package/expertise/security/foundations/index.md +25 -0
  394. package/expertise/security/foundations/owasp-top-10.md +1354 -0
  395. package/expertise/security/foundations/secrets-management.md +1217 -0
  396. package/expertise/security/foundations/secure-sdlc.md +700 -0
  397. package/expertise/security/foundations/supply-chain-security.md +698 -0
  398. package/expertise/security/index.md +31 -0
  399. package/expertise/security/infrastructure/cloud-security-aws.md +1296 -0
  400. package/expertise/security/infrastructure/cloud-security-gcp.md +1376 -0
  401. package/expertise/security/infrastructure/container-security.md +721 -0
  402. package/expertise/security/infrastructure/incident-response.md +1295 -0
  403. package/expertise/security/infrastructure/index.md +24 -0
  404. package/expertise/security/infrastructure/logging-and-monitoring.md +1618 -0
  405. package/expertise/security/infrastructure/network-security.md +1337 -0
  406. package/expertise/security/mobile/index.md +23 -0
  407. package/expertise/security/mobile/mobile-android-security.md +1218 -0
  408. package/expertise/security/mobile/mobile-binary-protection.md +1229 -0
  409. package/expertise/security/mobile/mobile-data-storage.md +1265 -0
  410. package/expertise/security/mobile/mobile-ios-security.md +1401 -0
  411. package/expertise/security/mobile/mobile-network-security.md +1520 -0
  412. package/expertise/security/smart-contract-security.md +594 -0
  413. package/expertise/security/testing/index.md +22 -0
  414. package/expertise/security/testing/penetration-testing.md +1258 -0
  415. package/expertise/security/testing/security-code-review.md +1765 -0
  416. package/expertise/security/testing/threat-modeling.md +1074 -0
  417. package/expertise/security/testing/vulnerability-scanning.md +1062 -0
  418. package/expertise/security/web/api-security.md +586 -0
  419. package/expertise/security/web/cors-and-headers.md +433 -0
  420. package/expertise/security/web/csrf.md +562 -0
  421. package/expertise/security/web/file-upload.md +1477 -0
  422. package/expertise/security/web/index.md +25 -0
  423. package/expertise/security/web/injection.md +1375 -0
  424. package/expertise/security/web/session-management.md +1101 -0
  425. package/expertise/security/web/xss.md +1158 -0
  426. package/exports/README.md +17 -0
  427. package/exports/hosts/claude/.claude/agents/clarifier.md +42 -0
  428. package/exports/hosts/claude/.claude/agents/content-author.md +63 -0
  429. package/exports/hosts/claude/.claude/agents/designer.md +55 -0
  430. package/exports/hosts/claude/.claude/agents/executor.md +55 -0
  431. package/exports/hosts/claude/.claude/agents/learner.md +51 -0
  432. package/exports/hosts/claude/.claude/agents/planner.md +53 -0
  433. package/exports/hosts/claude/.claude/agents/researcher.md +43 -0
  434. package/exports/hosts/claude/.claude/agents/reviewer.md +54 -0
  435. package/exports/hosts/claude/.claude/agents/specifier.md +47 -0
  436. package/exports/hosts/claude/.claude/agents/verifier.md +71 -0
  437. package/exports/hosts/claude/.claude/commands/author.md +42 -0
  438. package/exports/hosts/claude/.claude/commands/clarify.md +38 -0
  439. package/exports/hosts/claude/.claude/commands/design-review.md +46 -0
  440. package/exports/hosts/claude/.claude/commands/design.md +44 -0
  441. package/exports/hosts/claude/.claude/commands/discover.md +37 -0
  442. package/exports/hosts/claude/.claude/commands/execute.md +48 -0
  443. package/exports/hosts/claude/.claude/commands/learn.md +38 -0
  444. package/exports/hosts/claude/.claude/commands/plan-review.md +42 -0
  445. package/exports/hosts/claude/.claude/commands/plan.md +39 -0
  446. package/exports/hosts/claude/.claude/commands/prepare-next.md +37 -0
  447. package/exports/hosts/claude/.claude/commands/review.md +40 -0
  448. package/exports/hosts/claude/.claude/commands/run-audit.md +41 -0
  449. package/exports/hosts/claude/.claude/commands/spec-challenge.md +41 -0
  450. package/exports/hosts/claude/.claude/commands/specify.md +38 -0
  451. package/exports/hosts/claude/.claude/commands/verify.md +37 -0
  452. package/exports/hosts/claude/.claude/settings.json +34 -0
  453. package/exports/hosts/claude/CLAUDE.md +19 -0
  454. package/exports/hosts/claude/export.manifest.json +38 -0
  455. package/exports/hosts/claude/host-package.json +67 -0
  456. package/exports/hosts/codex/AGENTS.md +19 -0
  457. package/exports/hosts/codex/export.manifest.json +38 -0
  458. package/exports/hosts/codex/host-package.json +41 -0
  459. package/exports/hosts/cursor/.cursor/hooks.json +16 -0
  460. package/exports/hosts/cursor/.cursor/rules/wazir-core.mdc +19 -0
  461. package/exports/hosts/cursor/export.manifest.json +38 -0
  462. package/exports/hosts/cursor/host-package.json +42 -0
  463. package/exports/hosts/gemini/GEMINI.md +19 -0
  464. package/exports/hosts/gemini/export.manifest.json +38 -0
  465. package/exports/hosts/gemini/host-package.json +41 -0
  466. package/hooks/README.md +18 -0
  467. package/hooks/definitions/loop_cap_guard.yaml +21 -0
  468. package/hooks/definitions/post_tool_capture.yaml +24 -0
  469. package/hooks/definitions/pre_compact_summary.yaml +19 -0
  470. package/hooks/definitions/pre_tool_capture_route.yaml +19 -0
  471. package/hooks/definitions/protected_path_write_guard.yaml +19 -0
  472. package/hooks/definitions/session_start.yaml +19 -0
  473. package/hooks/definitions/stop_handoff_harvest.yaml +20 -0
  474. package/hooks/loop-cap-guard +17 -0
  475. package/hooks/post-tool-lint +36 -0
  476. package/hooks/protected-path-write-guard +17 -0
  477. package/hooks/session-start +41 -0
  478. package/llms-full.txt +2355 -0
  479. package/llms.txt +43 -0
  480. package/package.json +79 -0
  481. package/roles/README.md +20 -0
  482. package/roles/clarifier.md +42 -0
  483. package/roles/content-author.md +63 -0
  484. package/roles/designer.md +55 -0
  485. package/roles/executor.md +55 -0
  486. package/roles/learner.md +51 -0
  487. package/roles/planner.md +53 -0
  488. package/roles/researcher.md +43 -0
  489. package/roles/reviewer.md +54 -0
  490. package/roles/specifier.md +47 -0
  491. package/roles/verifier.md +71 -0
  492. package/schemas/README.md +24 -0
  493. package/schemas/accepted-learning.schema.json +20 -0
  494. package/schemas/author-artifact.schema.json +156 -0
  495. package/schemas/clarification.schema.json +19 -0
  496. package/schemas/design-artifact.schema.json +80 -0
  497. package/schemas/docs-claim.schema.json +18 -0
  498. package/schemas/export-manifest.schema.json +20 -0
  499. package/schemas/hook.schema.json +67 -0
  500. package/schemas/host-export-package.schema.json +18 -0
  501. package/schemas/implementation-plan.schema.json +19 -0
  502. package/schemas/proposed-learning.schema.json +19 -0
  503. package/schemas/research.schema.json +18 -0
  504. package/schemas/review.schema.json +29 -0
  505. package/schemas/run-manifest.schema.json +18 -0
  506. package/schemas/spec-challenge.schema.json +18 -0
  507. package/schemas/spec.schema.json +20 -0
  508. package/schemas/usage.schema.json +102 -0
  509. package/schemas/verification-proof.schema.json +29 -0
  510. package/schemas/wazir-manifest.schema.json +173 -0
  511. package/skills/README.md +40 -0
  512. package/skills/brainstorming/SKILL.md +77 -0
  513. package/skills/debugging/SKILL.md +50 -0
  514. package/skills/design/SKILL.md +61 -0
  515. package/skills/dispatching-parallel-agents/SKILL.md +128 -0
  516. package/skills/executing-plans/SKILL.md +70 -0
  517. package/skills/finishing-a-development-branch/SKILL.md +169 -0
  518. package/skills/humanize/SKILL.md +123 -0
  519. package/skills/init-pipeline/SKILL.md +124 -0
  520. package/skills/prepare-next/SKILL.md +20 -0
  521. package/skills/receiving-code-review/SKILL.md +123 -0
  522. package/skills/requesting-code-review/SKILL.md +105 -0
  523. package/skills/requesting-code-review/code-reviewer.md +108 -0
  524. package/skills/run-audit/SKILL.md +197 -0
  525. package/skills/scan-project/SKILL.md +41 -0
  526. package/skills/self-audit/SKILL.md +153 -0
  527. package/skills/subagent-driven-development/SKILL.md +154 -0
  528. package/skills/subagent-driven-development/code-quality-reviewer-prompt.md +26 -0
  529. package/skills/subagent-driven-development/implementer-prompt.md +102 -0
  530. package/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -0
  531. package/skills/tdd/SKILL.md +23 -0
  532. package/skills/using-git-worktrees/SKILL.md +163 -0
  533. package/skills/using-skills/SKILL.md +95 -0
  534. package/skills/verification/SKILL.md +22 -0
  535. package/skills/wazir/SKILL.md +463 -0
  536. package/skills/writing-plans/SKILL.md +30 -0
  537. package/skills/writing-skills/SKILL.md +157 -0
  538. package/skills/writing-skills/anthropic-best-practices.md +122 -0
  539. package/skills/writing-skills/persuasion-principles.md +50 -0
  540. package/templates/README.md +20 -0
  541. package/templates/artifacts/README.md +10 -0
  542. package/templates/artifacts/accepted-learning.md +19 -0
  543. package/templates/artifacts/accepted-learning.template.json +12 -0
  544. package/templates/artifacts/author.md +74 -0
  545. package/templates/artifacts/author.template.json +19 -0
  546. package/templates/artifacts/clarification.md +21 -0
  547. package/templates/artifacts/clarification.template.json +12 -0
  548. package/templates/artifacts/execute-notes.md +19 -0
  549. package/templates/artifacts/implementation-plan.md +21 -0
  550. package/templates/artifacts/implementation-plan.template.json +11 -0
  551. package/templates/artifacts/learning-proposal.md +19 -0
  552. package/templates/artifacts/next-run-handoff.md +21 -0
  553. package/templates/artifacts/plan-review.md +19 -0
  554. package/templates/artifacts/proposed-learning.template.json +12 -0
  555. package/templates/artifacts/research.md +21 -0
  556. package/templates/artifacts/research.template.json +12 -0
  557. package/templates/artifacts/review-findings.md +19 -0
  558. package/templates/artifacts/review.template.json +11 -0
  559. package/templates/artifacts/run-manifest.template.json +8 -0
  560. package/templates/artifacts/spec-challenge.md +19 -0
  561. package/templates/artifacts/spec-challenge.template.json +11 -0
  562. package/templates/artifacts/spec.md +21 -0
  563. package/templates/artifacts/spec.template.json +12 -0
  564. package/templates/artifacts/verification-proof.md +19 -0
  565. package/templates/artifacts/verification-proof.template.json +11 -0
  566. package/templates/examples/accepted-learning.example.json +14 -0
  567. package/templates/examples/author.example.json +152 -0
  568. package/templates/examples/clarification.example.json +15 -0
  569. package/templates/examples/docs-claim.example.json +8 -0
  570. package/templates/examples/export-manifest.example.json +7 -0
  571. package/templates/examples/host-export-package.example.json +11 -0
  572. package/templates/examples/implementation-plan.example.json +17 -0
  573. package/templates/examples/proposed-learning.example.json +13 -0
  574. package/templates/examples/research.example.json +15 -0
  575. package/templates/examples/research.example.md +6 -0
  576. package/templates/examples/review.example.json +17 -0
  577. package/templates/examples/run-manifest.example.json +9 -0
  578. package/templates/examples/spec-challenge.example.json +14 -0
  579. package/templates/examples/spec.example.json +21 -0
  580. package/templates/examples/verification-proof.example.json +21 -0
  581. package/templates/examples/wazir-manifest.example.yaml +65 -0
  582. package/templates/task-definition-schema.md +99 -0
  583. package/tooling/README.md +20 -0
  584. package/tooling/src/adapters/context-mode.js +50 -0
  585. package/tooling/src/capture/command.js +376 -0
  586. package/tooling/src/capture/store.js +99 -0
  587. package/tooling/src/capture/usage.js +270 -0
  588. package/tooling/src/checks/branches.js +50 -0
  589. package/tooling/src/checks/brand-truth.js +110 -0
  590. package/tooling/src/checks/changelog.js +231 -0
  591. package/tooling/src/checks/command-registry.js +36 -0
  592. package/tooling/src/checks/commits.js +102 -0
  593. package/tooling/src/checks/docs-drift.js +103 -0
  594. package/tooling/src/checks/docs-truth.js +201 -0
  595. package/tooling/src/checks/runtime-surface.js +156 -0
  596. package/tooling/src/cli.js +116 -0
  597. package/tooling/src/command-options.js +56 -0
  598. package/tooling/src/commands/validate.js +320 -0
  599. package/tooling/src/doctor/command.js +91 -0
  600. package/tooling/src/export/command.js +77 -0
  601. package/tooling/src/export/compiler.js +498 -0
  602. package/tooling/src/guards/loop-cap-guard.js +52 -0
  603. package/tooling/src/guards/protected-path-write-guard.js +67 -0
  604. package/tooling/src/index/command.js +152 -0
  605. package/tooling/src/index/storage.js +1061 -0
  606. package/tooling/src/index/summarizers.js +261 -0
  607. package/tooling/src/loaders.js +18 -0
  608. package/tooling/src/project-root.js +22 -0
  609. package/tooling/src/recall/command.js +225 -0
  610. package/tooling/src/schema-validator.js +30 -0
  611. package/tooling/src/state-root.js +40 -0
  612. package/tooling/src/status/command.js +71 -0
  613. package/wazir.manifest.yaml +135 -0
  614. package/workflows/README.md +19 -0
  615. package/workflows/author.md +42 -0
  616. package/workflows/clarify.md +38 -0
  617. package/workflows/design-review.md +46 -0
  618. package/workflows/design.md +44 -0
  619. package/workflows/discover.md +37 -0
  620. package/workflows/execute.md +48 -0
  621. package/workflows/learn.md +38 -0
  622. package/workflows/plan-review.md +42 -0
  623. package/workflows/plan.md +39 -0
  624. package/workflows/prepare-next.md +37 -0
  625. package/workflows/review.md +40 -0
  626. package/workflows/run-audit.md +41 -0
  627. package/workflows/spec-challenge.md +41 -0
  628. package/workflows/specify.md +38 -0
  629. package/workflows/verify.md +37 -0
@@ -0,0 +1,1073 @@
1
+ # Angular — Expertise Module
2
+
3
+ > An Angular specialist designs, builds, and maintains web applications using Angular (v17+),
4
+ > leveraging standalone components, signal-based reactivity, and the modern Angular toolchain.
5
+ > Scope spans component architecture, state management, performance optimization, SSR, security, and DevOps.
6
+
7
+ ---
8
+
9
+ ## Core Patterns & Conventions
10
+
11
+ ### Project Structure
12
+
13
+ **Standalone-first (Angular 19+ default):**
14
+
15
+ ```
16
+ src/
17
+ app/
18
+ app.component.ts # Root standalone component
19
+ app.config.ts # provideRouter, provideHttpClient, etc.
20
+ app.routes.ts # Top-level route config
21
+ core/ # Singletons: auth, error handler, interceptors
22
+ interceptors/
23
+ guards/
24
+ services/
25
+ shared/ # Reusable pipes, directives, UI primitives
26
+ components/
27
+ directives/
28
+ pipes/
29
+ features/
30
+ dashboard/
31
+ dashboard.component.ts
32
+ dashboard.routes.ts
33
+ components/ # Dumb/presentational components
34
+ services/ # Feature-scoped services
35
+ models/
36
+ users/
37
+ ...
38
+ layouts/ # Shell components (sidebar, header)
39
+ environments/
40
+ environment.ts
41
+ environment.prod.ts
42
+ ```
43
+
44
+ **Nx Monorepo (enterprise):**
45
+
46
+ ```
47
+ apps/
48
+ web-app/
49
+ admin-app/
50
+ libs/
51
+ shared/ui/ # Reusable UI components
52
+ shared/data-access/ # HTTP services, stores
53
+ shared/util/ # Pure utility functions
54
+ feature-dashboard/ # Feature library
55
+ feature-auth/
56
+ ```
57
+
58
+ Nx enforces module boundaries via `@nx/enforce-module-boundaries` lint rule. Library categories: `feature`, `data-access`, `ui`, `util`, `shell`.
59
+
60
+ ### Naming Conventions (Angular Style Guide)
61
+
62
+ | Artifact | Pattern | Example |
63
+ |-------------------|------------------------------------|--------------------------------|
64
+ | Component | `feature-name.component.ts` | `user-list.component.ts` |
65
+ | Service | `feature-name.service.ts` | `auth.service.ts` |
66
+ | Directive | `feature-name.directive.ts` | `highlight.directive.ts` |
67
+ | Pipe | `feature-name.pipe.ts` | `truncate.pipe.ts` |
68
+ | Guard | `feature-name.guard.ts` | `auth.guard.ts` |
69
+ | Interceptor | `feature-name.interceptor.ts` | `error.interceptor.ts` |
70
+ | Interface/Model | `feature-name.model.ts` | `user.model.ts` |
71
+ | Route config | `feature-name.routes.ts` | `dashboard.routes.ts` |
72
+
73
+ - Use `kebab-case` for file names, `PascalCase` for classes, `camelCase` for methods/properties.
74
+ - Prefix selectors: `app-` for app components, `shared-` for shared library components.
75
+ - One class per file. Max 400 lines per component file — split if larger.
76
+
77
+ ### Architecture Patterns
78
+
79
+ **Smart (Container) vs Dumb (Presentational) Components:**
80
+
81
+ - **Smart components**: inject services, manage state, dispatch actions, handle routing. Located in `features/<name>/`.
82
+ - **Dumb components**: receive data via `input()`, emit events via `output()`. Located in `features/<name>/components/` or `shared/components/`.
83
+ - Dumb components must have zero service dependencies and `changeDetection: ChangeDetectionStrategy.OnPush`.
84
+
85
+ **Feature-based architecture**: group all related code (components, services, routes, models) inside a single feature directory. Each feature owns its own routes file and lazy-loads independently.
86
+
87
+ ### Signal-Based Reactivity (Angular 17+)
88
+
89
+ Signals are Angular's synchronous, fine-grained reactivity primitive. As of Angular 19-20, signals, `computed()`, `effect()`, `linkedSignal()`, `input()`, `output()`, `viewChild()`, and `contentChild()` are all stable.
90
+
91
+ ```typescript
92
+ // Signal basics
93
+ count = signal(0);
94
+ doubleCount = computed(() => this.count() * 2);
95
+
96
+ // Signal inputs (replacing @Input)
97
+ name = input<string>(); // optional
98
+ name = input.required<string>(); // required
99
+ name = input('default'); // with default
100
+
101
+ // Signal outputs (replacing @Output)
102
+ clicked = output<MouseEvent>();
103
+
104
+ // Model inputs (two-way binding)
105
+ value = model<string>(''); // parent binds with [(value)]
106
+
107
+ // Signal queries (replacing @ViewChild/@ContentChild)
108
+ myRef = viewChild<ElementRef>('myRef');
109
+ items = contentChildren(ItemComponent);
110
+ ```
111
+
112
+ **`effect()`** runs side effects when signals change. Use sparingly — prefer `computed()` for derived state:
113
+
114
+ ```typescript
115
+ effect(() => {
116
+ console.log(`Count changed: ${this.count()}`);
117
+ });
118
+ ```
119
+
120
+ **`linkedSignal()`** (Angular 19+): a writable signal that resets when a source changes:
121
+
122
+ ```typescript
123
+ selectedIndex = linkedSignal({
124
+ source: this.items,
125
+ computation: () => 0 // reset to 0 when items change
126
+ });
127
+ ```
128
+
129
+ **`resource()` / `rxResource()`** (Angular 19+): declarative async data fetching tied to signals:
130
+
131
+ ```typescript
132
+ userData = rxResource({
133
+ request: () => ({ id: this.userId() }),
134
+ loader: ({ request }) => this.http.get<User>(`/api/users/${request.id}`)
135
+ });
136
+ // userData.value(), userData.isLoading(), userData.error()
137
+ ```
138
+
139
+ ### State Management
140
+
141
+ **Tier 1 — Local component state**: plain `signal()` + `computed()`. Sufficient for most components.
142
+
143
+ **Tier 2 — Shared feature state**: injectable service with signals:
144
+
145
+ ```typescript
146
+ @Injectable({ providedIn: 'root' })
147
+ export class CartService {
148
+ private readonly _items = signal<CartItem[]>([]);
149
+ readonly items = this._items.asReadonly();
150
+ readonly total = computed(() =>
151
+ this._items().reduce((sum, i) => sum + i.price * i.qty, 0)
152
+ );
153
+
154
+ addItem(item: CartItem) {
155
+ this._items.update(items => [...items, item]);
156
+ }
157
+ }
158
+ ```
159
+
160
+ **Tier 3 — NgRx SignalStore** (for complex shared state with plugins):
161
+
162
+ ```typescript
163
+ export const ProductStore = signalStore(
164
+ { providedIn: 'root' },
165
+ withState({ products: [] as Product[], loading: false }),
166
+ withComputed(({ products }) => ({
167
+ count: computed(() => products().length),
168
+ })),
169
+ withMethods((store, http = inject(HttpClient)) => ({
170
+ loadProducts: rxMethod<void>(
171
+ pipe(
172
+ tap(() => patchState(store, { loading: true })),
173
+ switchMap(() => http.get<Product[]>('/api/products')),
174
+ tap(products => patchState(store, { products, loading: false }))
175
+ )
176
+ ),
177
+ }))
178
+ );
179
+ ```
180
+
181
+ **Tier 4 — NgRx Store** (global Redux pattern): use only when you need DevTools time-travel, action logging across the entire app, or complex action orchestration with Effects. High boilerplate cost (actions, reducers, selectors, effects).
182
+
183
+ ### Routing
184
+
185
+ **Standalone route config (Angular 17+):**
186
+
187
+ ```typescript
188
+ // app.routes.ts
189
+ export const routes: Routes = [
190
+ { path: '', component: HomeComponent },
191
+ {
192
+ path: 'dashboard',
193
+ loadComponent: () => import('./features/dashboard/dashboard.component')
194
+ .then(m => m.DashboardComponent),
195
+ },
196
+ {
197
+ path: 'admin',
198
+ loadChildren: () => import('./features/admin/admin.routes')
199
+ .then(m => m.ADMIN_ROUTES),
200
+ canActivate: [authGuard],
201
+ },
202
+ ];
203
+ ```
204
+
205
+ **Functional guards (Angular 15+):**
206
+
207
+ ```typescript
208
+ export const authGuard: CanActivateFn = (route, state) => {
209
+ const auth = inject(AuthService);
210
+ const router = inject(Router);
211
+ return auth.isAuthenticated() ? true : router.createUrlTree(['/login']);
212
+ };
213
+ ```
214
+
215
+ - Prefer `loadComponent` for single-component routes and `loadChildren` for feature route groups.
216
+ - Use `resolve` for route data pre-fetching. Use `canMatch` to conditionally load different components for the same route path.
217
+
218
+ ### Data Flow Patterns
219
+
220
+ - **Template binding**: prefer signals over observables. Convert observables with `toSignal()` before template binding.
221
+ - **Service-to-component**: return signals from services; use `computed()` for derived state.
222
+ - **Component-to-component**: use `input()` / `output()` for parent-child; use a shared signal service for sibling communication.
223
+ - **RxJS operators** remain essential for: `debounceTime`, `switchMap`, `retry`, `combineLatest`, `merge`, `takeUntilDestroyed`.
224
+
225
+ ### Error Handling
226
+
227
+ **Global ErrorHandler:**
228
+
229
+ ```typescript
230
+ @Injectable()
231
+ export class GlobalErrorHandler implements ErrorHandler {
232
+ handleError(error: unknown): void {
233
+ // Log to Sentry / external service
234
+ console.error('Unhandled error:', error);
235
+ }
236
+ }
237
+
238
+ // Provide in app.config.ts
239
+ { provide: ErrorHandler, useClass: GlobalErrorHandler }
240
+ ```
241
+
242
+ **HTTP error interceptor (functional):**
243
+
244
+ ```typescript
245
+ export const errorInterceptor: HttpInterceptorFn = (req, next) =>
246
+ next(req).pipe(
247
+ retry({ count: 2, delay: 1000 }),
248
+ catchError((error: HttpErrorResponse) => {
249
+ if (error.status === 401) inject(Router).navigate(['/login']);
250
+ return throwError(() => error);
251
+ })
252
+ );
253
+ ```
254
+
255
+ ### Logging and Observability
256
+
257
+ - Use a centralized `LoggerService` that wraps `console.*` and can route to external providers (Sentry, Datadog, Application Insights).
258
+ - Instrument HTTP calls via interceptor: log request/response timings, status codes, error rates.
259
+ - Use Angular's `ErrorHandler` to funnel all unhandled errors to the logging service.
260
+ - In production, integrate Sentry Angular SDK (`@sentry/angular`) for error tracking with source maps.
261
+
262
+ ---
263
+
264
+ ## Anti-Patterns & Pitfalls
265
+
266
+ ### 1. Not using `OnPush` change detection
267
+ **Why**: Default change detection checks the entire component subtree on every event. This causes thousands of unnecessary re-renders in large apps, degrading performance. With signals and standalone components, always pair with `OnPush`.
268
+
269
+ ### 2. Calling methods in templates
270
+ **Why**: Angular re-evaluates template expressions on every change detection cycle. A method call like `{{ getTotal() }}` runs repeatedly, even when inputs have not changed. Use `computed()` signals or pure pipes instead.
271
+
272
+ ### 3. Forgetting to unsubscribe from observables
273
+ **Why**: Leaked subscriptions cause memory leaks, stale callbacks, and erratic behavior. Use `takeUntilDestroyed()` (Angular 16+), `DestroyRef`, or convert to signals with `toSignal()` (which auto-unsubscribes).
274
+
275
+ ### 4. Nested subscriptions (subscribe-inside-subscribe)
276
+ **Why**: Creates tightly coupled, hard-to-test code. Misses error propagation and cancellation semantics. Use `switchMap`, `mergeMap`, or `concatMap` instead.
277
+
278
+ ### 5. "God components" with too many responsibilities
279
+ **Why**: Components exceeding 300+ lines with mixed template logic, HTTP calls, and business rules are untestable and unmaintainable. Extract business logic to services and split into smart/dumb component pairs.
280
+
281
+ ### 6. Overusing `any` type
282
+ **Why**: Defeats TypeScript's compile-time safety. Bugs slip to runtime that the compiler would catch. Use strict typing; enable `strict: true` in `tsconfig.json`. Use `unknown` if the type is truly uncertain.
283
+
284
+ ### 7. Direct DOM manipulation (ElementRef.nativeElement, document.querySelector)
285
+ **Why**: Bypasses Angular's sanitization (XSS risk), breaks SSR compatibility, and fights the framework's rendering pipeline. Use `Renderer2`, template variables, or signal-based `viewChild()`.
286
+
287
+ ### 8. Putting everything in a single shared module
288
+ **Why**: Shared modules that re-export dozens of components become import-everything bundles, killing tree-shaking. With standalone components, import only what each component needs directly.
289
+
290
+ ### 9. Storing sensitive tokens in localStorage
291
+ **Why**: localStorage is accessible to any script on the page, making it vulnerable to XSS exfiltration. Store tokens in HttpOnly cookies set by the server.
292
+
293
+ ### 10. Importing entire RxJS or lodash
294
+ **Why**: `import * as rxjs from 'rxjs'` or `import _ from 'lodash'` prevents tree-shaking, inflating bundle size by 50-200 KB. Import specific operators: `import { map } from 'rxjs/operators'` or use `lodash-es` with named imports.
295
+
296
+ ### 11. Using `async` pipe AND `toSignal()` for the same stream
297
+ **Why**: Double subscription causes duplicate HTTP calls and inconsistent state. Choose one: `toSignal()` for signal-based templates, `async` pipe for legacy observable templates.
298
+
299
+ ### 12. Mutating signal values in place
300
+ **Why**: `this.items().push(newItem)` mutates the array without notifying the signal. Signals detect changes by reference. Always use `update()` with a new reference: `this.items.update(arr => [...arr, newItem])`.
301
+
302
+ ### 13. Overusing `effect()` for state derivation
303
+ **Why**: `effect()` is for side effects (logging, localStorage sync), not computed state. Using `effect()` to set other signals creates hidden dependencies and glitch potential. Use `computed()` for derived state.
304
+
305
+ ### 14. Not lazy-loading feature routes
306
+ **Why**: Eager loading all features means users download the entire app upfront. Route-level lazy loading with `loadComponent` / `loadChildren` can cut initial bundle size by 40-70%.
307
+
308
+ ### 15. Ignoring `trackBy` in `@for` loops
309
+ **Why**: Without `track`, Angular destroys and recreates all DOM nodes on every change. The `track` expression (required in `@for`) tells Angular which items are the same across renders, enabling efficient DOM recycling.
310
+
311
+ ---
312
+
313
+ ## Testing Strategy
314
+
315
+ ### Component Testing (TestBed)
316
+
317
+ ```typescript
318
+ describe('UserListComponent', () => {
319
+ let component: UserListComponent;
320
+ let fixture: ComponentFixture<UserListComponent>;
321
+
322
+ beforeEach(async () => {
323
+ await TestBed.configureTestingModule({
324
+ imports: [UserListComponent], // standalone components go in imports
325
+ providers: [
326
+ { provide: UserService, useValue: { getUsers: () => signal([]) } }
327
+ ],
328
+ }).compileComponents();
329
+
330
+ fixture = TestBed.createComponent(UserListComponent);
331
+ component = fixture.componentInstance;
332
+ });
333
+
334
+ it('should render user names', () => {
335
+ fixture.componentRef.setInput('users', [{ name: 'Alice' }]);
336
+ fixture.detectChanges();
337
+ expect(fixture.nativeElement.textContent).toContain('Alice');
338
+ });
339
+ });
340
+ ```
341
+
342
+ **Component Harnesses** (Angular CDK): provide a stable, abstraction-layer API for interacting with Angular Material components in tests, decoupling test code from DOM structure.
343
+
344
+ ### Service Testing
345
+
346
+ ```typescript
347
+ describe('AuthService', () => {
348
+ let service: AuthService;
349
+ let httpMock: HttpTestingController;
350
+
351
+ beforeEach(() => {
352
+ TestBed.configureTestingModule({
353
+ providers: [
354
+ AuthService,
355
+ provideHttpClient(),
356
+ provideHttpClientTesting(),
357
+ ],
358
+ });
359
+ service = TestBed.inject(AuthService);
360
+ httpMock = TestBed.inject(HttpTestingController);
361
+ });
362
+
363
+ it('should login and store token', () => {
364
+ service.login('user', 'pass').subscribe(res => {
365
+ expect(res.token).toBe('abc');
366
+ });
367
+ httpMock.expectOne('/api/login').flush({ token: 'abc' });
368
+ });
369
+ });
370
+ ```
371
+
372
+ ### E2E Testing (Playwright)
373
+
374
+ Playwright has fully replaced Protractor (deprecated since Angular 15). Use `@ngx-playwright/test` or Playwright directly.
375
+
376
+ ```typescript
377
+ // e2e/dashboard.spec.ts
378
+ import { test, expect } from '@playwright/test';
379
+
380
+ test('should display dashboard after login', async ({ page }) => {
381
+ await page.goto('/login');
382
+ await page.fill('[data-testid="email"]', 'admin@test.com');
383
+ await page.fill('[data-testid="password"]', 'password');
384
+ await page.click('[data-testid="submit"]');
385
+ await expect(page).toHaveURL('/dashboard');
386
+ await expect(page.locator('h1')).toHaveText('Dashboard');
387
+ });
388
+ ```
389
+
390
+ - Use `data-testid` attributes for stable selectors.
391
+ - Run in CI with `--reporter=html` for visual reports.
392
+
393
+ ### Signal Testing Patterns
394
+
395
+ Test signals by reading their current value after triggering changes:
396
+
397
+ ```typescript
398
+ it('should compute doubled count', () => {
399
+ const component = TestBed.createComponent(CounterComponent).componentInstance;
400
+ component.count.set(5);
401
+ expect(component.doubleCount()).toBe(10);
402
+ });
403
+ ```
404
+
405
+ For `effect()`, use `TestBed.flushEffects()` (Angular 18+) to synchronously flush pending effects in tests.
406
+
407
+ ### Marble Testing (RxJS)
408
+
409
+ Use `TestScheduler` from `rxjs/testing` for deterministic observable testing:
410
+
411
+ ```typescript
412
+ it('should debounce search input', () => {
413
+ const scheduler = new TestScheduler((actual, expected) => {
414
+ expect(actual).toEqual(expected);
415
+ });
416
+
417
+ scheduler.run(({ cold, expectObservable }) => {
418
+ const input$ = cold('--a--b----c|');
419
+ const expected = '--------b-------c|';
420
+ expectObservable(input$.pipe(debounceTime(5, scheduler))).toBe(expected);
421
+ });
422
+ });
423
+ ```
424
+
425
+ ### Angular 21+ Testing Revolution
426
+
427
+ - **Vitest** is becoming the default unit test runner (replacing Karma/Jest).
428
+ - **Testronaut** provides Playwright-based component testing that uses the Angular CLI build pipeline natively.
429
+
430
+ ---
431
+
432
+ ## Performance Considerations
433
+
434
+ ### Change Detection
435
+
436
+ **OnPush + Signals = Optimal**: OnPush components only re-render when their inputs change or signals they read are updated. Signals provide fine-grained tracking so Angular knows exactly which components to check.
437
+
438
+ **Zoneless Angular (v18+ experimental, v20.2+ stable, v21+ default):**
439
+
440
+ ```typescript
441
+ // app.config.ts
442
+ export const appConfig: ApplicationConfig = {
443
+ providers: [
444
+ provideExperimentalZonelessChangeDetection(), // v18-19
445
+ // provideZonelessChangeDetection(), // v20.2+ stable
446
+ ],
447
+ };
448
+ ```
449
+
450
+ Benefits: ~30-50 KB bundle reduction, 40-50% LCP improvement, cleaner stack traces, no Zone.js monkey-patching of async APIs.
451
+
452
+ **Requirements for zoneless**: all components must use `OnPush` or signals. No reliance on Zone.js-triggered change detection.
453
+
454
+ ### Lazy Loading and Deferred Views
455
+
456
+ **Route-level lazy loading**: `loadComponent` / `loadChildren` in route config.
457
+
458
+ **`@defer` blocks (Angular 17+):**
459
+
460
+ ```html
461
+ @defer (on viewport) {
462
+ <app-heavy-chart [data]="chartData()" />
463
+ } @placeholder {
464
+ <div class="skeleton-chart"></div>
465
+ } @loading (minimum 300ms) {
466
+ <app-spinner />
467
+ } @error {
468
+ <p>Failed to load chart</p>
469
+ }
470
+ ```
471
+
472
+ Triggers: `on idle`, `on viewport`, `on interaction`, `on hover`, `on timer(ms)`, `when condition`.
473
+
474
+ `@defer` reduces initial bundle size by code-splitting deferred components and their dependencies into separate chunks automatically.
475
+
476
+ ### SSR (Angular SSR, formerly Angular Universal)
477
+
478
+ - Built-in since Angular 17 via `@angular/ssr` package (replaces `@nguniversal/*`).
479
+ - **Hydration** (stable v17+): server-rendered HTML is reused by the client, avoiding DOM destruction/recreation.
480
+ - **Incremental Hydration** (v19.2+): combines `@defer` with SSR — server renders placeholder HTML, client hydrates deferred blocks only when triggered, loading less JavaScript upfront.
481
+ - **Hybrid Rendering** (v19+): per-route SSR/SSG/CSR configuration in `server.ts`.
482
+
483
+ ```typescript
484
+ // server.ts — route-level rendering mode
485
+ serverRoutes: [
486
+ { path: '', renderMode: RenderMode.Prerender }, // SSG
487
+ { path: 'dashboard', renderMode: RenderMode.Server }, // SSR
488
+ { path: 'admin/**', renderMode: RenderMode.Client }, // CSR
489
+ ]
490
+ ```
491
+
492
+ ### Bundle Size Optimization
493
+
494
+ - **Standalone components** enable better tree-shaking — no NgModule barrel imports.
495
+ - Use `@defer` for below-the-fold components and heavy third-party libraries (chart libraries, rich text editors).
496
+ - Analyze bundles with `npx ng build --stats-json` + `webpack-bundle-analyzer` or `source-map-explorer`.
497
+ - Enable production optimizations: `ng build --configuration production` applies minification, tree-shaking, and dead-code elimination.
498
+
499
+ ### Image Optimization (NgOptimizedImage)
500
+
501
+ ```html
502
+ <img ngSrc="hero.jpg" width="1200" height="600" priority />
503
+ <img ngSrc="thumb.jpg" width="200" height="200" />
504
+ ```
505
+
506
+ - `priority` attribute sets `fetchpriority="high"` and `loading="eager"` for LCP images.
507
+ - Non-priority images automatically get `loading="lazy"`.
508
+ - Requires explicit `width` and `height` to prevent layout shift, or use `fill` for fluid images.
509
+ - Connect an image CDN loader (Cloudinary, Imgix, etc.) for automatic `srcset` generation.
510
+
511
+ ---
512
+
513
+ ## Security Considerations
514
+
515
+ ### Built-in XSS Protection
516
+
517
+ Angular treats all template-bound values as untrusted by default and sanitizes them. This covers:
518
+ - HTML interpolation (`{{ }}` and `[innerHTML]`)
519
+ - URL bindings (`[href]`, `[src]`)
520
+ - Style bindings
521
+
522
+ **Do NOT bypass with**: `bypassSecurityTrustHtml()` unless absolutely necessary and the content is verified safe. Document every usage with a security justification comment.
523
+
524
+ **Avoid**: `ElementRef.nativeElement.innerHTML`, `document.createElement`, and dynamic code execution — these bypass Angular's sanitizer entirely.
525
+
526
+ ### CSRF Protection
527
+
528
+ ```typescript
529
+ // app.config.ts
530
+ provideHttpClient(
531
+ withXsrfConfiguration({
532
+ cookieName: 'XSRF-TOKEN', // cookie name from server
533
+ headerName: 'X-XSRF-TOKEN', // header sent with requests
534
+ })
535
+ )
536
+ ```
537
+
538
+ Server must set the XSRF cookie and validate the header. Angular's `HttpClient` reads the cookie and attaches the header automatically on mutating requests (POST, PUT, DELETE).
539
+
540
+ ### Content Security Policy (CSP)
541
+
542
+ Minimum CSP for Angular apps:
543
+
544
+ ```
545
+ Content-Security-Policy:
546
+ default-src 'self';
547
+ script-src 'self' 'nonce-{RANDOM}';
548
+ style-src 'self' 'nonce-{RANDOM}';
549
+ img-src 'self' data: https:;
550
+ connect-src 'self' https://api.example.com;
551
+ ```
552
+
553
+ - Angular 17+ supports `nonce` for inline styles via `ngCspNonce` attribute or `CSP_NONCE` injection token.
554
+ - Avoid `unsafe-inline` for scripts. Use nonces or hashes.
555
+
556
+ ### Authentication
557
+
558
+ - Use `angular-auth-oidc-client` for OpenID Connect / OAuth 2.0 flows.
559
+ - Store tokens in HttpOnly, Secure, SameSite cookies — never in `localStorage` or `sessionStorage`.
560
+ - Implement token refresh via HTTP interceptor before expiry.
561
+ - Use route guards (`canActivate`, `canMatch`) to protect routes client-side; always enforce authorization server-side.
562
+
563
+ ---
564
+
565
+ ## Integration Patterns
566
+
567
+ ### HTTP (HttpClient)
568
+
569
+ **Functional interceptors (Angular 15+, recommended):**
570
+
571
+ ```typescript
572
+ // app.config.ts
573
+ provideHttpClient(
574
+ withInterceptors([authInterceptor, loggingInterceptor, retryInterceptor])
575
+ )
576
+ ```
577
+
578
+ **Retry with exponential backoff:**
579
+
580
+ ```typescript
581
+ export const retryInterceptor: HttpInterceptorFn = (req, next) =>
582
+ next(req).pipe(
583
+ retry({
584
+ count: 3,
585
+ delay: (error, retryCount) => {
586
+ if (error.status >= 400 && error.status < 500) return throwError(() => error);
587
+ return timer(Math.pow(2, retryCount) * 1000); // 2s, 4s, 8s
588
+ },
589
+ })
590
+ );
591
+ ```
592
+
593
+ **Request context tokens** for per-request configuration:
594
+
595
+ ```typescript
596
+ const CACHE_ENABLED = new HttpContextToken<boolean>(() => false);
597
+
598
+ // In service
599
+ this.http.get('/api/data', {
600
+ context: new HttpContext().set(CACHE_ENABLED, true),
601
+ });
602
+
603
+ // In interceptor
604
+ if (req.context.get(CACHE_ENABLED)) { /* serve from cache */ }
605
+ ```
606
+
607
+ ### Forms (Reactive, Typed)
608
+
609
+ **Typed FormGroup (Angular 14+):**
610
+
611
+ ```typescript
612
+ export class ProfileFormComponent {
613
+ private fb = inject(NonNullableFormBuilder);
614
+
615
+ form = this.fb.group({
616
+ name: ['', [Validators.required, Validators.minLength(2)]],
617
+ email: ['', [Validators.required, Validators.email]],
618
+ address: this.fb.group({
619
+ street: [''],
620
+ city: [''],
621
+ zip: ['', Validators.pattern(/^\d{5}$/)],
622
+ }),
623
+ });
624
+
625
+ onSubmit() {
626
+ if (this.form.invalid) return;
627
+ const value = this.form.getRawValue(); // fully typed
628
+ // value.name is string, value.address.zip is string
629
+ }
630
+ }
631
+ ```
632
+
633
+ - Use `NonNullableFormBuilder` so `.reset()` returns to initial values, not null.
634
+ - Access controls via `this.form.controls.name` (typed) rather than `this.form.get('name')` (untyped).
635
+ - For dynamic forms, use `FormArray` with typed element types.
636
+
637
+ ### Angular Material / CDK
638
+
639
+ - Import only needed components: `import { MatButtonModule } from '@angular/material/button'`.
640
+ - Use CDK primitives (`Overlay`, `DragDrop`, `A11y`, `Clipboard`) for custom UI without Material styling.
641
+ - Use component harnesses in tests: `const button = await loader.getHarness(MatButtonHarness)`.
642
+
643
+ ### Real-time (WebSocket, SSE)
644
+
645
+ ```typescript
646
+ @Injectable({ providedIn: 'root' })
647
+ export class WebSocketService {
648
+ private socket$ = webSocket<Message>('wss://api.example.com/ws');
649
+
650
+ messages$ = this.socket$.pipe(
651
+ retry({ delay: 3000 }), // auto-reconnect
652
+ share(), // share among subscribers
653
+ );
654
+
655
+ send(msg: Message) {
656
+ this.socket$.next(msg);
657
+ }
658
+ }
659
+ ```
660
+
661
+ For SSE (Server-Sent Events), use native `EventSource` API wrapped in an Observable or signal via `rxResource`.
662
+
663
+ ---
664
+
665
+ ## DevOps & Deployment
666
+
667
+ ### Angular CLI and Build System
668
+
669
+ **esbuild + Vite (Angular 17+ default):**
670
+
671
+ - Production builds via esbuild: `ng build` — ~56% faster than Webpack (8 min to 3.5 min in large projects).
672
+ - Dev server via Vite: `ng serve` — cold start ~12s (down from ~45s with Webpack).
673
+ - Output is ESM (`.mjs` files) by default. Ensure Node.js 20+ in CI and Docker.
674
+
675
+ ```json
676
+ // angular.json
677
+ {
678
+ "architect": {
679
+ "build": {
680
+ "builder": "@angular/build:application",
681
+ "options": {
682
+ "outputPath": "dist/my-app",
683
+ "index": "src/index.html",
684
+ "browser": "src/main.ts",
685
+ "server": "src/main.server.ts"
686
+ }
687
+ }
688
+ }
689
+ }
690
+ ```
691
+
692
+ ### Docker Patterns
693
+
694
+ **Multi-stage Dockerfile:**
695
+
696
+ ```dockerfile
697
+ # Build stage
698
+ FROM node:20-alpine AS build
699
+ WORKDIR /app
700
+ COPY package*.json ./
701
+ RUN npm ci
702
+ COPY . .
703
+ RUN npx ng build --configuration production
704
+
705
+ # Production stage (static SPA)
706
+ FROM nginx:alpine
707
+ COPY --from=build /app/dist/my-app/browser /usr/share/nginx/html
708
+ COPY nginx.conf /etc/nginx/conf.d/default.conf
709
+ EXPOSE 80
710
+
711
+ # Production stage (SSR)
712
+ FROM node:20-alpine AS ssr
713
+ WORKDIR /app
714
+ COPY --from=build /app/dist/my-app .
715
+ EXPOSE 4000
716
+ CMD ["node", "server/server.mjs"]
717
+ ```
718
+
719
+ **nginx.conf for SPA routing:**
720
+
721
+ ```nginx
722
+ server {
723
+ listen 80;
724
+ root /usr/share/nginx/html;
725
+ index index.html;
726
+
727
+ location / {
728
+ try_files $uri $uri/ /index.html;
729
+ }
730
+
731
+ location /assets/ {
732
+ expires 1y;
733
+ add_header Cache-Control "public, immutable";
734
+ }
735
+ }
736
+ ```
737
+
738
+ ### CI/CD
739
+
740
+ ```yaml
741
+ # GitHub Actions example
742
+ jobs:
743
+ build-and-test:
744
+ runs-on: ubuntu-latest
745
+ steps:
746
+ - uses: actions/checkout@v4
747
+ - uses: actions/setup-node@v4
748
+ with:
749
+ node-version: 20
750
+ cache: 'npm'
751
+ - run: npm ci
752
+ - run: npx ng lint
753
+ - run: npx ng test --watch=false --browsers=ChromeHeadless --code-coverage
754
+ - run: npx ng build --configuration production
755
+ - run: npx playwright install --with-deps
756
+ - run: npx playwright test
757
+ - uses: actions/upload-artifact@v4
758
+ with:
759
+ name: dist
760
+ path: dist/
761
+ ```
762
+
763
+ - Cache `node_modules` and `.angular/cache` for faster CI.
764
+ - Run lint, unit tests, build, and E2E in parallel where possible.
765
+ - Use `--affected` with Nx to only build/test changed projects.
766
+
767
+ ### Environment Files
768
+
769
+ ```typescript
770
+ // environments/environment.ts (dev)
771
+ export const environment = {
772
+ production: false,
773
+ apiUrl: 'http://localhost:3000/api',
774
+ };
775
+
776
+ // environments/environment.prod.ts
777
+ export const environment = {
778
+ production: true,
779
+ apiUrl: 'https://api.example.com',
780
+ };
781
+ ```
782
+
783
+ For runtime configuration (Docker/K8s), load config from `/assets/config.json` at app startup via `APP_INITIALIZER` — avoids rebuilding for each environment.
784
+
785
+ ### Monitoring (Sentry)
786
+
787
+ ```typescript
788
+ // app.config.ts
789
+ import * as Sentry from '@sentry/angular';
790
+
791
+ Sentry.init({
792
+ dsn: environment.sentryDsn,
793
+ integrations: [Sentry.browserTracingIntegration()],
794
+ tracesSampleRate: 0.2,
795
+ });
796
+
797
+ export const appConfig: ApplicationConfig = {
798
+ providers: [
799
+ { provide: ErrorHandler, useValue: Sentry.createErrorHandler() },
800
+ { provide: Sentry.TraceService, deps: [Router] },
801
+ {
802
+ provide: APP_INITIALIZER,
803
+ useFactory: () => () => {},
804
+ deps: [Sentry.TraceService],
805
+ multi: true,
806
+ },
807
+ ],
808
+ };
809
+ ```
810
+
811
+ Upload source maps in CI: `npx sentry-cli sourcemaps upload dist/`.
812
+
813
+ ---
814
+
815
+ ## Decision Trees
816
+
817
+ ### Signals vs RxJS
818
+
819
+ ```
820
+ Need to manage UI state or component state?
821
+ -> YES: Use signal() + computed()
822
+ Need derived/computed values from existing state?
823
+ -> YES: Use computed()
824
+ Need to react to user events with debounce, throttle, switchMap?
825
+ -> YES: Use RxJS operators
826
+ Need to combine multiple async streams (merge, combineLatest, race)?
827
+ -> YES: Use RxJS
828
+ Working with HttpClient responses?
829
+ -> Simple request: Use rxResource() or toSignal(this.http.get(...))
830
+ -> Complex retry/polling/cancellation: Use RxJS pipe
831
+ Need to bridge signal <-> observable?
832
+ -> Observable to Signal: toSignal()
833
+ -> Signal to Observable: toObservable()
834
+ ```
835
+
836
+ **Rule of thumb**: Signals for state (synchronous, value-based), RxJS for events and streams (asynchronous, time-based).
837
+
838
+ ### NgRx vs Service-Based State
839
+
840
+ ```
841
+ Is state local to one component or feature?
842
+ -> YES: signal() in component or feature service
843
+ Is state shared across multiple features?
844
+ -> Simple (2-5 properties): Injectable service with signals
845
+ -> Medium complexity: NgRx SignalStore
846
+ -> Complex (many entities, optimistic updates, undo/redo): NgRx Store
847
+ Do you need Redux DevTools time-travel debugging?
848
+ -> YES: NgRx Store
849
+ Do you need action logging / audit trail?
850
+ -> YES: NgRx Store
851
+ Is the team unfamiliar with Redux concepts?
852
+ -> YES: Start with services + signals, adopt NgRx SignalStore if needed
853
+ ```
854
+
855
+ ### Standalone vs Module-Based Architecture
856
+
857
+ ```
858
+ Starting a new project (Angular 17+)?
859
+ -> YES: Standalone components (default since Angular 19)
860
+ Existing project with NgModules?
861
+ -> Small/medium: Migrate to standalone incrementally
862
+ -> Large enterprise: Migrate feature-by-feature; use importProvidersFrom() for legacy module compat
863
+ Using third-party libraries that require NgModules?
864
+ -> Wrap with importProvidersFrom() in providers array
865
+ Need to share declarations across many components?
866
+ -> Create barrel export file or shared component library
867
+ -> Do NOT create a giant SharedModule
868
+ ```
869
+
870
+ **Angular team guidance**: Standalone is the future. NgModules are in maintenance mode. All new Angular APIs are standalone-first.
871
+
872
+ ---
873
+
874
+ ## Code Examples
875
+
876
+ ### 1. Standalone Component with Signals and OnPush
877
+
878
+ ```typescript
879
+ // user-card.component.ts
880
+ import { Component, input, output, ChangeDetectionStrategy } from '@angular/core';
881
+ import { DatePipe } from '@angular/common';
882
+
883
+ @Component({
884
+ selector: 'app-user-card',
885
+ standalone: true,
886
+ imports: [DatePipe],
887
+ changeDetection: ChangeDetectionStrategy.OnPush,
888
+ template: `
889
+ <div class="card">
890
+ <h3>{{ user().name }}</h3>
891
+ <p>{{ user().email }}</p>
892
+ <p>Joined: {{ user().joinedAt | date:'mediumDate' }}</p>
893
+ <button (click)="selected.emit(user())">Select</button>
894
+ </div>
895
+ `,
896
+ })
897
+ export class UserCardComponent {
898
+ user = input.required<User>();
899
+ selected = output<User>();
900
+ }
901
+ ```
902
+
903
+ ### 2. Data Fetching with rxResource and Signals
904
+
905
+ ```typescript
906
+ // product-list.component.ts
907
+ import { Component, signal, inject } from '@angular/core';
908
+ import { rxResource } from '@angular/core/rxjs-interop';
909
+ import { HttpClient } from '@angular/common/http';
910
+ import { FormsModule } from '@angular/forms';
911
+
912
+ @Component({
913
+ selector: 'app-product-list',
914
+ standalone: true,
915
+ imports: [FormsModule],
916
+ template: `
917
+ <input [(ngModel)]="searchTerm" placeholder="Search..." />
918
+
919
+ @if (products.isLoading()) {
920
+ <app-spinner />
921
+ }
922
+
923
+ @if (products.error()) {
924
+ <p class="error">Failed to load products</p>
925
+ }
926
+
927
+ @for (product of products.value(); track product.id) {
928
+ <app-product-card [product]="product" />
929
+ } @empty {
930
+ <p>No products found</p>
931
+ }
932
+ `,
933
+ })
934
+ export class ProductListComponent {
935
+ private http = inject(HttpClient);
936
+ searchTerm = signal('');
937
+
938
+ products = rxResource({
939
+ request: () => ({ q: this.searchTerm() }),
940
+ loader: ({ request }) =>
941
+ this.http.get<Product[]>('/api/products', { params: { q: request.q } }),
942
+ });
943
+ }
944
+ ```
945
+
946
+ ### 3. Functional Interceptor Chain
947
+
948
+ ```typescript
949
+ // interceptors/auth.interceptor.ts
950
+ import { HttpInterceptorFn } from '@angular/common/http';
951
+ import { inject } from '@angular/core';
952
+
953
+ export const authInterceptor: HttpInterceptorFn = (req, next) => {
954
+ const token = inject(AuthService).accessToken();
955
+ if (!token) return next(req);
956
+
957
+ const authReq = req.clone({
958
+ setHeaders: { Authorization: `Bearer ${token}` },
959
+ });
960
+ return next(authReq);
961
+ };
962
+
963
+ // interceptors/logging.interceptor.ts
964
+ export const loggingInterceptor: HttpInterceptorFn = (req, next) => {
965
+ const start = performance.now();
966
+ return next(req).pipe(
967
+ tap({
968
+ next: () => {
969
+ const duration = Math.round(performance.now() - start);
970
+ console.log(`[HTTP] ${req.method} ${req.url} -- ${duration}ms`);
971
+ },
972
+ error: (err) => {
973
+ console.error(`[HTTP ERROR] ${req.method} ${req.url}`, err.status);
974
+ },
975
+ })
976
+ );
977
+ };
978
+
979
+ // app.config.ts
980
+ provideHttpClient(
981
+ withInterceptors([authInterceptor, loggingInterceptor, retryInterceptor]),
982
+ withXsrfConfiguration({ cookieName: 'XSRF-TOKEN', headerName: 'X-XSRF-TOKEN' })
983
+ )
984
+ ```
985
+
986
+ ### 4. NgRx SignalStore with Entities
987
+
988
+ ```typescript
989
+ // stores/todo.store.ts
990
+ import { signalStore, withState, withMethods, withComputed, patchState } from '@ngrx/signals';
991
+ import { withEntities, setAllEntities, addEntity, removeEntity } from '@ngrx/signals/entities';
992
+ import { rxMethod } from '@ngrx/signals/rxjs-interop';
993
+ import { pipe, switchMap, tap } from 'rxjs';
994
+
995
+ export const TodoStore = signalStore(
996
+ { providedIn: 'root' },
997
+ withEntities<Todo>(),
998
+ withState({ loading: false, filter: 'all' as 'all' | 'active' | 'done' }),
999
+ withComputed(({ entities, filter }) => ({
1000
+ filteredTodos: computed(() => {
1001
+ const f = filter();
1002
+ if (f === 'all') return entities();
1003
+ return entities().filter(t => (f === 'done') === t.completed);
1004
+ }),
1005
+ remaining: computed(() => entities().filter(t => !t.completed).length),
1006
+ })),
1007
+ withMethods((store, http = inject(HttpClient)) => ({
1008
+ loadTodos: rxMethod<void>(
1009
+ pipe(
1010
+ tap(() => patchState(store, { loading: true })),
1011
+ switchMap(() => http.get<Todo[]>('/api/todos')),
1012
+ tap(todos => {
1013
+ patchState(store, setAllEntities(todos));
1014
+ patchState(store, { loading: false });
1015
+ })
1016
+ )
1017
+ ),
1018
+ addTodo(title: string) {
1019
+ const todo: Todo = { id: crypto.randomUUID(), title, completed: false };
1020
+ patchState(store, addEntity(todo));
1021
+ },
1022
+ removeTodo(id: string) {
1023
+ patchState(store, removeEntity(id));
1024
+ },
1025
+ setFilter(filter: 'all' | 'active' | 'done') {
1026
+ patchState(store, { filter });
1027
+ },
1028
+ }))
1029
+ );
1030
+ ```
1031
+
1032
+ ### 5. Deferred Loading with @defer
1033
+
1034
+ ```typescript
1035
+ @Component({
1036
+ selector: 'app-analytics-page',
1037
+ standalone: true,
1038
+ imports: [HeroSectionComponent],
1039
+ template: `
1040
+ <app-hero-section [title]="pageTitle()" />
1041
+
1042
+ @defer (on viewport) {
1043
+ <app-heavy-chart [data]="chartData()" />
1044
+ } @placeholder {
1045
+ <div class="chart-skeleton" style="height: 400px"></div>
1046
+ } @loading (minimum 200ms) {
1047
+ <app-spinner />
1048
+ }
1049
+
1050
+ @defer (on idle) {
1051
+ <app-recommendations [userId]="userId()" />
1052
+ } @placeholder {
1053
+ <p>Loading recommendations...</p>
1054
+ }
1055
+
1056
+ @defer (on interaction(loadComments)) {
1057
+ <app-comments [postId]="postId()" />
1058
+ } @placeholder {
1059
+ <button #loadComments>Load Comments</button>
1060
+ }
1061
+ `,
1062
+ })
1063
+ export class AnalyticsPageComponent {
1064
+ pageTitle = input.required<string>();
1065
+ chartData = input.required<ChartData[]>();
1066
+ userId = input.required<string>();
1067
+ postId = input.required<string>();
1068
+ }
1069
+ ```
1070
+
1071
+ ---
1072
+
1073
+ *Researched: 2026-03-07 | Sources: [Angular Official Docs](https://angular.dev), [Angular Blog 2025 Strategy](https://blog.angular.dev/angular-2025-strategy-9ca333dfc334), [Angular Signals Guide](https://angular.dev/guide/signals), [RxJS Interop](https://angular.dev/ecosystem/rxjs-interop), [Nx Angular Architecture Guide](https://nx.dev/blog/architecting-angular-applications), [Nx State Management 2025](https://nx.dev/blog/angular-state-management-2025), [Angular Security](https://angular.dev/best-practices/security), [NgRx SignalStore](https://ngrx.io/guide/signals), [Angular SSR Guide](https://angular.dev/guide/ssr), [Angular Zoneless](https://angular.dev/guide/zoneless), [NgOptimizedImage](https://angular.dev/guide/image-optimization), [AngularArchitects SSR](https://www.angulararchitects.io/blog/guide-for-ssr/), [Angular Interceptors](https://angular.dev/guide/http/interceptors), [Angular Typed Forms](https://angular.dev/guide/forms/typed-forms), [InfoQ Angular 21](https://www.infoq.com/news/2025/11/angular-21-released/), [Signals vs RxJS](https://angularexperts.io/blog/signals-vs-rxjs/), [Chrome NgOptimizedImage](https://developer.chrome.com/blog/angular_ngoptimizedimage/), [Angular Zoneless Performance](https://javascript-conference.com/blog/angular-20-zoneless-mode-performance-migration-guide/)*