@take-out/docs 0.0.42

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.
package/triggers.md ADDED
@@ -0,0 +1,450 @@
1
+ ---
2
+ name: triggers
3
+ description: PostgreSQL database triggers guide for automation and data consistency. INVOKE WHEN: creating triggers, trigger functions, plpgsql, BEFORE/AFTER triggers, INSERT/UPDATE/DELETE events, maintaining derived data, syncing tables, audit trails, cascading updates, counter maintenance, reaction counts, reply counts.
4
+ ---
5
+
6
+ # Database Triggers Guide
7
+
8
+ ## Overview
9
+
10
+ This guide documents the PostgreSQL triggers used in the start.chat application.
11
+ Triggers are database functions that automatically execute in response to
12
+ certain database events (INSERT, UPDATE, DELETE). They maintain data
13
+ consistency, update derived data, and sync information across tables without
14
+ requiring application-level code.
15
+
16
+ ## Architecture
17
+
18
+ ### Trigger Categories
19
+
20
+ The application uses triggers for four main purposes:
21
+
22
+ 1. Search Indexing - Sync messages and data to search documents
23
+ 2. Statistics Aggregation - Track message reactions and chat activity
24
+ 3. Counter Maintenance - Keep thread reply counts accurate
25
+ 4. Relationship Tracking - Monitor private chat interactions
26
+
27
+ ### Naming Conventions
28
+
29
+ - Trigger Functions: `update_*()` or `sync_*_to_*()` format
30
+ - Triggers: `*Trigger` or `*_sync` suffix
31
+ - Stats Tables: `*Stats` suffix for aggregated data
32
+
33
+ ## Core Triggers
34
+
35
+ ### 1. Search Document Synchronization
36
+
37
+ Purpose: Automatically indexes messages and data for full-text and vector
38
+ search.
39
+
40
+ #### Message Search Sync
41
+
42
+ ```sql
43
+ CREATE TRIGGER message_search_sync
44
+ AFTER INSERT OR UPDATE OR DELETE ON message
45
+ FOR EACH ROW
46
+ EXECUTE FUNCTION sync_message_to_search();
47
+ ```
48
+
49
+ Function Logic:
50
+
51
+ - INSERT/UPDATE: Indexes non-draft, non-hidden messages with content
52
+ - DELETE: Removes message from search index
53
+ - Filters out messages with `type = 'draft'` or `type = 'hidden'`
54
+ - Only indexes messages where `deleted = false`
55
+ - Creates document ID as `msg_{message_id}`
56
+
57
+ Key Features:
58
+
59
+ - Extracts first 100 characters as title
60
+ - Maintains server and channel associations
61
+ - Sets reliability score (1-5 scale)
62
+ - Updates timestamps for freshness
63
+
64
+ #### Data Search Sync
65
+
66
+ ```sql
67
+ CREATE TRIGGER data_search_sync
68
+ AFTER INSERT OR UPDATE OR DELETE ON data
69
+ FOR EACH ROW
70
+ EXECUTE FUNCTION sync_data_to_search();
71
+ ```
72
+
73
+ Function Logic:
74
+
75
+ - Indexes all data entries with their key-value pairs
76
+ - Associates with app installations
77
+ - Preserves category and type metadata
78
+ - Creates document ID as `data_{data_id}`
79
+
80
+ ### 2. Message Reaction Statistics
81
+
82
+ Purpose: Maintains aggregated reaction counts and user lists for efficient UI
83
+ rendering.
84
+
85
+ #### Reaction Stats Triggers
86
+
87
+ ```sql
88
+ CREATE TRIGGER messageReactionInsertTrigger
89
+ AFTER INSERT ON messageReaction
90
+ FOR EACH ROW
91
+ EXECUTE FUNCTION updateMessageReactionStats();
92
+
93
+ CREATE TRIGGER messageReactionDeleteTrigger
94
+ AFTER DELETE ON messageReaction
95
+ FOR EACH ROW
96
+ EXECUTE FUNCTION updateMessageReactionStats();
97
+ ```
98
+
99
+ Function Logic:
100
+
101
+ - INSERT: Recalculates stats for message/reaction combination
102
+ - DELETE: Updates or removes stats based on remaining reactions
103
+ - Aggregates total reaction count, first three users, reaction value and image
104
+ - Uses window functions for efficient ordering
105
+
106
+ Performance Optimizations:
107
+
108
+ - Deletes and re-inserts stats (faster than UPDATE)
109
+ - Limits user list to first 3 for UI
110
+ - Uses ROW_NUMBER() for deterministic ordering
111
+
112
+ ### 3. Thread Reply Counters
113
+
114
+ Purpose: Maintains accurate reply counts for thread displays.
115
+
116
+ #### Reply Count Triggers
117
+
118
+ ```sql
119
+ CREATE TRIGGER threadReplyCountInsertTrigger
120
+ AFTER INSERT ON message
121
+ FOR EACH ROW
122
+ WHEN (NEW.threadId IS NOT NULL)
123
+ EXECUTE FUNCTION updateThreadReplyCount();
124
+
125
+ CREATE TRIGGER threadReplyCountUpdateTrigger
126
+ AFTER UPDATE OF deleted ON message
127
+ FOR EACH ROW
128
+ WHEN (NEW.threadId IS NOT NULL OR OLD.threadId IS NOT NULL)
129
+ EXECUTE FUNCTION updateThreadReplyCount();
130
+
131
+ CREATE TRIGGER threadReplyCountDeleteTrigger
132
+ AFTER DELETE ON message
133
+ FOR EACH ROW
134
+ WHEN (OLD.threadId IS NOT NULL)
135
+ EXECUTE FUNCTION updateThreadReplyCount();
136
+ ```
137
+
138
+ Function Logic:
139
+
140
+ - Counts non-deleted messages in thread
141
+ - Excludes the original thread message
142
+ - Caps count at 11 for "10+" display
143
+ - Handles soft deletes (deleted flag changes)
144
+ - Checks thread existence before updates (prevents cascade delete conflicts)
145
+ - Skips update when deleting thread's original message
146
+
147
+ Edge Cases Handled:
148
+
149
+ - Message moves between threads
150
+ - Soft delete/undelete operations
151
+ - Hard deletes
152
+ - Thread without replies
153
+ - Cascade deletes when original message is deleted
154
+
155
+ ### 4. Private Chat Statistics
156
+
157
+ Purpose: Tracks interaction frequency between users in private chats.
158
+
159
+ #### Private Chat Stats Trigger
160
+
161
+ ```sql
162
+ CREATE TRIGGER update_private_chats_stats_on_message_trigger
163
+ AFTER INSERT ON message
164
+ FOR EACH ROW
165
+ EXECUTE FUNCTION update_private_chats_stats_on_message();
166
+ ```
167
+
168
+ Function Logic:
169
+
170
+ - Detects messages in private chat servers
171
+ - Updates stats for all parent servers where both users are members
172
+ - Tracks message counts (week/month/year), last message timestamp, interaction
173
+ score
174
+ - Uses UPSERT pattern for efficiency
175
+
176
+ Score Calculation:
177
+
178
+ ```sql
179
+ score = CASE
180
+ WHEN messageCountWeek > 0
181
+ THEN messageCountWeek * 10 + messageCountMonth
182
+ ELSE messageCountMonth * 2 + messageCountYear
183
+ END
184
+ ```
185
+
186
+ ## Implementation Patterns
187
+
188
+ ### 1. UPSERT Pattern
189
+
190
+ Most triggers use INSERT ... ON CONFLICT DO UPDATE for idempotency:
191
+
192
+ ```sql
193
+ INSERT INTO stats_table (...)
194
+ VALUES (...)
195
+ ON CONFLICT (unique_key) DO UPDATE SET
196
+ field = EXCLUDED.field,
197
+ updated_at = NOW();
198
+ ```
199
+
200
+ ### 2. Conditional Execution
201
+
202
+ Triggers use WHEN clauses to avoid unnecessary function calls:
203
+
204
+ ```sql
205
+ CREATE TRIGGER trigger_name
206
+ AFTER INSERT ON table
207
+ FOR EACH ROW
208
+ WHEN (NEW.field IS NOT NULL)
209
+ EXECUTE FUNCTION function_name();
210
+ ```
211
+
212
+ ### 3. Multi-Operation Handling
213
+
214
+ Functions check TG_OP to handle different operations:
215
+
216
+ ```sql
217
+ IF TG_OP = 'INSERT' THEN
218
+ -- insert logic
219
+ ELSIF TG_OP = 'UPDATE' THEN
220
+ -- update logic
221
+ ELSIF TG_OP = 'DELETE' THEN
222
+ -- delete logic
223
+ END IF;
224
+ ```
225
+
226
+ ### 4. Cascade Delete Safety
227
+
228
+ Prevent foreign key violations during cascade deletes:
229
+
230
+ ```sql
231
+ IF TG_OP = 'DELETE' THEN
232
+ SELECT EXISTS(SELECT 1 FROM parent_table WHERE id = OLD.parent_id) INTO parent_exists;
233
+
234
+ IF NOT parent_exists THEN
235
+ RETURN OLD;
236
+ END IF
237
+
238
+ UPDATE parent_table SET counter = counter - 1 WHERE id = OLD.parent_id;
239
+ END IF;
240
+ ```
241
+
242
+ ### 5. Bulk Operations
243
+
244
+ Initial population uses batch inserts with conflict handling:
245
+
246
+ ```sql
247
+ INSERT INTO search_documents (...)
248
+ SELECT ... FROM source_table
249
+ WHERE conditions
250
+ ON CONFLICT DO NOTHING;
251
+ ```
252
+
253
+ ## Performance Considerations
254
+
255
+ ### Index Strategy
256
+
257
+ Each trigger-maintained table has appropriate indexes:
258
+
259
+ ```sql
260
+ CREATE INDEX idx_search_vector USING GIN(search_vector);
261
+ CREATE INDEX idx_embedding USING ivfflat(embedding vector_cosine_ops);
262
+ CREATE INDEX idx_server_id ON search_documents(server_id);
263
+ ```
264
+
265
+ ### Optimization Techniques
266
+
267
+ 1. Minimal Updates: Only update changed fields
268
+ 2. Early Returns: Exit quickly for non-applicable rows
269
+ 3. Batch Processing: Use CTEs for complex aggregations
270
+ 4. Index Usage: Ensure queries use available indexes
271
+ 5. Connection Pooling: Triggers reuse database connections
272
+
273
+ ### Performance Monitoring
274
+
275
+ Monitor trigger performance with:
276
+
277
+ ```sql
278
+ SELECT
279
+ schemaname,
280
+ tablename,
281
+ calls,
282
+ total_time,
283
+ mean,
284
+ max
285
+ FROM pg_stat_user_functions
286
+ WHERE schemaname = 'public';
287
+ ```
288
+
289
+ ## Migration Management
290
+
291
+ ### Adding Triggers
292
+
293
+ 1. Create function first
294
+ 2. Create trigger
295
+ 3. Backfill existing data
296
+ 4. Test with sample operations
297
+
298
+ Example migration structure:
299
+
300
+ ```typescript
301
+ export async function up(client: PoolClient) {
302
+ await client.query(`CREATE OR REPLACE FUNCTION ...`)
303
+ await client.query(`CREATE TRIGGER ...`)
304
+ await client.query(`INSERT INTO ... SELECT ...`)
305
+ }
306
+ ```
307
+
308
+ ### Modifying Triggers
309
+
310
+ 1. Drop existing trigger (not function)
311
+ 2. Modify function with CREATE OR REPLACE
312
+ 3. Recreate trigger
313
+ 4. Test thoroughly
314
+
315
+ ### Version Control
316
+
317
+ - Each trigger change gets a new migration file
318
+ - Include rollback logic in down() function
319
+ - Document breaking changes
320
+ - Test migrations on staging first
321
+
322
+ ## Debugging Triggers
323
+
324
+ ### Enable Trigger Debugging
325
+
326
+ ```sql
327
+ SET log_statement = 'all';
328
+ SET log_min_messages = 'debug1';
329
+
330
+ SELECT * FROM pg_trigger WHERE tgname = 'trigger_name';
331
+ ```
332
+
333
+ ### Common Issues
334
+
335
+ 1. Infinite Loops: Trigger updates same table
336
+
337
+ - Solution: Use UPDATE ... WHERE to limit scope
338
+
339
+ 2. Missing Data: Trigger conditions too restrictive
340
+
341
+ - Solution: Review WHEN clauses and IF conditions
342
+
343
+ 3. Performance Degradation: Complex calculations in trigger
344
+
345
+ - Solution: Consider async processing or materialized views
346
+
347
+ 4. Constraint Violations: Foreign key issues during deletes
348
+
349
+ - Solution: Add proper CASCADE options or existence checks
350
+
351
+ 5. Cascade Delete Conflicts: Trigger tries to update rows being deleted
352
+ - Problem: When a parent record is deleted with CASCADE, triggers may attempt
353
+ to update child records that are also being deleted
354
+ - Solution: Check if related records still exist before updating them
355
+ - Example: Thread reply count trigger checks if thread exists before updating
356
+ when message is deleted
357
+
358
+ ### Testing Triggers
359
+
360
+ ```sql
361
+ BEGIN;
362
+ INSERT INTO table_name (...) VALUES (...);
363
+ SELECT * FROM affected_table WHERE ...;
364
+ ROLLBACK;
365
+
366
+ BEGIN;
367
+ UPDATE table_name SET field = value WHERE id = ...;
368
+ SELECT * FROM affected_table WHERE ...;
369
+ ROLLBACK;
370
+
371
+ BEGIN;
372
+ DELETE FROM table_name WHERE id = ...;
373
+ SELECT * FROM affected_table WHERE ...;
374
+ ROLLBACK;
375
+ ```
376
+
377
+ ## Best Practices
378
+
379
+ ### 1. Trigger Design
380
+
381
+ - Keep trigger functions focused and simple
382
+ - Avoid complex business logic in triggers
383
+ - Use triggers for data integrity, not application logic
384
+ - Document trigger side effects
385
+
386
+ ### 2. Error Handling
387
+
388
+ - Use proper exception handling in functions
389
+ - Log errors to application logs
390
+ - Provide meaningful error messages
391
+ - Consider failure recovery strategies
392
+
393
+ ### 3. Maintenance
394
+
395
+ - Regular VACUUM and ANALYZE on trigger-maintained tables
396
+ - Monitor trigger execution times
397
+ - Review and optimize slow triggers
398
+ - Keep trigger documentation updated
399
+
400
+ ### 4. Security
401
+
402
+ - Validate data within trigger functions
403
+ - Use proper permissions on trigger functions
404
+ - Avoid dynamic SQL in triggers
405
+ - Sanitize inputs when building queries
406
+
407
+ ## Future Enhancements
408
+
409
+ ### Planned Improvements
410
+
411
+ 1. Async Processing: Move heavy computations to background jobs
412
+ 2. Partitioning: Partition large stats tables by date
413
+ 3. Caching: Add Redis caching for frequently accessed stats
414
+ 4. Event Streaming: Publish trigger events to message queue
415
+
416
+ ### Potential New Triggers
417
+
418
+ - User activity tracking
419
+ - Content moderation flags
420
+ - Audit logging
421
+ - Real-time notifications
422
+ - Cache invalidation
423
+
424
+ ## Monitoring & Alerts
425
+
426
+ ### Key Metrics
427
+
428
+ Monitor these metrics for trigger health:
429
+
430
+ 1. Execution Time: Average and max trigger execution time
431
+ 2. Error Rate: Failed trigger executions
432
+ 3. Table Bloat: Size of trigger-maintained tables
433
+ 4. Lock Contention: Waiting queries due to triggers
434
+ 5. Index Usage: Ensure indexes are being used
435
+
436
+ ### Alert Thresholds
437
+
438
+ - Trigger execution > 100ms
439
+ - Error rate > 1%
440
+ - Table bloat > 20%
441
+ - Lock wait time > 1s
442
+ - Index scan ratio < 90%
443
+
444
+ ## Conclusion
445
+
446
+ Database triggers provide powerful automation for maintaining data consistency
447
+ and derived information. When used appropriately, they reduce application
448
+ complexity and ensure data integrity. However, they must be carefully designed,
449
+ thoroughly tested, and continuously monitored to prevent performance issues and
450
+ maintain system reliability.
@@ -0,0 +1,127 @@
1
+ ---
2
+ name: xcodebuild-mcp
3
+ description: iOS debugging with XcodeBuildMCP. INVOKE WHEN: run or test react native, debug ios, debug native, ios simulator, run simulator, ios device, device debugging, xcode build, native app debugging, simulator logs, capture screenshot, ui automation, test ios, run on device, launch simulator.
4
+ ---
5
+
6
+ # xcodebuild mcp
7
+
8
+ ai-powered xcode automation for building, testing, and debugging ios apps.
9
+
10
+ ## setup
11
+
12
+ xcodebuildmcp is configured in `.mcp.json` at the repo root. install axe for ui automation:
13
+
14
+ ```bash
15
+ brew install cameroncooke/axe/axe
16
+ ```
17
+
18
+ ### requirements
19
+
20
+ - macos 14.5+
21
+ - xcode 16.x+
22
+ - node.js 18.x+
23
+
24
+ ## common tasks
25
+
26
+ ### build and run on simulator
27
+
28
+ ```
29
+ build the ios app and run it on iphone 16 pro simulator
30
+ ```
31
+
32
+ ### debug with logs
33
+
34
+ ```
35
+ capture simulator logs while I test the login flow
36
+ ```
37
+
38
+ ### run on physical device
39
+
40
+ requires code signing configured in xcode. then:
41
+
42
+ ```
43
+ deploy to my connected iphone and show logs
44
+ ```
45
+
46
+ ### capture evidence
47
+
48
+ ```
49
+ take a screenshot of the current simulator state
50
+ record a video of me testing this flow
51
+ ```
52
+
53
+ ### ui automation
54
+
55
+ ```
56
+ tap the login button
57
+ scroll down on the simulator
58
+ describe the current ui elements
59
+ ```
60
+
61
+ ## available tools
62
+
63
+ ### simulator management
64
+
65
+ - list/boot simulators
66
+ - install and launch apps
67
+ - capture logs, screenshots, video
68
+ - perform gestures (tap, swipe, scroll)
69
+ - describe ui elements for automation
70
+
71
+ ### device management
72
+
73
+ - discover connected devices (usb/wifi)
74
+ - install and launch apps
75
+ - capture logs
76
+ - stop running apps
77
+
78
+ ### build & test
79
+
80
+ - build for any platform (macos, ios sim, ios device)
81
+ - run test suites
82
+ - list schemes and configurations
83
+
84
+ ## debugging workflow
85
+
86
+ 1. build and run on simulator
87
+
88
+ ```
89
+ build takeout for ios simulator and run on iphone 16 pro
90
+ ```
91
+
92
+ 2. capture logs while testing
93
+
94
+ ```
95
+ show simulator logs filtered for "error"
96
+ ```
97
+
98
+ 3. capture screenshot on issue
99
+
100
+ ```
101
+ take a screenshot now
102
+ ```
103
+
104
+ 4. check ui state
105
+
106
+ ```
107
+ describe the current ui elements on screen
108
+ ```
109
+
110
+ ## troubleshooting
111
+
112
+ run the doctor command to diagnose issues:
113
+
114
+ ```bash
115
+ npx xcodebuildmcp doctor
116
+ ```
117
+
118
+ common issues:
119
+
120
+ - **build fails**: check xcode command line tools: `xcode-select -p`
121
+ - **device not found**: ensure device is trusted and connected
122
+ - **ui automation fails**: ensure axe is installed via homebrew
123
+
124
+ ## links
125
+
126
+ - https://www.xcodebuildmcp.com
127
+ - https://github.com/cameroncooke/XcodeBuildMCP