feat: add appointments, campaigns, admin, storage, tests and various updates

- Add new routers: admin, appointments, campaigns
- Add storage service and logging config
- Add migrations directory and test suite with pytest config
- Add supabase_migration_features.sql
- Update models, dependencies, config, and existing routers
- Remove whatsapp_service (deleted)
- Update pyproject.toml and uv.lock dependencies

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
belviskhoremk
2026-04-03 09:11:58 +00:00
parent 9dccc83293
commit 92d4c2fc5e
51 changed files with 7076 additions and 515 deletions

View File

@@ -89,6 +89,17 @@ async def stripe_webhook(
supabase = get_supabase()
event_type = event.get("type", "")
event_id = event.get("id", "")
# Idempotency check: skip already-processed events
if event_id:
existing = supabase.table("stripe_webhook_events") \
.select("stripe_event_id") \
.eq("stripe_event_id", event_id) \
.execute()
if existing.data:
logger.info(f"Stripe event {event_id} already processed, skipping")
return {"received": True}
if event_type == "checkout.session.completed":
session = event["data"]["object"]
@@ -140,6 +151,16 @@ async def stripe_webhook(
except Exception as e:
logger.warning(f"Failed to send cancellation notification: {e}")
# Record event as processed
if event_id:
try:
supabase.table("stripe_webhook_events").insert({
"stripe_event_id": event_id,
"event_type": event_type,
}).execute()
except Exception as e:
logger.warning(f"Failed to record stripe event {event_id}: {e}")
return {"received": True}
except HTTPException: