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,590 @@
1
+ # Platform File — React Native
2
+
3
+ Read `architecture-core.md` first. This file supplies the React Native-specific implementation of
4
+ the universal layers: folder tree, DI mechanism, state/HTTP/storage/navigation patterns, naming
5
+ extensions, and anti-patterns. Everything under "Stack Fingerprint Defaults" applies **only** when
6
+ Phase 1 detection (see `SKILL.md`) found nothing in the target repo — if the repo already uses a
7
+ different state library, HTTP client, storage, or navigation library, generate against what's
8
+ already there instead.
9
+
10
+ ---
11
+
12
+ ## Stack Fingerprint Defaults (greenfield only)
13
+
14
+ | Concern | Detect first (search for) | Default if nothing detected |
15
+ |---|---|---|
16
+ | Language | — | TypeScript, strict mode |
17
+ | State management | `createSlice(`, `create(` from `'zustand'`, `makeAutoObservable(`/`observable(` (mobx), `useReducer`+`createContext` | Redux Toolkit (`createSlice`, `createAsyncThunk`) + RTK Query (`createApi`) |
18
+ | HTTP client | `axios.create(`, `fetch(`, `createApi(`, React Query hooks | Axios with interceptors |
19
+ | Local storage | `MMKV`, `AsyncStorage`, `react-native-keychain` | MMKV (`SafeMMKV` wrapper) for general data; Keychain for secrets/tokens |
20
+ | Navigation | `@react-navigation/native`, `expo-router`, `react-native-navigation` (Wix) | React Navigation v6+, native-stack |
21
+ | DI mechanism | existing `di/[feature]Container.ts` or `di/[feature]DI.ts` files | manual DI — Pattern A or B below |
22
+ | Test runner | `jest.config.*`, test script in `package.json` | Jest |
23
+
24
+ ---
25
+
26
+ ## Folder Tree
27
+
28
+ ```
29
+ src/
30
+ ├── app/ # App bootstrap — orchestration only
31
+ │ ├── AppWrapper.tsx # Root component, cache hydration, offline overlay
32
+ │ ├── index.ts
33
+ │ ├── NetworkMonitor.tsx
34
+ │ ├── NoInternetScreen.tsx
35
+ │ ├── useNetworkStatus.ts
36
+ │ ├── di/
37
+ │ │ ├── container.ts # Global DI container — wires all feature containers
38
+ │ │ └── index.ts
39
+ │ ├── environment/
40
+ │ │ ├── authConfig.ts # OAuth / auth provider config
41
+ │ │ ├── env.ts # Environment variable accessors (no raw process.env)
42
+ │ │ └── index.ts
43
+ │ ├── offline/
44
+ │ │ ├── OfflineOverlayController.tsx
45
+ │ │ ├── offlineOverlayTypes.ts
46
+ │ │ └── index.ts
47
+ │ ├── routing/
48
+ │ │ ├── AppNavigator.tsx # Top-level (decides auth vs main)
49
+ │ │ ├── RootNavigator.tsx # Authenticated root
50
+ │ │ ├── MainTabsNavigator.tsx
51
+ │ │ ├── TabsNavigator.tsx
52
+ │ │ └── index.ts
53
+ │ └── state/
54
+ │ └── store.ts # Redux store configuration
55
+
56
+ ├── core/ # Infrastructure — shared by all features
57
+ │ ├── api/
58
+ │ │ ├── axiosClient.ts # Singleton Axios instance + interceptors + SSL pinning
59
+ │ │ ├── apiErrorHandler.ts
60
+ │ │ ├── AppError.ts # Typed error class hierarchy
61
+ │ │ ├── tokenProvider.ts # Token getter/setter (prevents circular deps)
62
+ │ │ ├── unauthorizedHandler.ts
63
+ │ │ ├── requestUtils.ts # Header builders, nonce generation
64
+ │ │ └── index.ts
65
+ │ ├── cache/
66
+ │ │ ├── baseApiSlice.ts # Single createApi instance for the whole app
67
+ │ │ ├── axiosBaseQuery.ts
68
+ │ │ ├── CacheConfig.ts
69
+ │ │ ├── hydrateCacheOnStart.ts
70
+ │ │ ├── persistenceMiddleware.ts
71
+ │ │ └── persistenceRegistry.ts
72
+ │ ├── config/
73
+ │ │ ├── constants.ts
74
+ │ │ └── index.ts
75
+ │ ├── device/
76
+ │ │ ├── smsComposer.ts
77
+ │ │ └── index.ts
78
+ │ ├── error/
79
+ │ │ ├── errorHandler.ts
80
+ │ │ └── index.ts
81
+ │ ├── logging/
82
+ │ │ ├── loggerService.ts
83
+ │ │ ├── auditLogger.ts
84
+ │ │ ├── correlationId.ts
85
+ │ │ └── index.ts
86
+ │ ├── permissions/
87
+ │ │ ├── permissionsService.ts
88
+ │ │ └── index.ts
89
+ │ ├── resilience/
90
+ │ │ ├── offlineModeService.ts
91
+ │ │ ├── resilienceService.ts
92
+ │ │ └── index.ts
93
+ │ ├── security/
94
+ │ │ ├── EncryptionService.ts
95
+ │ │ ├── DeviceSecurityCheck.ts
96
+ │ │ ├── entitlementService.ts
97
+ │ │ ├── SSLPinningAdapter.ts
98
+ │ │ └── index.ts
99
+ │ ├── storage/
100
+ │ │ ├── mmkvStorageService.ts
101
+ │ │ ├── SafeMMKV.ts
102
+ │ │ ├── keychainService.ts
103
+ │ │ ├── authTokenStorage.ts
104
+ │ │ ├── storageService.ts
105
+ │ │ └── index.ts
106
+ │ ├── store/
107
+ │ │ └── hooks.ts # useAppDispatch, useAppSelector
108
+ │ ├── streaming/
109
+ │ │ ├── websocket.ts
110
+ │ │ └── index.ts
111
+ │ └── analytics/
112
+ │ ├── eventTracker.ts
113
+ │ ├── pushNotificationService.ts
114
+ │ └── index.ts
115
+
116
+ ├── features/ # One folder per feature, fully self-contained
117
+ │ └── [feature-name]/
118
+ │ ├── domain/ # Pure TypeScript — ZERO framework imports
119
+ │ │ ├── entities/
120
+ │ │ ├── usecases/
121
+ │ │ ├── repositories/ # Interfaces only (I-prefixed)
122
+ │ │ └── index.ts
123
+ │ ├── data/
124
+ │ │ ├── api/ # Feature-specific Axios API client class
125
+ │ │ ├── dtos/ # Raw API response shapes
126
+ │ │ ├── mappers/ # mapTo pure functions
127
+ │ │ ├── repositories/ # Concrete implementations
128
+ │ │ ├── cache/ # Optional feature cache helpers
129
+ │ │ ├── config/ # Feature API base URLs, endpoint paths
130
+ │ │ ├── mock/ # Static mock responses (dev/test only)
131
+ │ │ └── index.ts
132
+ │ ├── presentation/
133
+ │ │ ├── screens/
134
+ │ │ ├── components/
135
+ │ │ ├── hooks/
136
+ │ │ ├── navigation/ # Typed route param lists + navigators
137
+ │ │ ├── state/ # Redux slices, thunks, selectors (or detected equivalent)
138
+ │ │ ├── viewmodels/
139
+ │ │ ├── styles/
140
+ │ │ ├── config/ # Use case singleton instances, constants
141
+ │ │ ├── utils/
142
+ │ │ ├── validation/
143
+ │ │ ├── providers/
144
+ │ │ └── index.ts
145
+ │ ├── di/
146
+ │ │ └── [Feature]Container.ts
147
+ │ ├── assets/
148
+ │ ├── __tests__/
149
+ │ └── index.ts # Public API — barrel exports everything public
150
+
151
+ ├── shared/
152
+ │ └── theme/ # Design tokens only — NO logic, NO components
153
+
154
+ ├── services/
155
+ │ └── [ExternalServiceHelper].ts
156
+
157
+ ├── constants/
158
+ │ ├── [eventNames].ts
159
+ │ └── [propertyKeys].ts
160
+
161
+ └── types/
162
+ ├── env.d.ts
163
+ └── thirdParty.d.ts
164
+ ```
165
+
166
+ ### Monorepo variant (Yarn Workspaces) — only when the target repo already uses one
167
+
168
+ ```
169
+ packages/
170
+ ├── common-domain/ # Pure TypeScript: BaseEntity, BaseUseCase, Result monad, error types
171
+ ├── common-data/ # HTTP infrastructure, storage adapters, base repository impl
172
+ └── common-presentation/ # Reusable UI: components, theme, hooks, icons
173
+ ```
174
+
175
+ ---
176
+
177
+ ## Dependency Rules (RN-specific detail on top of architecture-core.md)
178
+
179
+ ```
180
+ packages/common-domain ← no external deps
181
+ packages/common-data ← imports common-domain only
182
+ packages/common-presentation ← imports common-domain, common-data
183
+
184
+ core/ ← imports packages/* only; MUST NOT import features/*
185
+ features/[x]/domain/ ← imports common-domain ONLY; zero React/Redux/Axios
186
+ features/[x]/data/ ← imports core/, common-data, own domain/
187
+ features/[x]/presentation/ ← imports core/, packages/*, own domain/, own data/
188
+ features/[x]/di/ ← imports all layers of own feature + core/
189
+ app/ ← imports all features/* (orchestration only)
190
+ shared/ ← no imports from features/ or core/
191
+ ```
192
+
193
+ ## TypeScript Path Aliases
194
+
195
+ Read `tsconfig.json` for existing paths before inventing any. If none exist, propose (and confirm
196
+ with the user before writing):
197
+
198
+ ```json
199
+ {
200
+ "compilerOptions": {
201
+ "baseUrl": "./src",
202
+ "paths": {
203
+ "@/*": ["./*"],
204
+ "@core/*": ["./core/*"],
205
+ "@features/*": ["./features/*"],
206
+ "@app": ["./app/index"],
207
+ "@app/*": ["./app/*"],
208
+ "@shared/*": ["./shared/*"],
209
+ "@services/*": ["./services/*"]
210
+ }
211
+ }
212
+ }
213
+ ```
214
+
215
+ Mirror any alias exactly in `babel.config.js` via the `module-resolver` plugin.
216
+
217
+ ---
218
+
219
+ ## Naming Extensions (RN-specific, on top of architecture-core.md)
220
+
221
+ | Artifact | Convention | Example |
222
+ |----------|------------|---------|
223
+ | Feature folder | kebab-case | `portfolio-summary`, `user-profile` |
224
+ | Entity file | PascalCase | `HoldingEntity.ts` |
225
+ | Repository interface | `I` + PascalCase + `Repository` | `IHoldingRepository.ts` |
226
+ | Repository implementation | PascalCase + `RepositoryImpl` | `HoldingRepositoryImpl.ts` |
227
+ | Use case file | PascalCase + `UseCase` | `GetHoldingSummaryUseCase.ts` |
228
+ | API client class | PascalCase + `ApiClient` | `HoldingApiClient.ts` |
229
+ | DTO file | PascalCase + `DTO` | `HoldingSummaryDTO.ts` |
230
+ | Mapper function | `mapTo` prefix | `mapHoldingDTOToDomain` |
231
+ | Redux slice file | camelCase + `Slice` | `holdingSlice.ts` |
232
+ | Redux thunks file | camelCase + `Thunks` | `holdingThunks.ts` |
233
+ | Selectors file | camelCase + `Selectors` (optional) | `holdingSelectors.ts` |
234
+ | Screen file | PascalCase + `Screen` | `HoldingDetailScreen.tsx` |
235
+ | Hook file | `use` + PascalCase | `useHoldingSummary.ts` |
236
+ | ViewModel hook | `use` + PascalCase + `ViewModel` | `useHoldingViewModel.ts` |
237
+ | Navigator param list | PascalCase + `StackParamList` | `HoldingStackParamList` |
238
+ | Route names file | camelCase + `Routes` | `holdingRoutes.ts` |
239
+ | DI container (getter pattern) | camelCase + `Container` | `holdingContainer.ts` |
240
+ | DI container (factory pattern) | camelCase + `DI` | `holdingDI.ts` |
241
+ | Selector function | `select` + PascalCase | `selectHoldingTotal` |
242
+ | Mock file | `.mock.ts` suffix or `/mock/` folder | `holdingResponse.mock.ts` |
243
+ | Test file | `.test.ts` or `.spec.ts` | `HoldingRepositoryImpl.test.ts` |
244
+ | ThunkExtra interface | PascalCase + `ThunkExtra` | `HoldingThunkExtra` |
245
+ | Loading state | `'idle' \| 'loading' \| 'succeeded' \| 'failed'` string union | never a `boolean` |
246
+
247
+ ---
248
+
249
+ ## DI Pattern A — Lazy Getter Object (most features)
250
+
251
+ ```ts
252
+ // src/features/[feature]/di/[feature]Container.ts
253
+ import { [Feature]ApiClient } from '../data/api/[Feature]ApiClient';
254
+ import { [Feature]RepositoryImpl } from '../data/repositories/[Feature]RepositoryImpl';
255
+ import { Get[Item]UseCase } from '../domain/usecases/Get[Item]UseCase';
256
+
257
+ let _apiClient: [Feature]ApiClient | null = null;
258
+ let _repo: [Feature]RepositoryImpl | null = null;
259
+
260
+ function getApiClient(): [Feature]ApiClient {
261
+ if (!_apiClient) _apiClient = new [Feature]ApiClient();
262
+ return _apiClient;
263
+ }
264
+
265
+ function getRepository(): [Feature]RepositoryImpl {
266
+ if (!_repo) _repo = new [Feature]RepositoryImpl(getApiClient());
267
+ return _repo;
268
+ }
269
+
270
+ export const [feature]Container = {
271
+ get get[Item]UseCase() {
272
+ return new Get[Item]UseCase(getRepository());
273
+ },
274
+ };
275
+ ```
276
+
277
+ ## DI Pattern B — Factory Function (features with multiple ThunkExtra types)
278
+
279
+ ```ts
280
+ // src/features/[feature]/di/[feature]DI.ts
281
+ import { [Feature]DataSource } from '../data/datasources/[Feature]DataSource';
282
+ import { [Feature]RepositoryImpl } from '../data/repositories/[Feature]RepositoryImpl';
283
+ import { Get[Item]UseCase } from '../domain/useCases/[Feature]UseCases';
284
+ import type { [Feature]ThunkExtra } from '../presentation/state/[concern]Thunks';
285
+
286
+ export function create[Feature]ThunkExtra(): [Feature]ThunkExtra {
287
+ const dataSource = new [Feature]DataSource();
288
+ const repository = new [Feature]RepositoryImpl(dataSource);
289
+ const get[Item]UseCase = new Get[Item]UseCase(repository);
290
+ return { get[Item]UseCase };
291
+ }
292
+ ```
293
+
294
+ ## Auth — Special Case
295
+
296
+ Auth does not use either container pattern. Creates module-level singletons in
297
+ `presentation/config/useCaseInstances.ts` and re-exports from `app/di/container.ts`.
298
+
299
+ **Token getter pattern (prevents circular imports):**
300
+
301
+ ```ts
302
+ // src/core/api/tokenProvider.ts
303
+ let _getToken: (() => string | null) | null = null;
304
+ export const setTokenGetter = (fn: () => string | null) => { _getToken = fn; };
305
+ export const getToken = (): string | null => _getToken?.() ?? null;
306
+
307
+ // Auth feature registers during session restore:
308
+ setTokenGetter(() => authCache.getAccessToken());
309
+
310
+ // Axios interceptor reads it:
311
+ const token = getToken();
312
+ if (token) config.headers.Authorization = `Bearer ${token}`;
313
+ ```
314
+
315
+ ---
316
+
317
+ ## Redux Store Configuration
318
+
319
+ ```ts
320
+ // src/app/state/store.ts
321
+ import { configureStore } from '@reduxjs/toolkit';
322
+ import { setupListeners } from '@reduxjs/toolkit/query';
323
+ import { baseApiSlice } from '@core/cache/baseApiSlice';
324
+ import { createPersistenceMiddleware } from '@core/cache/persistenceMiddleware';
325
+ import persistenceRegistry from '@core/cache/persistenceRegistry';
326
+ import { [feature]Reducer } from '@features/[feature]/presentation/state';
327
+ import { [feature]Container } from '@features/[feature]/di/[Feature]Container';
328
+
329
+ export const store = configureStore({
330
+ reducer: {
331
+ [feature]: [feature]Reducer,
332
+ [baseApiSlice.reducerPath]: baseApiSlice.reducer,
333
+ },
334
+ middleware: (getDefault) =>
335
+ getDefault({
336
+ thunk: { extraArgument: { ...[feature]Container } },
337
+ serializableCheck: { ignoredActions: [], ignoredPaths: [] },
338
+ })
339
+ .concat(baseApiSlice.middleware)
340
+ .concat(createPersistenceMiddleware(persistenceRegistry)),
341
+ });
342
+
343
+ setupListeners(store.dispatch);
344
+
345
+ export type RootState = ReturnType<typeof store.getState>;
346
+ export type AppDispatch = typeof store.dispatch;
347
+ ```
348
+
349
+ ## Redux Slice Pattern
350
+
351
+ ```ts
352
+ // src/features/[feature]/presentation/state/[concern]Slice.ts
353
+ import { createSlice, PayloadAction } from '@reduxjs/toolkit';
354
+ import { fetch[Concern] } from './[concern]Thunks';
355
+ import type { [Concern]Entity } from '../../domain/entities';
356
+
357
+ export type LoadingState = 'idle' | 'loading' | 'succeeded' | 'failed';
358
+
359
+ interface [Concern]State {
360
+ data: [Concern]Entity | null;
361
+ loading: LoadingState;
362
+ error: string | null;
363
+ }
364
+
365
+ const initialState: [Concern]State = { data: null, loading: 'idle', error: null };
366
+
367
+ const [concern]Slice = createSlice({
368
+ name: '[feature]/[concern]',
369
+ initialState,
370
+ reducers: {
371
+ reset[Concern]: () => initialState,
372
+ set[Concern]: (state, action: PayloadAction<[Concern]Entity>) => {
373
+ state.data = action.payload;
374
+ },
375
+ },
376
+ extraReducers: (builder) => {
377
+ builder
378
+ .addCase(fetch[Concern].pending, (state) => { state.loading = 'loading'; state.error = null; })
379
+ .addCase(fetch[Concern].fulfilled, (state, action) => { state.loading = 'succeeded'; state.data = action.payload; })
380
+ .addCase(fetch[Concern].rejected, (state, action) => { state.loading = 'failed'; state.error = action.error.message ?? 'Unknown error'; });
381
+ },
382
+ });
383
+
384
+ export const { reset[Concern], set[Concern] } = [concern]Slice.actions;
385
+ export const [concern]Reducer = [concern]Slice.reducer;
386
+ ```
387
+
388
+ ## Redux Thunk Pattern
389
+
390
+ ```ts
391
+ // src/features/[feature]/presentation/state/[concern]Thunks.ts
392
+ import { createAsyncThunk } from '@reduxjs/toolkit';
393
+ import type { Get[Concern]UseCase } from '../../domain/usecases/Get[Concern]UseCase';
394
+
395
+ // ThunkExtra interface defined HERE — not in the DI container file
396
+ export interface [Feature]ThunkExtra {
397
+ get[Concern]UseCase: Get[Concern]UseCase;
398
+ }
399
+
400
+ export const fetch[Concern] = createAsyncThunk(
401
+ '[feature]/fetch[Concern]',
402
+ async (args: [RequestArgs], thunkAPI) => {
403
+ const { get[Concern]UseCase } = thunkAPI.extra as [Feature]ThunkExtra;
404
+ return get[Concern]UseCase.execute(args);
405
+ },
406
+ );
407
+ ```
408
+
409
+ ## Selector Pattern
410
+
411
+ ```ts
412
+ // [concern]Selectors.ts — raw state reads
413
+ import type { RootState } from '@app/state/store';
414
+
415
+ export const select[Concern]Data = (state: RootState) => state.[feature].[concern].data;
416
+ export const select[Concern]Loading = (state: RootState) => state.[feature].[concern].loading;
417
+ export const select[Concern]Error = (state: RootState) => state.[feature].[concern].error;
418
+
419
+ // [concern]ViewModelSelectors.ts — composed selectors for screens
420
+ import { createSelector } from '@reduxjs/toolkit';
421
+ export const select[Concern]ViewModel = createSelector(
422
+ [select[Concern]Data, select[Concern]Loading, select[Concern]Error],
423
+ (data, loading, error) => ({ data, loading, error }),
424
+ );
425
+ ```
426
+
427
+ ## RTK Query Endpoint Pattern
428
+
429
+ ```ts
430
+ // src/features/[feature]/data/api/[feature]ApiSlice.ts
431
+ import { baseApiSlice } from '@core/cache/baseApiSlice';
432
+ import type { [Item]DTO } from '../dtos/[Item]DTO';
433
+ import type { [Item]Entity } from '../../domain/entities';
434
+ import { map[Item]DTOToDomain } from '../mappers/[feature]Mappers';
435
+
436
+ export const [feature]ApiSlice = baseApiSlice.injectEndpoints({
437
+ endpoints: (build) => ({
438
+ get[Item]: build.query<[Item]Entity, [RequestArgs]>({
439
+ query: (args) => ({ url: '/[endpoint]', method: 'POST', data: args }),
440
+ transformResponse: (raw: [Item]DTO) => map[Item]DTOToDomain(raw),
441
+ keepUnusedDataFor: 300,
442
+ }),
443
+ }),
444
+ overrideExisting: false,
445
+ });
446
+
447
+ export const { useGet[Item]Query } = [feature]ApiSlice;
448
+ ```
449
+
450
+ ## Domain Layer Pattern
451
+
452
+ ```ts
453
+ // domain/repositories/I[Feature]Repository.ts
454
+ export interface I[Feature]Repository {
455
+ get[Item](args: [RequestArgs]): Promise<[Item]Entity>;
456
+ }
457
+
458
+ // domain/usecases/Get[Item]UseCase.ts
459
+ export class Get[Item]UseCase {
460
+ constructor(private readonly repository: I[Feature]Repository) {}
461
+ async execute(args: [RequestArgs]): Promise<[Item]Entity> {
462
+ return this.repository.get[Item](args);
463
+ }
464
+ }
465
+ ```
466
+
467
+ ## Data Layer Pattern
468
+
469
+ ```ts
470
+ // data/api/[Feature]ApiClient.ts
471
+ import { axiosClient } from '@core/api/axiosClient';
472
+
473
+ export class [Feature]ApiClient {
474
+ async get[Item](args: [RequestArgs]): Promise<[Item]DTO> {
475
+ const response = await axiosClient.post('/[endpoint]', args);
476
+ return response.data;
477
+ }
478
+ }
479
+
480
+ // data/repositories/[Feature]RepositoryImpl.ts
481
+ import type { I[Feature]Repository } from '../../domain/repositories/I[Feature]Repository';
482
+ import type { [Feature]ApiClient } from '../api/[Feature]ApiClient';
483
+ import { map[Item]DTOToDomain } from '../mappers/[feature]Mappers';
484
+
485
+ export class [Feature]RepositoryImpl implements I[Feature]Repository {
486
+ constructor(private readonly apiClient: [Feature]ApiClient) {}
487
+ async get[Item](args: [RequestArgs]): Promise<[Item]Entity> {
488
+ const dto = await this.apiClient.get[Item](args);
489
+ return map[Item]DTOToDomain(dto);
490
+ }
491
+ }
492
+ ```
493
+
494
+ ## Navigation Pattern
495
+
496
+ ```ts
497
+ // presentation/navigation/[feature]Routes.ts
498
+ import type { NativeStackScreenProps } from '@react-navigation/native-stack';
499
+
500
+ export type [Feature]StackParamList = {
501
+ [Feature]Main: undefined;
502
+ [Feature]Detail: { id: string; entrySource?: 'list' | 'search' };
503
+ };
504
+
505
+ export type [Feature]MainScreenProps = NativeStackScreenProps<[Feature]StackParamList, '[Feature]Main'>;
506
+ export type [Feature]DetailScreenProps = NativeStackScreenProps<[Feature]StackParamList, '[Feature]Detail'>;
507
+ ```
508
+
509
+ Tab bar visibility: call `getFocusedRouteNameFromRoute()` in `MainTabsNavigator` to hide the tab bar
510
+ when a detail screen is focused.
511
+
512
+ ## Typed Store Hooks
513
+
514
+ ```ts
515
+ // src/core/store/hooks.ts
516
+ import { useDispatch, useSelector } from 'react-redux';
517
+ import type { RootState, AppDispatch } from '@app/state/store';
518
+
519
+ export const useAppDispatch = () => useDispatch<AppDispatch>();
520
+ export const useAppSelector = <T>(selector: (state: RootState) => T): T => useSelector(selector);
521
+ ```
522
+
523
+ ---
524
+
525
+ ## Offline Resilience Rules
526
+
527
+ 1. RTK Query global: `refetchOnReconnect: true` + call `setupListeners(store.dispatch)` after store creation.
528
+ 2. Mutating operations when `NetInfo.isConnected === false` → enqueue in offline queue service.
529
+ 3. Offline queue persists to MMKV (survives app kills).
530
+ 4. `OfflineOverlayController` intercepts Android hardware back button to dismiss overlay, not navigate.
531
+ 5. On reconnect, queue flushes automatically — UI does not trigger it.
532
+
533
+ ## Security Rules (mobile-specific — on top of architecture-core.md)
534
+
535
+ 1. All tokens in MMKV with AES-256 encryption — never AsyncStorage.
536
+ 2. Every outbound request signed with nonce (UUID v4) and correlation ID header.
537
+ 3. Authorization header: `Bearer <token>`.
538
+ 4. Device security check (root/jailbreak) runs at app boot before any network calls.
539
+ 5. SSL pinning applied at the Axios adapter layer — never `rejectUnauthorized: false`.
540
+ 6. Encryption keys managed via native Keychain/Keystore — never in the JS bundle.
541
+
542
+ ---
543
+
544
+ ## Anti-Patterns (RN-specific, on top of architecture-core.md)
545
+
546
+ - **Never** use `useDispatch` / `useSelector` directly — always use `useAppDispatch` / `useAppSelector`.
547
+ - **Never** use a `boolean` for loading state in a Redux slice — use `'idle' | 'loading' | 'succeeded' | 'failed'`.
548
+ - **Never** define `ThunkExtra` inside the DI container file — define it in the thunks file alongside the thunks that use it.
549
+ - **Never** call `.get[Feature]HookDependencies()` from inside a thunk — cast `thunkAPI.extra` directly to the `ThunkExtra` type.
550
+ - **Never** use the class-based `getInstance()` singleton pattern for feature DI containers — use module-level lazy variables with getter objects (Pattern A) or factory functions (Pattern B).
551
+ - **Never** create use cases as module-level singletons in a feature container (except auth) — use ES6 getter properties that create a fresh instance per access.
552
+ - **Never** store secrets or tokens in `AsyncStorage` — use MMKV with AES-256 encryption or Keychain/Keystore.
553
+ - **Never** store encryption keys in the JS bundle — use native Keychain/Keystore.
554
+ - **Never** bypass SSL pinning in production code — even for testing.
555
+ - **Never** use `rejectUnauthorized: false` in Axios config.
556
+
557
+ ---
558
+
559
+ ## Worked Example
560
+
561
+ **Request**: "Add a watchlist feature with ability to fetch and display watchlist items."
562
+
563
+ **Artifacts**:
564
+ - Domain: `WatchlistItemEntity`, `IWatchlistRepository`, `GetWatchlistUseCase`
565
+ - Data: `WatchlistApiClient`, `WatchlistItemDTO`, `mapWatchlistDTOToDomain`, `WatchlistRepositoryImpl`
566
+ - Presentation: `watchlistSlice`, `watchlistThunks`, `watchlistSelectors`, `WatchlistScreen`
567
+ - DI: `watchlistContainer` (Pattern A)
568
+
569
+ **Output**:
570
+ ```
571
+ Created:
572
+ src/features/watchlist/domain/entities/WatchlistItemEntity.ts
573
+ src/features/watchlist/domain/repositories/IWatchlistRepository.ts
574
+ src/features/watchlist/domain/usecases/GetWatchlistUseCase.ts
575
+ src/features/watchlist/data/api/WatchlistApiClient.ts
576
+ src/features/watchlist/data/dtos/WatchlistItemDTO.ts
577
+ src/features/watchlist/data/mappers/watchlistMappers.ts
578
+ src/features/watchlist/data/repositories/WatchlistRepositoryImpl.ts
579
+ src/features/watchlist/presentation/state/watchlistSlice.ts
580
+ src/features/watchlist/presentation/state/watchlistThunks.ts
581
+ src/features/watchlist/presentation/state/watchlistSelectors.ts
582
+ src/features/watchlist/presentation/screens/WatchlistScreen.tsx
583
+ src/features/watchlist/di/watchlistContainer.ts
584
+ src/features/watchlist/index.ts
585
+
586
+ Updated:
587
+ src/app/state/store.ts (added reducer + container to extraArgument)
588
+
589
+ Dependency check: PASS — no layer boundary violations detected
590
+ ```