@buivietphi/skill-mobile-mt 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.
@@ -0,0 +1,407 @@
1
+ # Anti-Pattern Detection — Scan for Common Mistakes
2
+
3
+ > Auto-detect patterns that cause crashes, leaks, or store rejections.
4
+
5
+ ## When to Use
6
+
7
+ - Before committing code
8
+ - During code review
9
+ - When instrumentation/observability code is added
10
+ - Before PR submission
11
+
12
+ ---
13
+
14
+ ## Detection Categories
15
+
16
+ ### 1. PII (Personally Identifiable Information) Leaks
17
+
18
+ **CRITICAL** - Compliance risk (GDPR, CCPA, HIPAA)
19
+
20
+ ```
21
+ PATTERNS TO DETECT:
22
+ ❌ email / phone / ssn / credit_card / address / dob (date of birth)
23
+ ❌ properties: ["user_email": user.email]
24
+ ❌ tags: ["phone": user.phone]
25
+ ❌ trackEvent("login", ["ssn": ssn])
26
+ ❌ console.log("User: ${user.email}")
27
+
28
+ ✅ SAFE ALTERNATIVES:
29
+ ✓ properties: ["has_email": user.email != nil]
30
+ ✓ tags: ["user_tier": "premium"] // Enum, not PII
31
+ ✓ trackEvent("login", ["user_type": userType])
32
+ ✓ console.log("User: ${user.id}") // UUID, not PII
33
+ ```
34
+
35
+ **Auto-Fix Suggestion:**
36
+ ```
37
+ Found: properties: ["email": user.email]
38
+ Fix → properties: ["has_email": user.email != nil]
39
+
40
+ Found: tags: ["user_id": userId]
41
+ Fix → tags: ["user_tier": user.subscription.tier]
42
+ ```
43
+
44
+ ---
45
+
46
+ ### 2. High Cardinality
47
+
48
+ **CRITICAL** - Explodes storage, kills query performance
49
+
50
+ ```
51
+ PATTERNS TO DETECT:
52
+ ❌ user_id / session_id / uuid / timestamp / device_id as TAG values
53
+ ❌ tags: ["user_id": "uuid-123"] // Unlimited unique values
54
+ ❌ tags: ["timestamp": Date.now()] // Unbounded
55
+ ❌ dimensions: ["request_id": requestId] // High cardinality
56
+
57
+ ✅ SAFE ALTERNATIVES:
58
+ ✓ tags: ["user_tier": "free|premium|enterprise"] // Low cardinality (3 values)
59
+ ✓ tags: ["hour": date.getHours()] // Low cardinality (0-23)
60
+ ✓ dimensions: ["status_code": "200|404|500"] // Low cardinality
61
+
62
+ RULE: Tags should have < 100 unique values over 30 days
63
+ ```
64
+
65
+ **Auto-Fix Suggestion:**
66
+ ```
67
+ Found: tags: ["user_id": userId]
68
+ Why bad: user_id has unlimited unique values → storage explosion
69
+ Fix →
70
+ Option 1: Remove tag (use session correlation instead)
71
+ Option 2: tags: ["user_tier": user.tier] // Categorize
72
+ Option 3: Move to context field (not a tag)
73
+ ```
74
+
75
+ ---
76
+
77
+ ### 3. Unbounded Payloads
78
+
79
+ **HIGH** - Hits size limits, network cost
80
+
81
+ ```
82
+ PATTERNS TO DETECT:
83
+ ❌ Entire objects: extras: ["state": appState]
84
+ ❌ Large arrays: extras: ["cart": cart.items] // If items can be 1000+
85
+ ❌ Unfiltered user input: extras: ["search_query": query] // No length limit
86
+ ❌ Nested objects: extras: ["user": user] // Can be recursive
87
+
88
+ ✅ SAFE ALTERNATIVES:
89
+ ✓ extras: ["cart_item_count": cart.items.count] // Aggregate
90
+ ✓ extras: ["has_state": appState != nil] // Boolean
91
+ ✓ extras: ["search_query_length": query.length] // Derived
92
+ ✓ extras: ["user_tier": user.tier] // Extract specific field
93
+
94
+ RULE: Extras should be < 10KB total per event
95
+ ```
96
+
97
+ **Auto-Fix Suggestion:**
98
+ ```
99
+ Found: extras: ["cart": cart]
100
+ Why bad: cart can be 1000+ items → 100KB+
101
+ Fix →
102
+ extras: [
103
+ "cart_item_count": cart.items.count,
104
+ "cart_total": cart.total,
105
+ "cart_has_promo": cart.promo != nil
106
+ ]
107
+ ```
108
+
109
+ ---
110
+
111
+ ### 4. Unstructured Logs
112
+
113
+ **MEDIUM** - Can't query or aggregate
114
+
115
+ ```
116
+ PATTERNS TO DETECT:
117
+ ❌ String interpolation: console.log(`User ${userId} failed`)
118
+ ❌ Free-form text: log("Something went wrong")
119
+ ❌ Mixed formats: log("Error: code=500, user=123")
120
+
121
+ ✅ STRUCTURED ALTERNATIVES:
122
+ ✓ logger.error("user_login_failed", { user_id: userId, reason: "timeout" })
123
+ ✓ trackEvent("error", {
124
+ error_type: "login_failed",
125
+ user_id: userId,
126
+ reason: "timeout"
127
+ })
128
+ ```
129
+
130
+ ---
131
+
132
+ ### 5. Sync Telemetry on Main Thread
133
+
134
+ **HIGH** - UI freezes
135
+
136
+ ```
137
+ PATTERNS TO DETECT:
138
+ ❌ trackEvent(...) in render / build / Composable
139
+ ❌ captureError(...) without async / background
140
+ ❌ flush() on main thread
141
+ ❌ Network call inside instrumentation without queue
142
+
143
+ ✅ SAFE ALTERNATIVES:
144
+ ✓ trackEvent(...) → batches automatically (Sentry, Amplitude)
145
+ ✓ captureError(...) → sends async (Firebase Crashlytics)
146
+ ✓ Use background queue: DispatchQueue.global().async { ... }
147
+ ✓ InteractionManager.runAfterInteractions(() => { ... })
148
+ ```
149
+
150
+ ---
151
+
152
+ ### 6. Missing Context
153
+
154
+ **MEDIUM** - Events without correlation
155
+
156
+ ```
157
+ REQUIRED CONTEXT FOR EVERY EVENT:
158
+ □ session_id (correlation)
159
+ □ screen (where it happened)
160
+ □ job_name (business goal: "checkout", "onboarding")
161
+ □ job_step (which step: "cart_review", "payment")
162
+ □ app_version (which release)
163
+
164
+ PATTERNS TO DETECT:
165
+ ❌ trackEvent("button_tapped") // What button? Which screen?
166
+ ❌ captureError(error) // No context
167
+
168
+ ✅ COMPLETE EXAMPLES:
169
+ ✓ trackEvent("button_tapped", {
170
+ button: "checkout_submit",
171
+ screen: "CartScreen",
172
+ job_name: "checkout",
173
+ job_step: "cart_review",
174
+ session_id: sessionId,
175
+ app_version: "1.2.3"
176
+ })
177
+
178
+ ✓ captureError(error, {
179
+ screen: "PaymentScreen",
180
+ job_name: "checkout",
181
+ job_step: "payment",
182
+ session_id: sessionId
183
+ })
184
+ ```
185
+
186
+ ---
187
+
188
+ ### 7. Mobile-Specific Anti-Patterns
189
+
190
+ #### React Native
191
+
192
+ ```
193
+ ❌ console.log in production (massive bottleneck)
194
+ ❌ require() in render (re-executes every frame)
195
+ ❌ Anonymous functions in FlatList renderItem
196
+ ❌ Inline styles in render
197
+ ❌ AsyncStorage for tokens (use SecureStore)
198
+
199
+ ✅ CORRECT:
200
+ ✓ __DEV__ && console.log(...)
201
+ ✓ const Component = React.lazy(() => import(...))
202
+ ✓ const renderItem = useCallback((item) => ..., [])
203
+ ✓ const styles = StyleSheet.create({ ... })
204
+ ✓ SecureStore.setItemAsync('token', token)
205
+ ```
206
+
207
+ #### Flutter
208
+
209
+ ```
210
+ ❌ print() in production
211
+ ❌ setState in build()
212
+ ❌ Unbounded ListView (use ListView.builder)
213
+ ❌ SharedPreferences for tokens (use flutter_secure_storage)
214
+
215
+ ✅ CORRECT:
216
+ ✓ kDebugMode && print(...)
217
+ ✓ setState in event handlers, not build
218
+ ✓ ListView.builder(itemCount: items.length, ...)
219
+ ✓ await secureStorage.write(key: 'token', value: token)
220
+ ```
221
+
222
+ #### iOS
223
+
224
+ ```
225
+ ❌ Force unwrap (!) without nil check
226
+ ❌ Retain cycles ([self] in closures)
227
+ ❌ UserDefaults for tokens (use Keychain)
228
+ ❌ Heavy work on main thread
229
+
230
+ ✅ CORRECT:
231
+ ✓ guard let value = optional else { return }
232
+ ✓ Capture [weak self] or [unowned self]
233
+ ✓ KeychainWrapper.standard.set(token, forKey: "token")
234
+ ✓ DispatchQueue.global().async { ... }
235
+ ```
236
+
237
+ #### Android
238
+
239
+ ```
240
+ ❌ !! (force unwrap) without null check
241
+ ❌ Memory leaks (Activity/Context references)
242
+ ❌ SharedPreferences for tokens (use EncryptedSharedPreferences)
243
+ ❌ AsyncTask (deprecated, use WorkManager)
244
+
245
+ ✅ CORRECT:
246
+ ✓ val value = optional ?: return
247
+ ✓ Use ViewModel, avoid Activity refs in background
248
+ ✓ EncryptedSharedPreferences for sensitive data
249
+ ✓ WorkManager for background tasks
250
+ ```
251
+
252
+ ---
253
+
254
+ ## Detection Workflow
255
+
256
+ ```
257
+ PRE-COMMIT HOOK:
258
+ 1. Scan all changed files for anti-patterns
259
+ 2. Flag CRITICAL (block commit) vs HIGH (warn) vs MEDIUM (suggest)
260
+ 3. Provide auto-fix suggestions
261
+ 4. Run again after fix
262
+
263
+ DURING CODE REVIEW:
264
+ 1. Agent scans PR diff
265
+ 2. Comments on lines with anti-patterns
266
+ 3. Suggests fixes inline
267
+ 4. Links to this doc for explanation
268
+
269
+ CONTINUOUS:
270
+ 1. Periodic full codebase scan
271
+ 2. Generate report: violations by severity
272
+ 3. Track trends (increasing/decreasing)
273
+ 4. Alert if CRITICAL violations increase
274
+ ```
275
+
276
+ ---
277
+
278
+ ## Severity Levels
279
+
280
+ | Severity | Impact | Action |
281
+ |----------|--------|--------|
282
+ | **CRITICAL** | PII leak, compliance risk | Block commit/PR |
283
+ | **HIGH** | Performance issue, crashes | Block commit, allow override |
284
+ | **MEDIUM** | Code smell, maintainability | Warn, suggest fix |
285
+ | **LOW** | Style, best practice | Suggest, don't block |
286
+
287
+ ---
288
+
289
+ ## Example: Full Detection Report
290
+
291
+ ```
292
+ FILE: src/features/auth/LoginScreen.tsx
293
+ LINE 45: ❌ CRITICAL - PII Leak
294
+ Found: trackEvent("login", { email: user.email })
295
+ Fix: trackEvent("login", { has_email: user.email != nil })
296
+ Why: Email is PII → GDPR/CCPA violation
297
+
298
+ LINE 67: ❌ HIGH - High Cardinality
299
+ Found: tags: ["user_id": userId]
300
+ Fix: tags: ["user_tier": user.tier]
301
+ Why: user_id unbounded → storage explosion
302
+
303
+ LINE 89: ❌ MEDIUM - Missing Context
304
+ Found: captureError(error)
305
+ Fix: captureError(error, { screen: "LoginScreen", job_name: "auth" })
306
+ Why: Can't correlate error without context
307
+
308
+ FILE: src/services/analytics.ts
309
+ LINE 23: ❌ CRITICAL - Sync Telemetry on Main Thread
310
+ Found: trackEvent(...) in render()
311
+ Fix: Move to useEffect or InteractionManager.runAfterInteractions
312
+ Why: Blocks UI rendering → janky experience
313
+
314
+ Summary:
315
+ 2 CRITICAL (block)
316
+ 1 HIGH (warn)
317
+ 1 MEDIUM (suggest)
318
+ ```
319
+
320
+ ---
321
+
322
+ ## Auto-Fix Templates
323
+
324
+ ### PII → Boolean
325
+ ```typescript
326
+ // Before
327
+ trackEvent("signup", { email: user.email })
328
+
329
+ // After
330
+ trackEvent("signup", { has_email: user.email !== undefined })
331
+ ```
332
+
333
+ ### High Cardinality → Enum
334
+ ```typescript
335
+ // Before
336
+ tags: ["user_id": userId]
337
+
338
+ // After
339
+ tags: ["user_tier": user.subscription.tier] // "free" | "premium" | "enterprise"
340
+ ```
341
+
342
+ ### Unbounded → Aggregate
343
+ ```typescript
344
+ // Before
345
+ extras: ["cart": cart]
346
+
347
+ // After
348
+ extras: [
349
+ "cart_item_count": cart.items.length,
350
+ "cart_total_cents": cart.totalCents
351
+ ]
352
+ ```
353
+
354
+ ### Missing Context → Complete
355
+ ```typescript
356
+ // Before
357
+ trackEvent("button_tapped")
358
+
359
+ // After
360
+ trackEvent("button_tapped", {
361
+ button: "checkout_submit",
362
+ screen: "CartScreen",
363
+ job_name: "checkout",
364
+ job_step: "cart_review",
365
+ session_id: sessionManager.currentSessionId,
366
+ app_version: Constants.expoConfig?.version
367
+ })
368
+ ```
369
+
370
+ ---
371
+
372
+ ## Integration with CI/CD
373
+
374
+ ```bash
375
+ # Pre-commit hook
376
+ .git/hooks/pre-commit:
377
+ npm run detect-anti-patterns -- --severity=critical --block
378
+
379
+ # PR Check
380
+ .github/workflows/pr-check.yml:
381
+ - name: Detect Anti-Patterns
382
+ run: npm run detect-anti-patterns -- --severity=high --report
383
+
384
+ # Weekly Scan
385
+ .github/workflows/weekly-scan.yml:
386
+ schedule: cron('0 0 * * 0') # Every Sunday
387
+ run: npm run detect-anti-patterns -- --full-scan --report
388
+ ```
389
+
390
+ ---
391
+
392
+ ## Learning from AI Tools
393
+
394
+ **Common mistakes AI tools make:**
395
+
396
+ | Tool | Mistake | Why |
397
+ |------|---------|-----|
398
+ | Cursor | Logs PII directly | Doesn't know GDPR/CCPA |
399
+ | Cline | Uses user_id as tag | Doesn't understand cardinality |
400
+ | Windsurf | Passes entire state objects | Doesn't check payload size |
401
+ | Devin | Sync telemetry on main thread | Doesn't profile performance impact |
402
+
403
+ **This skill avoids these by:**
404
+ - Scanning before commit
405
+ - Auto-suggesting fixes
406
+ - Blocking CRITICAL violations
407
+ - Teaching best practices
@@ -0,0 +1,71 @@
1
+ # Bug Detection — Auto Scanner
2
+
3
+ > Always loaded. All platforms.
4
+
5
+ ---
6
+
7
+ ## Scan Order (by severity)
8
+
9
+ ### 1. Crash Risks (CRITICAL)
10
+ ```
11
+ ├── Force unwrap (! / !! / non-null assertion)
12
+ ├── Array out of bounds
13
+ ├── Unhandled null on API response
14
+ ├── Missing try/catch on async ops
15
+ ├── Missing error boundaries (RN)
16
+ ├── Infinite recursion
17
+ └── Division by zero
18
+ ```
19
+
20
+ ### 2. Memory Leaks (HIGH)
21
+ ```
22
+ RN: useEffect without cleanup, listeners not removed, timers not cleared
23
+ Flutter: StreamSubscription/Controller not disposed
24
+ iOS: [weak self] missing, observers not removed
25
+ Android: Context leak, BroadcastReceiver not unregistered
26
+ ```
27
+
28
+ ### 3. Race Conditions (HIGH)
29
+ ```
30
+ ├── Button tappable during async op → add isSubmitting flag
31
+ ├── setState after unmount → track mounted state
32
+ ├── Multiple 401s → queue token refresh
33
+ └── Optimistic update without rollback → save previous state
34
+ ```
35
+
36
+ ### 4. Security (HIGH)
37
+ ```
38
+ ├── Hardcoded secrets → env / secure config
39
+ ├── Tokens in AsyncStorage/SharedPrefs → SecureStore/Keychain
40
+ ├── Sensitive data in logs → strip before logging
41
+ ├── Deep links unvalidated → validate params
42
+ └── Debug mode in release → strip debug flags
43
+ ```
44
+
45
+ ### 5. Performance (MEDIUM)
46
+ ```
47
+ ├── ScrollView for long lists → FlatList/ListView.builder/LazyColumn
48
+ ├── Inline functions in render → useCallback/memo/const
49
+ ├── Index as key → stable unique ID
50
+ ├── Large images unoptimized → resize, cache
51
+ ├── Main thread blocking → background thread
52
+ └── Missing pagination → add cursor/offset
53
+ ```
54
+
55
+ ### 6. UX (MEDIUM)
56
+ ```
57
+ ├── Touch targets < 44pt/48dp
58
+ ├── Missing loading/error/empty states
59
+ ├── No keyboard dismiss
60
+ ├── Missing safe area handling
61
+ └── No accessibility labels
62
+ ```
63
+
64
+ ## Report Format
65
+
66
+ ```
67
+ 🐛 [SEVERITY] — [file:line]
68
+ Issue: [description]
69
+ Impact: [what breaks]
70
+ Fix: [code change]
71
+ ```
@@ -0,0 +1,125 @@
1
+ # CLAUDE.md Template for Mobile Projects
2
+
3
+ > Copy this file to your project root as `CLAUDE.md`.
4
+ > Claude Code reads it automatically every session — no invocation needed.
5
+
6
+ ---
7
+
8
+ ## How to use
9
+
10
+ 1. Copy this file to your project: `cp CLAUDE.md.template CLAUDE.md`
11
+ 2. Edit the sections marked with `[FILL IN]`
12
+ 3. Claude will follow these rules automatically in every conversation
13
+
14
+ ---
15
+
16
+ ## Template (copy below this line)
17
+
18
+ ---
19
+
20
+ # Project: [FILL IN: Your App Name]
21
+
22
+ ## Stack
23
+
24
+ - **Framework:** [React Native CLI / Expo SDK XX / Flutter X.X / iOS / Android]
25
+ - **Language:** [TypeScript / JavaScript / Dart / Swift / Kotlin]
26
+ - **State:** [Redux Toolkit / Zustand / Riverpod / BLoC / StateFlow]
27
+ - **Navigation:** [React Navigation v6 / Expo Router / GoRouter / UIKit / Jetpack]
28
+ - **API:** [axios / fetch / Dio / Firebase / GraphQL]
29
+ - **Package Manager:** [yarn / npm / pnpm / bun / flutter pub]
30
+
31
+ ## Project Structure
32
+
33
+ ```
34
+ [FILL IN: paste your src/ or lib/ tree here]
35
+ src/
36
+ ├── features/
37
+ │ ├── auth/
38
+ │ └── home/
39
+ ├── shared/
40
+ │ ├── components/
41
+ │ └── utils/
42
+ ```
43
+
44
+ ## Conventions
45
+
46
+ - **Naming:** [PascalCase screens, camelCase hooks/services]
47
+ - **Imports:** [absolute @/ aliases / relative paths]
48
+ - **Styling:** [StyleSheet / NativeWind / styled-components / Compose / SwiftUI]
49
+
50
+ ## Auto-Check Rules (apply after EVERY code change)
51
+
52
+ Before saying "done" on any task, automatically verify:
53
+
54
+ ```
55
+ □ No console.log / print / NSLog in production code
56
+ □ No hardcoded secrets, API keys, or tokens
57
+ □ No token storage in AsyncStorage / SharedPreferences / UserDefaults
58
+ □ All async operations wrapped in try/catch
59
+ □ All 4 states handled: loading / error / empty / success
60
+ □ useEffect / dispose / viewModelScope has cleanup
61
+ □ FlatList (not ScrollView) for lists > 20 items
62
+ □ No force unwrap (! / !! / as!) without null check
63
+ □ TypeScript: no implicit 'any'
64
+ □ New screens registered in navigator
65
+ □ Imports resolve (no broken paths)
66
+ ```
67
+
68
+ If ANY check fails → fix it before marking done.
69
+
70
+ ## Performance Rules (apply when building lists, animations, heavy screens)
71
+
72
+ ```
73
+ □ FlatList with keyExtractor + getItemLayout (if fixed height)
74
+ □ React.memo on list item components
75
+ □ useCallback on handlers passed to list items
76
+ □ Images: use FastImage / expo-image, specify width+height
77
+ □ Animations: use react-native-reanimated (not Animated API)
78
+ □ No heavy computation on main thread (use InteractionManager)
79
+ ```
80
+
81
+ ## Security Rules (non-negotiable)
82
+
83
+ ```
84
+ □ Tokens → SecureStore / Keychain / EncryptedSharedPreferences ONLY
85
+ □ Deep link params → validate before use
86
+ □ API calls → HTTPS only
87
+ □ Sensitive data → never in logs
88
+ □ User input → sanitize before display (XSS)
89
+ ```
90
+
91
+ ## What NOT to do
92
+
93
+ ```
94
+ □ NEVER suggest migrating to a different framework/architecture
95
+ □ NEVER change state management library
96
+ □ NEVER add packages without checking SDK compatibility first
97
+ □ NEVER mix package managers (yarn + npm)
98
+ □ NEVER create new files for one-off operations
99
+ □ NEVER add comments to code you didn't change
100
+ ```
101
+
102
+ ## Preferred Commands
103
+
104
+ ```bash
105
+ # Install
106
+ [yarn install / npm install / flutter pub get / pod install]
107
+
108
+ # Run
109
+ [yarn ios / yarn android / flutter run / xcodebuild / ./gradlew]
110
+
111
+ # Test
112
+ [yarn test / flutter test / xcodebuild test]
113
+
114
+ # Lint
115
+ [yarn lint / flutter analyze / swiftlint]
116
+ ```
117
+
118
+ ## Notes
119
+
120
+ [FILL IN: any project-specific quirks, known issues, or important context]
121
+
122
+ Example:
123
+ - Auth uses custom JWT refresh logic in src/services/auth/tokenManager.ts
124
+ - Push notifications require manual certificate setup (see docs/push-setup.md)
125
+ - Android flavor: 'staging' points to staging API, 'production' to prod