skillstore-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 (231) hide show
  1. package/README.md +95 -0
  2. package/data/bundles/devflow-complete.json +19 -0
  3. package/data/free-skills/devflow-agile/manifest.json +19 -0
  4. package/data/free-skills/devflow-agile/plugin/commands/agile/retro.md +23 -0
  5. package/data/free-skills/devflow-agile/plugin/commands/agile/review.md +21 -0
  6. package/data/free-skills/devflow-agile/plugin/commands/agile/sprint.md +30 -0
  7. package/data/free-skills/devflow-agile/plugin/commands/agile/standup.md +20 -0
  8. package/data/free-skills/devflow-agile/plugin/commands/agile.md +35 -0
  9. package/data/free-skills/devflow-agile/plugin/commands/devflow.md +42 -0
  10. package/data/free-skills/devflow-agile/plugin/skills/developer/SKILL.md +93 -0
  11. package/data/free-skills/devflow-agile/plugin/skills/developer/assets/sample-output.md +182 -0
  12. package/data/free-skills/devflow-agile/plugin/skills/developer/references/clean-architecture.md +361 -0
  13. package/data/free-skills/devflow-agile/plugin/skills/developer/references/clean-code-guide.md +207 -0
  14. package/data/free-skills/devflow-agile/plugin/skills/developer/references/debugging-methodology.md +191 -0
  15. package/data/free-skills/devflow-agile/template/agents/agile-coach.md +76 -0
  16. package/data/free-skills/devflow-agile/template/workflows/agile-sprint-workflow.md +81 -0
  17. package/data/free-skills/devflow-bootstrap/manifest.json +8 -0
  18. package/data/free-skills/devflow-bootstrap/plugin/commands/bootstrap/auto.md +31 -0
  19. package/data/free-skills/devflow-bootstrap/plugin/commands/bootstrap.md +38 -0
  20. package/data/free-skills/devflow-bootstrap/plugin/commands/devflow.md +20 -0
  21. package/data/free-skills/devflow-bootstrap/plugin/skills/project-scaffold/SKILL.md +56 -0
  22. package/data/free-skills/devflow-bootstrap/plugin/skills/project-scaffold/assets/sample-output.md +216 -0
  23. package/data/free-skills/devflow-bootstrap/plugin/skills/project-scaffold/references/architecture-decisions.md +254 -0
  24. package/data/free-skills/devflow-bootstrap/plugin/skills/project-scaffold/references/stack-templates.md +400 -0
  25. package/data/free-skills/devflow-bootstrap/template/agents/bootstrap-specialist.md +56 -0
  26. package/data/free-skills/devflow-bootstrap/template/workflows/bootstrap-workflow.md +70 -0
  27. package/data/free-skills/devflow-docs/manifest.json +8 -0
  28. package/data/free-skills/devflow-docs/plugin/commands/devflow.md +20 -0
  29. package/data/free-skills/devflow-docs/plugin/commands/docs/generate.md +17 -0
  30. package/data/free-skills/devflow-docs/plugin/commands/docs/parse.md +19 -0
  31. package/data/free-skills/devflow-docs/plugin/commands/docs.md +26 -0
  32. package/data/free-skills/devflow-docs/plugin/skills/pdf-processor/SKILL.md +59 -0
  33. package/data/free-skills/devflow-docs/plugin/skills/pdf-processor/assets/sample-output.md +114 -0
  34. package/data/free-skills/devflow-docs/plugin/skills/pdf-processor/references/extraction-techniques.md +115 -0
  35. package/data/free-skills/devflow-docs/plugin/skills/pdf-processor/references/ocr-strategies.md +167 -0
  36. package/data/free-skills/devflow-docs/template/agents/docs-specialist.md +35 -0
  37. package/data/free-skills/devflow-docs/template/workflows/docs-workflow.md +70 -0
  38. package/data/free-skills/devflow-postproject/manifest.json +13 -0
  39. package/data/free-skills/devflow-postproject/plugin/commands/devflow.md +34 -0
  40. package/data/free-skills/devflow-postproject/plugin/commands/postproject/handover.md +21 -0
  41. package/data/free-skills/devflow-postproject/plugin/commands/postproject/retro.md +21 -0
  42. package/data/free-skills/devflow-postproject/plugin/commands/postproject/support.md +21 -0
  43. package/data/free-skills/devflow-postproject/plugin/commands/postproject.md +32 -0
  44. package/data/free-skills/devflow-postproject/plugin/skills/retrospective/SKILL.md +70 -0
  45. package/data/free-skills/devflow-postproject/plugin/skills/retrospective/assets/sample-output.md +79 -0
  46. package/data/free-skills/devflow-postproject/plugin/skills/retrospective/references/facilitation-techniques.md +178 -0
  47. package/data/free-skills/devflow-postproject/plugin/skills/retrospective/references/lessons-learned-template.md +118 -0
  48. package/data/free-skills/devflow-postproject/plugin/skills/retrospective/references/retro-techniques.md +100 -0
  49. package/data/free-skills/devflow-postproject/template/agents/transition-manager.md +71 -0
  50. package/data/free-skills/devflow-postproject/template/workflows/transition-workflow.md +72 -0
  51. package/data/free-skills/devflow-presale/manifest.json +15 -0
  52. package/data/free-skills/devflow-presale/plugin/commands/devflow.md +47 -0
  53. package/data/free-skills/devflow-presale/plugin/commands/presale/analyze.md +30 -0
  54. package/data/free-skills/devflow-presale/plugin/commands/presale/estimate.md +30 -0
  55. package/data/free-skills/devflow-presale/plugin/commands/presale/price.md +30 -0
  56. package/data/free-skills/devflow-presale/plugin/commands/presale/propose.md +30 -0
  57. package/data/free-skills/devflow-presale/plugin/commands/presale.md +42 -0
  58. package/data/free-skills/devflow-presale/plugin/skills/requirement-analysis/SKILL.md +63 -0
  59. package/data/free-skills/devflow-presale/plugin/skills/requirement-analysis/assets/sample-output.md +129 -0
  60. package/data/free-skills/devflow-presale/plugin/skills/requirement-analysis/references/extraction-framework.md +140 -0
  61. package/data/free-skills/devflow-presale/plugin/skills/requirement-analysis/references/output-template.md +132 -0
  62. package/data/free-skills/devflow-presale/template/agents/presale-lead.md +83 -0
  63. package/data/free-skills/devflow-presale/template/agents/proposal-reviewer.md +63 -0
  64. package/data/free-skills/devflow-presale/template/workflows/presale-workflow.md +70 -0
  65. package/data/registry/categories.json +7 -0
  66. package/data/registry/packages.json +184 -0
  67. package/data/shared/framework/agents/brainstormer.md +74 -0
  68. package/data/shared/framework/agents/code-reviewer.md +87 -0
  69. package/data/shared/framework/agents/debugger.md +84 -0
  70. package/data/shared/framework/agents/docs-manager.md +55 -0
  71. package/data/shared/framework/agents/git-manager.md +59 -0
  72. package/data/shared/framework/agents/planner.md +68 -0
  73. package/data/shared/framework/agents/researcher.md +66 -0
  74. package/data/shared/framework/agents/tester.md +65 -0
  75. package/data/shared/framework/commands/cook/auto.md +27 -0
  76. package/data/shared/framework/commands/cook.md +45 -0
  77. package/data/shared/framework/commands/fix/ci.md +21 -0
  78. package/data/shared/framework/commands/fix/test.md +26 -0
  79. package/data/shared/framework/commands/fix/types.md +29 -0
  80. package/data/shared/framework/commands/fix.md +26 -0
  81. package/data/shared/framework/commands/git/cm.md +37 -0
  82. package/data/shared/framework/commands/git/pr.md +40 -0
  83. package/data/shared/framework/config/CLAUDE.md.template +26 -0
  84. package/data/shared/framework/config/settings.json +41 -0
  85. package/data/shared/framework/config/skillstore.config.json +29 -0
  86. package/data/shared/framework/hooks/discord-notify.sh +85 -0
  87. package/data/shared/framework/hooks/docs-sync.sh +53 -0
  88. package/data/shared/framework/hooks/modularization-hook.js +103 -0
  89. package/data/shared/framework/hooks/notification.js +94 -0
  90. package/data/shared/framework/hooks/quality-gate.js +109 -0
  91. package/data/shared/framework/hooks/scout-block.js +77 -0
  92. package/data/shared/framework/hooks/telegram-notify.sh +77 -0
  93. package/data/shared/framework/protocols/error-recovery.md +80 -0
  94. package/data/shared/framework/protocols/orchestration-protocol.md +112 -0
  95. package/data/shared/framework/quality/review-protocol.md +76 -0
  96. package/data/shared/framework/quality/verification-protocol.md +66 -0
  97. package/data/shared/framework/rules/development-rules.md +75 -0
  98. package/data/shared/framework/skills/backend-development/SKILL.md +77 -0
  99. package/data/shared/framework/skills/backend-development/assets/sample-output.md +175 -0
  100. package/data/shared/framework/skills/backend-development/references/advanced-patterns.md +180 -0
  101. package/data/shared/framework/skills/backend-development/references/api-design-guide.md +160 -0
  102. package/data/shared/framework/skills/backend-development/references/architecture-patterns.md +183 -0
  103. package/data/shared/framework/skills/backend-development/references/observability-resilience.md +155 -0
  104. package/data/shared/framework/skills/backend-development/references/troubleshooting.md +199 -0
  105. package/data/shared/framework/skills/codebase-analysis/SKILL.md +72 -0
  106. package/data/shared/framework/skills/codebase-analysis/assets/sample-output.md +263 -0
  107. package/data/shared/framework/skills/codebase-analysis/references/analysis-techniques.md +241 -0
  108. package/data/shared/framework/skills/codebase-analysis/references/dependency-mapping.md +280 -0
  109. package/data/shared/framework/skills/codebase-analysis/references/tech-debt-assessment.md +208 -0
  110. package/data/shared/framework/skills/databases/SKILL.md +72 -0
  111. package/data/shared/framework/skills/databases/assets/sample-output.md +212 -0
  112. package/data/shared/framework/skills/databases/references/advanced-data-patterns.md +259 -0
  113. package/data/shared/framework/skills/databases/references/query-optimization.md +214 -0
  114. package/data/shared/framework/skills/databases/references/schema-design.md +159 -0
  115. package/data/shared/framework/skills/databases/references/troubleshooting.md +214 -0
  116. package/data/shared/framework/skills/debugging-investigation/SKILL.md +84 -0
  117. package/data/shared/framework/skills/debugging-investigation/assets/sample-output.md +314 -0
  118. package/data/shared/framework/skills/debugging-investigation/references/systematic-debugging.md +197 -0
  119. package/data/shared/framework/skills/debugging-investigation/references/tool-specific-guides.md +202 -0
  120. package/data/shared/framework/skills/debugging-investigation/references/troubleshooting-patterns.md +196 -0
  121. package/data/shared/framework/skills/frontend-development/SKILL.md +67 -0
  122. package/data/shared/framework/skills/frontend-development/assets/sample-output.md +110 -0
  123. package/data/shared/framework/skills/frontend-development/references/component-patterns.md +112 -0
  124. package/data/shared/framework/skills/frontend-development/references/performance-guide.md +169 -0
  125. package/data/shared/framework/skills/frontend-development/references/routing-forms-realtime.md +374 -0
  126. package/data/shared/framework/skills/frontend-development/references/ssr-rsc-patterns.md +284 -0
  127. package/data/shared/framework/skills/frontend-development/references/troubleshooting.md +154 -0
  128. package/data/shared/framework/skills/mobile-development/SKILL.md +67 -0
  129. package/data/shared/framework/skills/mobile-development/assets/sample-output.md +382 -0
  130. package/data/shared/framework/skills/mobile-development/references/mobile-patterns.md +681 -0
  131. package/data/shared/framework/skills/mobile-development/references/mobile-performance.md +524 -0
  132. package/data/shared/framework/skills/mobile-development/references/troubleshooting.md +158 -0
  133. package/data/shared/framework/skills/security-audit/SKILL.md +83 -0
  134. package/data/shared/framework/skills/security-audit/assets/sample-output.md +451 -0
  135. package/data/shared/framework/skills/security-audit/references/owasp-checklist.md +580 -0
  136. package/data/shared/framework/skills/security-audit/references/secure-coding-patterns.md +433 -0
  137. package/data/shared/framework/skills/security-audit/references/vulnerability-remediation.md +331 -0
  138. package/data/shared/framework/skills/ui-generation/SKILL.md +70 -0
  139. package/data/shared/framework/skills/ui-generation/assets/sample-output.md +139 -0
  140. package/data/shared/framework/skills/ui-generation/references/accessibility-responsive.md +127 -0
  141. package/data/shared/framework/skills/ui-generation/references/compound-components.md +252 -0
  142. package/data/shared/framework/skills/ui-generation/references/generation-patterns.md +110 -0
  143. package/data/shared/framework/skills/ui-generation/references/storybook-design-system.md +278 -0
  144. package/data/shared/framework/skills/ui-generation/references/troubleshooting.md +198 -0
  145. package/data/shared/framework/workflows/documentation-management.md +58 -0
  146. package/data/shared/framework/workflows/primary-workflow.md +88 -0
  147. package/dist/commands/activate.d.ts +3 -0
  148. package/dist/commands/activate.d.ts.map +1 -0
  149. package/dist/commands/activate.js +34 -0
  150. package/dist/commands/activate.js.map +1 -0
  151. package/dist/commands/bundle.d.ts +3 -0
  152. package/dist/commands/bundle.d.ts.map +1 -0
  153. package/dist/commands/bundle.js +64 -0
  154. package/dist/commands/bundle.js.map +1 -0
  155. package/dist/commands/install.d.ts +3 -0
  156. package/dist/commands/install.d.ts.map +1 -0
  157. package/dist/commands/install.js +99 -0
  158. package/dist/commands/install.js.map +1 -0
  159. package/dist/commands/list.d.ts +3 -0
  160. package/dist/commands/list.d.ts.map +1 -0
  161. package/dist/commands/list.js +37 -0
  162. package/dist/commands/list.js.map +1 -0
  163. package/dist/commands/search.d.ts +3 -0
  164. package/dist/commands/search.d.ts.map +1 -0
  165. package/dist/commands/search.js +30 -0
  166. package/dist/commands/search.js.map +1 -0
  167. package/dist/commands/status.d.ts +3 -0
  168. package/dist/commands/status.d.ts.map +1 -0
  169. package/dist/commands/status.js +35 -0
  170. package/dist/commands/status.js.map +1 -0
  171. package/dist/commands/update.d.ts +3 -0
  172. package/dist/commands/update.d.ts.map +1 -0
  173. package/dist/commands/update.js +68 -0
  174. package/dist/commands/update.js.map +1 -0
  175. package/dist/download/cache.d.ts +3 -0
  176. package/dist/download/cache.d.ts.map +1 -0
  177. package/dist/download/cache.js +18 -0
  178. package/dist/download/cache.js.map +1 -0
  179. package/dist/download/client.d.ts +2 -0
  180. package/dist/download/client.d.ts.map +1 -0
  181. package/dist/download/client.js +58 -0
  182. package/dist/download/client.js.map +1 -0
  183. package/dist/index.d.ts +3 -0
  184. package/dist/index.d.ts.map +1 -0
  185. package/dist/index.js +23 -0
  186. package/dist/index.js.map +1 -0
  187. package/dist/installer/file-copier.d.ts +6 -0
  188. package/dist/installer/file-copier.d.ts.map +1 -0
  189. package/dist/installer/file-copier.js +32 -0
  190. package/dist/installer/file-copier.js.map +1 -0
  191. package/dist/installer/plugin-installer.d.ts +12 -0
  192. package/dist/installer/plugin-installer.d.ts.map +1 -0
  193. package/dist/installer/plugin-installer.js +33 -0
  194. package/dist/installer/plugin-installer.js.map +1 -0
  195. package/dist/installer/template-installer.d.ts +12 -0
  196. package/dist/installer/template-installer.d.ts.map +1 -0
  197. package/dist/installer/template-installer.js +45 -0
  198. package/dist/installer/template-installer.js.map +1 -0
  199. package/dist/license/crypto.d.ts +16 -0
  200. package/dist/license/crypto.d.ts.map +1 -0
  201. package/dist/license/crypto.js +50 -0
  202. package/dist/license/crypto.js.map +1 -0
  203. package/dist/license/license-store.d.ts +19 -0
  204. package/dist/license/license-store.d.ts.map +1 -0
  205. package/dist/license/license-store.js +99 -0
  206. package/dist/license/license-store.js.map +1 -0
  207. package/dist/license/validator.d.ts +32 -0
  208. package/dist/license/validator.d.ts.map +1 -0
  209. package/dist/license/validator.js +81 -0
  210. package/dist/license/validator.js.map +1 -0
  211. package/dist/registry/loader.d.ts +30 -0
  212. package/dist/registry/loader.d.ts.map +1 -0
  213. package/dist/registry/loader.js +22 -0
  214. package/dist/registry/loader.js.map +1 -0
  215. package/dist/registry/search-engine.d.ts +9 -0
  216. package/dist/registry/search-engine.d.ts.map +1 -0
  217. package/dist/registry/search-engine.js +30 -0
  218. package/dist/registry/search-engine.js.map +1 -0
  219. package/dist/utils/config.d.ts +14 -0
  220. package/dist/utils/config.d.ts.map +1 -0
  221. package/dist/utils/config.js +28 -0
  222. package/dist/utils/config.js.map +1 -0
  223. package/dist/utils/logger.d.ts +9 -0
  224. package/dist/utils/logger.d.ts.map +1 -0
  225. package/dist/utils/logger.js +22 -0
  226. package/dist/utils/logger.js.map +1 -0
  227. package/dist/utils/paths.d.ts +20 -0
  228. package/dist/utils/paths.d.ts.map +1 -0
  229. package/dist/utils/paths.js +79 -0
  230. package/dist/utils/paths.js.map +1 -0
  231. package/package.json +54 -0
