devendra-skill-package 1.0.2

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 (223) hide show
  1. package/.github/skills/boiler-project-generator/SKILL.md +103 -0
  2. package/.github/skills/boiler-project-generator/assets/templates/android/README.md +3 -0
  3. package/.github/skills/boiler-project-generator/assets/templates/angular/README.md +3 -0
  4. package/.github/skills/boiler-project-generator/assets/templates/flutter/README.md +3 -0
  5. package/.github/skills/boiler-project-generator/assets/templates/ios/README.md +3 -0
  6. package/.github/skills/boiler-project-generator/assets/templates/react/README.md +3 -0
  7. package/.github/skills/boiler-project-generator/assets/templates/react-native/README.md +3 -0
  8. package/.github/skills/boiler-project-generator/assets/templates/react-native/api-setup.ts +76 -0
  9. package/.github/skills/boiler-project-generator/assets/templates/react-native/component-primary-button.tsx +29 -0
  10. package/.github/skills/boiler-project-generator/assets/templates/react-native/env-config.env +4 -0
  11. package/.github/skills/boiler-project-generator/assets/templates/react-native/feature-auth-screen.tsx +45 -0
  12. package/.github/skills/boiler-project-generator/assets/templates/react-native/feature-dashboard-screen.tsx +45 -0
  13. package/.github/skills/boiler-project-generator/assets/templates/react-native/feature-profile-screen.tsx +45 -0
  14. package/.github/skills/boiler-project-generator/assets/templates/react-native/hook-use-app-boot.ts +11 -0
  15. package/.github/skills/boiler-project-generator/assets/templates/react-native/navigation-setup.tsx +25 -0
  16. package/.github/skills/boiler-project-generator/assets/templates/react-native/project-structure.md +24 -0
  17. package/.github/skills/boiler-project-generator/assets/templates/react-native/redux-hooks.ts +5 -0
  18. package/.github/skills/boiler-project-generator/assets/templates/react-native/redux-session-slice.ts +29 -0
  19. package/.github/skills/boiler-project-generator/assets/templates/react-native/redux-store.ts +15 -0
  20. package/.github/skills/boiler-project-generator/assets/templates/react-native/theme-index.ts +23 -0
  21. package/.github/skills/boiler-project-generator/assets/templates/react-native/utils-helpers.ts +7 -0
  22. package/.github/skills/boiler-project-generator/metadata.yaml +29 -0
  23. package/.github/skills/boiler-project-generator/references/android.md +19 -0
  24. package/.github/skills/boiler-project-generator/references/angular.md +14 -0
  25. package/.github/skills/boiler-project-generator/references/flutter.md +17 -0
  26. package/.github/skills/boiler-project-generator/references/ios.md +17 -0
  27. package/.github/skills/boiler-project-generator/references/react-native.md +103 -0
  28. package/.github/skills/boiler-project-generator/references/react.md +17 -0
  29. package/.github/skills/boiler-project-generator/scripts/angular.js +43 -0
  30. package/.github/skills/boiler-project-generator/scripts/generate-project.mjs +107 -0
  31. package/.github/skills/boiler-project-generator/scripts/init.js +105 -0
  32. package/.github/skills/boiler-project-generator/scripts/react-native.js +1041 -0
  33. package/.github/skills/boiler-project-generator/scripts/react.js +32 -0
  34. package/.github/skills/clean-architecture-generator/SKILL.md +235 -0
  35. package/.github/skills/clean-architecture-generator/references/architecture-core.md +126 -0
  36. package/.github/skills/clean-architecture-generator/references/platform-angular.md +374 -0
  37. package/.github/skills/clean-architecture-generator/references/platform-flutter.md +366 -0
  38. package/.github/skills/clean-architecture-generator/references/platform-react-native.md +590 -0
  39. package/.github/skills/clean-architecture-generator/references/platform-react.md +261 -0
  40. package/.github/skills/code-test-coverage-analyzer/SKILL.md +1358 -0
  41. package/.github/skills/code-test-coverage-analyzer/assets/config-questionnaire.md +118 -0
  42. package/.github/skills/code-test-coverage-analyzer/assets/conflict-resolution-protocol.md +99 -0
  43. package/.github/skills/code-test-coverage-analyzer/assets/coverage-calculation-rules.md +294 -0
  44. package/.github/skills/code-test-coverage-analyzer/assets/multi-strategy-search.md +145 -0
  45. package/.github/skills/code-test-coverage-analyzer/assets/output-file-contracts.md +651 -0
  46. package/.github/skills/code-test-coverage-analyzer/assets/status-definitions.md +273 -0
  47. package/.github/skills/code-test-coverage-analyzer/examples/example-invocation.md +208 -0
  48. package/.github/skills/code-test-coverage-analyzer/references/android-patterns.md +229 -0
  49. package/.github/skills/code-test-coverage-analyzer/references/angular-patterns.md +177 -0
  50. package/.github/skills/code-test-coverage-analyzer/references/backend-patterns.md +383 -0
  51. package/.github/skills/code-test-coverage-analyzer/references/flutter-patterns.md +254 -0
  52. package/.github/skills/code-test-coverage-analyzer/references/ios-patterns.md +228 -0
  53. package/.github/skills/code-test-coverage-analyzer/references/react-native-patterns.md +431 -0
  54. package/.github/skills/code-test-coverage-analyzer/references/react-patterns.md +206 -0
  55. package/.github/skills/code-test-coverage-analyzer/scripts/detect-platform.ps1 +261 -0
  56. package/.github/skills/code-test-coverage-analyzer/scripts/scan-repository.ps1 +242 -0
  57. package/.github/skills/code-test-coverage-analyzer/templates/brd-compliance-row.md +107 -0
  58. package/.github/skills/code-test-coverage-analyzer/templates/test-case-row.md +130 -0
  59. package/.github/skills/code-test-coverage-analyzer/templates/user-story-compliance-row.md +170 -0
  60. package/.github/skills/custom-font-integrator/SKILL.md +373 -0
  61. package/.github/skills/custom-font-integrator/assets/FontTestScreen.js +150 -0
  62. package/.github/skills/custom-font-integrator/references/example-info-plist.xml +21 -0
  63. package/.github/skills/custom-font-integrator/scripts/setup-fonts.sh +99 -0
  64. package/.github/skills/encryption-decryption-utility/Instructions.md +282 -0
  65. package/.github/skills/encryption-decryption-utility/README.md +222 -0
  66. package/.github/skills/encryption-decryption-utility/SKILL.md +645 -0
  67. package/.github/skills/encryption-decryption-utility/assets/encryption-config-template.json +13 -0
  68. package/.github/skills/encryption-decryption-utility/assets/platform-matrix.json +180 -0
  69. package/.github/skills/encryption-decryption-utility/metadata.yaml +51 -0
  70. package/.github/skills/encryption-decryption-utility/references/android-crypto.md +157 -0
  71. package/.github/skills/encryption-decryption-utility/references/angular-crypto.md +130 -0
  72. package/.github/skills/encryption-decryption-utility/references/approach-1-webcrypto.md +95 -0
  73. package/.github/skills/encryption-decryption-utility/references/approach-2-rsa-aes-cbc.md +111 -0
  74. package/.github/skills/encryption-decryption-utility/references/approach-3-aes-sharedkey.md +114 -0
  75. package/.github/skills/encryption-decryption-utility/references/architecture.md +233 -0
  76. package/.github/skills/encryption-decryption-utility/references/backend-alignment.md +506 -0
  77. package/.github/skills/encryption-decryption-utility/references/dependency-guidance.md +234 -0
  78. package/.github/skills/encryption-decryption-utility/references/ec-implementation.md +832 -0
  79. package/.github/skills/encryption-decryption-utility/references/error-handling-playbook.md +234 -0
  80. package/.github/skills/encryption-decryption-utility/references/flutter-crypto.md +105 -0
  81. package/.github/skills/encryption-decryption-utility/references/ios-crypto.md +338 -0
  82. package/.github/skills/encryption-decryption-utility/references/native-rsa-implementation.md +373 -0
  83. package/.github/skills/encryption-decryption-utility/references/node-crypto.md +86 -0
  84. package/.github/skills/encryption-decryption-utility/references/react-crypto.md +105 -0
  85. package/.github/skills/encryption-decryption-utility/references/react-native-crypto.md +1001 -0
  86. package/.github/skills/encryption-decryption-utility/references/react-web-crypto.md +668 -0
  87. package/.github/skills/encryption-decryption-utility/references/security-checklist.md +176 -0
  88. package/.github/skills/encryption-decryption-utility/references/web-crypto.md +74 -0
  89. package/.github/skills/encryption-decryption-utility/scripts/detect.js +128 -0
  90. package/.github/skills/encryption-decryption-utility/scripts/install.js +1713 -0
  91. package/.github/skills/encryption-decryption-utility/scripts/setup.js +800 -0
  92. package/.github/skills/encryption-decryption-utility/template.md +241 -0
  93. package/.github/skills/encryption-decryption-utility/templates/config-questionnaire.md +467 -0
  94. package/.github/skills/encryption-decryption-utility/templates/delivery-checklist.md +206 -0
  95. package/.github/skills/encryption-decryption-utility/templates/implementation-plan.md +304 -0
  96. package/.github/skills/feature-generator/SKILL.MD +2741 -0
  97. package/.github/skills/feature-generator/assets/fingerprint-schema.json +385 -0
  98. package/.github/skills/feature-generator/assets/spec-template.md +172 -0
  99. package/.github/skills/feature-generator/assets/transform-rules.json +82 -0
  100. package/.github/skills/feature-generator/references/api-envelope-patterns.md +327 -0
  101. package/.github/skills/feature-generator/references/screen-logic-patterns.md +399 -0
  102. package/.github/skills/feature-generator/references/state-library-patterns.md +464 -0
  103. package/.github/skills/figma-ui-mapper/README.md +34 -0
  104. package/.github/skills/figma-ui-mapper/SKILL.md +101 -0
  105. package/.github/skills/figma-ui-mapper/assets/templates/component-map-template.md +30 -0
  106. package/.github/skills/figma-ui-mapper/assets/templates/generation-report-template.md +49 -0
  107. package/.github/skills/figma-ui-mapper/metadata.yaml +22 -0
  108. package/.github/skills/figma-ui-mapper/references/android.md +11 -0
  109. package/.github/skills/figma-ui-mapper/references/angular.md +18 -0
  110. package/.github/skills/figma-ui-mapper/references/capacitor.md +18 -0
  111. package/.github/skills/figma-ui-mapper/references/common.md +23 -0
  112. package/.github/skills/figma-ui-mapper/references/expo.md +18 -0
  113. package/.github/skills/figma-ui-mapper/references/flutter.md +18 -0
  114. package/.github/skills/figma-ui-mapper/references/frameworks/angular/rules.md +23 -0
  115. package/.github/skills/figma-ui-mapper/references/frameworks/capacitor/rules.md +23 -0
  116. package/.github/skills/figma-ui-mapper/references/frameworks/expo/rules.md +23 -0
  117. package/.github/skills/figma-ui-mapper/references/frameworks/flutter/rules.md +23 -0
  118. package/.github/skills/figma-ui-mapper/references/frameworks/ionic/rules.md +23 -0
  119. package/.github/skills/figma-ui-mapper/references/frameworks/kotlin-multiplatform/rules.md +23 -0
  120. package/.github/skills/figma-ui-mapper/references/frameworks/native-android/rules.md +23 -0
  121. package/.github/skills/figma-ui-mapper/references/frameworks/native-ios/rules.md +23 -0
  122. package/.github/skills/figma-ui-mapper/references/frameworks/next/rules.md +23 -0
  123. package/.github/skills/figma-ui-mapper/references/frameworks/nuxt/rules.md +23 -0
  124. package/.github/skills/figma-ui-mapper/references/frameworks/react/rules.md +19 -0
  125. package/.github/skills/figma-ui-mapper/references/frameworks/react-native/rules.md +23 -0
  126. package/.github/skills/figma-ui-mapper/references/frameworks/svelte/rules.md +23 -0
  127. package/.github/skills/figma-ui-mapper/references/frameworks/vue/rules.md +23 -0
  128. package/.github/skills/figma-ui-mapper/references/ionic.md +18 -0
  129. package/.github/skills/figma-ui-mapper/references/ios.md +11 -0
  130. package/.github/skills/figma-ui-mapper/references/kotlin-multiplatform.md +18 -0
  131. package/.github/skills/figma-ui-mapper/references/native-android.md +18 -0
  132. package/.github/skills/figma-ui-mapper/references/native-ios.md +18 -0
  133. package/.github/skills/figma-ui-mapper/references/next.md +18 -0
  134. package/.github/skills/figma-ui-mapper/references/nuxt.md +18 -0
  135. package/.github/skills/figma-ui-mapper/references/react-figma-guideline.md +21 -0
  136. package/.github/skills/figma-ui-mapper/references/react-native.md +18 -0
  137. package/.github/skills/figma-ui-mapper/references/react.md +18 -0
  138. package/.github/skills/figma-ui-mapper/references/script-usage.md +46 -0
  139. package/.github/skills/figma-ui-mapper/references/svelte.md +18 -0
  140. package/.github/skills/figma-ui-mapper/references/vue.md +18 -0
  141. package/.github/skills/figma-ui-mapper/references/workflow.md +74 -0
  142. package/.github/skills/figma-ui-mapper/scripts/generate-page-through-figma.js +635 -0
  143. package/.github/skills/figma-ui-mapper/scripts/generate-react-page-through-figma.js +4 -0
  144. package/.github/skills/frontend-task-breakdown/SKILL.md +734 -0
  145. package/.github/skills/md-file-converter/SKILL.md +291 -0
  146. package/.github/skills/md-file-converter/config/formats.json +114 -0
  147. package/.github/skills/md-file-converter/extractors/extract-docx.sh +120 -0
  148. package/.github/skills/md-file-converter/extractors/extract-eml.py +108 -0
  149. package/.github/skills/md-file-converter/extractors/extract-pdf.sh +97 -0
  150. package/.github/skills/md-file-converter/extractors/extract-pptx.py +143 -0
  151. package/.github/skills/md-file-converter/extractors/extract-xlsx.py +175 -0
  152. package/.github/skills/md-file-converter/scripts/check-tools.sh +47 -0
  153. package/.github/skills/md-file-converter/scripts/extract-archive.sh +83 -0
  154. package/.github/skills/md-file-converter/scripts/extract-ocr.sh +77 -0
  155. package/.github/skills/md-file-converter/scripts/get-metadata.sh +57 -0
  156. package/.github/skills/md-file-converter/templates/output.md +73 -0
  157. package/.github/skills/md-file-converter/templates/unsupported-object.md +6 -0
  158. package/.github/skills/mockAPI-contract-generator/SKILL.md +607 -0
  159. package/.github/skills/test-case-validator/CHANGELOG.md +155 -0
  160. package/.github/skills/test-case-validator/CONFIGURATION.md +130 -0
  161. package/.github/skills/test-case-validator/EXAMPLES.md +50 -0
  162. package/.github/skills/test-case-validator/QUALITY_SCORING.md +98 -0
  163. package/.github/skills/test-case-validator/README.md +111 -0
  164. package/.github/skills/test-case-validator/REPORT_TEMPLATE.md +116 -0
  165. package/.github/skills/test-case-validator/SKILL.md +209 -0
  166. package/.github/skills/test-case-validator/SYSTEM_PROMPT.md +127 -0
  167. package/.github/skills/test-case-validator/TRACEABILITY_ENGINE.md +152 -0
  168. package/.github/skills/test-case-validator/VALIDATION_RULES.md +411 -0
  169. package/.github/skills/test-case-validator/config/default.config.yaml +62 -0
  170. package/.github/skills/test-case-validator/docs/ARCHITECTURE.md +66 -0
  171. package/.github/skills/test-case-validator/docs/EXTENDING.md +85 -0
  172. package/.github/skills/test-case-validator/docs/FAQ.md +88 -0
  173. package/.github/skills/test-case-validator/docs/VERSIONING.md +55 -0
  174. package/.github/skills/test-case-validator/examples/example-1-manual-qa-ecommerce/input-brd.md +43 -0
  175. package/.github/skills/test-case-validator/examples/example-1-manual-qa-ecommerce/input-test-cases.csv +9 -0
  176. package/.github/skills/test-case-validator/examples/example-1-manual-qa-ecommerce/input-user-story.md +29 -0
  177. package/.github/skills/test-case-validator/examples/example-1-manual-qa-ecommerce/output-report.md +303 -0
  178. package/.github/skills/test-case-validator/examples/example-2-automated-frontend-suite/input-spec.md +43 -0
  179. package/.github/skills/test-case-validator/examples/example-2-automated-frontend-suite/input-test-files-index.md +56 -0
  180. package/.github/skills/test-case-validator/examples/example-2-automated-frontend-suite/output-report.md +274 -0
  181. package/.github/skills/test-case-validator/prompts/00-applicability-resolution.md +61 -0
  182. package/.github/skills/test-case-validator/prompts/01-extraction-user-story.md +58 -0
  183. package/.github/skills/test-case-validator/prompts/02-extraction-brd.md +64 -0
  184. package/.github/skills/test-case-validator/prompts/03-extraction-test-cases.md +92 -0
  185. package/.github/skills/test-case-validator/prompts/04-traceability-matrix.md +41 -0
  186. package/.github/skills/test-case-validator/prompts/05-coverage-analysis.md +46 -0
  187. package/.github/skills/test-case-validator/prompts/06-missing-scenario-detection.md +32 -0
  188. package/.github/skills/test-case-validator/prompts/07-duplicate-detection.md +36 -0
  189. package/.github/skills/test-case-validator/prompts/08-risk-analysis.md +39 -0
  190. package/.github/skills/test-case-validator/prompts/09-gated-wiring-validation.md +53 -0
  191. package/.github/skills/test-case-validator/prompts/10-observation-report.md +56 -0
  192. package/.github/skills/test-case-validator/prompts/11-final-report-assembly.md +57 -0
  193. package/.github/skills/test-case-validator/templates/coverage-table.md +25 -0
  194. package/.github/skills/test-case-validator/templates/executive-summary.md +38 -0
  195. package/.github/skills/test-case-validator/templates/final-summary-block.md +87 -0
  196. package/.github/skills/test-case-validator/templates/observation-entry.md +41 -0
  197. package/.github/skills/test-case-validator/templates/rtm-row.md +25 -0
  198. package/.github/skills/validation-engine-builder/README.md +50 -0
  199. package/.github/skills/validation-engine-builder/SKILL.md +241 -0
  200. package/.github/skills/validation-engine-builder/references/core.md +158 -0
  201. package/.github/skills/validation-engine-builder/references/platform-angular.md +166 -0
  202. package/.github/skills/validation-engine-builder/references/platform-flutter.md +118 -0
  203. package/.github/skills/validation-engine-builder/references/platform-react-native.md +170 -0
  204. package/.github/skills/validation-engine-builder/references/platform-react.md +94 -0
  205. package/.github/skills/validation-engine-builder/scripts/apply-to-project.js +80 -0
  206. package/.github/skills/validation-engine-builder/scripts/generate-angular.js +271 -0
  207. package/.github/skills/validation-engine-builder/scripts/generate-flutter.js +298 -0
  208. package/.github/skills/validation-engine-builder/scripts/generate-react-native.js +217 -0
  209. package/.github/skills/validation-engine-builder/scripts/generate-react.js +163 -0
  210. package/.github/skills/validation-engine-builder/scripts/install-deps.js +53 -0
  211. package/.github/skills/validation-engine-builder/scripts/shared/detect-platform.js +68 -0
  212. package/.github/skills/validation-engine-builder/scripts/shared/npm-deps.js +103 -0
  213. package/.github/skills/validation-engine-builder/scripts/shared/rhf-hook.js +43 -0
  214. package/.github/skills/validation-engine-builder/scripts/shared/ts-messages-regex.js +62 -0
  215. package/.github/skills/validation-engine-builder/scripts/shared/util.js +44 -0
  216. package/.github/skills/validation-engine-builder/scripts/shared/yup-schemas.js +80 -0
  217. package/.github/skills/validation-engine-builder/template.md +73 -0
  218. package/.github/skills/validation-engine-builder/templates/messages.json +22 -0
  219. package/.github/skills/validation-engine-builder/templates/regex.json +16 -0
  220. package/.github/skills/validation-engine-builder/templates/schemas.json +48 -0
  221. package/bin/index.js +145 -0
  222. package/package.json +22 -0
  223. package/readme.md +0 -0
