@buivietphi/skill-mobile-mt 2.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