@@ -0,0 +1,681 @@
1
+ # Mobile Development Patterns
2
+
3
+ ## React Native Patterns
4
+
5
+ ### Functional Components with Hooks
6
+ All components should be functional. Use hooks for lifecycle and side effects.
7
+
8
+ ```typescript
9
+ // Screen component with data fetching
10
+ function OrderListScreen() {
11
+ const navigation = useNavigation<OrderStackNav>();
12
+ const { data, isLoading, refetch } = useOrders();
13
+ const insets = useSafeAreaInsets();
14
+
15
+ if (isLoading) return <OrderListSkeleton />;
16
+
17
+ return (
18
+ <View style={{ paddingTop: insets.top }}>
19
+ <FlatList
20
+ data={data}
21
+ renderItem={({ item }) => (
22
+ <OrderCard
23
+ order={item}
24
+ onPress={() => navigation.navigate('OrderDetail', { id: item.id })}
25
+ />
26
+ )}
27
+ keyExtractor={(item) => item.id}
28
+ onRefresh={refetch}
29
+ refreshing={isLoading}
30
+ />
31
+ </View>
32
+ );
33
+ }
34
+ ```
35
+
36
+ ### Custom Hooks for Business Logic
37
+ Separate data logic from UI. Every hook has a single responsibility.
38
+
39
+ ```typescript
40
+ // useOrders.ts — encapsulates order fetching, caching, and mutation
41
+ export function useOrders(filters?: OrderFilters) {
42
+ return useQuery({
43
+ queryKey: ['orders', filters],
44
+ queryFn: () => orderApi.list(filters),
45
+ staleTime: 30_000,
46
+ });
47
+ }
48
+
49
+ export function useCreateOrder() {
50
+ const queryClient = useQueryClient();
51
+ return useMutation({
52
+ mutationFn: orderApi.create,
53
+ onSuccess: () => queryClient.invalidateQueries({ queryKey: ['orders'] }),
54
+ });
55
+ }
56
+ ```
57
+
58
+ ### Navigation (React Navigation)
59
+
60
+ ```typescript
61
+ // Type-safe navigation setup
62
+ type RootStackParamList = {
63
+ Home: undefined;
64
+ OrderDetail: { id: string };
65
+ Checkout: { cartId: string };
66
+ };
67
+
68
+ const Stack = createNativeStackNavigator<RootStackParamList>();
69
+
70
+ function AppNavigator() {
71
+ const { isAuthenticated } = useAuth();
72
+
73
+ return (
74
+ <Stack.Navigator>
75
+ {isAuthenticated ? (
76
+ <>
77
+ <Stack.Screen name="Home" component={HomeScreen} />
78
+ <Stack.Screen name="OrderDetail" component={OrderDetailScreen} />
79
+ <Stack.Screen
80
+ name="Checkout"
81
+ component={CheckoutScreen}
82
+ options={{ presentation: 'modal' }}
83
+ />
84
+ </>
85
+ ) : (
86
+ <Stack.Screen name="Login" component={LoginScreen} />
87
+ )}
88
+ </Stack.Navigator>
89
+ );
90
+ }
91
+ ```
92
+
93
+ ### State Management (Zustand)
94
+
95
+ ```typescript
96
+ // Lightweight global store — no boilerplate
97
+ interface CartStore {
98
+ items: CartItem[];
99
+ addItem: (item: CartItem) => void;
100
+ removeItem: (id: string) => void;
101
+ total: () => number;
102
+ clear: () => void;
103
+ }
104
+
105
+ export const useCartStore = create<CartStore>((set, get) => ({
106
+ items: [],
107
+ addItem: (item) => set((s) => ({ items: [...s.items, item] })),
108
+ removeItem: (id) => set((s) => ({ items: s.items.filter((i) => i.id !== id) })),
109
+ total: () => get().items.reduce((sum, i) => sum + i.price * i.quantity, 0),
110
+ clear: () => set({ items: [] }),
111
+ }));
112
+ ```
113
+
114
+ ### Native Modules
115
+ When you need platform APIs not exposed by React Native:
116
+
117
+ ```typescript
118
+ // Turbo Module (New Architecture)
119
+ import { TurboModuleRegistry } from 'react-native';
120
+
121
+ interface HapticSpec extends TurboModule {
122
+ impact(style: 'light' | 'medium' | 'heavy'): void;
123
+ notification(type: 'success' | 'warning' | 'error'): void;
124
+ }
125
+
126
+ export const HapticModule = TurboModuleRegistry.getEnforcing<HapticSpec>('Haptic');
127
+ ```
128
+
129
+ **Rule**: Prefer community libraries (`react-native-haptic-feedback`) over writing native modules. Only write custom modules for proprietary SDK integrations.
130
+
131
+ ## Flutter Patterns
132
+
133
+ ### Widget Composition
134
+ Build complex UIs by composing small, focused widgets.
135
+
136
+ ```dart
137
+ // Screen widget — orchestrates layout
138
+ class OrderListScreen extends StatelessWidget {
139
+ @override
140
+ Widget build(BuildContext context) {
141
+ return Scaffold(
142
+ appBar: AppBar(title: const Text('Orders')),
143
+ body: const OrderListBody(),
144
+ floatingActionButton: const NewOrderFab(),
145
+ );
146
+ }
147
+ }
148
+
149
+ // Extracted widget — testable, reusable
150
+ class OrderCard extends StatelessWidget {
151
+ final Order order;
152
+ final VoidCallback onTap;
153
+
154
+ const OrderCard({required this.order, required this.onTap});
155
+
156
+ @override
157
+ Widget build(BuildContext context) {
158
+ return Card(
159
+ child: ListTile(
160
+ title: Text(order.title),
161
+ subtitle: Text(order.status.label),
162
+ trailing: Text('\$${order.total.toStringAsFixed(2)}'),
163
+ onTap: onTap,
164
+ ),
165
+ );
166
+ }
167
+ }
168
+ ```
169
+
170
+ ### State Management (Riverpod)
171
+
172
+ ```dart
173
+ // Provider for order list
174
+ final ordersProvider = FutureProvider.autoDispose<List<Order>>((ref) {
175
+ return ref.read(orderRepositoryProvider).fetchOrders();
176
+ });
177
+
178
+ // In widget
179
+ class OrderListBody extends ConsumerWidget {
180
+ @override
181
+ Widget build(BuildContext context, WidgetRef ref) {
182
+ final ordersAsync = ref.watch(ordersProvider);
183
+
184
+ return ordersAsync.when(
185
+ data: (orders) => ListView.builder(
186
+ itemCount: orders.length,
187
+ itemBuilder: (_, i) => OrderCard(
188
+ order: orders[i],
189
+ onTap: () => context.push('/orders/${orders[i].id}'),
190
+ ),
191
+ ),
192
+ loading: () => const OrderListSkeleton(),
193
+ error: (e, _) => ErrorRetry(onRetry: () => ref.invalidate(ordersProvider)),
194
+ );
195
+ }
196
+ }
197
+ ```
198
+
199
+ ### BLoC Pattern (for complex event-driven flows)
200
+
201
+ ```dart
202
+ // Events
203
+ sealed class CartEvent {}
204
+ class AddToCart extends CartEvent { final Product product; AddToCart(this.product); }
205
+ class RemoveFromCart extends CartEvent { final String productId; RemoveFromCart(this.productId); }
206
+
207
+ // State
208
+ class CartState {
209
+ final List<CartItem> items;
210
+ double get total => items.fold(0, (sum, i) => sum + i.price * i.quantity);
211
+ const CartState({this.items = const []});
212
+ }
213
+
214
+ // BLoC
215
+ class CartBloc extends Bloc<CartEvent, CartState> {
216
+ CartBloc() : super(const CartState()) {
217
+ on<AddToCart>((event, emit) {
218
+ emit(CartState(items: [...state.items, CartItem.fromProduct(event.product)]));
219
+ });
220
+ on<RemoveFromCart>((event, emit) {
221
+ emit(CartState(items: state.items.where((i) => i.productId != event.productId).toList()));
222
+ });
223
+ }
224
+ }
225
+ ```
226
+
227
+ ### Navigation (GoRouter)
228
+
229
+ ```dart
230
+ final router = GoRouter(
231
+ initialLocation: '/',
232
+ redirect: (context, state) {
233
+ final isAuth = ref.read(authProvider).isAuthenticated;
234
+ if (!isAuth && !state.matchedLocation.startsWith('/login')) return '/login';
235
+ return null;
236
+ },
237
+ routes: [
238
+ GoRoute(path: '/', builder: (_, __) => const HomeScreen()),
239
+ GoRoute(
240
+ path: '/orders/:id',
241
+ builder: (_, state) => OrderDetailScreen(id: state.pathParameters['id']!),
242
+ ),
243
+ ShellRoute(
244
+ builder: (_, __, child) => MainShell(child: child),
245
+ routes: [
246
+ GoRoute(path: '/home', builder: (_, __) => const HomeTab()),
247
+ GoRoute(path: '/search', builder: (_, __) => const SearchTab()),
248
+ GoRoute(path: '/profile', builder: (_, __) => const ProfileTab()),
249
+ ],
250
+ ),
251
+ ],
252
+ );
253
+ ```
254
+
255
+ ### Platform Channels (for native interop)
256
+
257
+ ```dart
258
+ // Dart side
259
+ class NativePayment {
260
+ static const _channel = MethodChannel('com.app/payment');
261
+
262
+ static Future<PaymentResult> processPayment(PaymentRequest req) async {
263
+ final result = await _channel.invokeMethod('processPayment', req.toJson());
264
+ return PaymentResult.fromJson(result);
265
+ }
266
+ }
267
+ ```
268
+
269
+ ## Expo vs Bare Workflow
270
+
271
+ ### Decision Matrix
272
+
273
+ | Factor | Expo Managed | Bare Workflow |
274
+ |--------|-------------|---------------|
275
+ | **Setup time** | Minutes | Hours (Xcode + Android Studio) |
276
+ | **OTA updates** | EAS Update built-in | Manual CodePush setup |
277
+ | **Native modules** | Expo Modules API | Direct Turbo Modules |
278
+ | **CI/CD** | EAS Build (cloud) | Self-hosted or Fastlane |
279
+ | **Custom native code** | Via config plugins or dev client | Full native access |
280
+ | **App size** | Larger (includes Expo runtime) | Smaller (only what you use) |
281
+ | **Upgrade path** | `npx expo install` | Manual RN upgrade (can be painful) |
282
+
283
+ **Start with Expo Managed** unless you need:
284
+ - A specific native SDK with no Expo wrapper (rare — check expo packages first)
285
+ - Custom build configurations not supported by config plugins
286
+ - App size under 15MB (games, utilities)
287
+
288
+ ### Expo Router (File-Based Routing)
289
+
290
+ ```
291
+ app/
292
+ ├── _layout.tsx ← Root layout (providers, fonts)
293
+ ├── (tabs)/
294
+ │ ├── _layout.tsx ← Tab navigator
295
+ │ ├── index.tsx ← Home tab
296
+ │ ├── search.tsx ← Search tab
297
+ │ └── profile.tsx ← Profile tab
298
+ ├── restaurant/
299
+ │ └── [id].tsx ← Dynamic route /restaurant/123
300
+ ├── checkout/
301
+ │ ├── _layout.tsx ← Checkout stack
302
+ │ ├── cart.tsx
303
+ │ └── payment.tsx
304
+ └── +not-found.tsx ← 404 screen
305
+ ```
306
+
307
+ ```typescript
308
+ // app/restaurant/[id].tsx
309
+ import { useLocalSearchParams } from 'expo-router';
310
+
311
+ export default function RestaurantScreen() {
312
+ const { id } = useLocalSearchParams<{ id: string }>();
313
+ // fetch restaurant by id...
314
+ }
315
+ ```
316
+
317
+ ### EAS Build + EAS Update
318
+
319
+ ```bash
320
+ # Build for internal testing
321
+ eas build --platform all --profile preview
322
+
323
+ # OTA update (no app store review needed)
324
+ eas update --branch production --message "Fix cart total calculation"
325
+
326
+ # Build for store submission
327
+ eas build --platform all --profile production
328
+ eas submit --platform all
329
+ ```
330
+
331
+ **OTA Update Rules**:
332
+ - JS-only changes: OTA safe (bug fixes, UI tweaks, copy changes)
333
+ - Native dependency changes: requires new build (new SDK, permission changes)
334
+ - Always test OTA updates on preview branch before production
335
+
336
+ ### Crash Reporting Setup
337
+
338
+ ```typescript
339
+ // Sentry integration (works with Expo)
340
+ import * as Sentry from '@sentry/react-native';
341
+
342
+ Sentry.init({
343
+ dsn: process.env.EXPO_PUBLIC_SENTRY_DSN,
344
+ tracesSampleRate: 0.2, // 20% of transactions
345
+ profilesSampleRate: 0.1,
346
+ enableAutoSessionTracking: true,
347
+ attachStacktrace: true,
348
+ });
349
+
350
+ // Wrap root component
351
+ export default Sentry.wrap(App);
352
+
353
+ // Manual breadcrumbs for important actions
354
+ Sentry.addBreadcrumb({
355
+ category: 'order',
356
+ message: `Order placed: ${orderId}`,
357
+ level: 'info',
358
+ });
359
+ ```
360
+
361
+ **Source Maps**: EAS Build automatically uploads source maps to Sentry when configured:
362
+ ```json
363
+ // app.json
364
+ {
365
+ "expo": {
366
+ "plugins": ["@sentry/react-native/expo"]
367
+ }
368
+ }
369
+ ```
370
+
371
+ ### Native Module Decision Tree
372
+
373
+ ```
374
+ Need native functionality?
375
+
376
+ ├─ Check expo packages first (expo-camera, expo-location, etc.)
377
+ │ → Found? Use it. Done.
378
+
379
+ ├─ Check community libraries (react-native-*)
380
+ │ → Found + maintained? Use it. Done.
381
+
382
+ ├─ Expo Modules API (write once, both platforms)
383
+ │ → Preferred for new modules. Swift + Kotlin.
384
+
385
+ └─ Turbo Modules (React Native core)
386
+ → For performance-critical or complex native code.
387
+ → Requires C++ for shared implementation.
388
+ ```
389
+
390
+ ## Cross-Platform Considerations
391
+
392
+ ### Shared Logic vs Platform-Specific UI
393
+
394
+ ```
395
+ Shared (80%+): Platform-specific (20%):
396
+ ├── Business logic ├── Navigation transitions
397
+ ├── API clients ├── Date/time pickers
398
+ ├── State management ├── Action sheets vs bottom sheets
399
+ ├── Data models ├── Pull-to-refresh behavior
400
+ ├── Validation rules ├── Haptic feedback patterns
401
+ └── Utility functions └── System settings integration
402
+ ```
403
+
404
+ ### Decision Matrix
405
+
406
+ | Concern | React Native Approach | Flutter Approach |
407
+ |---------|----------------------|------------------|
408
+ | Navigation | React Navigation | GoRouter |
409
+ | State (simple) | Zustand / Jotai | Riverpod |
410
+ | State (complex) | Redux Toolkit | BLoC |
411
+ | Server state | TanStack Query | Riverpod + Repository |
412
+ | Local DB | WatermelonDB / MMKV | Drift / Hive |
413
+ | Styling | StyleSheet + Nativewind | Theme + custom widgets |
414
+ | Native access | Turbo Modules | Platform channels |
415
+ | Testing | Jest + Detox | flutter_test + integration_test |
416
+
417
+ ## Navigation Patterns
418
+
419
+ ### Stack Navigation
420
+ Primary screens push onto a stack. Use for drill-down flows.
421
+ ```
422
+ Home → Product List → Product Detail → Add to Cart
423
+ ```
424
+
425
+ ### Tab Navigation
426
+ Top-level sections. 3-5 tabs maximum. Each tab maintains its own stack.
427
+ ```
428
+ ┌─────────┬──────────┬─────────┬──────────┐
429
+ │ Home │ Search │ Orders │ Profile │
430
+ └─────────┴──────────┴─────────┴──────────┘
431
+ ```
432
+
433
+ ### Drawer Navigation
434
+ Side menu for apps with many sections. Less common in modern apps — prefer tabs.
435
+
436
+ ### Deep Linking
437
+ Essential for push notification taps, email links, and sharing.
438
+
439
+ ```typescript
440
+ // React Native — linking config
441
+ const linking = {
442
+ prefixes: ['myapp://', 'https://myapp.com'],
443
+ config: {
444
+ screens: {
445
+ Home: '',
446
+ OrderDetail: 'orders/:id',
447
+ Checkout: 'checkout/:cartId',
448
+ },
449
+ },
450
+ };
451
+ ```
452
+
453
+ **Test deep links**: `npx uri-scheme open myapp://orders/123 --ios` or `adb shell am start -d "myapp://orders/123"`.
454
+
455
+ ## State Management Comparison
456
+
457
+ Pick the simplest option that satisfies your needs:
458
+
459
+ | Complexity | RN Solution | Flutter Solution | When |
460
+ |-----------|-------------|------------------|------|
461
+ | Single component | `useState` | `StatefulWidget` / `ValueNotifier` | Toggle, input, animation |
462
+ | Parent-child | Props + callbacks | Constructor params + callbacks | Shared between 2-3 widgets |
463
+ | Feature scope | Context + `useReducer` | `Riverpod` scoped provider | Auth, theme, feature settings |
464
+ | Global | Zustand / Redux Toolkit | BLoC / Riverpod global | Cart, notifications, complex flows |
465
+ | Server data | TanStack Query | Riverpod `FutureProvider` | API data with cache + revalidation |
466
+
467
+ **Rule**: If data comes from an API, use a server-state library first. Only copy to global state if multiple features need to mutate it independently.
468
+
469
+ ## Offline-First Patterns
470
+
471
+ ### Architecture
472
+
473
+ ```
474
+ ┌─────────────────────────────────────────┐
475
+ │ UI Layer │
476
+ ├─────────────────────────────────────────┤
477
+ │ Repository Layer │
478
+ │ ┌──────────┐ ┌──────────────────────┐ │
479
+ │ │ Local DB │←→│ Sync Engine │ │
480
+ │ │ (source │ │ ┌──────────────────┐ │ │
481
+ │ │ of truth)│ │ │ Pending Queue │ │ │
482
+ │ └──────────┘ │ │ Conflict Resolver│ │ │
483
+ │ │ │ Retry Manager │ │ │
484
+ │ │ └──────────────────┘ │ │
485
+ │ └───────────┬──────────┘ │
486
+ ├────────────────────────────┼────────────┤
487
+ │ Remote API │
488
+ └─────────────────────────────────────────┘
489
+ ```
490
+
491
+ ### Sync Queue
492
+ Queue mutations when offline. Process when connection returns.
493
+
494
+ ```typescript
495
+ interface PendingAction {
496
+ id: string;
497
+ type: 'CREATE' | 'UPDATE' | 'DELETE';
498
+ entity: string;
499
+ payload: any;
500
+ createdAt: number;
501
+ retryCount: number;
502
+ }
503
+
504
+ // On reconnect: process queue in order, handle conflicts
505
+ async function processSyncQueue(queue: PendingAction[]) {
506
+ for (const action of queue.sort((a, b) => a.createdAt - b.createdAt)) {
507
+ try {
508
+ await syncAction(action);
509
+ await removeFromQueue(action.id);
510
+ } catch (error) {
511
+ if (isConflict(error)) {
512
+ await resolveConflict(action, error);
513
+ } else if (action.retryCount < MAX_RETRIES) {
514
+ await incrementRetry(action.id);
515
+ } else {
516
+ await moveToDeadLetter(action);
517
+ }
518
+ }
519
+ }
520
+ }
521
+ ```
522
+
523
+ ### Conflict Resolution Strategies
524
+
525
+ | Strategy | Description | Best For |
526
+ |----------|-------------|----------|
527
+ | Last write wins | Timestamp-based, latest change wins | Simple fields (name, status) |
528
+ | Server wins | Server version always takes precedence | Financial data, inventory |
529
+ | Client wins | Client version takes precedence | Draft content, user preferences |
530
+ | Manual merge | Show both versions, let user choose | Collaborative editing |
531
+
532
+ ## Push Notifications
533
+
534
+ ### Setup Checklist
535
+
536
+ 1. **FCM/APNs configuration**: Register app with Firebase/Apple Developer portal
537
+ 2. **Token management**: Store device token on backend, refresh on app launch
538
+ 3. **Permission request**: Ask at a contextual moment, not on first launch
539
+ 4. **Payload handling**: Handle notification when app is in foreground, background, and terminated
540
+ 5. **Channel management** (Android): Create channels for different notification types
541
+
542
+ ### Token Lifecycle
543
+
544
+ ```typescript
545
+ // On app launch — always refresh token
546
+ async function initPushNotifications() {
547
+ const permission = await requestPermission();
548
+ if (permission !== 'granted') return;
549
+
550
+ const token = await getDeviceToken();
551
+ await api.registerDevice({ token, platform: Platform.OS });
552
+
553
+ // Listen for token refresh
554
+ onTokenRefresh((newToken) => {
555
+ api.registerDevice({ token: newToken, platform: Platform.OS });
556
+ });
557
+ }
558
+ ```
559
+
560
+ ### Notification Handling
561
+
562
+ ```typescript
563
+ // Foreground — show in-app banner (not system notification)
564
+ onForegroundMessage((message) => {
565
+ showInAppNotification({
566
+ title: message.title,
567
+ body: message.body,
568
+ onPress: () => navigateToScreen(message.data),
569
+ });
570
+ });
571
+
572
+ // Background/terminated — user tapped notification
573
+ onNotificationOpened((message) => {
574
+ navigateToScreen(message.data);
575
+ });
576
+
577
+ // Data-only notifications — silent processing
578
+ onBackgroundMessage(async (message) => {
579
+ await syncDataInBackground(message.data);
580
+ });
581
+ ```
582
+
583
+ ## Permissions Handling
584
+
585
+ ### Request Pattern
586
+
587
+ Never request permissions at app launch. Request at the moment of need with context.
588
+
589
+ ```typescript
590
+ async function requestCameraPermission(): Promise<boolean> {
591
+ const status = await check(PERMISSIONS.IOS.CAMERA);
592
+
593
+ switch (status) {
594
+ case 'granted':
595
+ return true;
596
+ case 'denied':
597
+ // First time — show system dialog
598
+ const result = await request(PERMISSIONS.IOS.CAMERA);
599
+ return result === 'granted';
600
+ case 'blocked':
601
+ // Previously denied — show explanation and link to settings
602
+ showPermissionDialog({
603
+ title: 'Camera Access Needed',
604
+ message: 'To scan barcodes, allow camera access in Settings.',
605
+ onOpenSettings: () => openSettings(),
606
+ });
607
+ return false;
608
+ default:
609
+ return false;
610
+ }
611
+ }
612
+ ```
613
+
614
+ ### Permissions Checklist
615
+
616
+ | Permission | When to Request | Fallback |
617
+ |-----------|----------------|----------|
618
+ | Camera | User taps "Scan" or "Take Photo" | Manual text input |
619
+ | Location | User opens map or delivery tracking | Manual address entry |
620
+ | Notifications | After first meaningful action (first order) | In-app notification center |
621
+ | Photo Library | User taps "Upload Photo" | Camera capture instead |
622
+ | Contacts | User taps "Invite Friends" | Share link manually |
623
+
624
+ ## App Lifecycle Management
625
+
626
+ ### States and Transitions
627
+
628
+ ```
629
+ ┌──────────┐ ┌────────────┐ ┌────────────┐
630
+ │ Launched │────→│ Foreground │←───→│ Background │
631
+ └──────────┘ └────────────┘ └─────┬──────┘
632
+
633
+ ┌─────▼──────┐
634
+ │ Terminated │
635
+ └─────────────┘
636
+ ```
637
+
638
+ ### What to Do in Each State
639
+
640
+ | Transition | Action |
641
+ |-----------|--------|
642
+ | Launch → Foreground | Init services, check auth, fetch fresh data |
643
+ | Foreground → Background | Save draft state, pause timers, disconnect sockets |
644
+ | Background → Foreground | Refresh stale data, reconnect sockets, check auth |
645
+ | Background → Terminated | Persist critical state to local DB |
646
+
647
+ ```typescript
648
+ // React Native
649
+ useEffect(() => {
650
+ const sub = AppState.addEventListener('change', (state) => {
651
+ if (state === 'active') {
652
+ queryClient.refetchQueries({ type: 'active', stale: true });
653
+ reconnectWebSocket();
654
+ }
655
+ if (state === 'background') {
656
+ saveDraftState();
657
+ disconnectWebSocket();
658
+ }
659
+ });
660
+ return () => sub.remove();
661
+ }, []);
662
+ ```
663
+
664
+ ```dart
665
+ // Flutter
666
+ class _AppLifecycleState extends State<App> with WidgetsBindingObserver {
667
+ @override
668
+ void didChangeAppLifecycleState(AppLifecycleState state) {
669
+ switch (state) {
670
+ case AppLifecycleState.resumed:
671
+ ref.invalidate(ordersProvider); // Refresh data
672
+ break;
673
+ case AppLifecycleState.paused:
674
+ ref.read(draftProvider.notifier).saveToDisk();
675
+ break;
676
+ default:
677
+ break;
678
+ }
679
+ }
680
+ }
681
+ ```