@@ -0,0 +1,374 @@
1
+ # Platform File — Angular
2
+
3
+ Read `architecture-core.md` first. Angular differs from the React-family platforms in one
4
+ structural way that changes how DI is implemented: **Angular has a built-in, framework-native
5
+ dependency injection system.** The manual "DI Pattern A / Pattern B" containers used for React
6
+ Native and React do not apply here — do not port them. Use Angular's own `@Injectable` /
7
+ `providers` mechanism instead (detailed below).
8
+
9
+ Everything under "Stack Fingerprint Defaults" applies **only** when Phase 1 detection found nothing
10
+ in the target repo.
11
+
12
+ ---
13
+
14
+ ## Sub-Variant Detection (run before anything else)
15
+
16
+ | Signal | Sub-variant | Affects |
17
+ |---|---|---|
18
+ | `src/app/app.config.ts` exists, no `app.module.ts` | Standalone components (Angular 14+) | Feature wiring goes in each component's `providers` array or `app.config.ts`; no `NgModule` is created |
19
+ | `src/app/app.module.ts` exists | NgModule-based | Feature wiring goes in a `[Feature]Module` with a `providers` array |
20
+
21
+ State the detected sub-variant before generating any file — it changes where the repository→use
22
+ case provider mapping is registered.
23
+
24
+ ---
25
+
26
+ ## Stack Fingerprint Defaults (greenfield only)
27
+
28
+ | Concern | Detect first (search for) | Default if nothing detected |
29
+ |---|---|---|
30
+ | Language | — | TypeScript, strict mode |
31
+ | State management | `@ngrx/store` imports (`createReducer`, `createFeature`), `@ngrx/signals`, `@datorama/akita`, `@ngxs/store`, `signal(`/`computed(` from `@angular/core` used as app state | Plain RxJS: an injectable `[Feature]Store` service holding a `BehaviorSubject` per concern, exposed as `Observable` |
32
+ | HTTP client | `HttpClient` from `@angular/common/http` (this is Angular's standard client — still verify it's actually imported, not a wrapped Axios instance) | `HttpClient` with a functional `HttpInterceptorFn` |
33
+ | Storage | existing `StorageService`/`localStorage`/`sessionStorage` wrapper | injectable `StorageService` wrapping `sessionStorage` for tokens, `localStorage` for non-sensitive UI state |
34
+ | Routing | `app.routes.ts` / `RouterModule.forRoot(` | Angular Router with lazy-loaded feature routes |
35
+ | DI mechanism | — (Angular always has DI) | `@Injectable({ providedIn: 'root' })` for app-wide singletons, or feature-scoped providers array for feature-scoped instances |
36
+ | Test runner | `karma.conf.js`, `jest.config.*` | Whatever the project already runs (Angular CLI defaults to Karma+Jasmine; many teams migrate to Jest) — do not silently switch an existing project's test runner |
37
+
38
+ ---
39
+
40
+ ## Folder Tree
41
+
42
+ ```
43
+ src/app/
44
+ ├── app.component.ts
45
+ ├── app.config.ts # standalone bootstrap providers (or app.module.ts if NgModule-based)
46
+ ├── app.routes.ts
47
+
48
+ ├── core/ # Infrastructure — shared by all features
49
+ │ ├── api/
50
+ │ │ ├── api-error-handler.ts
51
+ │ │ ├── app-error.ts
52
+ │ │ └── token.provider.ts # Token getter/setter (prevents circular deps)
53
+ │ ├── interceptors/
54
+ │ │ ├── auth.interceptor.ts # attaches Authorization header
55
+ │ │ └── error.interceptor.ts # maps HTTP errors to AppError
56
+ │ ├── guards/
57
+ │ │ └── auth.guard.ts # CanActivateFn
58
+ │ ├── storage/
59
+ │ │ └── storage.service.ts
60
+ │ └── logging/
61
+ │ └── logger.service.ts
62
+
63
+ ├── features/
64
+ │ └── [feature-name]/
65
+ │ ├── domain/ # Pure TypeScript — ZERO Angular imports
66
+ │ │ ├── entities/
67
+ │ │ │ └── [item].entity.ts
68
+ │ │ ├── repositories/
69
+ │ │ │ └── [feature].repository.ts # abstract class — see DI section
70
+ │ │ └── use-cases/
71
+ │ │ └── get-[item].use-case.ts
72
+ │ ├── data/
73
+ │ │ ├── dtos/
74
+ │ │ │ └── [item].dto.ts
75
+ │ │ ├── mappers/
76
+ │ │ │ └── [feature].mapper.ts
77
+ │ │ └── repositories/
78
+ │ │ └── [feature].repository.impl.ts
79
+ │ ├── presentation/
80
+ │ │ ├── pages/
81
+ │ │ │ └── [feature]-page/
82
+ │ │ │ ├── [feature]-page.component.ts
83
+ │ │ │ ├── [feature]-page.component.html
84
+ │ │ │ └── [feature]-page.component.scss
85
+ │ │ ├── components/
86
+ │ │ └── state/
87
+ │ │ └── [feature].store.ts # RxJS store service, or NgRx feature slice if detected
88
+ │ ├── [feature].routes.ts
89
+ │ └── [feature].providers.ts # provider array wiring [Feature]Repository → [Feature]RepositoryImpl
90
+
91
+ └── shared/
92
+ └── ui/ # Reusable presentational components with no feature dependency
93
+ ```
94
+
95
+ ---
96
+
97
+ ## Naming Extensions (Angular-specific — official Angular style guide, not invented)
98
+
99
+ Angular's own style guide uses **kebab-case file names with a dot-separated type suffix**, and
100
+ explicitly recommends **against** an `I`-prefix on interface/abstraction names (no Hungarian
101
+ notation). This is different from the RN/React convention in this skill and must not be mixed in:
102
+
103
+ | Artifact | Convention | Example |
104
+ |----------|------------|---------|
105
+ | Feature folder | kebab-case | `portfolio-summary`, `user-profile` |
106
+ | Entity file | kebab-case + `.entity.ts` | `holding.entity.ts` (class `HoldingEntity`) |
107
+ | Repository abstraction | kebab-case + `.repository.ts`, **no `I` prefix** | `holding.repository.ts` (abstract class `HoldingRepository`) |
108
+ | Repository implementation | kebab-case + `.repository.impl.ts` | `holding.repository.impl.ts` (class `HoldingRepositoryImpl`) |
109
+ | Use case file | kebab-case + `.use-case.ts` | `get-holding-summary.use-case.ts` (class `GetHoldingSummaryUseCase`) |
110
+ | DTO file | kebab-case + `.dto.ts` | `holding-summary.dto.ts` |
111
+ | Mapper file | kebab-case + `.mapper.ts`, function named `mapTo…` | `holding.mapper.ts` → `mapHoldingDtoToDomain` |
112
+ | Component (page) | kebab-case + `.component.ts` | `holding-detail-page.component.ts` (class `HoldingDetailPageComponent`) |
113
+ | Store/state service | kebab-case + `.store.ts` | `holding.store.ts` (class `HoldingStore`) |
114
+ | Route guard | kebab-case + `.guard.ts` | `auth.guard.ts` |
115
+ | Interceptor | kebab-case + `.interceptor.ts` | `auth.interceptor.ts` |
116
+ | Providers file | kebab-case + `.providers.ts` | `holding.providers.ts` |
117
+ | Test file | same base name + `.spec.ts` | `holding.repository.impl.spec.ts` |
118
+ | Loading state | `'idle' \| 'loading' \| 'succeeded' \| 'failed'` string union | never a `boolean` |
119
+
120
+ ---
121
+
122
+ ## DI — Angular's Framework-Native Mechanism (do not use RN/React manual containers)
123
+
124
+ **Why this is different:** a TypeScript `interface` has no runtime representation, so Angular's DI
125
+ cannot inject one directly. The correct Angular idiom is to make the repository contract an
126
+ **abstract class** (which does have a runtime token) and bind the concrete implementation to it via
127
+ a `providers` array — this is how Angular's own documentation and the wider community express
128
+ "interface-based DI."
129
+
130
+ ```ts
131
+ // domain/repositories/[feature].repository.ts
132
+ import { Observable } from 'rxjs';
133
+ import type { [Item]Entity } from '../entities/[item].entity';
134
+
135
+ export abstract class [Feature]Repository {
136
+ abstract get[Item](args: [RequestArgs]): Observable<[Item]Entity>;
137
+ }
138
+ ```
139
+
140
+ ```ts
141
+ // domain/use-cases/get-[item].use-case.ts
142
+ import { Injectable } from '@angular/core';
143
+ import { Observable } from 'rxjs';
144
+ import { [Feature]Repository } from '../repositories/[feature].repository';
145
+ import type { [Item]Entity } from '../entities/[item].entity';
146
+
147
+ @Injectable()
148
+ export class Get[Item]UseCase {
149
+ constructor(private readonly repository: [Feature]Repository) {}
150
+
151
+ execute(args: [RequestArgs]): Observable<[Item]Entity> {
152
+ return this.repository.get[Item](args);
153
+ }
154
+ }
155
+ ```
156
+
157
+ ```ts
158
+ // data/repositories/[feature].repository.impl.ts
159
+ import { Injectable } from '@angular/core';
160
+ import { HttpClient } from '@angular/common/http';
161
+ import { Observable, map } from 'rxjs';
162
+ import { [Feature]Repository } from '../../domain/repositories/[feature].repository';
163
+ import type { [Item]Entity } from '../../domain/entities/[item].entity';
164
+ import type { [Item]Dto } from '../dtos/[item].dto';
165
+ import { map[Item]DtoToDomain } from '../mappers/[feature].mapper';
166
+
167
+ @Injectable()
168
+ export class [Feature]RepositoryImpl extends [Feature]Repository {
169
+ constructor(private readonly http: HttpClient) { super(); }
170
+
171
+ get[Item](args: [RequestArgs]): Observable<[Item]Entity> {
172
+ return this.http.post<[Item]Dto>('/[endpoint]', args).pipe(map(map[Item]DtoToDomain));
173
+ }
174
+ }
175
+ ```
176
+
177
+ ```ts
178
+ // features/[feature-name]/[feature].providers.ts
179
+ import type { Provider } from '@angular/core';
180
+ import { [Feature]Repository } from './domain/repositories/[feature].repository';
181
+ import { [Feature]RepositoryImpl } from './data/repositories/[feature].repository.impl';
182
+ import { Get[Item]UseCase } from './domain/use-cases/get-[item].use-case';
183
+
184
+ export const [FEATURE]_PROVIDERS: Provider[] = [
185
+ { provide: [Feature]Repository, useClass: [Feature]RepositoryImpl },
186
+ Get[Item]UseCase,
187
+ ];
188
+ ```
189
+
190
+ Register `[FEATURE]_PROVIDERS` in exactly one place:
191
+ - **Standalone**: the feature's routed component's `providers` array, or on the lazy route in
192
+ `app.routes.ts` (`{ path: '[feature]', providers: [FEATURE]_PROVIDERS], loadComponent: … }`) so
193
+ the providers are scoped to the feature, not app-wide.
194
+ - **NgModule**: the feature's `[Feature]Module`'s `providers` array.
195
+
196
+ **Never** add `providedIn: 'root'` to a feature-specific repository/use-case unless the feature is
197
+ genuinely meant to be a global singleton (auth is a legitimate exception, same as in RN/React) —
198
+ feature-scoped providers keep one feature from leaking its DI graph into another.
199
+
200
+ ---
201
+
202
+ ## State Pattern — Plain RxJS Store (default when no NgRx/Akita/Signals detected)
203
+
204
+ ```ts
205
+ // presentation/state/[feature].store.ts
206
+ import { Injectable } from '@angular/core';
207
+ import { BehaviorSubject, Observable } from 'rxjs';
208
+ import type { [Item]Entity } from '../../domain/entities/[item].entity';
209
+
210
+ export type LoadingState = 'idle' | 'loading' | 'succeeded' | 'failed';
211
+
212
+ interface [Feature]State {
213
+ data: [Item]Entity | null;
214
+ loading: LoadingState;
215
+ error: string | null;
216
+ }
217
+
218
+ const initialState: [Feature]State = { data: null, loading: 'idle', error: null };
219
+
220
+ @Injectable()
221
+ export class [Feature]Store {
222
+ private readonly state$ = new BehaviorSubject<[Feature]State>(initialState);
223
+
224
+ readonly data$: Observable<[Item]Entity | null> = this.state$.pipe(map(s => s.data));
225
+ readonly loading$: Observable<LoadingState> = this.state$.pipe(map(s => s.loading));
226
+ readonly error$: Observable<string | null> = this.state$.pipe(map(s => s.error));
227
+
228
+ constructor(private readonly get[Item]UseCase: Get[Item]UseCase) {}
229
+
230
+ load(args: [RequestArgs]): void {
231
+ this.patch({ loading: 'loading', error: null });
232
+ this.get[Item]UseCase.execute(args).subscribe({
233
+ next: (data) => this.patch({ data, loading: 'succeeded' }),
234
+ error: (err) => this.patch({ loading: 'failed', error: err?.message ?? 'Unknown error' }),
235
+ });
236
+ }
237
+
238
+ private patch(partial: Partial<[Feature]State>): void {
239
+ this.state$.next({ ...this.state$.value, ...partial });
240
+ }
241
+ }
242
+ ```
243
+
244
+ Register `[Feature]Store` in the same `providers` array as the repository/use case. Component
245
+ subscribes via the `async` pipe in the template (`data$ | async`) — never a manual `.subscribe()`
246
+ in a component without unsubscribing (see Anti-Patterns).
247
+
248
+ **If NgRx (or another state library) is detected** in the target repo, use that instead — a feature
249
+ slice/store keyed to the feature, following the same file location (`presentation/state/`), not
250
+ this BehaviorSubject pattern. Do not introduce a second state-management library alongside an
251
+ existing one.
252
+
253
+ ## HTTP Interceptor Pattern
254
+
255
+ ```ts
256
+ // core/interceptors/auth.interceptor.ts
257
+ import type { HttpInterceptorFn } from '@angular/common/http';
258
+ import { getToken } from '../api/token.provider';
259
+
260
+ export const authInterceptor: HttpInterceptorFn = (req, next) => {
261
+ const token = getToken();
262
+ if (!token) return next(req);
263
+ return next(req.clone({ setHeaders: { Authorization: `Bearer ${token}` } }));
264
+ };
265
+ ```
266
+
267
+ Register in `app.config.ts`: `provideHttpClient(withInterceptors([authInterceptor, errorInterceptor]))`.
268
+
269
+ ## Route Guard Pattern
270
+
271
+ ```ts
272
+ // core/guards/auth.guard.ts
273
+ import type { CanActivateFn } from '@angular/router';
274
+ import { inject } from '@angular/core';
275
+ import { Router } from '@angular/router';
276
+ import { AuthTokenStore } from '../../features/auth/presentation/state/auth-token.store';
277
+
278
+ export const authGuard: CanActivateFn = () => {
279
+ const hasToken = !!inject(AuthTokenStore).getToken();
280
+ if (hasToken) return true;
281
+ inject(Router).navigate(['/login']);
282
+ return false;
283
+ };
284
+ ```
285
+
286
+ ## Route Definition Pattern
287
+
288
+ ```ts
289
+ // features/[feature-name]/[feature].routes.ts
290
+ import type { Routes } from '@angular/router';
291
+ import { [FEATURE]_PROVIDERS } from './[feature].providers';
292
+
293
+ export const [FEATURE]_ROUTES: Routes = [
294
+ {
295
+ path: '',
296
+ providers: [FEATURE]_PROVIDERS,
297
+ children: [
298
+ { path: '', loadComponent: () => import('./presentation/pages/[feature]-page/[feature]-page.component').then(m => m.[Feature]PageComponent) },
299
+ { path: ':id', loadComponent: () => import('./presentation/pages/[feature]-detail-page/[feature]-detail-page.component').then(m => m.[Feature]DetailPageComponent) },
300
+ ],
301
+ },
302
+ ];
303
+ ```
304
+
305
+ Mount with `{ path: '[feature]', loadChildren: () => import('./features/[feature-name]/[feature].routes').then(m => m.[FEATURE]_ROUTES) }` in the parent `app.routes.ts`.
306
+
307
+ ## Domain / Data Layer Patterns
308
+
309
+ See the DI section above — the abstract-class repository and its implementation together constitute
310
+ both the domain contract and the data-layer implementation pattern for Angular.
311
+
312
+ ---
313
+
314
+ ## Security Rules (Angular/browser-specific — on top of architecture-core.md)
315
+
316
+ 1. There is no OS Keychain in a browser. Prefer an httpOnly cookie set by the server for tokens; if
317
+ client-side storage is required, prefer in-memory (a service field) with refresh-token rotation
318
+ over `localStorage`.
319
+ 2. **Never** use `localStorage` for tokens without explicitly flagging the XSS-persistence tradeoff
320
+ to the user — same rule as `platform-react.md`.
321
+ 3. Angular's built-in sanitization (`DomSanitizer`) protects template bindings from XSS by default —
322
+ **never** call `bypassSecurityTrustHtml`/`bypassSecurityTrustScript` on user-controlled content.
323
+
324
+ ---
325
+
326
+ ## Anti-Patterns (Angular-specific, on top of architecture-core.md)
327
+
328
+ - **Never** try to inject a plain TypeScript `interface` — Angular's DI has no runtime token for it.
329
+ Use an abstract class (see DI section) or an `InjectionToken<T>` with a factory provider.
330
+ - **Never** call `HttpClient` directly from a component — always go through the feature's
331
+ `[Feature]Repository` via constructor injection.
332
+ - **Never** put business logic in a component class — it belongs in a use case.
333
+ - **Never** subscribe to an `Observable` in a component without unsubscribing — use the `async`
334
+ pipe, or `takeUntilDestroyed()` (Angular 16+) if a manual subscription is unavoidable. An
335
+ un-unsubscribed subscription is a memory leak on every navigation away from the component.
336
+ - **Never** register a feature's providers with `providedIn: 'root'` unless the feature is
337
+ genuinely meant to be a global singleton — keep feature DI scoped to the feature's route/component.
338
+ - **Never** mix the `I`-prefix convention from `platform-react-native.md`/`platform-react.md` into
339
+ Angular code — Angular naming has no `I` prefix (see Naming Extensions).
340
+ - **Never** use `any` — use a specific type or `unknown` with a type guard.
341
+
342
+ ---
343
+
344
+ ## Worked Example
345
+
346
+ **Request**: "Add a watchlist feature with ability to fetch and display watchlist items."
347
+
348
+ **Artifacts**:
349
+ - Domain: `holding.entity.ts` → `WatchlistItemEntity`; `watchlist.repository.ts` (abstract class) → `WatchlistRepository`; `get-watchlist.use-case.ts` → `GetWatchlistUseCase`
350
+ - Data: `watchlist-item.dto.ts`, `watchlist.mapper.ts` → `mapWatchlistItemDtoToDomain`, `watchlist.repository.impl.ts` → `WatchlistRepositoryImpl`
351
+ - Presentation: `watchlist.store.ts` → `WatchlistStore`, `watchlist-page.component.ts`/`.html`/`.scss`
352
+ - Wiring: `watchlist.providers.ts`, `watchlist.routes.ts`
353
+
354
+ **Output**:
355
+ ```
356
+ Created:
357
+ src/app/features/watchlist/domain/entities/watchlist-item.entity.ts
358
+ src/app/features/watchlist/domain/repositories/watchlist.repository.ts
359
+ src/app/features/watchlist/domain/use-cases/get-watchlist.use-case.ts
360
+ src/app/features/watchlist/data/dtos/watchlist-item.dto.ts
361
+ src/app/features/watchlist/data/mappers/watchlist.mapper.ts
362
+ src/app/features/watchlist/data/repositories/watchlist.repository.impl.ts
363
+ src/app/features/watchlist/presentation/state/watchlist.store.ts
364
+ src/app/features/watchlist/presentation/pages/watchlist-page/watchlist-page.component.ts
365
+ src/app/features/watchlist/presentation/pages/watchlist-page/watchlist-page.component.html
366
+ src/app/features/watchlist/presentation/pages/watchlist-page/watchlist-page.component.scss
367
+ src/app/features/watchlist/watchlist.providers.ts
368
+ src/app/features/watchlist/watchlist.routes.ts
369
+
370
+ Updated:
371
+ src/app/app.routes.ts (added lazy-loaded watchlist route)
372
+
373
+ Dependency check: PASS — no layer boundary violations detected
374
+ ```