summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AGENTS.md80
1 files changed, 80 insertions, 0 deletions
diff --git a/AGENTS.md b/AGENTS.md
index b39c1a1..f70adaf 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -549,6 +549,86 @@ lint Omni/YourNamespace.hs
**Fix all reported errors** related to your changes before marking the task as complete. This ensures code quality and prevents breaking the build for other contributors.
+## Database Migrations
+
+### SQLite Limitations
+
+When writing migrations for SQLite databases:
+
+1. **Cannot add UNIQUE constraints via ALTER TABLE** - SQLite's ALTER TABLE doesn't support adding constraints. Add columns without UNIQUE and rely on application logic to enforce uniqueness.
+
+ ```python
+ # Wrong - will fail silently
+ cursor.execute("ALTER TABLE users ADD COLUMN email TEXT UNIQUE")
+
+ # Correct - add without UNIQUE
+ cursor.execute("ALTER TABLE users ADD COLUMN email TEXT")
+ ```
+
+2. **Always log migration failures** - Don't silently swallow exceptions. Use `logger.debug()` to log when columns already exist.
+
+3. **Migrations run on startup** - `Database.init_db()` should be called in the `main()` function of web services to ensure migrations run every time the service starts.
+
+## Testing External API Integrations
+
+When integrating with external services like Stripe, payment processors, or other APIs:
+
+### Mock Webhooks in Tests
+
+Instead of calling real APIs, mock the webhook payloads:
+
+```python
+class TestWebhookHandling(Test.TestCase):
+ def test_subscription_created(self):
+ # Mock the webhook payload structure
+ subscription = {
+ "id": "sub_test123",
+ "customer": "cus_test123",
+ "status": "active",
+ # ... other fields
+ }
+ _handle_webhook(subscription)
+ # Assert expected database changes
+```
+
+### Local Webhook Testing
+
+For services like Stripe that send webhooks:
+
+1. **Use CLI tools** - Most services provide CLI tools for local testing:
+ ```bash
+ stripe listen --forward-to localhost:8000/webhook
+ stripe trigger checkout.session.completed
+ ```
+
+2. **Bypass signature verification in test mode** - Check if secret is configured before verifying signatures:
+ ```python
+ if WEBHOOK_SECRET:
+ event = verify_signature(payload, signature, WEBHOOK_SECRET)
+ else:
+ logger.warning("Signature verification skipped (test mode)")
+ event = json.loads(payload)
+ ```
+
+3. **Handle API version differences** - External APIs change over time. Use fallbacks for field names:
+ ```python
+ # Try multiple field names for compatibility
+ period_start = (
+ subscription.get("current_period_start")
+ or subscription.get("billing_cycle_anchor")
+ or subscription.get("start_date")
+ )
+ ```
+
+### Verify with Database Inspection
+
+When debugging integrations, check the database directly:
+```bash
+sqlite3 path/to/db.db "SELECT * FROM table WHERE condition;"
+```
+
+This confirms whether webhooks/integrations actually updated the data.
+
## Future Enhancements
Planned features (not yet implemented):