elevenlabs-webhook-nodejs 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.
- package/.claude/settings.local.json +27 -0
- package/.dockerignore +6 -0
- package/.env.example +43 -0
- package/BEFORE-PRODUCTION.md +32 -0
- package/Dockerfile +23 -0
- package/SYSTEM_OVERVIEW.md +942 -0
- package/SYSTEM_STATUS.md +332 -0
- package/backup_script/main.py +146 -0
- package/baileys/.dockerignore +7 -0
- package/baileys/Dockerfile +13 -0
- package/baileys/README.md +412 -0
- package/baileys/index.js +499 -0
- package/baileys/package-lock.json +2532 -0
- package/baileys/package.json +25 -0
- package/baileys/server.js +96 -0
- package/baileys/src/config.js +55 -0
- package/baileys/src/middleware/api-key.js +16 -0
- package/baileys/src/routes/accounts.js +51 -0
- package/baileys/src/routes/chats.js +103 -0
- package/baileys/src/routes/webhooks.js +34 -0
- package/baileys/src/services/account-store.js +259 -0
- package/baileys/src/services/webhook-dispatcher.js +161 -0
- package/baileys/src/services/worker-manager.js +597 -0
- package/baileys/src/utils/jid.js +79 -0
- package/baileys/src/utils/logger.js +16 -0
- package/baileys/src/utils/use-mongodb-auth-state.js +122 -0
- package/baileys/worker.js +721 -0
- package/dist/app.d.ts +1 -0
- package/dist/app.js +84 -0
- package/dist/app.js.map +1 -0
- package/dist/config/agentPrompts.json +19 -0
- package/dist/config/database.d.ts +1 -0
- package/dist/config/database.js +26 -0
- package/dist/config/database.js.map +1 -0
- package/dist/config/env.d.ts +41 -0
- package/dist/config/env.js +81 -0
- package/dist/config/env.js.map +1 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.js +73 -0
- package/dist/config/index.js.map +1 -0
- package/dist/controllers/webhook.controller.d.ts +10 -0
- package/dist/controllers/webhook.controller.js +128 -0
- package/dist/controllers/webhook.controller.js.map +1 -0
- package/dist/errors/index.d.ts +4 -0
- package/dist/errors/index.js +13 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/hooks/webhookValidator.d.ts +2 -0
- package/dist/hooks/webhookValidator.js +47 -0
- package/dist/hooks/webhookValidator.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +55 -0
- package/dist/index.js.map +1 -0
- package/dist/migrations/001_session-architecture.d.ts +3 -0
- package/dist/migrations/001_session-architecture.js +119 -0
- package/dist/migrations/001_session-architecture.js.map +1 -0
- package/dist/migrations/002_agent-ref.d.ts +3 -0
- package/dist/migrations/002_agent-ref.js +55 -0
- package/dist/migrations/002_agent-ref.js.map +1 -0
- package/dist/migrations/003_shift-schedule.d.ts +3 -0
- package/dist/migrations/003_shift-schedule.js +48 -0
- package/dist/migrations/003_shift-schedule.js.map +1 -0
- package/dist/migrations/004_invert-shift-to-clinic-hours.d.ts +3 -0
- package/dist/migrations/004_invert-shift-to-clinic-hours.js +27 -0
- package/dist/migrations/004_invert-shift-to-clinic-hours.js.map +1 -0
- package/dist/migrations/005_composite-baileys-chat-ids.d.ts +3 -0
- package/dist/migrations/005_composite-baileys-chat-ids.js +47 -0
- package/dist/migrations/005_composite-baileys-chat-ids.js.map +1 -0
- package/dist/migrations/migration.model.d.ts +18 -0
- package/dist/migrations/migration.model.js +45 -0
- package/dist/migrations/migration.model.js.map +1 -0
- package/dist/migrations/migration.routes.d.ts +2 -0
- package/dist/migrations/migration.routes.js +37 -0
- package/dist/migrations/migration.routes.js.map +1 -0
- package/dist/migrations/migration.runner.d.ts +19 -0
- package/dist/migrations/migration.runner.js +74 -0
- package/dist/migrations/migration.runner.js.map +1 -0
- package/dist/models/ConversationClaim.d.ts +13 -0
- package/dist/models/ConversationClaim.js +44 -0
- package/dist/models/ConversationClaim.js.map +1 -0
- package/dist/models/ConversationEvaluation.d.ts +23 -0
- package/dist/models/ConversationEvaluation.js +92 -0
- package/dist/models/ConversationEvaluation.js.map +1 -0
- package/dist/models/Summary.d.ts +37 -0
- package/dist/models/Summary.js +78 -0
- package/dist/models/Summary.js.map +1 -0
- package/dist/models/Transcription.d.ts +34 -0
- package/dist/models/Transcription.js +71 -0
- package/dist/models/Transcription.js.map +1 -0
- package/dist/models/WhatsAppRecipient.d.ts +23 -0
- package/dist/models/WhatsAppRecipient.js +53 -0
- package/dist/models/WhatsAppRecipient.js.map +1 -0
- package/dist/modules/admin/admin.routes.d.ts +2 -0
- package/dist/modules/admin/admin.routes.js +1966 -0
- package/dist/modules/admin/admin.routes.js.map +1 -0
- package/dist/modules/admin/elevenlabs-test-chat.routes.d.ts +2 -0
- package/dist/modules/admin/elevenlabs-test-chat.routes.js +158 -0
- package/dist/modules/admin/elevenlabs-test-chat.routes.js.map +1 -0
- package/dist/modules/admin/whatsapp-test-chat.routes.d.ts +2 -0
- package/dist/modules/admin/whatsapp-test-chat.routes.js +204 -0
- package/dist/modules/admin/whatsapp-test-chat.routes.js.map +1 -0
- package/dist/modules/agents/agent.model.d.ts +38 -0
- package/dist/modules/agents/agent.model.js +92 -0
- package/dist/modules/agents/agent.model.js.map +1 -0
- package/dist/modules/agents/agent.routes.d.ts +2 -0
- package/dist/modules/agents/agent.routes.js +61 -0
- package/dist/modules/agents/agent.routes.js.map +1 -0
- package/dist/modules/appointment-validation/appointment-validation.model.d.ts +76 -0
- package/dist/modules/appointment-validation/appointment-validation.model.js +118 -0
- package/dist/modules/appointment-validation/appointment-validation.model.js.map +1 -0
- package/dist/modules/appointment-validation/appointment-validation.routes.d.ts +2 -0
- package/dist/modules/appointment-validation/appointment-validation.routes.js +202 -0
- package/dist/modules/appointment-validation/appointment-validation.routes.js.map +1 -0
- package/dist/modules/appointment-validation/appointment-validation.service.d.ts +53 -0
- package/dist/modules/appointment-validation/appointment-validation.service.js +827 -0
- package/dist/modules/appointment-validation/appointment-validation.service.js.map +1 -0
- package/dist/modules/auth/auth.model.d.ts +17 -0
- package/dist/modules/auth/auth.model.js +64 -0
- package/dist/modules/auth/auth.model.js.map +1 -0
- package/dist/modules/auth/auth.routes.d.ts +2 -0
- package/dist/modules/auth/auth.routes.js +202 -0
- package/dist/modules/auth/auth.routes.js.map +1 -0
- package/dist/modules/auth/auth.service.d.ts +28 -0
- package/dist/modules/auth/auth.service.js +183 -0
- package/dist/modules/auth/auth.service.js.map +1 -0
- package/dist/modules/auth/refresh-token.model.d.ts +13 -0
- package/dist/modules/auth/refresh-token.model.js +52 -0
- package/dist/modules/auth/refresh-token.model.js.map +1 -0
- package/dist/modules/billing/billing-alert.model.d.ts +16 -0
- package/dist/modules/billing/billing-alert.model.js +47 -0
- package/dist/modules/billing/billing-alert.model.js.map +1 -0
- package/dist/modules/billing/billing-period-snapshot.model.d.ts +35 -0
- package/dist/modules/billing/billing-period-snapshot.model.js +68 -0
- package/dist/modules/billing/billing-period-snapshot.model.js.map +1 -0
- package/dist/modules/billing/billing.model.d.ts +18 -0
- package/dist/modules/billing/billing.model.js +62 -0
- package/dist/modules/billing/billing.model.js.map +1 -0
- package/dist/modules/billing/billing.routes.d.ts +2 -0
- package/dist/modules/billing/billing.routes.js +63 -0
- package/dist/modules/billing/billing.routes.js.map +1 -0
- package/dist/modules/billing/billing.service.d.ts +69 -0
- package/dist/modules/billing/billing.service.js +498 -0
- package/dist/modules/billing/billing.service.js.map +1 -0
- package/dist/modules/billing/payment.model.d.ts +24 -0
- package/dist/modules/billing/payment.model.js +57 -0
- package/dist/modules/billing/payment.model.js.map +1 -0
- package/dist/modules/calls/call.model.d.ts +41 -0
- package/dist/modules/calls/call.model.js +97 -0
- package/dist/modules/calls/call.model.js.map +1 -0
- package/dist/modules/calls/call.routes.d.ts +2 -0
- package/dist/modules/calls/call.routes.js +103 -0
- package/dist/modules/calls/call.routes.js.map +1 -0
- package/dist/modules/campaigns/campaign.model.d.ts +45 -0
- package/dist/modules/campaigns/campaign.model.js +98 -0
- package/dist/modules/campaigns/campaign.model.js.map +1 -0
- package/dist/modules/campaigns/campaign.routes.d.ts +2 -0
- package/dist/modules/campaigns/campaign.routes.js +323 -0
- package/dist/modules/campaigns/campaign.routes.js.map +1 -0
- package/dist/modules/campaigns/campaign.service.d.ts +11 -0
- package/dist/modules/campaigns/campaign.service.js +86 -0
- package/dist/modules/campaigns/campaign.service.js.map +1 -0
- package/dist/modules/google-calendar/google-calendar.routes.d.ts +2 -0
- package/dist/modules/google-calendar/google-calendar.routes.js +32 -0
- package/dist/modules/google-calendar/google-calendar.routes.js.map +1 -0
- package/dist/modules/inbound-call/inbound-call-config.model.d.ts +20 -0
- package/dist/modules/inbound-call/inbound-call-config.model.js +68 -0
- package/dist/modules/inbound-call/inbound-call-config.model.js.map +1 -0
- package/dist/modules/inbound-call/inbound-call.routes.d.ts +2 -0
- package/dist/modules/inbound-call/inbound-call.routes.js +243 -0
- package/dist/modules/inbound-call/inbound-call.routes.js.map +1 -0
- package/dist/modules/leads/lead.model.d.ts +24 -0
- package/dist/modules/leads/lead.model.js +54 -0
- package/dist/modules/leads/lead.model.js.map +1 -0
- package/dist/modules/leads/lead.routes.d.ts +2 -0
- package/dist/modules/leads/lead.routes.js +201 -0
- package/dist/modules/leads/lead.routes.js.map +1 -0
- package/dist/modules/plans/plan.model.d.ts +25 -0
- package/dist/modules/plans/plan.model.js +59 -0
- package/dist/modules/plans/plan.model.js.map +1 -0
- package/dist/modules/surveys/survey.model.d.ts +30 -0
- package/dist/modules/surveys/survey.model.js +75 -0
- package/dist/modules/surveys/survey.model.js.map +1 -0
- package/dist/modules/surveys/survey.routes.d.ts +2 -0
- package/dist/modules/surveys/survey.routes.js +153 -0
- package/dist/modules/surveys/survey.routes.js.map +1 -0
- package/dist/modules/tenants/tenant.model.d.ts +86 -0
- package/dist/modules/tenants/tenant.model.js +127 -0
- package/dist/modules/tenants/tenant.model.js.map +1 -0
- package/dist/modules/tenants/tenant.routes.d.ts +2 -0
- package/dist/modules/tenants/tenant.routes.js +65 -0
- package/dist/modules/tenants/tenant.routes.js.map +1 -0
- package/dist/modules/users/user.routes.d.ts +2 -0
- package/dist/modules/users/user.routes.js +106 -0
- package/dist/modules/users/user.routes.js.map +1 -0
- package/dist/modules/webhooks/elevenlabs-tool.routes.d.ts +20 -0
- package/dist/modules/webhooks/elevenlabs-tool.routes.js +85 -0
- package/dist/modules/webhooks/elevenlabs-tool.routes.js.map +1 -0
- package/dist/modules/webhooks/elevenlabs-tool.service.d.ts +11 -0
- package/dist/modules/webhooks/elevenlabs-tool.service.js +360 -0
- package/dist/modules/webhooks/elevenlabs-tool.service.js.map +1 -0
- package/dist/modules/webhooks/elevenlabs.routes.d.ts +2 -0
- package/dist/modules/webhooks/elevenlabs.routes.js +34 -0
- package/dist/modules/webhooks/elevenlabs.routes.js.map +1 -0
- package/dist/modules/webhooks/elevenlabs.service.d.ts +6 -0
- package/dist/modules/webhooks/elevenlabs.service.js +512 -0
- package/dist/modules/webhooks/elevenlabs.service.js.map +1 -0
- package/dist/modules/webhooks/unipile.routes.d.ts +2 -0
- package/dist/modules/webhooks/unipile.routes.js +780 -0
- package/dist/modules/webhooks/unipile.routes.js.map +1 -0
- package/dist/modules/whatsapp/appointment.model.d.ts +27 -0
- package/dist/modules/whatsapp/appointment.model.js +58 -0
- package/dist/modules/whatsapp/appointment.model.js.map +1 -0
- package/dist/modules/whatsapp/operator-request.model.d.ts +29 -0
- package/dist/modules/whatsapp/operator-request.model.js +65 -0
- package/dist/modules/whatsapp/operator-request.model.js.map +1 -0
- package/dist/modules/whatsapp/stt-usage.model.d.ts +16 -0
- package/dist/modules/whatsapp/stt-usage.model.js +53 -0
- package/dist/modules/whatsapp/stt-usage.model.js.map +1 -0
- package/dist/modules/whatsapp/whatsapp-chat.model.d.ts +23 -0
- package/dist/modules/whatsapp/whatsapp-chat.model.js +55 -0
- package/dist/modules/whatsapp/whatsapp-chat.model.js.map +1 -0
- package/dist/modules/whatsapp/whatsapp-contact-profile.model.d.ts +23 -0
- package/dist/modules/whatsapp/whatsapp-contact-profile.model.js +54 -0
- package/dist/modules/whatsapp/whatsapp-contact-profile.model.js.map +1 -0
- package/dist/modules/whatsapp/whatsapp-message.model.d.ts +30 -0
- package/dist/modules/whatsapp/whatsapp-message.model.js +52 -0
- package/dist/modules/whatsapp/whatsapp-message.model.js.map +1 -0
- package/dist/modules/whatsapp/whatsapp-session.model.d.ts +33 -0
- package/dist/modules/whatsapp/whatsapp-session.model.js +65 -0
- package/dist/modules/whatsapp/whatsapp-session.model.js.map +1 -0
- package/dist/modules/whatsapp/whatsapp.routes.d.ts +2 -0
- package/dist/modules/whatsapp/whatsapp.routes.js +1237 -0
- package/dist/modules/whatsapp/whatsapp.routes.js.map +1 -0
- package/dist/plugins/cors.d.ts +3 -0
- package/dist/plugins/cors.js +11 -0
- package/dist/plugins/cors.js.map +1 -0
- package/dist/plugins/jwt.d.ts +3 -0
- package/dist/plugins/jwt.js +22 -0
- package/dist/plugins/jwt.js.map +1 -0
- package/dist/plugins/rawBody.d.ts +3 -0
- package/dist/plugins/rawBody.js +16 -0
- package/dist/plugins/rawBody.js.map +1 -0
- package/dist/plugins/rbac.d.ts +5 -0
- package/dist/plugins/rbac.js +29 -0
- package/dist/plugins/rbac.js.map +1 -0
- package/dist/routes/admin.routes.d.ts +2 -0
- package/dist/routes/admin.routes.js +169 -0
- package/dist/routes/admin.routes.js.map +1 -0
- package/dist/routes/health.routes.d.ts +2 -0
- package/dist/routes/health.routes.js +16 -0
- package/dist/routes/health.routes.js.map +1 -0
- package/dist/routes/webhook.routes.d.ts +2 -0
- package/dist/routes/webhook.routes.js +17 -0
- package/dist/routes/webhook.routes.js.map +1 -0
- package/dist/services/ai/base.ai.d.ts +19 -0
- package/dist/services/ai/base.ai.js +120 -0
- package/dist/services/ai/base.ai.js.map +1 -0
- package/dist/services/ai/gemini.service.d.ts +11 -0
- package/dist/services/ai/gemini.service.js +43 -0
- package/dist/services/ai/gemini.service.js.map +1 -0
- package/dist/services/ai/index.d.ts +2 -0
- package/dist/services/ai/index.js +26 -0
- package/dist/services/ai/index.js.map +1 -0
- package/dist/services/ai/openai.service.d.ts +11 -0
- package/dist/services/ai/openai.service.js +50 -0
- package/dist/services/ai/openai.service.js.map +1 -0
- package/dist/services/elevenlabs.service.d.ts +52 -0
- package/dist/services/elevenlabs.service.js +447 -0
- package/dist/services/elevenlabs.service.js.map +1 -0
- package/dist/services/google-calendar.service.d.ts +60 -0
- package/dist/services/google-calendar.service.js +494 -0
- package/dist/services/google-calendar.service.js.map +1 -0
- package/dist/services/inbound-call-schedule.service.d.ts +11 -0
- package/dist/services/inbound-call-schedule.service.js +162 -0
- package/dist/services/inbound-call-schedule.service.js.map +1 -0
- package/dist/services/netgsm.service.d.ts +41 -0
- package/dist/services/netgsm.service.js +89 -0
- package/dist/services/netgsm.service.js.map +1 -0
- package/dist/services/unipile.service.d.ts +41 -0
- package/dist/services/unipile.service.js +149 -0
- package/dist/services/unipile.service.js.map +1 -0
- package/dist/services/whatsapp-agent.service.d.ts +139 -0
- package/dist/services/whatsapp-agent.service.js +2055 -0
- package/dist/services/whatsapp-agent.service.js.map +1 -0
- package/dist/services/whatsapp.service.d.ts +26 -0
- package/dist/services/whatsapp.service.js +206 -0
- package/dist/services/whatsapp.service.js.map +1 -0
- package/dist/templates/index.d.ts +39 -0
- package/dist/templates/index.js +35 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/templates/receptionist.d.ts +2 -0
- package/dist/templates/receptionist.js +39 -0
- package/dist/templates/receptionist.js.map +1 -0
- package/dist/templates/survey.d.ts +2 -0
- package/dist/templates/survey.js +41 -0
- package/dist/templates/survey.js.map +1 -0
- package/dist/types/index.d.ts +173 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/logger.d.ts +3 -0
- package/dist/utils/logger.js +105 -0
- package/dist/utils/logger.js.map +1 -0
- package/docker-compose.nestjs.yml +89 -0
- package/docker-compose.yml +78 -0
- package/docs/AI_AGENT_ENHANCEMENT_PLAN.md +164 -0
- package/docs/API.md +1193 -0
- package/docs/API_ENDPOINTS.md +344 -0
- package/docs/ARCHITECTURE.md +305 -0
- package/docs/AUTH_API.md +252 -0
- package/docs/BILLING_SMS_ALERTS.md +94 -0
- package/docs/CHAT_ASSIGNMENT_SYSTEM.md +118 -0
- package/docs/CLIENT_TOOLS_AND_FEATURES.md +337 -0
- package/docs/ELEVENLABS_WEBHOOK_TOOLS.md +644 -0
- package/docs/FRONTEND_CHECKLIST.md +227 -0
- package/docs/IMPLEMENTATION_STATUS.md +470 -0
- package/docs/MIGRATION_GUIDE.md +96 -0
- package/docs/MISSINGS_REPORT.md +507 -0
- package/docs/NESTJS_MIGRATION_REFERENCE.md +5136 -0
- package/docs/PROJECT_DESCRIPTION.md +1038 -0
- package/docs/SCALING.md +148 -0
- package/docs/SESSION_SUMMARY_2026_03_17.md +135 -0
- package/docs/WHATSAPP_AGENT.md +1086 -0
- package/docs/architecture/00-SYSTEM-OVERVIEW.md +318 -0
- package/docs/architecture/01-DATABASE-SCHEMA.md +2564 -0
- package/docs/architecture/02-AUTHENTICATION.md +1040 -0
- package/docs/architecture/03-MULTI-CLINIC.md +742 -0
- package/docs/architecture/04-WHATSAPP-AGENT.md +608 -0
- package/docs/architecture/05-OPERATOR-WORKFLOW.md +444 -0
- package/docs/architecture/06-BAILEYS-MICROSERVICE.md +616 -0
- package/docs/architecture/07-APPOINTMENTS.md +849 -0
- package/docs/architecture/08-VOICE-CALLS.md +470 -0
- package/docs/architecture/09-OUTBOUND-CAMPAIGNS.md +542 -0
- package/docs/architecture/10-CLIENT-TOOLS.md +665 -0
- package/docs/architecture/11-BILLING.md +458 -0
- package/docs/architecture/12-SECURITY.md +216 -0
- package/docs/architecture/13-LOGGING-AUDIT.md +549 -0
- package/docs/architecture/14-META-BUSINESS-API.md +454 -0
- package/docs/architecture/15-AI-MODULE.md +479 -0
- package/docs/architecture/16-BACKGROUND-JOBS.md +469 -0
- package/docs/architecture/17-REALTIME-LIVECHAT.md +447 -0
- package/docs/architecture/18-FILE-STORAGE.md +410 -0
- package/docs/architecture/19-PATIENTS.md +1034 -0
- package/docs/architecture/20-TREATMENTS-AND-PLANS.md +774 -0
- package/docs/architecture/21-BEFORE-AFTER-PHOTOS.md +519 -0
- package/docs/database.md +456 -0
- package/docs/ornek-randevu-onay.csv +3 -0
- package/ecosystem.config.js +16 -0
- package/elevenlabs-convai-api-reference.md +1171 -0
- package/frontend/.dockerignore +2 -0
- package/frontend/Dockerfile +24 -0
- package/frontend/README.md +75 -0
- package/frontend/components.json +25 -0
- package/frontend/eslint.config.js +23 -0
- package/frontend/index.html +13 -0
- package/frontend/nginx.conf +37 -0
- package/frontend/package-lock.json +8709 -0
- package/frontend/package.json +71 -0
- package/frontend/public/favicon.svg +1 -0
- package/frontend/public/icons.svg +24 -0
- package/frontend/src/App.tsx +125 -0
- package/frontend/src/components/error-boundary.tsx +50 -0
- package/frontend/src/components/shared/activity-timeline.tsx +66 -0
- package/frontend/src/components/shared/appointment-calendar.css +80 -0
- package/frontend/src/components/shared/appointment-calendar.tsx +245 -0
- package/frontend/src/components/shared/chat-bubble.tsx +72 -0
- package/frontend/src/components/shared/combobox.tsx +119 -0
- package/frontend/src/components/shared/confirm-dialog.tsx +57 -0
- package/frontend/src/components/shared/data-table-pagination.tsx +97 -0
- package/frontend/src/components/shared/data-table-toolbar.tsx +39 -0
- package/frontend/src/components/shared/empty-state.tsx +27 -0
- package/frontend/src/components/shared/file-upload.tsx +140 -0
- package/frontend/src/components/shared/index.ts +20 -0
- package/frontend/src/components/shared/language-switcher.tsx +29 -0
- package/frontend/src/components/shared/notification-dropdown.tsx +115 -0
- package/frontend/src/components/shared/page-header.tsx +23 -0
- package/frontend/src/components/shared/stat-card.tsx +37 -0
- package/frontend/src/components/shared/status-badge.tsx +70 -0
- package/frontend/src/components/shared/status-dot.tsx +43 -0
- package/frontend/src/components/ui/alert-dialog.tsx +187 -0
- package/frontend/src/components/ui/alert.tsx +76 -0
- package/frontend/src/components/ui/avatar.tsx +109 -0
- package/frontend/src/components/ui/badge.tsx +52 -0
- package/frontend/src/components/ui/breadcrumb.tsx +125 -0
- package/frontend/src/components/ui/button.tsx +60 -0
- package/frontend/src/components/ui/calendar.tsx +219 -0
- package/frontend/src/components/ui/card.tsx +103 -0
- package/frontend/src/components/ui/chart.tsx +371 -0
- package/frontend/src/components/ui/checkbox.tsx +29 -0
- package/frontend/src/components/ui/collapsible.tsx +19 -0
- package/frontend/src/components/ui/command.tsx +194 -0
- package/frontend/src/components/ui/dialog.tsx +158 -0
- package/frontend/src/components/ui/dropdown-menu.tsx +268 -0
- package/frontend/src/components/ui/input-group.tsx +156 -0
- package/frontend/src/components/ui/input.tsx +20 -0
- package/frontend/src/components/ui/label.tsx +20 -0
- package/frontend/src/components/ui/pagination.tsx +130 -0
- package/frontend/src/components/ui/popover.tsx +90 -0
- package/frontend/src/components/ui/progress.tsx +83 -0
- package/frontend/src/components/ui/radio-group.tsx +36 -0
- package/frontend/src/components/ui/scroll-area.tsx +54 -0
- package/frontend/src/components/ui/select.tsx +199 -0
- package/frontend/src/components/ui/separator.tsx +23 -0
- package/frontend/src/components/ui/sheet.tsx +138 -0
- package/frontend/src/components/ui/sidebar.tsx +723 -0
- package/frontend/src/components/ui/skeleton.tsx +13 -0
- package/frontend/src/components/ui/sonner.tsx +47 -0
- package/frontend/src/components/ui/switch.tsx +30 -0
- package/frontend/src/components/ui/table.tsx +114 -0
- package/frontend/src/components/ui/tabs.tsx +82 -0
- package/frontend/src/components/ui/textarea.tsx +18 -0
- package/frontend/src/components/ui/toggle-group.tsx +89 -0
- package/frontend/src/components/ui/toggle.tsx +43 -0
- package/frontend/src/components/ui/tooltip.tsx +64 -0
- package/frontend/src/hooks/use-mobile.ts +19 -0
- package/frontend/src/i18n/index.ts +20 -0
- package/frontend/src/i18n/locales/en.json +786 -0
- package/frontend/src/i18n/locales/tr.json +786 -0
- package/frontend/src/index.css +134 -0
- package/frontend/src/layouts/admin-layout.tsx +111 -0
- package/frontend/src/layouts/app-header.tsx +130 -0
- package/frontend/src/layouts/app-layout.tsx +19 -0
- package/frontend/src/layouts/app-sidebar.tsx +212 -0
- package/frontend/src/layouts/auth-guard.tsx +31 -0
- package/frontend/src/layouts/mobile-sidebar.tsx +120 -0
- package/frontend/src/lib/api.ts +68 -0
- package/frontend/src/lib/hooks/use-appointments.ts +224 -0
- package/frontend/src/lib/hooks/use-availability-blocks.ts +83 -0
- package/frontend/src/lib/hooks/use-chats.ts +236 -0
- package/frontend/src/lib/hooks/use-clinic-detail.ts +171 -0
- package/frontend/src/lib/hooks/use-clinics.ts +37 -0
- package/frontend/src/lib/hooks/use-doctor-calendar.ts +80 -0
- package/frontend/src/lib/hooks/use-examinations.ts +89 -0
- package/frontend/src/lib/hooks/use-medical-history.ts +52 -0
- package/frontend/src/lib/hooks/use-patients.ts +296 -0
- package/frontend/src/lib/hooks/use-photo-sets.ts +118 -0
- package/frontend/src/lib/hooks/use-treatment-plans.ts +152 -0
- package/frontend/src/lib/hooks/use-treatments.ts +125 -0
- package/frontend/src/lib/hooks/use-users.ts +172 -0
- package/frontend/src/lib/utils.ts +6 -0
- package/frontend/src/main.tsx +17 -0
- package/frontend/src/pages/admin/agents/detail.tsx +774 -0
- package/frontend/src/pages/admin/agents/import.tsx +280 -0
- package/frontend/src/pages/admin/agents/index.tsx +245 -0
- package/frontend/src/pages/admin/ai-playground.tsx +543 -0
- package/frontend/src/pages/appointments/create-appointment-dialog.tsx +390 -0
- package/frontend/src/pages/appointments/index.tsx +860 -0
- package/frontend/src/pages/audit/index.tsx +24 -0
- package/frontend/src/pages/auth/login.tsx +194 -0
- package/frontend/src/pages/billing/index.tsx +24 -0
- package/frontend/src/pages/calendar/index.tsx +704 -0
- package/frontend/src/pages/calendar-connections/index.tsx +295 -0
- package/frontend/src/pages/calls/index.tsx +24 -0
- package/frontend/src/pages/campaigns/index.tsx +24 -0
- package/frontend/src/pages/chats/index.tsx +981 -0
- package/frontend/src/pages/clinics/index.tsx +224 -0
- package/frontend/src/pages/clinics/settings.tsx +412 -0
- package/frontend/src/pages/components-showcase.tsx +773 -0
- package/frontend/src/pages/connections/index.tsx +328 -0
- package/frontend/src/pages/dashboard.tsx +50 -0
- package/frontend/src/pages/leads/index.tsx +24 -0
- package/frontend/src/pages/my-schedule/index.tsx +496 -0
- package/frontend/src/pages/patients/create-patient-dialog.tsx +358 -0
- package/frontend/src/pages/patients/detail.tsx +1195 -0
- package/frontend/src/pages/patients/edit-patient-dialog.tsx +387 -0
- package/frontend/src/pages/patients/examinations-tab.tsx +460 -0
- package/frontend/src/pages/patients/index.tsx +381 -0
- package/frontend/src/pages/patients/medical-history-dialog.tsx +207 -0
- package/frontend/src/pages/patients/photo-sets-tab.tsx +616 -0
- package/frontend/src/pages/patients/timeline-tab.tsx +164 -0
- package/frontend/src/pages/patients/treatment-plans-tab.tsx +598 -0
- package/frontend/src/pages/phone-numbers/detail.tsx +427 -0
- package/frontend/src/pages/phone-numbers/index.tsx +455 -0
- package/frontend/src/pages/platform/index.tsx +454 -0
- package/frontend/src/pages/settings/index.tsx +126 -0
- package/frontend/src/pages/treatments/index.tsx +487 -0
- package/frontend/src/pages/users/doctor-profile.tsx +672 -0
- package/frontend/src/pages/users/edit.tsx +329 -0
- package/frontend/src/pages/users/index.tsx +407 -0
- package/frontend/src/pages/validation/index.tsx +24 -0
- package/frontend/src/stores/auth.store.ts +108 -0
- package/frontend/src/stores/ui.store.ts +41 -0
- package/frontend/tsconfig.app.json +32 -0
- package/frontend/tsconfig.json +13 -0
- package/frontend/tsconfig.node.json +26 -0
- package/frontend/vite.config.ts +29 -0
- package/nestjs/.dockerignore +5 -0
- package/nestjs/.env.docker +64 -0
- package/nestjs/.prettierrc +4 -0
- package/nestjs/Dockerfile +36 -0
- package/nestjs/README.md +98 -0
- package/nestjs/eslint.config.mjs +35 -0
- package/nestjs/nest-cli.json +8 -0
- package/nestjs/package-lock.json +13390 -0
- package/nestjs/package.json +114 -0
- package/nestjs/prisma/migrations/20260409161536_add_message_metadata_fields/migration.sql +1746 -0
- package/nestjs/prisma/migrations/20260410140436_add_agent_ai_fields/migration.sql +36 -0
- package/nestjs/prisma/migrations/20260410175519_add_agent_clinic_assignments/migration.sql +21 -0
- package/nestjs/prisma/migrations/20260412094344_make_agent_tenant_optional/migration.sql +2 -0
- package/nestjs/prisma/migrations/20260412110008_add_admin_chat_sessions/migration.sql +47 -0
- package/nestjs/prisma/migrations/migration_lock.toml +3 -0
- package/nestjs/prisma/schema.prisma +1843 -0
- package/nestjs/prisma/seed.ts +375 -0
- package/nestjs/prisma.config.ts +14 -0
- package/nestjs/src/admin/admin.controller.ts +27 -0
- package/nestjs/src/admin/admin.module.ts +16 -0
- package/nestjs/src/admin/admin.service.ts +91 -0
- package/nestjs/src/admin/ai-chat-session.service.ts +454 -0
- package/nestjs/src/admin/ai-test.controller.ts +191 -0
- package/nestjs/src/admin/superadmin.controller.ts +106 -0
- package/nestjs/src/agents/agents.controller.ts +262 -0
- package/nestjs/src/agents/agents.module.ts +13 -0
- package/nestjs/src/agents/agents.service.ts +733 -0
- package/nestjs/src/agents/dto/create-agent.dto.ts +99 -0
- package/nestjs/src/agents/dto/index.ts +2 -0
- package/nestjs/src/agents/dto/update-agent.dto.ts +148 -0
- package/nestjs/src/app.module.ts +115 -0
- package/nestjs/src/appointment-validation/appointment-validation.controller.ts +194 -0
- package/nestjs/src/appointment-validation/appointment-validation.module.ts +16 -0
- package/nestjs/src/appointment-validation/appointment-validation.service.ts +450 -0
- package/nestjs/src/appointment-validation/dto/create-batch.dto.ts +105 -0
- package/nestjs/src/appointment-validation/dto/index.ts +1 -0
- package/nestjs/src/appointment-validation/processors/validation-dispatch.processor.ts +26 -0
- package/nestjs/src/appointment-validation/processors/validation-sync.processor.ts +23 -0
- package/nestjs/src/appointments/appointments.controller.ts +268 -0
- package/nestjs/src/appointments/appointments.module.ts +13 -0
- package/nestjs/src/appointments/appointments.service.ts +773 -0
- package/nestjs/src/appointments/dto/create-appointment.dto.ts +72 -0
- package/nestjs/src/appointments/dto/index.ts +4 -0
- package/nestjs/src/appointments/dto/query-appointments.dto.ts +60 -0
- package/nestjs/src/appointments/dto/update-appointment.dto.ts +43 -0
- package/nestjs/src/appointments/dto/update-status.dto.ts +18 -0
- package/nestjs/src/appointments/processors/reminder.processor.ts +243 -0
- package/nestjs/src/audit/audit.controller.ts +84 -0
- package/nestjs/src/audit/audit.decorator.ts +20 -0
- package/nestjs/src/audit/audit.interceptor.ts +67 -0
- package/nestjs/src/audit/audit.interfaces.ts +15 -0
- package/nestjs/src/audit/audit.module.ts +12 -0
- package/nestjs/src/audit/audit.service.ts +177 -0
- package/nestjs/src/auth/auth.controller.ts +116 -0
- package/nestjs/src/auth/auth.module.ts +25 -0
- package/nestjs/src/auth/auth.service.ts +612 -0
- package/nestjs/src/auth/dto/change-password.dto.ts +13 -0
- package/nestjs/src/auth/dto/forgot-password.dto.ts +8 -0
- package/nestjs/src/auth/dto/index.ts +6 -0
- package/nestjs/src/auth/dto/login.dto.ts +13 -0
- package/nestjs/src/auth/dto/refresh.dto.ts +8 -0
- package/nestjs/src/auth/dto/register.dto.ts +28 -0
- package/nestjs/src/auth/dto/reset-password.dto.ts +13 -0
- package/nestjs/src/auth/permissions.config.ts +85 -0
- package/nestjs/src/availability-blocks/availability-blocks.controller.ts +83 -0
- package/nestjs/src/availability-blocks/availability-blocks.module.ts +10 -0
- package/nestjs/src/availability-blocks/availability-blocks.service.ts +202 -0
- package/nestjs/src/billing/billing.controller.ts +104 -0
- package/nestjs/src/billing/billing.module.ts +12 -0
- package/nestjs/src/billing/billing.service.ts +398 -0
- package/nestjs/src/billing/dto/index.ts +2 -0
- package/nestjs/src/billing/dto/query-billing.dto.ts +29 -0
- package/nestjs/src/billing/dto/record-payment.dto.ts +60 -0
- package/nestjs/src/billing/processors/alerts.processor.ts +216 -0
- package/nestjs/src/billing/processors/snapshot.processor.ts +181 -0
- package/nestjs/src/calls/calls.controller.ts +92 -0
- package/nestjs/src/calls/calls.module.ts +10 -0
- package/nestjs/src/calls/calls.service.ts +359 -0
- package/nestjs/src/calls/dto/index.ts +1 -0
- package/nestjs/src/calls/dto/query-calls.dto.ts +46 -0
- package/nestjs/src/clinics/clinics.controller.ts +226 -0
- package/nestjs/src/clinics/clinics.module.ts +11 -0
- package/nestjs/src/clinics/clinics.service.ts +203 -0
- package/nestjs/src/clinics/dto/create-clinic.dto.ts +40 -0
- package/nestjs/src/clinics/dto/create-meta-connection.dto.ts +44 -0
- package/nestjs/src/clinics/dto/index.ts +4 -0
- package/nestjs/src/clinics/dto/update-clinic.dto.ts +133 -0
- package/nestjs/src/clinics/dto/update-meta-connection.dto.ts +22 -0
- package/nestjs/src/clinics/meta-connections.service.ts +210 -0
- package/nestjs/src/common/decorators/accessible-clinics.decorator.ts +9 -0
- package/nestjs/src/common/decorators/current-user.decorator.ts +10 -0
- package/nestjs/src/common/decorators/features.decorator.ts +7 -0
- package/nestjs/src/common/decorators/index.ts +4 -0
- package/nestjs/src/common/decorators/permissions.decorator.ts +13 -0
- package/nestjs/src/common/gateways/events.gateway.ts +157 -0
- package/nestjs/src/common/guards/clinic-access.guard.ts +40 -0
- package/nestjs/src/common/guards/features.guard.ts +38 -0
- package/nestjs/src/common/guards/index.ts +5 -0
- package/nestjs/src/common/guards/jwt-auth.guard.ts +54 -0
- package/nestjs/src/common/guards/permissions.guard.ts +50 -0
- package/nestjs/src/common/guards/superadmin.guard.ts +35 -0
- package/nestjs/src/common/interceptors/request-context.interceptor.ts +32 -0
- package/nestjs/src/common/interceptors/superadmin-tenant.interceptor.ts +42 -0
- package/nestjs/src/common/interfaces/jwt-payload.interface.ts +11 -0
- package/nestjs/src/config/config.module.ts +13 -0
- package/nestjs/src/database/database.module.ts +9 -0
- package/nestjs/src/database/prisma.service.ts +20 -0
- package/nestjs/src/database/tenant-context.ts +27 -0
- package/nestjs/src/google-calendar/google-calendar.controller.ts +259 -0
- package/nestjs/src/google-calendar/google-calendar.module.ts +10 -0
- package/nestjs/src/google-calendar/google-calendar.service.ts +811 -0
- package/nestjs/src/integrations/ai/ai.interface.ts +74 -0
- package/nestjs/src/integrations/ai/ai.module.ts +11 -0
- package/nestjs/src/integrations/ai/ai.service.ts +148 -0
- package/nestjs/src/integrations/ai/providers/anthropic.provider.ts +146 -0
- package/nestjs/src/integrations/ai/providers/openai.provider.ts +158 -0
- package/nestjs/src/integrations/elevenlabs/elevenlabs.module.ts +8 -0
- package/nestjs/src/integrations/elevenlabs/elevenlabs.service.ts +226 -0
- package/nestjs/src/integrations/encryption/encryption.module.ts +9 -0
- package/nestjs/src/integrations/encryption/encryption.service.ts +31 -0
- package/nestjs/src/integrations/image/image.module.ts +9 -0
- package/nestjs/src/integrations/image/image.service.ts +61 -0
- package/nestjs/src/integrations/meta-business/meta-business.module.ts +10 -0
- package/nestjs/src/integrations/meta-business/meta-instagram.service.ts +94 -0
- package/nestjs/src/integrations/meta-business/meta-webhook.service.ts +52 -0
- package/nestjs/src/integrations/meta-business/meta-whatsapp.service.ts +254 -0
- package/nestjs/src/integrations/minio/minio.module.ts +9 -0
- package/nestjs/src/integrations/minio/minio.service.ts +88 -0
- package/nestjs/src/integrations/netgsm/netgsm.module.ts +8 -0
- package/nestjs/src/integrations/netgsm/netgsm.service.ts +17 -0
- package/nestjs/src/integrations/tektippay/tektippay.module.ts +8 -0
- package/nestjs/src/integrations/tektippay/tektippay.service.ts +23 -0
- package/nestjs/src/leads/dto/index.ts +2 -0
- package/nestjs/src/leads/dto/query-leads.dto.ts +50 -0
- package/nestjs/src/leads/dto/update-lead.dto.ts +26 -0
- package/nestjs/src/leads/leads.controller.ts +184 -0
- package/nestjs/src/leads/leads.module.ts +10 -0
- package/nestjs/src/leads/leads.service.ts +375 -0
- package/nestjs/src/logging/logging.controller.ts +82 -0
- package/nestjs/src/logging/logging.module.ts +11 -0
- package/nestjs/src/logging/logging.service.ts +180 -0
- package/nestjs/src/main.ts +86 -0
- package/nestjs/src/outbound-campaigns/dto/create-campaign.dto.ts +47 -0
- package/nestjs/src/outbound-campaigns/dto/index.ts +3 -0
- package/nestjs/src/outbound-campaigns/dto/update-campaign.dto.ts +31 -0
- package/nestjs/src/outbound-campaigns/dto/upload-entries.dto.ts +35 -0
- package/nestjs/src/outbound-campaigns/outbound-campaigns.controller.ts +307 -0
- package/nestjs/src/outbound-campaigns/outbound-campaigns.module.ts +13 -0
- package/nestjs/src/outbound-campaigns/outbound-campaigns.service.ts +471 -0
- package/nestjs/src/outbound-campaigns/processors/campaign-dispatch.processor.ts +366 -0
- package/nestjs/src/patients/documents.service.ts +231 -0
- package/nestjs/src/patients/dto/create-examination.dto.ts +34 -0
- package/nestjs/src/patients/dto/create-note.dto.ts +14 -0
- package/nestjs/src/patients/dto/create-patient.dto.ts +86 -0
- package/nestjs/src/patients/dto/create-photo-set.dto.ts +32 -0
- package/nestjs/src/patients/dto/index.ts +10 -0
- package/nestjs/src/patients/dto/update-examination.dto.ts +29 -0
- package/nestjs/src/patients/dto/update-medical-history.dto.ts +47 -0
- package/nestjs/src/patients/dto/update-patient.dto.ts +87 -0
- package/nestjs/src/patients/dto/update-photo-set.dto.ts +28 -0
- package/nestjs/src/patients/dto/upload-document.dto.ts +31 -0
- package/nestjs/src/patients/dto/upload-photo.dto.ts +27 -0
- package/nestjs/src/patients/examinations.service.ts +271 -0
- package/nestjs/src/patients/medical-history.service.ts +149 -0
- package/nestjs/src/patients/notes.service.ts +172 -0
- package/nestjs/src/patients/patients.controller.ts +485 -0
- package/nestjs/src/patients/patients.module.ts +22 -0
- package/nestjs/src/patients/patients.service.ts +412 -0
- package/nestjs/src/patients/photo-sets.service.ts +389 -0
- package/nestjs/src/phone-numbers/dto/create-phone-number.dto.ts +57 -0
- package/nestjs/src/phone-numbers/dto/index.ts +3 -0
- package/nestjs/src/phone-numbers/dto/update-phone-number.dto.ts +38 -0
- package/nestjs/src/phone-numbers/dto/update-schedule.dto.ts +39 -0
- package/nestjs/src/phone-numbers/phone-numbers.controller.ts +125 -0
- package/nestjs/src/phone-numbers/phone-numbers.module.ts +10 -0
- package/nestjs/src/phone-numbers/phone-numbers.service.ts +209 -0
- package/nestjs/src/plans/dto/create-plan.dto.ts +70 -0
- package/nestjs/src/plans/dto/index.ts +2 -0
- package/nestjs/src/plans/dto/update-plan.dto.ts +80 -0
- package/nestjs/src/plans/plans.controller.ts +50 -0
- package/nestjs/src/plans/plans.module.ts +10 -0
- package/nestjs/src/plans/plans.service.ts +115 -0
- package/nestjs/src/platform/dto/create-tenant.dto.ts +36 -0
- package/nestjs/src/platform/dto/index.ts +2 -0
- package/nestjs/src/platform/dto/update-tenant-platform.dto.ts +44 -0
- package/nestjs/src/platform/platform.controller.ts +79 -0
- package/nestjs/src/platform/platform.module.ts +10 -0
- package/nestjs/src/platform/platform.service.ts +301 -0
- package/nestjs/src/queue/queue.module.ts +56 -0
- package/nestjs/src/redis/redis.module.ts +20 -0
- package/nestjs/src/tenants/dto/index.ts +1 -0
- package/nestjs/src/tenants/dto/update-tenant.dto.ts +15 -0
- package/nestjs/src/tenants/tenants.controller.ts +45 -0
- package/nestjs/src/tenants/tenants.module.ts +10 -0
- package/nestjs/src/tenants/tenants.service.ts +41 -0
- package/nestjs/src/tools/adapters/elevenlabs-http.adapter.ts +51 -0
- package/nestjs/src/tools/adapters/elevenlabs-ws.adapter.ts +59 -0
- package/nestjs/src/tools/handlers/calendar.tools.ts +441 -0
- package/nestjs/src/tools/handlers/notification.tools.ts +34 -0
- package/nestjs/src/tools/handlers/operator.tools.ts +303 -0
- package/nestjs/src/tools/handlers/patient.tools.ts +242 -0
- package/nestjs/src/tools/handlers/payment.tools.ts +43 -0
- package/nestjs/src/tools/handlers/validation.tools.ts +152 -0
- package/nestjs/src/tools/tool-registry.service.ts +221 -0
- package/nestjs/src/tools/tool.decorator.ts +16 -0
- package/nestjs/src/tools/tool.interfaces.ts +26 -0
- package/nestjs/src/tools/tools.module.ts +50 -0
- package/nestjs/src/treatments/dto/create-plan-item.dto.ts +27 -0
- package/nestjs/src/treatments/dto/create-treatment-plan.dto.ts +69 -0
- package/nestjs/src/treatments/dto/create-treatment.dto.ts +59 -0
- package/nestjs/src/treatments/dto/index.ts +6 -0
- package/nestjs/src/treatments/dto/update-plan-item.dto.ts +23 -0
- package/nestjs/src/treatments/dto/update-treatment-plan.dto.ts +22 -0
- package/nestjs/src/treatments/dto/update-treatment.dto.ts +70 -0
- package/nestjs/src/treatments/treatment-plans.service.ts +362 -0
- package/nestjs/src/treatments/treatments.controller.ts +265 -0
- package/nestjs/src/treatments/treatments.module.ts +14 -0
- package/nestjs/src/treatments/treatments.service.ts +165 -0
- package/nestjs/src/users/doctor-profiles.service.ts +202 -0
- package/nestjs/src/users/dto/index.ts +4 -0
- package/nestjs/src/users/dto/invite-user.dto.ts +52 -0
- package/nestjs/src/users/dto/update-clinic-assignments.dto.ts +9 -0
- package/nestjs/src/users/dto/update-doctor-profile.dto.ts +49 -0
- package/nestjs/src/users/dto/update-user.dto.ts +41 -0
- package/nestjs/src/users/users.controller.ts +142 -0
- package/nestjs/src/users/users.module.ts +11 -0
- package/nestjs/src/users/users.service.ts +250 -0
- package/nestjs/src/webhooks/elevenlabs-tool.controller.ts +66 -0
- package/nestjs/src/webhooks/elevenlabs-webhook.controller.ts +60 -0
- package/nestjs/src/webhooks/meta-webhook.controller.ts +178 -0
- package/nestjs/src/webhooks/processors/elevenlabs-webhook.processor.ts +28 -0
- package/nestjs/src/webhooks/webhooks.module.ts +17 -0
- package/nestjs/src/whatsapp/chat-context.service.ts +281 -0
- package/nestjs/src/whatsapp/dto/add-blacklist.dto.ts +13 -0
- package/nestjs/src/whatsapp/dto/index.ts +2 -0
- package/nestjs/src/whatsapp/dto/send-message.dto.ts +14 -0
- package/nestjs/src/whatsapp/listeners/meta-message.listener.ts +579 -0
- package/nestjs/src/whatsapp/meta-auth.controller.ts +268 -0
- package/nestjs/src/whatsapp/meta-instagram-auth.controller.ts +244 -0
- package/nestjs/src/whatsapp/operator.service.ts +692 -0
- package/nestjs/src/whatsapp/processors/cost-sweep.processor.ts +130 -0
- package/nestjs/src/whatsapp/processors/grace.processor.ts +191 -0
- package/nestjs/src/whatsapp/processors/message-buffer.processor.ts +138 -0
- package/nestjs/src/whatsapp/processors/message-cleanup.processor.ts +148 -0
- package/nestjs/src/whatsapp/processors/meta-token-refresh.processor.ts +114 -0
- package/nestjs/src/whatsapp/processors/operator-expiry.processor.ts +105 -0
- package/nestjs/src/whatsapp/processors/profile-update.processor.ts +234 -0
- package/nestjs/src/whatsapp/processors/session-cleanup.processor.ts +178 -0
- package/nestjs/src/whatsapp/processors/session-labels.processor.ts +248 -0
- package/nestjs/src/whatsapp/whatsapp-agent.service.ts +2506 -0
- package/nestjs/src/whatsapp/whatsapp-recovery.service.ts +117 -0
- package/nestjs/src/whatsapp/whatsapp.controller.ts +398 -0
- package/nestjs/src/whatsapp/whatsapp.module.ts +51 -0
- package/nestjs/src/whatsapp/whatsapp.service.ts +592 -0
- package/nestjs/test/app.e2e-spec.ts +25 -0
- package/nestjs/test/jest-e2e.json +9 -0
- package/nestjs/tsconfig.build.json +4 -0
- package/nestjs/tsconfig.json +25 -0
- package/nginx.example.conf +18 -0
- package/package.json +47 -0
- package/scripts/addRecipient.ts +48 -0
- package/scripts/listRecipients.ts +31 -0
- package/scripts/migrate-agent-ref.ts +86 -0
- package/scripts/migrate-sessions.ts +183 -0
- package/scripts/promote.ts +27 -0
- package/scripts/retrigger.ts +84 -0
- package/scripts/seed.ts +435 -0
- package/scripts/testSend.ts +63 -0
- package/src/app.ts +85 -0
- package/src/config/agentPrompts.json +19 -0
- package/src/config/database.ts +21 -0
- package/src/config/env.ts +94 -0
- package/src/config/index.ts +86 -0
- package/src/controllers/webhook.controller.ts +150 -0
- package/src/errors/index.ts +9 -0
- package/src/hooks/webhookValidator.ts +55 -0
- package/src/index.ts +68 -0
- package/src/migrations/001_session-architecture.ts +138 -0
- package/src/migrations/002_agent-ref.ts +65 -0
- package/src/migrations/003_shift-schedule.ts +55 -0
- package/src/migrations/004_invert-shift-to-clinic-hours.ts +30 -0
- package/src/migrations/005_composite-baileys-chat-ids.ts +60 -0
- package/src/migrations/migration.model.ts +27 -0
- package/src/migrations/migration.routes.ts +40 -0
- package/src/migrations/migration.runner.ts +112 -0
- package/src/models/ConversationClaim.ts +17 -0
- package/src/models/ConversationEvaluation.ts +91 -0
- package/src/models/Summary.ts +77 -0
- package/src/models/Transcription.ts +68 -0
- package/src/models/WhatsAppRecipient.ts +37 -0
- package/src/modules/admin/admin.routes.ts +2385 -0
- package/src/modules/admin/elevenlabs-test-chat.routes.ts +193 -0
- package/src/modules/admin/whatsapp-test-chat.routes.ts +244 -0
- package/src/modules/agents/agent.model.ts +93 -0
- package/src/modules/agents/agent.routes.ts +65 -0
- package/src/modules/appointment-validation/appointment-validation.model.ts +163 -0
- package/src/modules/appointment-validation/appointment-validation.routes.ts +275 -0
- package/src/modules/appointment-validation/appointment-validation.service.ts +1028 -0
- package/src/modules/auth/auth.model.ts +42 -0
- package/src/modules/auth/auth.routes.ts +199 -0
- package/src/modules/auth/auth.service.ts +210 -0
- package/src/modules/auth/refresh-token.model.ts +26 -0
- package/src/modules/billing/billing-alert.model.ts +28 -0
- package/src/modules/billing/billing-period-snapshot.model.ts +68 -0
- package/src/modules/billing/billing.model.ts +42 -0
- package/src/modules/billing/billing.routes.ts +67 -0
- package/src/modules/billing/billing.service.ts +562 -0
- package/src/modules/billing/payment.model.ts +42 -0
- package/src/modules/calls/call.model.ts +102 -0
- package/src/modules/calls/call.routes.ts +118 -0
- package/src/modules/campaigns/campaign.model.ts +111 -0
- package/src/modules/campaigns/campaign.routes.ts +402 -0
- package/src/modules/campaigns/campaign.service.ts +99 -0
- package/src/modules/google-calendar/google-calendar.routes.ts +31 -0
- package/src/modules/inbound-call/inbound-call-config.model.ts +49 -0
- package/src/modules/inbound-call/inbound-call.routes.ts +289 -0
- package/src/modules/leads/lead.model.ts +40 -0
- package/src/modules/leads/lead.routes.ts +246 -0
- package/src/modules/logs/log.model.ts +27 -0
- package/src/modules/logs/log.routes.ts +102 -0
- package/src/modules/plans/plan.model.ts +45 -0
- package/src/modules/surveys/survey.model.ts +70 -0
- package/src/modules/surveys/survey.routes.ts +187 -0
- package/src/modules/tenants/tenant.model.ts +181 -0
- package/src/modules/tenants/tenant.routes.ts +78 -0
- package/src/modules/users/user.routes.ts +126 -0
- package/src/modules/webhooks/elevenlabs-tool.routes.ts +94 -0
- package/src/modules/webhooks/elevenlabs-tool.service.ts +491 -0
- package/src/modules/webhooks/elevenlabs.routes.ts +34 -0
- package/src/modules/webhooks/elevenlabs.service.ts +565 -0
- package/src/modules/webhooks/unipile.routes.ts +917 -0
- package/src/modules/whatsapp/appointment.model.ts +47 -0
- package/src/modules/whatsapp/operator-request.model.ts +58 -0
- package/src/modules/whatsapp/stt-usage.model.ts +30 -0
- package/src/modules/whatsapp/whatsapp-chat.model.ts +39 -0
- package/src/modules/whatsapp/whatsapp-contact-profile.model.ts +41 -0
- package/src/modules/whatsapp/whatsapp-message.model.ts +41 -0
- package/src/modules/whatsapp/whatsapp-session.model.ts +60 -0
- package/src/modules/whatsapp/whatsapp.routes.ts +1435 -0
- package/src/plugins/cors.ts +7 -0
- package/src/plugins/jwt.ts +18 -0
- package/src/plugins/rawBody.ts +12 -0
- package/src/plugins/rbac.ts +24 -0
- package/src/routes/admin.routes.ts +208 -0
- package/src/routes/health.routes.ts +12 -0
- package/src/routes/webhook.routes.ts +12 -0
- package/src/services/ai/base.ai.ts +132 -0
- package/src/services/ai/gemini.service.ts +41 -0
- package/src/services/ai/index.ts +24 -0
- package/src/services/ai/openai.service.ts +48 -0
- package/src/services/elevenlabs.service.ts +532 -0
- package/src/services/google-calendar.service.ts +656 -0
- package/src/services/inbound-call-schedule.service.ts +174 -0
- package/src/services/netgsm.service.ts +128 -0
- package/src/services/unipile.service.ts +200 -0
- package/src/services/whatsapp-agent.service.ts +2479 -0
- package/src/services/whatsapp.service.ts +245 -0
- package/src/templates/index.ts +71 -0
- package/src/templates/receptionist.ts +44 -0
- package/src/templates/survey.ts +44 -0
- package/src/types/index.ts +218 -0
- package/src/utils/logger.ts +83 -0
- package/tsconfig.json +19 -0
- package/web/.dockerignore +4 -0
- package/web/Dockerfile +18 -0
- package/web/README.md +73 -0
- package/web/components.json +23 -0
- package/web/eslint.config.js +23 -0
- package/web/index.html +14 -0
- package/web/nginx.conf +18 -0
- package/web/package-lock.json +10292 -0
- package/web/package.json +48 -0
- package/web/public/favicon.ico +0 -0
- package/web/public/vite.svg +1 -0
- package/web/src/App.tsx +191 -0
- package/web/src/assets/react.svg +1 -0
- package/web/src/components/Layout.tsx +261 -0
- package/web/src/components/LeadConversation.tsx +251 -0
- package/web/src/components/ProtectedRoute.tsx +20 -0
- package/web/src/components/conversation-review/CardAudioPlayer.tsx +200 -0
- package/web/src/components/conversation-review/CardEvaluation.tsx +351 -0
- package/web/src/components/conversation-review/CardMetadata.tsx +44 -0
- package/web/src/components/conversation-review/ConversationCard.tsx +95 -0
- package/web/src/components/conversation-review/ReviewContainer.tsx +120 -0
- package/web/src/components/conversation-review/ReviewFilters.tsx +88 -0
- package/web/src/components/empty-state.tsx +15 -0
- package/web/src/components/page-header.tsx +19 -0
- package/web/src/components/page-loader.tsx +32 -0
- package/web/src/components/pagination.tsx +38 -0
- package/web/src/components/stat-card.tsx +27 -0
- package/web/src/components/status-badge.tsx +125 -0
- package/web/src/components/ui/alert.tsx +66 -0
- package/web/src/components/ui/badge.tsx +48 -0
- package/web/src/components/ui/button.tsx +64 -0
- package/web/src/components/ui/card.tsx +92 -0
- package/web/src/components/ui/checkbox.tsx +32 -0
- package/web/src/components/ui/dialog.tsx +158 -0
- package/web/src/components/ui/dropdown-menu.tsx +255 -0
- package/web/src/components/ui/input.tsx +21 -0
- package/web/src/components/ui/label.tsx +22 -0
- package/web/src/components/ui/progress.tsx +29 -0
- package/web/src/components/ui/select.tsx +188 -0
- package/web/src/components/ui/separator.tsx +28 -0
- package/web/src/components/ui/sheet.tsx +123 -0
- package/web/src/components/ui/skeleton.tsx +13 -0
- package/web/src/components/ui/sonner.tsx +35 -0
- package/web/src/components/ui/table.tsx +116 -0
- package/web/src/components/ui/tabs.tsx +89 -0
- package/web/src/components/ui/textarea.tsx +18 -0
- package/web/src/components/ui/tooltip.tsx +57 -0
- package/web/src/components/whatsapp/ChatDetail.tsx +417 -0
- package/web/src/components/whatsapp/ChatHeader.tsx +78 -0
- package/web/src/components/whatsapp/ChatList.tsx +107 -0
- package/web/src/components/whatsapp/ChatListItem.tsx +60 -0
- package/web/src/components/whatsapp/MessageBubble.tsx +46 -0
- package/web/src/components/whatsapp/MessageInput.tsx +63 -0
- package/web/src/components/whatsapp/MessageStream.tsx +135 -0
- package/web/src/components/whatsapp/SessionDivider.tsx +65 -0
- package/web/src/components/whatsapp/SessionHistory.tsx +119 -0
- package/web/src/components/whatsapp/settings/AiSettingsTab.tsx +268 -0
- package/web/src/components/whatsapp/settings/CalendarTab.tsx +339 -0
- package/web/src/components/whatsapp/settings/ConnectionTab.tsx +236 -0
- package/web/src/components/whatsapp/settings/NotificationsTab.tsx +109 -0
- package/web/src/components/whatsapp/settings/OperatorTab.tsx +303 -0
- package/web/src/contexts/AuthContext.tsx +103 -0
- package/web/src/index.css +130 -0
- package/web/src/lib/api.ts +92 -0
- package/web/src/lib/utils.ts +6 -0
- package/web/src/main.tsx +10 -0
- package/web/src/pages/AppointmentDetail.tsx +206 -0
- package/web/src/pages/AppointmentValidation.tsx +157 -0
- package/web/src/pages/AppointmentValidationDetail.tsx +617 -0
- package/web/src/pages/AppointmentValidationNew.tsx +1005 -0
- package/web/src/pages/Appointments.tsx +283 -0
- package/web/src/pages/Billing.tsx +126 -0
- package/web/src/pages/CallDetail.tsx +293 -0
- package/web/src/pages/CallSettings.tsx +313 -0
- package/web/src/pages/Calls.tsx +188 -0
- package/web/src/pages/CampaignDetail.tsx +216 -0
- package/web/src/pages/CampaignNew.tsx +277 -0
- package/web/src/pages/CampaignResults.tsx +185 -0
- package/web/src/pages/Campaigns.tsx +171 -0
- package/web/src/pages/Dashboard.tsx +336 -0
- package/web/src/pages/InboundSchedule.tsx +246 -0
- package/web/src/pages/LeadDetail.tsx +183 -0
- package/web/src/pages/Leads.tsx +258 -0
- package/web/src/pages/Login.tsx +99 -0
- package/web/src/pages/Register.tsx +129 -0
- package/web/src/pages/Settings.tsx +133 -0
- package/web/src/pages/SurveyDetail.tsx +232 -0
- package/web/src/pages/SurveyPreview.tsx +179 -0
- package/web/src/pages/Surveys.tsx +207 -0
- package/web/src/pages/Users.tsx +199 -0
- package/web/src/pages/WhatsApp.tsx +147 -0
- package/web/src/pages/WhatsAppSettings.tsx +215 -0
- package/web/src/pages/admin/AdminBaileysMessageLog.tsx +331 -0
- package/web/src/pages/admin/AdminBaileysRawMessages.tsx +318 -0
- package/web/src/pages/admin/AdminConversationReview.tsx +116 -0
- package/web/src/pages/admin/AdminCredits.tsx +467 -0
- package/web/src/pages/admin/AdminElevenLabsAgentDetail.tsx +332 -0
- package/web/src/pages/admin/AdminElevenLabsAgents.tsx +164 -0
- package/web/src/pages/admin/AdminElevenLabsBatchCallDetail.tsx +214 -0
- package/web/src/pages/admin/AdminElevenLabsBatchCalls.tsx +293 -0
- package/web/src/pages/admin/AdminElevenLabsConversationDetail.tsx +230 -0
- package/web/src/pages/admin/AdminElevenLabsConversations.tsx +228 -0
- package/web/src/pages/admin/AdminElevenLabsInboundCalls.tsx +293 -0
- package/web/src/pages/admin/AdminElevenLabsPhoneNumbers.tsx +506 -0
- package/web/src/pages/admin/AdminElevenLabsTestChat.tsx +258 -0
- package/web/src/pages/admin/AdminElevenLabsWebhooks.tsx +289 -0
- package/web/src/pages/admin/AdminEvaluationDashboard.tsx +520 -0
- package/web/src/pages/admin/AdminLeads.tsx +339 -0
- package/web/src/pages/admin/AdminLogs.tsx +283 -0
- package/web/src/pages/admin/AdminMigrations.tsx +247 -0
- package/web/src/pages/admin/AdminPlans.tsx +313 -0
- package/web/src/pages/admin/AdminSystem.tsx +391 -0
- package/web/src/pages/admin/AdminTenantBillableItems.tsx +464 -0
- package/web/src/pages/admin/AdminTenantDetail.tsx +1317 -0
- package/web/src/pages/admin/AdminTenants.tsx +274 -0
- package/web/src/pages/admin/AdminWhatsApp.tsx +618 -0
- package/web/src/pages/admin/AdminWhatsAppTestChat.tsx +328 -0
- package/web/src/types/index.ts +242 -0
- package/web/tsconfig.app.json +32 -0
- package/web/tsconfig.json +13 -0
- package/web/tsconfig.node.json +26 -0
- package/web/vite.config.ts +23 -0
package/SYSTEM_STATUS.md
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
# Tektip VoiceAI SaaS Platform — System Status
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Multi-tenant SaaS platform that powers AI voice agents over phone lines and WhatsApp. Receives call data from ElevenLabs via webhooks, processes transcripts with AI (OpenAI/Gemini), manages WhatsApp AI chat sessions via Unipile + ElevenLabs WebSocket, and provides a full management dashboard.
|
|
6
|
+
|
|
7
|
+
**Codebase**: ~17,000+ lines backend TypeScript + ~5,000+ lines frontend TypeScript/React
|
|
8
|
+
**Status**: MVP feature-complete (Phases 0–6 done), WhatsApp Agent system with session-based architecture, not yet production-hardened
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Tech Stack
|
|
13
|
+
|
|
14
|
+
| Layer | Technology |
|
|
15
|
+
|-------|-----------|
|
|
16
|
+
| Runtime | Node.js + TypeScript 5.9 |
|
|
17
|
+
| Backend | Fastify 5 |
|
|
18
|
+
| Database | MongoDB (Mongoose 8) |
|
|
19
|
+
| Auth | JWT dual-token (access 15min + refresh 7d) with bcrypt |
|
|
20
|
+
| AI | OpenAI / Google Gemini (configurable via `AI_PROVIDER` env) |
|
|
21
|
+
| WhatsApp Agent | Unipile (message relay) + ElevenLabs WebSocket (text-only AI) |
|
|
22
|
+
| Notifications | Twilio WhatsApp |
|
|
23
|
+
| Frontend | React 19 + Vite 7 + Tailwind CSS v4 + shadcn/ui |
|
|
24
|
+
| UI Components | shadcn/ui (18 components), Radix UI primitives, Lucide icons |
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Architecture
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
┌─────────────────┐ ┌──────────────────┐ ┌─────────────┐
|
|
32
|
+
│ ElevenLabs │────▶│ Fastify API │────▶│ MongoDB │
|
|
33
|
+
│ (Webhooks + │◀───▶│ (Backend) │ │ │
|
|
34
|
+
│ WebSocket) │ └──────────────────┘ └─────────────┘
|
|
35
|
+
└─────────────────┘ │ │ ▲
|
|
36
|
+
│ │ │
|
|
37
|
+
▼ │ │
|
|
38
|
+
┌────────┤ │
|
|
39
|
+
│ ▼ │
|
|
40
|
+
┌─────┴──┐ ┌────┴────┐ ┌──────────┐
|
|
41
|
+
│ OpenAI │ │ React │ │ Unipile │
|
|
42
|
+
│ Gemini │ │ SPA │ │ WhatsApp │
|
|
43
|
+
└────────┘ └─────────┘ └──────────┘
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Backend Modules (`src/modules/`)
|
|
47
|
+
|
|
48
|
+
| Module | Files | Description |
|
|
49
|
+
|--------|-------|-------------|
|
|
50
|
+
| `auth` | model, routes, service, refresh-token model | Register, login, logout, refresh, `/auth/me` |
|
|
51
|
+
| `tenants` | model, routes | Tenant CRUD, settings, plan management |
|
|
52
|
+
| `users` | routes | User list, invite, delete (per tenant) |
|
|
53
|
+
| `agents` | model, routes | AI agent CRUD, toggle active/inactive |
|
|
54
|
+
| `calls` | model, routes | Call list (paginated + filtered), stats aggregation, detail |
|
|
55
|
+
| `surveys` | model, routes | Survey CRUD, question builder, duplicate |
|
|
56
|
+
| `campaigns` | model, routes, service | Campaign CRUD, state machine, phone list, results + CSV export |
|
|
57
|
+
| `billing` | model, routes, service | Usage summary, event history, call charge logging |
|
|
58
|
+
| `whatsapp` | models (chat, session, message), routes | WhatsApp Agent: chat management, session lifecycle, takeover/release/close |
|
|
59
|
+
| `webhooks` | routes, service | ElevenLabs post-call webhook + Unipile WhatsApp message webhook |
|
|
60
|
+
| `admin` | routes | Super admin: tenant management, feature toggle, system health, usage |
|
|
61
|
+
|
|
62
|
+
### Plugins (`src/plugins/`)
|
|
63
|
+
|
|
64
|
+
| Plugin | Purpose |
|
|
65
|
+
|--------|---------|
|
|
66
|
+
| `cors.ts` | CORS configuration |
|
|
67
|
+
| `jwt.ts` | JWT verification + `fastify.authenticate` decorator |
|
|
68
|
+
| `rawBody.ts` | Raw body for webhook signature verification |
|
|
69
|
+
| `rbac.ts` | `requireRole()` + `requireFeature()` middleware. Superadmin bypasses role checks. |
|
|
70
|
+
|
|
71
|
+
### Frontend Pages (18 total)
|
|
72
|
+
|
|
73
|
+
| Page | Route | Description |
|
|
74
|
+
|------|-------|-------------|
|
|
75
|
+
| Login | `/login` | Card-based login form |
|
|
76
|
+
| Register | `/register` | Registration with tenant creation |
|
|
77
|
+
| Layout | (shell) | Collapsible sidebar, dropdown user menu, Toaster |
|
|
78
|
+
| Dashboard | `/dashboard` | 8 stat cards + recent calls table |
|
|
79
|
+
| Calls | `/calls` | Paginated table with direction/status filters |
|
|
80
|
+
| CallDetail | `/calls/:id` | Tabs: summary, survey responses, transcript |
|
|
81
|
+
| Settings | `/settings` | Tabs: company info + user management with invite dialog |
|
|
82
|
+
| Billing | `/billing` | Usage stats + transaction history table |
|
|
83
|
+
| Surveys | `/surveys` | Survey list with create dialog, row actions (copy/delete) |
|
|
84
|
+
| SurveyDetail | `/surveys/:id` | Question builder (add/edit/remove), status management |
|
|
85
|
+
| SurveyPreview | `/surveys/:id/preview` | Interactive question-by-question preview |
|
|
86
|
+
| Campaigns | `/campaigns` | Campaign list with status filter + progress bars |
|
|
87
|
+
| CampaignNew | `/campaigns/new` | 3-step wizard: info → schedule → phone list |
|
|
88
|
+
| CampaignDetail | `/campaigns/:id` | Stats, state machine actions, phone list preview |
|
|
89
|
+
| CampaignResults | `/campaigns/:id/results` | Dynamic columns per survey question + CSV export |
|
|
90
|
+
| AdminTenants | `/admin/tenants` | Tenant list with search, create dialog |
|
|
91
|
+
| AdminTenantDetail | `/admin/tenants/:id` | Edit tenant, feature checkboxes, user/agent tables |
|
|
92
|
+
| AdminSystem | `/admin/system` | System health stats + per-tenant usage table |
|
|
93
|
+
| WhatsApp | `/whatsapp`, `/whatsapp/:chatId` | Two-panel WhatsApp Web-style layout: chat list (left) + chat detail (right). Both routes render the same component. |
|
|
94
|
+
|
|
95
|
+
### Shared Components (`web/src/components/`)
|
|
96
|
+
|
|
97
|
+
| Component | Usage |
|
|
98
|
+
|-----------|-------|
|
|
99
|
+
| `StatCard` | Dashboard, Billing, CampaignDetail, AdminTenantDetail, AdminSystem |
|
|
100
|
+
| `CallStatusBadge` | Dashboard, Calls, CallDetail, CampaignDetail, CampaignResults |
|
|
101
|
+
| `CampaignStatusBadge` | Campaigns, CampaignDetail |
|
|
102
|
+
| `SurveyStatusBadge` | Surveys |
|
|
103
|
+
| `DirectionBadge` | Dashboard, Calls, CallDetail |
|
|
104
|
+
| `BillingTypeBadge` | Billing |
|
|
105
|
+
| `PageHeader` | All pages |
|
|
106
|
+
| `PageLoader` / `TableLoader` | All pages (skeleton loading) |
|
|
107
|
+
| `EmptyState` | All table pages |
|
|
108
|
+
| `Pagination` | Calls, Campaigns, Billing, AdminTenants |
|
|
109
|
+
| `ChatModeBadge` | WhatsApp (AI/Human/Closed) |
|
|
110
|
+
| `SessionStatusBadge` | WhatsApp (shows "Bekleniyor" for waiting) |
|
|
111
|
+
|
|
112
|
+
#### WhatsApp Components (`web/src/components/whatsapp/`)
|
|
113
|
+
|
|
114
|
+
| Component | Purpose |
|
|
115
|
+
|-----------|---------|
|
|
116
|
+
| `ChatList` | Left panel: searchable list of chats with unread indicators |
|
|
117
|
+
| `ChatListItem` | Single chat row in the list (avatar, name, last message preview) |
|
|
118
|
+
| `ChatDetail` | Right panel: full chat view with header, messages, and input |
|
|
119
|
+
| `ChatHeader` | Top bar showing contact info, session status, takeover/release actions |
|
|
120
|
+
| `MessageStream` | Scrollable message area with auto-scroll and session dividers |
|
|
121
|
+
| `MessageBubble` | Individual message bubble (contact/ai/human styling) |
|
|
122
|
+
| `SessionDivider` | Visual separator between sessions with status label |
|
|
123
|
+
| `MessageInput` | Text input with send button, disabled during AI/closed modes |
|
|
124
|
+
| `SessionHistory` | Expandable list of past sessions for a chat |
|
|
125
|
+
| `SettingsDialog` | WhatsApp agent configuration dialog (buffer time, model, etc.) |
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Data Models
|
|
130
|
+
|
|
131
|
+
| Model | Key Fields |
|
|
132
|
+
|-------|-----------|
|
|
133
|
+
| **Tenant** | name, plan (free/starter/pro/premium), enabled_features[], settings. `settings.whatsapp_agent.agent_id` is ObjectId reference to Agent (not raw ElevenLabs string). |
|
|
134
|
+
| **User** | email, password (bcrypt), name, role (superadmin/admin/manager/viewer), tenant_id |
|
|
135
|
+
| **RefreshToken** | user_id, token, expires_at |
|
|
136
|
+
| **Agent** | tenant_id, elevenlabs_agent_id, phone_number, agent_template, direction, config, post_call_processing |
|
|
137
|
+
| **Call** | tenant_id, agent_id, campaign_id, direction, caller/callee_number, duration, status, transcript, llm_summary, survey_responses[] |
|
|
138
|
+
| **Survey** | tenant_id, name, description, questions[], status (draft/active/archived) |
|
|
139
|
+
| **Campaign** | tenant_id, name, survey_id, agent_id, status (draft→scheduled→running→paused→completed), phone_list[], schedule, stats |
|
|
140
|
+
| **BillingEvent** | tenant_id, type (call_charge/subscription/top_up/refund), amount, currency, call_id, description |
|
|
141
|
+
| **WhatsAppChat** | tenant_id, unipile_chat_id, contact_name, contact_phone, is_closed, active_session_id, last_message_at, message_count |
|
|
142
|
+
| **WhatsAppSession** | chat_id, tenant_id, status (waiting/active/resolved), resolved_by (human/ai/timeout), grace_deadline, taken_over_by, elevenlabs_conversation_id, message_count |
|
|
143
|
+
| **WhatsAppMessage** | chat_id, session_id, tenant_id, sender (contact/ai/human), text, sent_via_unipile |
|
|
144
|
+
|
|
145
|
+
### RBAC
|
|
146
|
+
|
|
147
|
+
| Role | Access |
|
|
148
|
+
|------|--------|
|
|
149
|
+
| `superadmin` | Everything (bypasses role checks) + admin panel |
|
|
150
|
+
| `admin` | Full tenant access, user management |
|
|
151
|
+
| `manager` | Read + write (create surveys, campaigns, etc.) |
|
|
152
|
+
| `viewer` | Read-only |
|
|
153
|
+
|
|
154
|
+
### Feature Gating
|
|
155
|
+
|
|
156
|
+
Features are toggled per tenant via `enabled_features[]`:
|
|
157
|
+
- `inbound_agent` — Inbound call handling
|
|
158
|
+
- `outbound_campaigns` — Campaign management
|
|
159
|
+
- `survey_builder` — Survey creation/management
|
|
160
|
+
- `whatsapp_notifications` — WhatsApp post-call notifications
|
|
161
|
+
- `whatsapp_agent` — WhatsApp AI chat agent (session-based)
|
|
162
|
+
|
|
163
|
+
Checked at runtime via `requireFeature()` middleware (queries DB, not stale JWT).
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Webhook Pipelines
|
|
168
|
+
|
|
169
|
+
### ElevenLabs Post-Call Webhook
|
|
170
|
+
```
|
|
171
|
+
POST /webhooks/elevenlabs
|
|
172
|
+
→ Verify HMAC-SHA256 signature (webhookValidator)
|
|
173
|
+
→ Respond 200 immediately
|
|
174
|
+
→ Background processing:
|
|
175
|
+
1. Look up Agent by elevenlabs_agent_id
|
|
176
|
+
2. Format transcript
|
|
177
|
+
3. Save Call record to MongoDB
|
|
178
|
+
4. Run post-call strategy:
|
|
179
|
+
- "summarize" → AI summary
|
|
180
|
+
- "extract_survey" → AI survey extraction
|
|
181
|
+
- "summarize_and_extract" → both
|
|
182
|
+
- "none" → skip
|
|
183
|
+
5. Send WhatsApp notification (if configured)
|
|
184
|
+
6. Log billing charge
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Unipile WhatsApp Webhook
|
|
188
|
+
```
|
|
189
|
+
POST /webhooks/unipile
|
|
190
|
+
→ Validate shared secret header (optional)
|
|
191
|
+
→ Respond 200 immediately
|
|
192
|
+
→ Background processing:
|
|
193
|
+
1. Find tenant by unipile_account_id
|
|
194
|
+
2. Validate phone number (reject group chats)
|
|
195
|
+
3. Check blacklist
|
|
196
|
+
4. Find/create WhatsAppChat
|
|
197
|
+
5. Look up or create WhatsAppSession
|
|
198
|
+
6. Route by session state:
|
|
199
|
+
- No session → create session (waiting), start grace timer
|
|
200
|
+
- Waiting → store message (timer running)
|
|
201
|
+
- Active (AI) → forward to WhatsAppAgentService
|
|
202
|
+
- Active (human) → store message only
|
|
203
|
+
7. Self-sent messages → resolve waiting sessions (preserving session_id on the message), detect human takeover
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Environment Variables
|
|
209
|
+
|
|
210
|
+
| Variable | Purpose |
|
|
211
|
+
|----------|---------|
|
|
212
|
+
| `PORT` | Server port |
|
|
213
|
+
| `MONGODB_URI` | MongoDB connection string |
|
|
214
|
+
| `JWT_SECRET` | Access token signing |
|
|
215
|
+
| `JWT_REFRESH_SECRET` | Refresh token signing |
|
|
216
|
+
| `JWT_ACCESS_EXPIRY` | Access token TTL (e.g. "15m") |
|
|
217
|
+
| `JWT_REFRESH_EXPIRY` | Refresh token TTL (e.g. "7d") |
|
|
218
|
+
| `ELEVENLABS_WEBHOOK_SECRET` | Webhook signature verification |
|
|
219
|
+
| `AI_PROVIDER` | "openai" or "gemini" |
|
|
220
|
+
| `OPENAI_API_KEY` / `OPENAI_MODEL` | OpenAI config |
|
|
221
|
+
| `GEMINI_API_KEY` / `GEMINI_MODEL` | Gemini config |
|
|
222
|
+
| `SUMMARY_LANGUAGE` / `SUMMARY_MAX_TOKENS` | AI summary settings |
|
|
223
|
+
| `TWILIO_ACCOUNT_SID` / `TWILIO_AUTH_TOKEN` / `TWILIO_WHATSAPP_NUMBER` | Twilio WhatsApp |
|
|
224
|
+
| `UNIPILE_API_KEY` / `UNIPILE_DSN` | Unipile WhatsApp API |
|
|
225
|
+
| `UNIPILE_WEBHOOK_SECRET` | Unipile webhook validation |
|
|
226
|
+
| `ELEVENLABS_API_KEY` | ElevenLabs SDK (agents, signed URLs) |
|
|
227
|
+
| `ADMIN_PASSWORD` | Legacy admin panel |
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## Scripts
|
|
232
|
+
|
|
233
|
+
| Script | Command | Purpose |
|
|
234
|
+
|--------|---------|---------|
|
|
235
|
+
| `seed.ts` | `tsx scripts/seed.ts` | Populate mock data (agents, calls, billing, surveys, campaigns) |
|
|
236
|
+
| `promote.ts` | `tsx scripts/promote.ts` | Promote first user to superadmin |
|
|
237
|
+
| `addRecipient.ts` | `npm run add:recipient` | Add WhatsApp recipient |
|
|
238
|
+
| `listRecipients.ts` | `npm run list:recipients` | List WhatsApp recipients |
|
|
239
|
+
| `retrigger.ts` | `npm run retrigger` | Re-process a webhook payload |
|
|
240
|
+
| `testSend.ts` | `npm run test:send` | Send test WhatsApp message |
|
|
241
|
+
| `migrate-sessions.ts` | `tsx scripts/migrate-sessions.ts` | Migrate WhatsApp chats to session-based architecture (supports `--dry-run`) |
|
|
242
|
+
| `migrate-agent-ref.ts` | `tsx scripts/migrate-agent-ref.ts` | Migrate tenant WhatsApp agent_id from raw string to Agent ObjectId reference (supports `--dry-run`) |
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## What's Done (Phases 0–6)
|
|
247
|
+
|
|
248
|
+
- **Phase 0 — Foundation**: Fastify + TS rewrite, MongoDB models, config, error handling, logging (Winston)
|
|
249
|
+
- **Phase 1 — Core Backend**: JWT dual-token auth, RBAC middleware, feature gating, tenant/user management
|
|
250
|
+
- **Phase 2 — Webhook Pipeline**: ElevenLabs webhook receiver, AI summary (OpenAI + Gemini), WhatsApp notifications, call storage
|
|
251
|
+
- **Phase 3 — Survey & Campaign Engine**: Survey builder with 4 question types + branch logic, campaign state machine, phone list management, results aggregation + CSV export
|
|
252
|
+
- **Phase 4 — Billing**: Per-call billing events, usage summary aggregation, event history with pagination
|
|
253
|
+
- **Phase 5 — React Dashboard**: 17-page SPA with auth, all CRUD operations, 3-step campaign wizard, survey preview
|
|
254
|
+
- **Phase 6 — Admin Panel**: Super admin routes, tenant management, feature toggles, system health dashboard, per-tenant usage
|
|
255
|
+
- **UI Overhaul**: Full shadcn/ui migration — Card/Table/Dialog/Select/Badge/Skeleton/Tabs/Progress components, collapsible sidebar with tooltips, Toaster notifications
|
|
256
|
+
- **WhatsApp AI Agent**: Full Unipile integration (QR connection, send/receive), ElevenLabs text-only WebSocket for AI responses, grace period pattern, session-based architecture (WhatsAppSession model), human takeover/release with "immediate response" option, blacklist management, stuck session sweeper, startup recovery
|
|
257
|
+
- **WebSocket reconnection** with exponential backoff (3 retries)
|
|
258
|
+
- **Session inactivity auto-resolve** (30min timeout)
|
|
259
|
+
- **Message buffer/debounce** (20s before AI responds)
|
|
260
|
+
- **Agent model integration** — tenant references Agent by ObjectId, checks `is_active`
|
|
261
|
+
- **WhatsApp UI redesign** — two-panel layout (WhatsApp Web-style) with session tabs and dividers
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## What's NOT Done / Known Gaps
|
|
266
|
+
|
|
267
|
+
### Recently Resolved
|
|
268
|
+
|
|
269
|
+
- ~~No error recovery for WebSocket~~ — Fixed: exponential backoff reconnection with 3 retries
|
|
270
|
+
- ~~WhatsApp UI needs redesign~~ — Fixed: two-panel WhatsApp Web-style layout with component-based architecture
|
|
271
|
+
|
|
272
|
+
### High Priority (Production Blockers)
|
|
273
|
+
|
|
274
|
+
1. **No automated tests** — Zero unit/integration/e2e tests exist
|
|
275
|
+
2. **No input validation** — Routes accept unvalidated body payloads (Zod is installed but unused)
|
|
276
|
+
3. **No rate limiting** — API endpoints have no rate limiting
|
|
277
|
+
4. **No HTTPS/TLS** — Assumes reverse proxy handles it
|
|
278
|
+
5. **No password reset flow** — No forgot password / email verification
|
|
279
|
+
6. **No audit logging** — No record of who changed what
|
|
280
|
+
7. **Campaign execution engine** — The campaign state machine exists but there's **no actual dialing engine** (no cron/worker to trigger outbound calls via ElevenLabs API). Campaigns can be created and managed, but calls aren't automatically initiated.
|
|
281
|
+
|
|
282
|
+
### Medium Priority
|
|
283
|
+
|
|
284
|
+
8. **No file upload for phone lists** — Only textarea paste (no CSV file upload)
|
|
285
|
+
9. **No real-time updates** — No WebSocket/SSE for live campaign progress
|
|
286
|
+
10. **No pagination on some endpoints** — Surveys list has no pagination
|
|
287
|
+
11. **No search/filter on calls by phone number** — Only direction + status filters
|
|
288
|
+
12. **No dark mode toggle** — CSS variables exist for dark mode but no UI toggle
|
|
289
|
+
13. **No mobile responsive design** — Sidebar doesn't collapse to hamburger on mobile
|
|
290
|
+
14. **No i18n framework** — Turkish strings are hardcoded throughout
|
|
291
|
+
15. **Agent management UI is minimal** — Can list/toggle agents but can't create them from the dashboard (only via admin API)
|
|
292
|
+
|
|
293
|
+
### Low Priority / Nice-to-Have
|
|
294
|
+
|
|
295
|
+
16. **No data export beyond campaign results** — No call export, no billing export
|
|
296
|
+
17. **No dashboard date range filters** — Stats are always all-time
|
|
297
|
+
18. **No user profile/password change** — Users can't update their own info
|
|
298
|
+
19. **No email notifications** — Only WhatsApp
|
|
299
|
+
20. **No webhook retry/dead letter queue** — Failed webhooks are logged but not retried
|
|
300
|
+
21. **Code splitting** — Single 541KB JS bundle (warning in build output)
|
|
301
|
+
22. **Legacy routes still registered** — `/legacy-admin` routes from old Express codebase
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## Running the System
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
# Backend (from root)
|
|
309
|
+
npm run dev # tsx watch src/index.ts
|
|
310
|
+
|
|
311
|
+
# Frontend (from web/)
|
|
312
|
+
cd web && npm run dev # Vite dev server on :5173
|
|
313
|
+
|
|
314
|
+
# Seed mock data
|
|
315
|
+
tsx scripts/seed.ts
|
|
316
|
+
|
|
317
|
+
# Promote user to superadmin
|
|
318
|
+
tsx scripts/promote.ts
|
|
319
|
+
|
|
320
|
+
# Production build
|
|
321
|
+
cd web && npm run build
|
|
322
|
+
npm run build && npm start
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
**Dev URLs**:
|
|
326
|
+
- Frontend: http://localhost:5173
|
|
327
|
+
- API: http://localhost:5173/api (proxied by Vite)
|
|
328
|
+
- Direct API: http://localhost:3000
|
|
329
|
+
|
|
330
|
+
---
|
|
331
|
+
|
|
332
|
+
*Last updated: February 2026*
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""backup_r2.py — MongoDB backup to Cloudflare R2 with Slack notifications."""
|
|
3
|
+
|
|
4
|
+
import os
|
|
5
|
+
import subprocess
|
|
6
|
+
import json
|
|
7
|
+
import ssl
|
|
8
|
+
import urllib.request
|
|
9
|
+
from datetime import datetime, timedelta
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
import boto3
|
|
13
|
+
import certifi
|
|
14
|
+
from dotenv import load_dotenv
|
|
15
|
+
|
|
16
|
+
# Load .env from parent directory
|
|
17
|
+
load_dotenv(Path(__file__).resolve().parent.parent / ".env")
|
|
18
|
+
|
|
19
|
+
# ── Config from .env ──
|
|
20
|
+
MONGODB_URI = os.getenv("MONGODB_URI", "mongodb://localhost:27017/asistan724")
|
|
21
|
+
MONGO_USER = os.getenv("MONGO_USER")
|
|
22
|
+
MONGO_PASS = os.getenv("MONGO_PASS")
|
|
23
|
+
BACKUP_DIR = os.getenv("BACKUP_DIR", "/tmp/backups")
|
|
24
|
+
RETENTION_DAYS = int(os.getenv("RETENTION_DAYS", "7"))
|
|
25
|
+
|
|
26
|
+
R2 = {
|
|
27
|
+
"bucket": os.getenv("R2_BUCKET"),
|
|
28
|
+
"endpoint": os.getenv("R2_ENDPOINT"),
|
|
29
|
+
"access_key": os.getenv("R2_ACCESS_KEY"),
|
|
30
|
+
"secret_key": os.getenv("R2_SECRET_KEY"),
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
SLACK_BOT_TOKEN = os.getenv("SLACK_BOT_TOKEN")
|
|
34
|
+
SLACK_CHANNEL = os.getenv("SLACK_CHANNEL")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def slack_notify(status: str, message: str):
|
|
38
|
+
emoji = "✅" if status == "success" else "❌"
|
|
39
|
+
color = "good" if status == "success" else "danger"
|
|
40
|
+
|
|
41
|
+
payload = json.dumps({
|
|
42
|
+
"channel": SLACK_CHANNEL,
|
|
43
|
+
"attachments": [{
|
|
44
|
+
"color": color,
|
|
45
|
+
"text": f"{emoji} *Backup {status}* — {datetime.now():%Y-%m-%d %H:%M}\n{message}"
|
|
46
|
+
}]
|
|
47
|
+
}).encode()
|
|
48
|
+
|
|
49
|
+
try:
|
|
50
|
+
req = urllib.request.Request(
|
|
51
|
+
"https://slack.com/api/chat.postMessage",
|
|
52
|
+
data=payload,
|
|
53
|
+
headers={
|
|
54
|
+
"Content-Type": "application/json",
|
|
55
|
+
"Authorization": f"Bearer {SLACK_BOT_TOKEN}"
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
context = ssl.create_default_context(cafile=certifi.where())
|
|
59
|
+
urllib.request.urlopen(req, context=context)
|
|
60
|
+
except Exception as e:
|
|
61
|
+
print(f"Slack notification failed: {e}")
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def get_r2_client():
|
|
65
|
+
return boto3.client(
|
|
66
|
+
"s3",
|
|
67
|
+
endpoint_url=R2["endpoint"],
|
|
68
|
+
aws_access_key_id=R2["access_key"],
|
|
69
|
+
aws_secret_access_key=R2["secret_key"],
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def dump_mongodb(output_path: str):
|
|
74
|
+
"""Run mongodump and produce a gzipped archive."""
|
|
75
|
+
print("Dumping MongoDB...")
|
|
76
|
+
cmd = ["mongodump", "--uri", MONGODB_URI, "--gzip", "--archive"]
|
|
77
|
+
|
|
78
|
+
if MONGO_USER and MONGO_PASS:
|
|
79
|
+
cmd += ["--username", MONGO_USER, "--password", MONGO_PASS,
|
|
80
|
+
"--authenticationDatabase", "admin"]
|
|
81
|
+
|
|
82
|
+
result = subprocess.run(cmd, capture_output=True)
|
|
83
|
+
|
|
84
|
+
if result.returncode != 0:
|
|
85
|
+
raise Exception(f"mongodump failed: {result.stderr.decode()}")
|
|
86
|
+
|
|
87
|
+
with open(output_path, "wb") as f:
|
|
88
|
+
f.write(result.stdout)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def upload_to_r2(client, local_path: str, r2_key: str):
|
|
92
|
+
print(f"Uploading {r2_key}...")
|
|
93
|
+
client.upload_file(local_path, R2["bucket"], r2_key)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def cleanup_old_backups(client):
|
|
97
|
+
print("Cleaning old backups...")
|
|
98
|
+
cutoff = datetime.now() - timedelta(days=RETENTION_DAYS)
|
|
99
|
+
|
|
100
|
+
paginator = client.get_paginator("list_objects_v2")
|
|
101
|
+
for page in paginator.paginate(Bucket=R2["bucket"], Prefix="portal-asistan-7-24/mongo_"):
|
|
102
|
+
for obj in page.get("Contents", []):
|
|
103
|
+
if obj["LastModified"].replace(tzinfo=None) < cutoff:
|
|
104
|
+
print(f" Deleting {obj['Key']}")
|
|
105
|
+
client.delete_object(Bucket=R2["bucket"], Key=obj["Key"])
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def file_size_human(path: str) -> str:
|
|
109
|
+
size = os.path.getsize(path)
|
|
110
|
+
for unit in ["B", "KB", "MB", "GB"]:
|
|
111
|
+
if size < 1024:
|
|
112
|
+
return f"{size:.1f}{unit}"
|
|
113
|
+
size /= 1024
|
|
114
|
+
return f"{size:.1f}TB"
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def main():
|
|
118
|
+
date_str = datetime.now().strftime("%Y-%m-%d_%H-%M")
|
|
119
|
+
backup_dir = Path(BACKUP_DIR)
|
|
120
|
+
backup_dir.mkdir(parents=True, exist_ok=True)
|
|
121
|
+
hostname = os.uname().nodename
|
|
122
|
+
|
|
123
|
+
db_file = str(backup_dir / f"mongo_{date_str}.gz")
|
|
124
|
+
|
|
125
|
+
try:
|
|
126
|
+
client = get_r2_client()
|
|
127
|
+
|
|
128
|
+
dump_mongodb(db_file)
|
|
129
|
+
db_size = file_size_human(db_file)
|
|
130
|
+
upload_to_r2(client, db_file, f"portal-asistan-7-24/mongo_{date_str}.gz")
|
|
131
|
+
|
|
132
|
+
cleanup_old_backups(client)
|
|
133
|
+
slack_notify("success", f"DB: {db_size}\nServer: {hostname}")
|
|
134
|
+
print("Backup complete!")
|
|
135
|
+
|
|
136
|
+
except Exception as e:
|
|
137
|
+
slack_notify("error", f"Failed: {e}\nServer: {hostname}")
|
|
138
|
+
print(f"Backup failed: {e}")
|
|
139
|
+
|
|
140
|
+
finally:
|
|
141
|
+
if os.path.exists(db_file):
|
|
142
|
+
os.remove(db_file)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
if __name__ == "__main__":
|
|
146
|
+
main()
|