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.
Files changed (969) hide show
  1. package/.claude/settings.local.json +27 -0
  2. package/.dockerignore +6 -0
  3. package/.env.example +43 -0
  4. package/BEFORE-PRODUCTION.md +32 -0
  5. package/Dockerfile +23 -0
  6. package/SYSTEM_OVERVIEW.md +942 -0
  7. package/SYSTEM_STATUS.md +332 -0
  8. package/backup_script/main.py +146 -0
  9. package/baileys/.dockerignore +7 -0
  10. package/baileys/Dockerfile +13 -0
  11. package/baileys/README.md +412 -0
  12. package/baileys/index.js +499 -0
  13. package/baileys/package-lock.json +2532 -0
  14. package/baileys/package.json +25 -0
  15. package/baileys/server.js +96 -0
  16. package/baileys/src/config.js +55 -0
  17. package/baileys/src/middleware/api-key.js +16 -0
  18. package/baileys/src/routes/accounts.js +51 -0
  19. package/baileys/src/routes/chats.js +103 -0
  20. package/baileys/src/routes/webhooks.js +34 -0
  21. package/baileys/src/services/account-store.js +259 -0
  22. package/baileys/src/services/webhook-dispatcher.js +161 -0
  23. package/baileys/src/services/worker-manager.js +597 -0
  24. package/baileys/src/utils/jid.js +79 -0
  25. package/baileys/src/utils/logger.js +16 -0
  26. package/baileys/src/utils/use-mongodb-auth-state.js +122 -0
  27. package/baileys/worker.js +721 -0
  28. package/dist/app.d.ts +1 -0
  29. package/dist/app.js +84 -0
  30. package/dist/app.js.map +1 -0
  31. package/dist/config/agentPrompts.json +19 -0
  32. package/dist/config/database.d.ts +1 -0
  33. package/dist/config/database.js +26 -0
  34. package/dist/config/database.js.map +1 -0
  35. package/dist/config/env.d.ts +41 -0
  36. package/dist/config/env.js +81 -0
  37. package/dist/config/env.js.map +1 -0
  38. package/dist/config/index.d.ts +3 -0
  39. package/dist/config/index.js +73 -0
  40. package/dist/config/index.js.map +1 -0
  41. package/dist/controllers/webhook.controller.d.ts +10 -0
  42. package/dist/controllers/webhook.controller.js +128 -0
  43. package/dist/controllers/webhook.controller.js.map +1 -0
  44. package/dist/errors/index.d.ts +4 -0
  45. package/dist/errors/index.js +13 -0
  46. package/dist/errors/index.js.map +1 -0
  47. package/dist/hooks/webhookValidator.d.ts +2 -0
  48. package/dist/hooks/webhookValidator.js +47 -0
  49. package/dist/hooks/webhookValidator.js.map +1 -0
  50. package/dist/index.d.ts +1 -0
  51. package/dist/index.js +55 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/migrations/001_session-architecture.d.ts +3 -0
  54. package/dist/migrations/001_session-architecture.js +119 -0
  55. package/dist/migrations/001_session-architecture.js.map +1 -0
  56. package/dist/migrations/002_agent-ref.d.ts +3 -0
  57. package/dist/migrations/002_agent-ref.js +55 -0
  58. package/dist/migrations/002_agent-ref.js.map +1 -0
  59. package/dist/migrations/003_shift-schedule.d.ts +3 -0
  60. package/dist/migrations/003_shift-schedule.js +48 -0
  61. package/dist/migrations/003_shift-schedule.js.map +1 -0
  62. package/dist/migrations/004_invert-shift-to-clinic-hours.d.ts +3 -0
  63. package/dist/migrations/004_invert-shift-to-clinic-hours.js +27 -0
  64. package/dist/migrations/004_invert-shift-to-clinic-hours.js.map +1 -0
  65. package/dist/migrations/005_composite-baileys-chat-ids.d.ts +3 -0
  66. package/dist/migrations/005_composite-baileys-chat-ids.js +47 -0
  67. package/dist/migrations/005_composite-baileys-chat-ids.js.map +1 -0
  68. package/dist/migrations/migration.model.d.ts +18 -0
  69. package/dist/migrations/migration.model.js +45 -0
  70. package/dist/migrations/migration.model.js.map +1 -0
  71. package/dist/migrations/migration.routes.d.ts +2 -0
  72. package/dist/migrations/migration.routes.js +37 -0
  73. package/dist/migrations/migration.routes.js.map +1 -0
  74. package/dist/migrations/migration.runner.d.ts +19 -0
  75. package/dist/migrations/migration.runner.js +74 -0
  76. package/dist/migrations/migration.runner.js.map +1 -0
  77. package/dist/models/ConversationClaim.d.ts +13 -0
  78. package/dist/models/ConversationClaim.js +44 -0
  79. package/dist/models/ConversationClaim.js.map +1 -0
  80. package/dist/models/ConversationEvaluation.d.ts +23 -0
  81. package/dist/models/ConversationEvaluation.js +92 -0
  82. package/dist/models/ConversationEvaluation.js.map +1 -0
  83. package/dist/models/Summary.d.ts +37 -0
  84. package/dist/models/Summary.js +78 -0
  85. package/dist/models/Summary.js.map +1 -0
  86. package/dist/models/Transcription.d.ts +34 -0
  87. package/dist/models/Transcription.js +71 -0
  88. package/dist/models/Transcription.js.map +1 -0
  89. package/dist/models/WhatsAppRecipient.d.ts +23 -0
  90. package/dist/models/WhatsAppRecipient.js +53 -0
  91. package/dist/models/WhatsAppRecipient.js.map +1 -0
  92. package/dist/modules/admin/admin.routes.d.ts +2 -0
  93. package/dist/modules/admin/admin.routes.js +1966 -0
  94. package/dist/modules/admin/admin.routes.js.map +1 -0
  95. package/dist/modules/admin/elevenlabs-test-chat.routes.d.ts +2 -0
  96. package/dist/modules/admin/elevenlabs-test-chat.routes.js +158 -0
  97. package/dist/modules/admin/elevenlabs-test-chat.routes.js.map +1 -0
  98. package/dist/modules/admin/whatsapp-test-chat.routes.d.ts +2 -0
  99. package/dist/modules/admin/whatsapp-test-chat.routes.js +204 -0
  100. package/dist/modules/admin/whatsapp-test-chat.routes.js.map +1 -0
  101. package/dist/modules/agents/agent.model.d.ts +38 -0
  102. package/dist/modules/agents/agent.model.js +92 -0
  103. package/dist/modules/agents/agent.model.js.map +1 -0
  104. package/dist/modules/agents/agent.routes.d.ts +2 -0
  105. package/dist/modules/agents/agent.routes.js +61 -0
  106. package/dist/modules/agents/agent.routes.js.map +1 -0
  107. package/dist/modules/appointment-validation/appointment-validation.model.d.ts +76 -0
  108. package/dist/modules/appointment-validation/appointment-validation.model.js +118 -0
  109. package/dist/modules/appointment-validation/appointment-validation.model.js.map +1 -0
  110. package/dist/modules/appointment-validation/appointment-validation.routes.d.ts +2 -0
  111. package/dist/modules/appointment-validation/appointment-validation.routes.js +202 -0
  112. package/dist/modules/appointment-validation/appointment-validation.routes.js.map +1 -0
  113. package/dist/modules/appointment-validation/appointment-validation.service.d.ts +53 -0
  114. package/dist/modules/appointment-validation/appointment-validation.service.js +827 -0
  115. package/dist/modules/appointment-validation/appointment-validation.service.js.map +1 -0
  116. package/dist/modules/auth/auth.model.d.ts +17 -0
  117. package/dist/modules/auth/auth.model.js +64 -0
  118. package/dist/modules/auth/auth.model.js.map +1 -0
  119. package/dist/modules/auth/auth.routes.d.ts +2 -0
  120. package/dist/modules/auth/auth.routes.js +202 -0
  121. package/dist/modules/auth/auth.routes.js.map +1 -0
  122. package/dist/modules/auth/auth.service.d.ts +28 -0
  123. package/dist/modules/auth/auth.service.js +183 -0
  124. package/dist/modules/auth/auth.service.js.map +1 -0
  125. package/dist/modules/auth/refresh-token.model.d.ts +13 -0
  126. package/dist/modules/auth/refresh-token.model.js +52 -0
  127. package/dist/modules/auth/refresh-token.model.js.map +1 -0
  128. package/dist/modules/billing/billing-alert.model.d.ts +16 -0
  129. package/dist/modules/billing/billing-alert.model.js +47 -0
  130. package/dist/modules/billing/billing-alert.model.js.map +1 -0
  131. package/dist/modules/billing/billing-period-snapshot.model.d.ts +35 -0
  132. package/dist/modules/billing/billing-period-snapshot.model.js +68 -0
  133. package/dist/modules/billing/billing-period-snapshot.model.js.map +1 -0
  134. package/dist/modules/billing/billing.model.d.ts +18 -0
  135. package/dist/modules/billing/billing.model.js +62 -0
  136. package/dist/modules/billing/billing.model.js.map +1 -0
  137. package/dist/modules/billing/billing.routes.d.ts +2 -0
  138. package/dist/modules/billing/billing.routes.js +63 -0
  139. package/dist/modules/billing/billing.routes.js.map +1 -0
  140. package/dist/modules/billing/billing.service.d.ts +69 -0
  141. package/dist/modules/billing/billing.service.js +498 -0
  142. package/dist/modules/billing/billing.service.js.map +1 -0
  143. package/dist/modules/billing/payment.model.d.ts +24 -0
  144. package/dist/modules/billing/payment.model.js +57 -0
  145. package/dist/modules/billing/payment.model.js.map +1 -0
  146. package/dist/modules/calls/call.model.d.ts +41 -0
  147. package/dist/modules/calls/call.model.js +97 -0
  148. package/dist/modules/calls/call.model.js.map +1 -0
  149. package/dist/modules/calls/call.routes.d.ts +2 -0
  150. package/dist/modules/calls/call.routes.js +103 -0
  151. package/dist/modules/calls/call.routes.js.map +1 -0
  152. package/dist/modules/campaigns/campaign.model.d.ts +45 -0
  153. package/dist/modules/campaigns/campaign.model.js +98 -0
  154. package/dist/modules/campaigns/campaign.model.js.map +1 -0
  155. package/dist/modules/campaigns/campaign.routes.d.ts +2 -0
  156. package/dist/modules/campaigns/campaign.routes.js +323 -0
  157. package/dist/modules/campaigns/campaign.routes.js.map +1 -0
  158. package/dist/modules/campaigns/campaign.service.d.ts +11 -0
  159. package/dist/modules/campaigns/campaign.service.js +86 -0
  160. package/dist/modules/campaigns/campaign.service.js.map +1 -0
  161. package/dist/modules/google-calendar/google-calendar.routes.d.ts +2 -0
  162. package/dist/modules/google-calendar/google-calendar.routes.js +32 -0
  163. package/dist/modules/google-calendar/google-calendar.routes.js.map +1 -0
  164. package/dist/modules/inbound-call/inbound-call-config.model.d.ts +20 -0
  165. package/dist/modules/inbound-call/inbound-call-config.model.js +68 -0
  166. package/dist/modules/inbound-call/inbound-call-config.model.js.map +1 -0
  167. package/dist/modules/inbound-call/inbound-call.routes.d.ts +2 -0
  168. package/dist/modules/inbound-call/inbound-call.routes.js +243 -0
  169. package/dist/modules/inbound-call/inbound-call.routes.js.map +1 -0
  170. package/dist/modules/leads/lead.model.d.ts +24 -0
  171. package/dist/modules/leads/lead.model.js +54 -0
  172. package/dist/modules/leads/lead.model.js.map +1 -0
  173. package/dist/modules/leads/lead.routes.d.ts +2 -0
  174. package/dist/modules/leads/lead.routes.js +201 -0
  175. package/dist/modules/leads/lead.routes.js.map +1 -0
  176. package/dist/modules/plans/plan.model.d.ts +25 -0
  177. package/dist/modules/plans/plan.model.js +59 -0
  178. package/dist/modules/plans/plan.model.js.map +1 -0
  179. package/dist/modules/surveys/survey.model.d.ts +30 -0
  180. package/dist/modules/surveys/survey.model.js +75 -0
  181. package/dist/modules/surveys/survey.model.js.map +1 -0
  182. package/dist/modules/surveys/survey.routes.d.ts +2 -0
  183. package/dist/modules/surveys/survey.routes.js +153 -0
  184. package/dist/modules/surveys/survey.routes.js.map +1 -0
  185. package/dist/modules/tenants/tenant.model.d.ts +86 -0
  186. package/dist/modules/tenants/tenant.model.js +127 -0
  187. package/dist/modules/tenants/tenant.model.js.map +1 -0
  188. package/dist/modules/tenants/tenant.routes.d.ts +2 -0
  189. package/dist/modules/tenants/tenant.routes.js +65 -0
  190. package/dist/modules/tenants/tenant.routes.js.map +1 -0
  191. package/dist/modules/users/user.routes.d.ts +2 -0
  192. package/dist/modules/users/user.routes.js +106 -0
  193. package/dist/modules/users/user.routes.js.map +1 -0
  194. package/dist/modules/webhooks/elevenlabs-tool.routes.d.ts +20 -0
  195. package/dist/modules/webhooks/elevenlabs-tool.routes.js +85 -0
  196. package/dist/modules/webhooks/elevenlabs-tool.routes.js.map +1 -0
  197. package/dist/modules/webhooks/elevenlabs-tool.service.d.ts +11 -0
  198. package/dist/modules/webhooks/elevenlabs-tool.service.js +360 -0
  199. package/dist/modules/webhooks/elevenlabs-tool.service.js.map +1 -0
  200. package/dist/modules/webhooks/elevenlabs.routes.d.ts +2 -0
  201. package/dist/modules/webhooks/elevenlabs.routes.js +34 -0
  202. package/dist/modules/webhooks/elevenlabs.routes.js.map +1 -0
  203. package/dist/modules/webhooks/elevenlabs.service.d.ts +6 -0
  204. package/dist/modules/webhooks/elevenlabs.service.js +512 -0
  205. package/dist/modules/webhooks/elevenlabs.service.js.map +1 -0
  206. package/dist/modules/webhooks/unipile.routes.d.ts +2 -0
  207. package/dist/modules/webhooks/unipile.routes.js +780 -0
  208. package/dist/modules/webhooks/unipile.routes.js.map +1 -0
  209. package/dist/modules/whatsapp/appointment.model.d.ts +27 -0
  210. package/dist/modules/whatsapp/appointment.model.js +58 -0
  211. package/dist/modules/whatsapp/appointment.model.js.map +1 -0
  212. package/dist/modules/whatsapp/operator-request.model.d.ts +29 -0
  213. package/dist/modules/whatsapp/operator-request.model.js +65 -0
  214. package/dist/modules/whatsapp/operator-request.model.js.map +1 -0
  215. package/dist/modules/whatsapp/stt-usage.model.d.ts +16 -0
  216. package/dist/modules/whatsapp/stt-usage.model.js +53 -0
  217. package/dist/modules/whatsapp/stt-usage.model.js.map +1 -0
  218. package/dist/modules/whatsapp/whatsapp-chat.model.d.ts +23 -0
  219. package/dist/modules/whatsapp/whatsapp-chat.model.js +55 -0
  220. package/dist/modules/whatsapp/whatsapp-chat.model.js.map +1 -0
  221. package/dist/modules/whatsapp/whatsapp-contact-profile.model.d.ts +23 -0
  222. package/dist/modules/whatsapp/whatsapp-contact-profile.model.js +54 -0
  223. package/dist/modules/whatsapp/whatsapp-contact-profile.model.js.map +1 -0
  224. package/dist/modules/whatsapp/whatsapp-message.model.d.ts +30 -0
  225. package/dist/modules/whatsapp/whatsapp-message.model.js +52 -0
  226. package/dist/modules/whatsapp/whatsapp-message.model.js.map +1 -0
  227. package/dist/modules/whatsapp/whatsapp-session.model.d.ts +33 -0
  228. package/dist/modules/whatsapp/whatsapp-session.model.js +65 -0
  229. package/dist/modules/whatsapp/whatsapp-session.model.js.map +1 -0
  230. package/dist/modules/whatsapp/whatsapp.routes.d.ts +2 -0
  231. package/dist/modules/whatsapp/whatsapp.routes.js +1237 -0
  232. package/dist/modules/whatsapp/whatsapp.routes.js.map +1 -0
  233. package/dist/plugins/cors.d.ts +3 -0
  234. package/dist/plugins/cors.js +11 -0
  235. package/dist/plugins/cors.js.map +1 -0
  236. package/dist/plugins/jwt.d.ts +3 -0
  237. package/dist/plugins/jwt.js +22 -0
  238. package/dist/plugins/jwt.js.map +1 -0
  239. package/dist/plugins/rawBody.d.ts +3 -0
  240. package/dist/plugins/rawBody.js +16 -0
  241. package/dist/plugins/rawBody.js.map +1 -0
  242. package/dist/plugins/rbac.d.ts +5 -0
  243. package/dist/plugins/rbac.js +29 -0
  244. package/dist/plugins/rbac.js.map +1 -0
  245. package/dist/routes/admin.routes.d.ts +2 -0
  246. package/dist/routes/admin.routes.js +169 -0
  247. package/dist/routes/admin.routes.js.map +1 -0
  248. package/dist/routes/health.routes.d.ts +2 -0
  249. package/dist/routes/health.routes.js +16 -0
  250. package/dist/routes/health.routes.js.map +1 -0
  251. package/dist/routes/webhook.routes.d.ts +2 -0
  252. package/dist/routes/webhook.routes.js +17 -0
  253. package/dist/routes/webhook.routes.js.map +1 -0
  254. package/dist/services/ai/base.ai.d.ts +19 -0
  255. package/dist/services/ai/base.ai.js +120 -0
  256. package/dist/services/ai/base.ai.js.map +1 -0
  257. package/dist/services/ai/gemini.service.d.ts +11 -0
  258. package/dist/services/ai/gemini.service.js +43 -0
  259. package/dist/services/ai/gemini.service.js.map +1 -0
  260. package/dist/services/ai/index.d.ts +2 -0
  261. package/dist/services/ai/index.js +26 -0
  262. package/dist/services/ai/index.js.map +1 -0
  263. package/dist/services/ai/openai.service.d.ts +11 -0
  264. package/dist/services/ai/openai.service.js +50 -0
  265. package/dist/services/ai/openai.service.js.map +1 -0
  266. package/dist/services/elevenlabs.service.d.ts +52 -0
  267. package/dist/services/elevenlabs.service.js +447 -0
  268. package/dist/services/elevenlabs.service.js.map +1 -0
  269. package/dist/services/google-calendar.service.d.ts +60 -0
  270. package/dist/services/google-calendar.service.js +494 -0
  271. package/dist/services/google-calendar.service.js.map +1 -0
  272. package/dist/services/inbound-call-schedule.service.d.ts +11 -0
  273. package/dist/services/inbound-call-schedule.service.js +162 -0
  274. package/dist/services/inbound-call-schedule.service.js.map +1 -0
  275. package/dist/services/netgsm.service.d.ts +41 -0
  276. package/dist/services/netgsm.service.js +89 -0
  277. package/dist/services/netgsm.service.js.map +1 -0
  278. package/dist/services/unipile.service.d.ts +41 -0
  279. package/dist/services/unipile.service.js +149 -0
  280. package/dist/services/unipile.service.js.map +1 -0
  281. package/dist/services/whatsapp-agent.service.d.ts +139 -0
  282. package/dist/services/whatsapp-agent.service.js +2055 -0
  283. package/dist/services/whatsapp-agent.service.js.map +1 -0
  284. package/dist/services/whatsapp.service.d.ts +26 -0
  285. package/dist/services/whatsapp.service.js +206 -0
  286. package/dist/services/whatsapp.service.js.map +1 -0
  287. package/dist/templates/index.d.ts +39 -0
  288. package/dist/templates/index.js +35 -0
  289. package/dist/templates/index.js.map +1 -0
  290. package/dist/templates/receptionist.d.ts +2 -0
  291. package/dist/templates/receptionist.js +39 -0
  292. package/dist/templates/receptionist.js.map +1 -0
  293. package/dist/templates/survey.d.ts +2 -0
  294. package/dist/templates/survey.js +41 -0
  295. package/dist/templates/survey.js.map +1 -0
  296. package/dist/types/index.d.ts +173 -0
  297. package/dist/types/index.js +3 -0
  298. package/dist/types/index.js.map +1 -0
  299. package/dist/utils/logger.d.ts +3 -0
  300. package/dist/utils/logger.js +105 -0
  301. package/dist/utils/logger.js.map +1 -0
  302. package/docker-compose.nestjs.yml +89 -0
  303. package/docker-compose.yml +78 -0
  304. package/docs/AI_AGENT_ENHANCEMENT_PLAN.md +164 -0
  305. package/docs/API.md +1193 -0
  306. package/docs/API_ENDPOINTS.md +344 -0
  307. package/docs/ARCHITECTURE.md +305 -0
  308. package/docs/AUTH_API.md +252 -0
  309. package/docs/BILLING_SMS_ALERTS.md +94 -0
  310. package/docs/CHAT_ASSIGNMENT_SYSTEM.md +118 -0
  311. package/docs/CLIENT_TOOLS_AND_FEATURES.md +337 -0
  312. package/docs/ELEVENLABS_WEBHOOK_TOOLS.md +644 -0
  313. package/docs/FRONTEND_CHECKLIST.md +227 -0
  314. package/docs/IMPLEMENTATION_STATUS.md +470 -0
  315. package/docs/MIGRATION_GUIDE.md +96 -0
  316. package/docs/MISSINGS_REPORT.md +507 -0
  317. package/docs/NESTJS_MIGRATION_REFERENCE.md +5136 -0
  318. package/docs/PROJECT_DESCRIPTION.md +1038 -0
  319. package/docs/SCALING.md +148 -0
  320. package/docs/SESSION_SUMMARY_2026_03_17.md +135 -0
  321. package/docs/WHATSAPP_AGENT.md +1086 -0
  322. package/docs/architecture/00-SYSTEM-OVERVIEW.md +318 -0
  323. package/docs/architecture/01-DATABASE-SCHEMA.md +2564 -0
  324. package/docs/architecture/02-AUTHENTICATION.md +1040 -0
  325. package/docs/architecture/03-MULTI-CLINIC.md +742 -0
  326. package/docs/architecture/04-WHATSAPP-AGENT.md +608 -0
  327. package/docs/architecture/05-OPERATOR-WORKFLOW.md +444 -0
  328. package/docs/architecture/06-BAILEYS-MICROSERVICE.md +616 -0
  329. package/docs/architecture/07-APPOINTMENTS.md +849 -0
  330. package/docs/architecture/08-VOICE-CALLS.md +470 -0
  331. package/docs/architecture/09-OUTBOUND-CAMPAIGNS.md +542 -0
  332. package/docs/architecture/10-CLIENT-TOOLS.md +665 -0
  333. package/docs/architecture/11-BILLING.md +458 -0
  334. package/docs/architecture/12-SECURITY.md +216 -0
  335. package/docs/architecture/13-LOGGING-AUDIT.md +549 -0
  336. package/docs/architecture/14-META-BUSINESS-API.md +454 -0
  337. package/docs/architecture/15-AI-MODULE.md +479 -0
  338. package/docs/architecture/16-BACKGROUND-JOBS.md +469 -0
  339. package/docs/architecture/17-REALTIME-LIVECHAT.md +447 -0
  340. package/docs/architecture/18-FILE-STORAGE.md +410 -0
  341. package/docs/architecture/19-PATIENTS.md +1034 -0
  342. package/docs/architecture/20-TREATMENTS-AND-PLANS.md +774 -0
  343. package/docs/architecture/21-BEFORE-AFTER-PHOTOS.md +519 -0
  344. package/docs/database.md +456 -0
  345. package/docs/ornek-randevu-onay.csv +3 -0
  346. package/ecosystem.config.js +16 -0
  347. package/elevenlabs-convai-api-reference.md +1171 -0
  348. package/frontend/.dockerignore +2 -0
  349. package/frontend/Dockerfile +24 -0
  350. package/frontend/README.md +75 -0
  351. package/frontend/components.json +25 -0
  352. package/frontend/eslint.config.js +23 -0
  353. package/frontend/index.html +13 -0
  354. package/frontend/nginx.conf +37 -0
  355. package/frontend/package-lock.json +8709 -0
  356. package/frontend/package.json +71 -0
  357. package/frontend/public/favicon.svg +1 -0
  358. package/frontend/public/icons.svg +24 -0
  359. package/frontend/src/App.tsx +125 -0
  360. package/frontend/src/components/error-boundary.tsx +50 -0
  361. package/frontend/src/components/shared/activity-timeline.tsx +66 -0
  362. package/frontend/src/components/shared/appointment-calendar.css +80 -0
  363. package/frontend/src/components/shared/appointment-calendar.tsx +245 -0
  364. package/frontend/src/components/shared/chat-bubble.tsx +72 -0
  365. package/frontend/src/components/shared/combobox.tsx +119 -0
  366. package/frontend/src/components/shared/confirm-dialog.tsx +57 -0
  367. package/frontend/src/components/shared/data-table-pagination.tsx +97 -0
  368. package/frontend/src/components/shared/data-table-toolbar.tsx +39 -0
  369. package/frontend/src/components/shared/empty-state.tsx +27 -0
  370. package/frontend/src/components/shared/file-upload.tsx +140 -0
  371. package/frontend/src/components/shared/index.ts +20 -0
  372. package/frontend/src/components/shared/language-switcher.tsx +29 -0
  373. package/frontend/src/components/shared/notification-dropdown.tsx +115 -0
  374. package/frontend/src/components/shared/page-header.tsx +23 -0
  375. package/frontend/src/components/shared/stat-card.tsx +37 -0
  376. package/frontend/src/components/shared/status-badge.tsx +70 -0
  377. package/frontend/src/components/shared/status-dot.tsx +43 -0
  378. package/frontend/src/components/ui/alert-dialog.tsx +187 -0
  379. package/frontend/src/components/ui/alert.tsx +76 -0
  380. package/frontend/src/components/ui/avatar.tsx +109 -0
  381. package/frontend/src/components/ui/badge.tsx +52 -0
  382. package/frontend/src/components/ui/breadcrumb.tsx +125 -0
  383. package/frontend/src/components/ui/button.tsx +60 -0
  384. package/frontend/src/components/ui/calendar.tsx +219 -0
  385. package/frontend/src/components/ui/card.tsx +103 -0
  386. package/frontend/src/components/ui/chart.tsx +371 -0
  387. package/frontend/src/components/ui/checkbox.tsx +29 -0
  388. package/frontend/src/components/ui/collapsible.tsx +19 -0
  389. package/frontend/src/components/ui/command.tsx +194 -0
  390. package/frontend/src/components/ui/dialog.tsx +158 -0
  391. package/frontend/src/components/ui/dropdown-menu.tsx +268 -0
  392. package/frontend/src/components/ui/input-group.tsx +156 -0
  393. package/frontend/src/components/ui/input.tsx +20 -0
  394. package/frontend/src/components/ui/label.tsx +20 -0
  395. package/frontend/src/components/ui/pagination.tsx +130 -0
  396. package/frontend/src/components/ui/popover.tsx +90 -0
  397. package/frontend/src/components/ui/progress.tsx +83 -0
  398. package/frontend/src/components/ui/radio-group.tsx +36 -0
  399. package/frontend/src/components/ui/scroll-area.tsx +54 -0
  400. package/frontend/src/components/ui/select.tsx +199 -0
  401. package/frontend/src/components/ui/separator.tsx +23 -0
  402. package/frontend/src/components/ui/sheet.tsx +138 -0
  403. package/frontend/src/components/ui/sidebar.tsx +723 -0
  404. package/frontend/src/components/ui/skeleton.tsx +13 -0
  405. package/frontend/src/components/ui/sonner.tsx +47 -0
  406. package/frontend/src/components/ui/switch.tsx +30 -0
  407. package/frontend/src/components/ui/table.tsx +114 -0
  408. package/frontend/src/components/ui/tabs.tsx +82 -0
  409. package/frontend/src/components/ui/textarea.tsx +18 -0
  410. package/frontend/src/components/ui/toggle-group.tsx +89 -0
  411. package/frontend/src/components/ui/toggle.tsx +43 -0
  412. package/frontend/src/components/ui/tooltip.tsx +64 -0
  413. package/frontend/src/hooks/use-mobile.ts +19 -0
  414. package/frontend/src/i18n/index.ts +20 -0
  415. package/frontend/src/i18n/locales/en.json +786 -0
  416. package/frontend/src/i18n/locales/tr.json +786 -0
  417. package/frontend/src/index.css +134 -0
  418. package/frontend/src/layouts/admin-layout.tsx +111 -0
  419. package/frontend/src/layouts/app-header.tsx +130 -0
  420. package/frontend/src/layouts/app-layout.tsx +19 -0
  421. package/frontend/src/layouts/app-sidebar.tsx +212 -0
  422. package/frontend/src/layouts/auth-guard.tsx +31 -0
  423. package/frontend/src/layouts/mobile-sidebar.tsx +120 -0
  424. package/frontend/src/lib/api.ts +68 -0
  425. package/frontend/src/lib/hooks/use-appointments.ts +224 -0
  426. package/frontend/src/lib/hooks/use-availability-blocks.ts +83 -0
  427. package/frontend/src/lib/hooks/use-chats.ts +236 -0
  428. package/frontend/src/lib/hooks/use-clinic-detail.ts +171 -0
  429. package/frontend/src/lib/hooks/use-clinics.ts +37 -0
  430. package/frontend/src/lib/hooks/use-doctor-calendar.ts +80 -0
  431. package/frontend/src/lib/hooks/use-examinations.ts +89 -0
  432. package/frontend/src/lib/hooks/use-medical-history.ts +52 -0
  433. package/frontend/src/lib/hooks/use-patients.ts +296 -0
  434. package/frontend/src/lib/hooks/use-photo-sets.ts +118 -0
  435. package/frontend/src/lib/hooks/use-treatment-plans.ts +152 -0
  436. package/frontend/src/lib/hooks/use-treatments.ts +125 -0
  437. package/frontend/src/lib/hooks/use-users.ts +172 -0
  438. package/frontend/src/lib/utils.ts +6 -0
  439. package/frontend/src/main.tsx +17 -0
  440. package/frontend/src/pages/admin/agents/detail.tsx +774 -0
  441. package/frontend/src/pages/admin/agents/import.tsx +280 -0
  442. package/frontend/src/pages/admin/agents/index.tsx +245 -0
  443. package/frontend/src/pages/admin/ai-playground.tsx +543 -0
  444. package/frontend/src/pages/appointments/create-appointment-dialog.tsx +390 -0
  445. package/frontend/src/pages/appointments/index.tsx +860 -0
  446. package/frontend/src/pages/audit/index.tsx +24 -0
  447. package/frontend/src/pages/auth/login.tsx +194 -0
  448. package/frontend/src/pages/billing/index.tsx +24 -0
  449. package/frontend/src/pages/calendar/index.tsx +704 -0
  450. package/frontend/src/pages/calendar-connections/index.tsx +295 -0
  451. package/frontend/src/pages/calls/index.tsx +24 -0
  452. package/frontend/src/pages/campaigns/index.tsx +24 -0
  453. package/frontend/src/pages/chats/index.tsx +981 -0
  454. package/frontend/src/pages/clinics/index.tsx +224 -0
  455. package/frontend/src/pages/clinics/settings.tsx +412 -0
  456. package/frontend/src/pages/components-showcase.tsx +773 -0
  457. package/frontend/src/pages/connections/index.tsx +328 -0
  458. package/frontend/src/pages/dashboard.tsx +50 -0
  459. package/frontend/src/pages/leads/index.tsx +24 -0
  460. package/frontend/src/pages/my-schedule/index.tsx +496 -0
  461. package/frontend/src/pages/patients/create-patient-dialog.tsx +358 -0
  462. package/frontend/src/pages/patients/detail.tsx +1195 -0
  463. package/frontend/src/pages/patients/edit-patient-dialog.tsx +387 -0
  464. package/frontend/src/pages/patients/examinations-tab.tsx +460 -0
  465. package/frontend/src/pages/patients/index.tsx +381 -0
  466. package/frontend/src/pages/patients/medical-history-dialog.tsx +207 -0
  467. package/frontend/src/pages/patients/photo-sets-tab.tsx +616 -0
  468. package/frontend/src/pages/patients/timeline-tab.tsx +164 -0
  469. package/frontend/src/pages/patients/treatment-plans-tab.tsx +598 -0
  470. package/frontend/src/pages/phone-numbers/detail.tsx +427 -0
  471. package/frontend/src/pages/phone-numbers/index.tsx +455 -0
  472. package/frontend/src/pages/platform/index.tsx +454 -0
  473. package/frontend/src/pages/settings/index.tsx +126 -0
  474. package/frontend/src/pages/treatments/index.tsx +487 -0
  475. package/frontend/src/pages/users/doctor-profile.tsx +672 -0
  476. package/frontend/src/pages/users/edit.tsx +329 -0
  477. package/frontend/src/pages/users/index.tsx +407 -0
  478. package/frontend/src/pages/validation/index.tsx +24 -0
  479. package/frontend/src/stores/auth.store.ts +108 -0
  480. package/frontend/src/stores/ui.store.ts +41 -0
  481. package/frontend/tsconfig.app.json +32 -0
  482. package/frontend/tsconfig.json +13 -0
  483. package/frontend/tsconfig.node.json +26 -0
  484. package/frontend/vite.config.ts +29 -0
  485. package/nestjs/.dockerignore +5 -0
  486. package/nestjs/.env.docker +64 -0
  487. package/nestjs/.prettierrc +4 -0
  488. package/nestjs/Dockerfile +36 -0
  489. package/nestjs/README.md +98 -0
  490. package/nestjs/eslint.config.mjs +35 -0
  491. package/nestjs/nest-cli.json +8 -0
  492. package/nestjs/package-lock.json +13390 -0
  493. package/nestjs/package.json +114 -0
  494. package/nestjs/prisma/migrations/20260409161536_add_message_metadata_fields/migration.sql +1746 -0
  495. package/nestjs/prisma/migrations/20260410140436_add_agent_ai_fields/migration.sql +36 -0
  496. package/nestjs/prisma/migrations/20260410175519_add_agent_clinic_assignments/migration.sql +21 -0
  497. package/nestjs/prisma/migrations/20260412094344_make_agent_tenant_optional/migration.sql +2 -0
  498. package/nestjs/prisma/migrations/20260412110008_add_admin_chat_sessions/migration.sql +47 -0
  499. package/nestjs/prisma/migrations/migration_lock.toml +3 -0
  500. package/nestjs/prisma/schema.prisma +1843 -0
  501. package/nestjs/prisma/seed.ts +375 -0
  502. package/nestjs/prisma.config.ts +14 -0
  503. package/nestjs/src/admin/admin.controller.ts +27 -0
  504. package/nestjs/src/admin/admin.module.ts +16 -0
  505. package/nestjs/src/admin/admin.service.ts +91 -0
  506. package/nestjs/src/admin/ai-chat-session.service.ts +454 -0
  507. package/nestjs/src/admin/ai-test.controller.ts +191 -0
  508. package/nestjs/src/admin/superadmin.controller.ts +106 -0
  509. package/nestjs/src/agents/agents.controller.ts +262 -0
  510. package/nestjs/src/agents/agents.module.ts +13 -0
  511. package/nestjs/src/agents/agents.service.ts +733 -0
  512. package/nestjs/src/agents/dto/create-agent.dto.ts +99 -0
  513. package/nestjs/src/agents/dto/index.ts +2 -0
  514. package/nestjs/src/agents/dto/update-agent.dto.ts +148 -0
  515. package/nestjs/src/app.module.ts +115 -0
  516. package/nestjs/src/appointment-validation/appointment-validation.controller.ts +194 -0
  517. package/nestjs/src/appointment-validation/appointment-validation.module.ts +16 -0
  518. package/nestjs/src/appointment-validation/appointment-validation.service.ts +450 -0
  519. package/nestjs/src/appointment-validation/dto/create-batch.dto.ts +105 -0
  520. package/nestjs/src/appointment-validation/dto/index.ts +1 -0
  521. package/nestjs/src/appointment-validation/processors/validation-dispatch.processor.ts +26 -0
  522. package/nestjs/src/appointment-validation/processors/validation-sync.processor.ts +23 -0
  523. package/nestjs/src/appointments/appointments.controller.ts +268 -0
  524. package/nestjs/src/appointments/appointments.module.ts +13 -0
  525. package/nestjs/src/appointments/appointments.service.ts +773 -0
  526. package/nestjs/src/appointments/dto/create-appointment.dto.ts +72 -0
  527. package/nestjs/src/appointments/dto/index.ts +4 -0
  528. package/nestjs/src/appointments/dto/query-appointments.dto.ts +60 -0
  529. package/nestjs/src/appointments/dto/update-appointment.dto.ts +43 -0
  530. package/nestjs/src/appointments/dto/update-status.dto.ts +18 -0
  531. package/nestjs/src/appointments/processors/reminder.processor.ts +243 -0
  532. package/nestjs/src/audit/audit.controller.ts +84 -0
  533. package/nestjs/src/audit/audit.decorator.ts +20 -0
  534. package/nestjs/src/audit/audit.interceptor.ts +67 -0
  535. package/nestjs/src/audit/audit.interfaces.ts +15 -0
  536. package/nestjs/src/audit/audit.module.ts +12 -0
  537. package/nestjs/src/audit/audit.service.ts +177 -0
  538. package/nestjs/src/auth/auth.controller.ts +116 -0
  539. package/nestjs/src/auth/auth.module.ts +25 -0
  540. package/nestjs/src/auth/auth.service.ts +612 -0
  541. package/nestjs/src/auth/dto/change-password.dto.ts +13 -0
  542. package/nestjs/src/auth/dto/forgot-password.dto.ts +8 -0
  543. package/nestjs/src/auth/dto/index.ts +6 -0
  544. package/nestjs/src/auth/dto/login.dto.ts +13 -0
  545. package/nestjs/src/auth/dto/refresh.dto.ts +8 -0
  546. package/nestjs/src/auth/dto/register.dto.ts +28 -0
  547. package/nestjs/src/auth/dto/reset-password.dto.ts +13 -0
  548. package/nestjs/src/auth/permissions.config.ts +85 -0
  549. package/nestjs/src/availability-blocks/availability-blocks.controller.ts +83 -0
  550. package/nestjs/src/availability-blocks/availability-blocks.module.ts +10 -0
  551. package/nestjs/src/availability-blocks/availability-blocks.service.ts +202 -0
  552. package/nestjs/src/billing/billing.controller.ts +104 -0
  553. package/nestjs/src/billing/billing.module.ts +12 -0
  554. package/nestjs/src/billing/billing.service.ts +398 -0
  555. package/nestjs/src/billing/dto/index.ts +2 -0
  556. package/nestjs/src/billing/dto/query-billing.dto.ts +29 -0
  557. package/nestjs/src/billing/dto/record-payment.dto.ts +60 -0
  558. package/nestjs/src/billing/processors/alerts.processor.ts +216 -0
  559. package/nestjs/src/billing/processors/snapshot.processor.ts +181 -0
  560. package/nestjs/src/calls/calls.controller.ts +92 -0
  561. package/nestjs/src/calls/calls.module.ts +10 -0
  562. package/nestjs/src/calls/calls.service.ts +359 -0
  563. package/nestjs/src/calls/dto/index.ts +1 -0
  564. package/nestjs/src/calls/dto/query-calls.dto.ts +46 -0
  565. package/nestjs/src/clinics/clinics.controller.ts +226 -0
  566. package/nestjs/src/clinics/clinics.module.ts +11 -0
  567. package/nestjs/src/clinics/clinics.service.ts +203 -0
  568. package/nestjs/src/clinics/dto/create-clinic.dto.ts +40 -0
  569. package/nestjs/src/clinics/dto/create-meta-connection.dto.ts +44 -0
  570. package/nestjs/src/clinics/dto/index.ts +4 -0
  571. package/nestjs/src/clinics/dto/update-clinic.dto.ts +133 -0
  572. package/nestjs/src/clinics/dto/update-meta-connection.dto.ts +22 -0
  573. package/nestjs/src/clinics/meta-connections.service.ts +210 -0
  574. package/nestjs/src/common/decorators/accessible-clinics.decorator.ts +9 -0
  575. package/nestjs/src/common/decorators/current-user.decorator.ts +10 -0
  576. package/nestjs/src/common/decorators/features.decorator.ts +7 -0
  577. package/nestjs/src/common/decorators/index.ts +4 -0
  578. package/nestjs/src/common/decorators/permissions.decorator.ts +13 -0
  579. package/nestjs/src/common/gateways/events.gateway.ts +157 -0
  580. package/nestjs/src/common/guards/clinic-access.guard.ts +40 -0
  581. package/nestjs/src/common/guards/features.guard.ts +38 -0
  582. package/nestjs/src/common/guards/index.ts +5 -0
  583. package/nestjs/src/common/guards/jwt-auth.guard.ts +54 -0
  584. package/nestjs/src/common/guards/permissions.guard.ts +50 -0
  585. package/nestjs/src/common/guards/superadmin.guard.ts +35 -0
  586. package/nestjs/src/common/interceptors/request-context.interceptor.ts +32 -0
  587. package/nestjs/src/common/interceptors/superadmin-tenant.interceptor.ts +42 -0
  588. package/nestjs/src/common/interfaces/jwt-payload.interface.ts +11 -0
  589. package/nestjs/src/config/config.module.ts +13 -0
  590. package/nestjs/src/database/database.module.ts +9 -0
  591. package/nestjs/src/database/prisma.service.ts +20 -0
  592. package/nestjs/src/database/tenant-context.ts +27 -0
  593. package/nestjs/src/google-calendar/google-calendar.controller.ts +259 -0
  594. package/nestjs/src/google-calendar/google-calendar.module.ts +10 -0
  595. package/nestjs/src/google-calendar/google-calendar.service.ts +811 -0
  596. package/nestjs/src/integrations/ai/ai.interface.ts +74 -0
  597. package/nestjs/src/integrations/ai/ai.module.ts +11 -0
  598. package/nestjs/src/integrations/ai/ai.service.ts +148 -0
  599. package/nestjs/src/integrations/ai/providers/anthropic.provider.ts +146 -0
  600. package/nestjs/src/integrations/ai/providers/openai.provider.ts +158 -0
  601. package/nestjs/src/integrations/elevenlabs/elevenlabs.module.ts +8 -0
  602. package/nestjs/src/integrations/elevenlabs/elevenlabs.service.ts +226 -0
  603. package/nestjs/src/integrations/encryption/encryption.module.ts +9 -0
  604. package/nestjs/src/integrations/encryption/encryption.service.ts +31 -0
  605. package/nestjs/src/integrations/image/image.module.ts +9 -0
  606. package/nestjs/src/integrations/image/image.service.ts +61 -0
  607. package/nestjs/src/integrations/meta-business/meta-business.module.ts +10 -0
  608. package/nestjs/src/integrations/meta-business/meta-instagram.service.ts +94 -0
  609. package/nestjs/src/integrations/meta-business/meta-webhook.service.ts +52 -0
  610. package/nestjs/src/integrations/meta-business/meta-whatsapp.service.ts +254 -0
  611. package/nestjs/src/integrations/minio/minio.module.ts +9 -0
  612. package/nestjs/src/integrations/minio/minio.service.ts +88 -0
  613. package/nestjs/src/integrations/netgsm/netgsm.module.ts +8 -0
  614. package/nestjs/src/integrations/netgsm/netgsm.service.ts +17 -0
  615. package/nestjs/src/integrations/tektippay/tektippay.module.ts +8 -0
  616. package/nestjs/src/integrations/tektippay/tektippay.service.ts +23 -0
  617. package/nestjs/src/leads/dto/index.ts +2 -0
  618. package/nestjs/src/leads/dto/query-leads.dto.ts +50 -0
  619. package/nestjs/src/leads/dto/update-lead.dto.ts +26 -0
  620. package/nestjs/src/leads/leads.controller.ts +184 -0
  621. package/nestjs/src/leads/leads.module.ts +10 -0
  622. package/nestjs/src/leads/leads.service.ts +375 -0
  623. package/nestjs/src/logging/logging.controller.ts +82 -0
  624. package/nestjs/src/logging/logging.module.ts +11 -0
  625. package/nestjs/src/logging/logging.service.ts +180 -0
  626. package/nestjs/src/main.ts +86 -0
  627. package/nestjs/src/outbound-campaigns/dto/create-campaign.dto.ts +47 -0
  628. package/nestjs/src/outbound-campaigns/dto/index.ts +3 -0
  629. package/nestjs/src/outbound-campaigns/dto/update-campaign.dto.ts +31 -0
  630. package/nestjs/src/outbound-campaigns/dto/upload-entries.dto.ts +35 -0
  631. package/nestjs/src/outbound-campaigns/outbound-campaigns.controller.ts +307 -0
  632. package/nestjs/src/outbound-campaigns/outbound-campaigns.module.ts +13 -0
  633. package/nestjs/src/outbound-campaigns/outbound-campaigns.service.ts +471 -0
  634. package/nestjs/src/outbound-campaigns/processors/campaign-dispatch.processor.ts +366 -0
  635. package/nestjs/src/patients/documents.service.ts +231 -0
  636. package/nestjs/src/patients/dto/create-examination.dto.ts +34 -0
  637. package/nestjs/src/patients/dto/create-note.dto.ts +14 -0
  638. package/nestjs/src/patients/dto/create-patient.dto.ts +86 -0
  639. package/nestjs/src/patients/dto/create-photo-set.dto.ts +32 -0
  640. package/nestjs/src/patients/dto/index.ts +10 -0
  641. package/nestjs/src/patients/dto/update-examination.dto.ts +29 -0
  642. package/nestjs/src/patients/dto/update-medical-history.dto.ts +47 -0
  643. package/nestjs/src/patients/dto/update-patient.dto.ts +87 -0
  644. package/nestjs/src/patients/dto/update-photo-set.dto.ts +28 -0
  645. package/nestjs/src/patients/dto/upload-document.dto.ts +31 -0
  646. package/nestjs/src/patients/dto/upload-photo.dto.ts +27 -0
  647. package/nestjs/src/patients/examinations.service.ts +271 -0
  648. package/nestjs/src/patients/medical-history.service.ts +149 -0
  649. package/nestjs/src/patients/notes.service.ts +172 -0
  650. package/nestjs/src/patients/patients.controller.ts +485 -0
  651. package/nestjs/src/patients/patients.module.ts +22 -0
  652. package/nestjs/src/patients/patients.service.ts +412 -0
  653. package/nestjs/src/patients/photo-sets.service.ts +389 -0
  654. package/nestjs/src/phone-numbers/dto/create-phone-number.dto.ts +57 -0
  655. package/nestjs/src/phone-numbers/dto/index.ts +3 -0
  656. package/nestjs/src/phone-numbers/dto/update-phone-number.dto.ts +38 -0
  657. package/nestjs/src/phone-numbers/dto/update-schedule.dto.ts +39 -0
  658. package/nestjs/src/phone-numbers/phone-numbers.controller.ts +125 -0
  659. package/nestjs/src/phone-numbers/phone-numbers.module.ts +10 -0
  660. package/nestjs/src/phone-numbers/phone-numbers.service.ts +209 -0
  661. package/nestjs/src/plans/dto/create-plan.dto.ts +70 -0
  662. package/nestjs/src/plans/dto/index.ts +2 -0
  663. package/nestjs/src/plans/dto/update-plan.dto.ts +80 -0
  664. package/nestjs/src/plans/plans.controller.ts +50 -0
  665. package/nestjs/src/plans/plans.module.ts +10 -0
  666. package/nestjs/src/plans/plans.service.ts +115 -0
  667. package/nestjs/src/platform/dto/create-tenant.dto.ts +36 -0
  668. package/nestjs/src/platform/dto/index.ts +2 -0
  669. package/nestjs/src/platform/dto/update-tenant-platform.dto.ts +44 -0
  670. package/nestjs/src/platform/platform.controller.ts +79 -0
  671. package/nestjs/src/platform/platform.module.ts +10 -0
  672. package/nestjs/src/platform/platform.service.ts +301 -0
  673. package/nestjs/src/queue/queue.module.ts +56 -0
  674. package/nestjs/src/redis/redis.module.ts +20 -0
  675. package/nestjs/src/tenants/dto/index.ts +1 -0
  676. package/nestjs/src/tenants/dto/update-tenant.dto.ts +15 -0
  677. package/nestjs/src/tenants/tenants.controller.ts +45 -0
  678. package/nestjs/src/tenants/tenants.module.ts +10 -0
  679. package/nestjs/src/tenants/tenants.service.ts +41 -0
  680. package/nestjs/src/tools/adapters/elevenlabs-http.adapter.ts +51 -0
  681. package/nestjs/src/tools/adapters/elevenlabs-ws.adapter.ts +59 -0
  682. package/nestjs/src/tools/handlers/calendar.tools.ts +441 -0
  683. package/nestjs/src/tools/handlers/notification.tools.ts +34 -0
  684. package/nestjs/src/tools/handlers/operator.tools.ts +303 -0
  685. package/nestjs/src/tools/handlers/patient.tools.ts +242 -0
  686. package/nestjs/src/tools/handlers/payment.tools.ts +43 -0
  687. package/nestjs/src/tools/handlers/validation.tools.ts +152 -0
  688. package/nestjs/src/tools/tool-registry.service.ts +221 -0
  689. package/nestjs/src/tools/tool.decorator.ts +16 -0
  690. package/nestjs/src/tools/tool.interfaces.ts +26 -0
  691. package/nestjs/src/tools/tools.module.ts +50 -0
  692. package/nestjs/src/treatments/dto/create-plan-item.dto.ts +27 -0
  693. package/nestjs/src/treatments/dto/create-treatment-plan.dto.ts +69 -0
  694. package/nestjs/src/treatments/dto/create-treatment.dto.ts +59 -0
  695. package/nestjs/src/treatments/dto/index.ts +6 -0
  696. package/nestjs/src/treatments/dto/update-plan-item.dto.ts +23 -0
  697. package/nestjs/src/treatments/dto/update-treatment-plan.dto.ts +22 -0
  698. package/nestjs/src/treatments/dto/update-treatment.dto.ts +70 -0
  699. package/nestjs/src/treatments/treatment-plans.service.ts +362 -0
  700. package/nestjs/src/treatments/treatments.controller.ts +265 -0
  701. package/nestjs/src/treatments/treatments.module.ts +14 -0
  702. package/nestjs/src/treatments/treatments.service.ts +165 -0
  703. package/nestjs/src/users/doctor-profiles.service.ts +202 -0
  704. package/nestjs/src/users/dto/index.ts +4 -0
  705. package/nestjs/src/users/dto/invite-user.dto.ts +52 -0
  706. package/nestjs/src/users/dto/update-clinic-assignments.dto.ts +9 -0
  707. package/nestjs/src/users/dto/update-doctor-profile.dto.ts +49 -0
  708. package/nestjs/src/users/dto/update-user.dto.ts +41 -0
  709. package/nestjs/src/users/users.controller.ts +142 -0
  710. package/nestjs/src/users/users.module.ts +11 -0
  711. package/nestjs/src/users/users.service.ts +250 -0
  712. package/nestjs/src/webhooks/elevenlabs-tool.controller.ts +66 -0
  713. package/nestjs/src/webhooks/elevenlabs-webhook.controller.ts +60 -0
  714. package/nestjs/src/webhooks/meta-webhook.controller.ts +178 -0
  715. package/nestjs/src/webhooks/processors/elevenlabs-webhook.processor.ts +28 -0
  716. package/nestjs/src/webhooks/webhooks.module.ts +17 -0
  717. package/nestjs/src/whatsapp/chat-context.service.ts +281 -0
  718. package/nestjs/src/whatsapp/dto/add-blacklist.dto.ts +13 -0
  719. package/nestjs/src/whatsapp/dto/index.ts +2 -0
  720. package/nestjs/src/whatsapp/dto/send-message.dto.ts +14 -0
  721. package/nestjs/src/whatsapp/listeners/meta-message.listener.ts +579 -0
  722. package/nestjs/src/whatsapp/meta-auth.controller.ts +268 -0
  723. package/nestjs/src/whatsapp/meta-instagram-auth.controller.ts +244 -0
  724. package/nestjs/src/whatsapp/operator.service.ts +692 -0
  725. package/nestjs/src/whatsapp/processors/cost-sweep.processor.ts +130 -0
  726. package/nestjs/src/whatsapp/processors/grace.processor.ts +191 -0
  727. package/nestjs/src/whatsapp/processors/message-buffer.processor.ts +138 -0
  728. package/nestjs/src/whatsapp/processors/message-cleanup.processor.ts +148 -0
  729. package/nestjs/src/whatsapp/processors/meta-token-refresh.processor.ts +114 -0
  730. package/nestjs/src/whatsapp/processors/operator-expiry.processor.ts +105 -0
  731. package/nestjs/src/whatsapp/processors/profile-update.processor.ts +234 -0
  732. package/nestjs/src/whatsapp/processors/session-cleanup.processor.ts +178 -0
  733. package/nestjs/src/whatsapp/processors/session-labels.processor.ts +248 -0
  734. package/nestjs/src/whatsapp/whatsapp-agent.service.ts +2506 -0
  735. package/nestjs/src/whatsapp/whatsapp-recovery.service.ts +117 -0
  736. package/nestjs/src/whatsapp/whatsapp.controller.ts +398 -0
  737. package/nestjs/src/whatsapp/whatsapp.module.ts +51 -0
  738. package/nestjs/src/whatsapp/whatsapp.service.ts +592 -0
  739. package/nestjs/test/app.e2e-spec.ts +25 -0
  740. package/nestjs/test/jest-e2e.json +9 -0
  741. package/nestjs/tsconfig.build.json +4 -0
  742. package/nestjs/tsconfig.json +25 -0
  743. package/nginx.example.conf +18 -0
  744. package/package.json +47 -0
  745. package/scripts/addRecipient.ts +48 -0
  746. package/scripts/listRecipients.ts +31 -0
  747. package/scripts/migrate-agent-ref.ts +86 -0
  748. package/scripts/migrate-sessions.ts +183 -0
  749. package/scripts/promote.ts +27 -0
  750. package/scripts/retrigger.ts +84 -0
  751. package/scripts/seed.ts +435 -0
  752. package/scripts/testSend.ts +63 -0
  753. package/src/app.ts +85 -0
  754. package/src/config/agentPrompts.json +19 -0
  755. package/src/config/database.ts +21 -0
  756. package/src/config/env.ts +94 -0
  757. package/src/config/index.ts +86 -0
  758. package/src/controllers/webhook.controller.ts +150 -0
  759. package/src/errors/index.ts +9 -0
  760. package/src/hooks/webhookValidator.ts +55 -0
  761. package/src/index.ts +68 -0
  762. package/src/migrations/001_session-architecture.ts +138 -0
  763. package/src/migrations/002_agent-ref.ts +65 -0
  764. package/src/migrations/003_shift-schedule.ts +55 -0
  765. package/src/migrations/004_invert-shift-to-clinic-hours.ts +30 -0
  766. package/src/migrations/005_composite-baileys-chat-ids.ts +60 -0
  767. package/src/migrations/migration.model.ts +27 -0
  768. package/src/migrations/migration.routes.ts +40 -0
  769. package/src/migrations/migration.runner.ts +112 -0
  770. package/src/models/ConversationClaim.ts +17 -0
  771. package/src/models/ConversationEvaluation.ts +91 -0
  772. package/src/models/Summary.ts +77 -0
  773. package/src/models/Transcription.ts +68 -0
  774. package/src/models/WhatsAppRecipient.ts +37 -0
  775. package/src/modules/admin/admin.routes.ts +2385 -0
  776. package/src/modules/admin/elevenlabs-test-chat.routes.ts +193 -0
  777. package/src/modules/admin/whatsapp-test-chat.routes.ts +244 -0
  778. package/src/modules/agents/agent.model.ts +93 -0
  779. package/src/modules/agents/agent.routes.ts +65 -0
  780. package/src/modules/appointment-validation/appointment-validation.model.ts +163 -0
  781. package/src/modules/appointment-validation/appointment-validation.routes.ts +275 -0
  782. package/src/modules/appointment-validation/appointment-validation.service.ts +1028 -0
  783. package/src/modules/auth/auth.model.ts +42 -0
  784. package/src/modules/auth/auth.routes.ts +199 -0
  785. package/src/modules/auth/auth.service.ts +210 -0
  786. package/src/modules/auth/refresh-token.model.ts +26 -0
  787. package/src/modules/billing/billing-alert.model.ts +28 -0
  788. package/src/modules/billing/billing-period-snapshot.model.ts +68 -0
  789. package/src/modules/billing/billing.model.ts +42 -0
  790. package/src/modules/billing/billing.routes.ts +67 -0
  791. package/src/modules/billing/billing.service.ts +562 -0
  792. package/src/modules/billing/payment.model.ts +42 -0
  793. package/src/modules/calls/call.model.ts +102 -0
  794. package/src/modules/calls/call.routes.ts +118 -0
  795. package/src/modules/campaigns/campaign.model.ts +111 -0
  796. package/src/modules/campaigns/campaign.routes.ts +402 -0
  797. package/src/modules/campaigns/campaign.service.ts +99 -0
  798. package/src/modules/google-calendar/google-calendar.routes.ts +31 -0
  799. package/src/modules/inbound-call/inbound-call-config.model.ts +49 -0
  800. package/src/modules/inbound-call/inbound-call.routes.ts +289 -0
  801. package/src/modules/leads/lead.model.ts +40 -0
  802. package/src/modules/leads/lead.routes.ts +246 -0
  803. package/src/modules/logs/log.model.ts +27 -0
  804. package/src/modules/logs/log.routes.ts +102 -0
  805. package/src/modules/plans/plan.model.ts +45 -0
  806. package/src/modules/surveys/survey.model.ts +70 -0
  807. package/src/modules/surveys/survey.routes.ts +187 -0
  808. package/src/modules/tenants/tenant.model.ts +181 -0
  809. package/src/modules/tenants/tenant.routes.ts +78 -0
  810. package/src/modules/users/user.routes.ts +126 -0
  811. package/src/modules/webhooks/elevenlabs-tool.routes.ts +94 -0
  812. package/src/modules/webhooks/elevenlabs-tool.service.ts +491 -0
  813. package/src/modules/webhooks/elevenlabs.routes.ts +34 -0
  814. package/src/modules/webhooks/elevenlabs.service.ts +565 -0
  815. package/src/modules/webhooks/unipile.routes.ts +917 -0
  816. package/src/modules/whatsapp/appointment.model.ts +47 -0
  817. package/src/modules/whatsapp/operator-request.model.ts +58 -0
  818. package/src/modules/whatsapp/stt-usage.model.ts +30 -0
  819. package/src/modules/whatsapp/whatsapp-chat.model.ts +39 -0
  820. package/src/modules/whatsapp/whatsapp-contact-profile.model.ts +41 -0
  821. package/src/modules/whatsapp/whatsapp-message.model.ts +41 -0
  822. package/src/modules/whatsapp/whatsapp-session.model.ts +60 -0
  823. package/src/modules/whatsapp/whatsapp.routes.ts +1435 -0
  824. package/src/plugins/cors.ts +7 -0
  825. package/src/plugins/jwt.ts +18 -0
  826. package/src/plugins/rawBody.ts +12 -0
  827. package/src/plugins/rbac.ts +24 -0
  828. package/src/routes/admin.routes.ts +208 -0
  829. package/src/routes/health.routes.ts +12 -0
  830. package/src/routes/webhook.routes.ts +12 -0
  831. package/src/services/ai/base.ai.ts +132 -0
  832. package/src/services/ai/gemini.service.ts +41 -0
  833. package/src/services/ai/index.ts +24 -0
  834. package/src/services/ai/openai.service.ts +48 -0
  835. package/src/services/elevenlabs.service.ts +532 -0
  836. package/src/services/google-calendar.service.ts +656 -0
  837. package/src/services/inbound-call-schedule.service.ts +174 -0
  838. package/src/services/netgsm.service.ts +128 -0
  839. package/src/services/unipile.service.ts +200 -0
  840. package/src/services/whatsapp-agent.service.ts +2479 -0
  841. package/src/services/whatsapp.service.ts +245 -0
  842. package/src/templates/index.ts +71 -0
  843. package/src/templates/receptionist.ts +44 -0
  844. package/src/templates/survey.ts +44 -0
  845. package/src/types/index.ts +218 -0
  846. package/src/utils/logger.ts +83 -0
  847. package/tsconfig.json +19 -0
  848. package/web/.dockerignore +4 -0
  849. package/web/Dockerfile +18 -0
  850. package/web/README.md +73 -0
  851. package/web/components.json +23 -0
  852. package/web/eslint.config.js +23 -0
  853. package/web/index.html +14 -0
  854. package/web/nginx.conf +18 -0
  855. package/web/package-lock.json +10292 -0
  856. package/web/package.json +48 -0
  857. package/web/public/favicon.ico +0 -0
  858. package/web/public/vite.svg +1 -0
  859. package/web/src/App.tsx +191 -0
  860. package/web/src/assets/react.svg +1 -0
  861. package/web/src/components/Layout.tsx +261 -0
  862. package/web/src/components/LeadConversation.tsx +251 -0
  863. package/web/src/components/ProtectedRoute.tsx +20 -0
  864. package/web/src/components/conversation-review/CardAudioPlayer.tsx +200 -0
  865. package/web/src/components/conversation-review/CardEvaluation.tsx +351 -0
  866. package/web/src/components/conversation-review/CardMetadata.tsx +44 -0
  867. package/web/src/components/conversation-review/ConversationCard.tsx +95 -0
  868. package/web/src/components/conversation-review/ReviewContainer.tsx +120 -0
  869. package/web/src/components/conversation-review/ReviewFilters.tsx +88 -0
  870. package/web/src/components/empty-state.tsx +15 -0
  871. package/web/src/components/page-header.tsx +19 -0
  872. package/web/src/components/page-loader.tsx +32 -0
  873. package/web/src/components/pagination.tsx +38 -0
  874. package/web/src/components/stat-card.tsx +27 -0
  875. package/web/src/components/status-badge.tsx +125 -0
  876. package/web/src/components/ui/alert.tsx +66 -0
  877. package/web/src/components/ui/badge.tsx +48 -0
  878. package/web/src/components/ui/button.tsx +64 -0
  879. package/web/src/components/ui/card.tsx +92 -0
  880. package/web/src/components/ui/checkbox.tsx +32 -0
  881. package/web/src/components/ui/dialog.tsx +158 -0
  882. package/web/src/components/ui/dropdown-menu.tsx +255 -0
  883. package/web/src/components/ui/input.tsx +21 -0
  884. package/web/src/components/ui/label.tsx +22 -0
  885. package/web/src/components/ui/progress.tsx +29 -0
  886. package/web/src/components/ui/select.tsx +188 -0
  887. package/web/src/components/ui/separator.tsx +28 -0
  888. package/web/src/components/ui/sheet.tsx +123 -0
  889. package/web/src/components/ui/skeleton.tsx +13 -0
  890. package/web/src/components/ui/sonner.tsx +35 -0
  891. package/web/src/components/ui/table.tsx +116 -0
  892. package/web/src/components/ui/tabs.tsx +89 -0
  893. package/web/src/components/ui/textarea.tsx +18 -0
  894. package/web/src/components/ui/tooltip.tsx +57 -0
  895. package/web/src/components/whatsapp/ChatDetail.tsx +417 -0
  896. package/web/src/components/whatsapp/ChatHeader.tsx +78 -0
  897. package/web/src/components/whatsapp/ChatList.tsx +107 -0
  898. package/web/src/components/whatsapp/ChatListItem.tsx +60 -0
  899. package/web/src/components/whatsapp/MessageBubble.tsx +46 -0
  900. package/web/src/components/whatsapp/MessageInput.tsx +63 -0
  901. package/web/src/components/whatsapp/MessageStream.tsx +135 -0
  902. package/web/src/components/whatsapp/SessionDivider.tsx +65 -0
  903. package/web/src/components/whatsapp/SessionHistory.tsx +119 -0
  904. package/web/src/components/whatsapp/settings/AiSettingsTab.tsx +268 -0
  905. package/web/src/components/whatsapp/settings/CalendarTab.tsx +339 -0
  906. package/web/src/components/whatsapp/settings/ConnectionTab.tsx +236 -0
  907. package/web/src/components/whatsapp/settings/NotificationsTab.tsx +109 -0
  908. package/web/src/components/whatsapp/settings/OperatorTab.tsx +303 -0
  909. package/web/src/contexts/AuthContext.tsx +103 -0
  910. package/web/src/index.css +130 -0
  911. package/web/src/lib/api.ts +92 -0
  912. package/web/src/lib/utils.ts +6 -0
  913. package/web/src/main.tsx +10 -0
  914. package/web/src/pages/AppointmentDetail.tsx +206 -0
  915. package/web/src/pages/AppointmentValidation.tsx +157 -0
  916. package/web/src/pages/AppointmentValidationDetail.tsx +617 -0
  917. package/web/src/pages/AppointmentValidationNew.tsx +1005 -0
  918. package/web/src/pages/Appointments.tsx +283 -0
  919. package/web/src/pages/Billing.tsx +126 -0
  920. package/web/src/pages/CallDetail.tsx +293 -0
  921. package/web/src/pages/CallSettings.tsx +313 -0
  922. package/web/src/pages/Calls.tsx +188 -0
  923. package/web/src/pages/CampaignDetail.tsx +216 -0
  924. package/web/src/pages/CampaignNew.tsx +277 -0
  925. package/web/src/pages/CampaignResults.tsx +185 -0
  926. package/web/src/pages/Campaigns.tsx +171 -0
  927. package/web/src/pages/Dashboard.tsx +336 -0
  928. package/web/src/pages/InboundSchedule.tsx +246 -0
  929. package/web/src/pages/LeadDetail.tsx +183 -0
  930. package/web/src/pages/Leads.tsx +258 -0
  931. package/web/src/pages/Login.tsx +99 -0
  932. package/web/src/pages/Register.tsx +129 -0
  933. package/web/src/pages/Settings.tsx +133 -0
  934. package/web/src/pages/SurveyDetail.tsx +232 -0
  935. package/web/src/pages/SurveyPreview.tsx +179 -0
  936. package/web/src/pages/Surveys.tsx +207 -0
  937. package/web/src/pages/Users.tsx +199 -0
  938. package/web/src/pages/WhatsApp.tsx +147 -0
  939. package/web/src/pages/WhatsAppSettings.tsx +215 -0
  940. package/web/src/pages/admin/AdminBaileysMessageLog.tsx +331 -0
  941. package/web/src/pages/admin/AdminBaileysRawMessages.tsx +318 -0
  942. package/web/src/pages/admin/AdminConversationReview.tsx +116 -0
  943. package/web/src/pages/admin/AdminCredits.tsx +467 -0
  944. package/web/src/pages/admin/AdminElevenLabsAgentDetail.tsx +332 -0
  945. package/web/src/pages/admin/AdminElevenLabsAgents.tsx +164 -0
  946. package/web/src/pages/admin/AdminElevenLabsBatchCallDetail.tsx +214 -0
  947. package/web/src/pages/admin/AdminElevenLabsBatchCalls.tsx +293 -0
  948. package/web/src/pages/admin/AdminElevenLabsConversationDetail.tsx +230 -0
  949. package/web/src/pages/admin/AdminElevenLabsConversations.tsx +228 -0
  950. package/web/src/pages/admin/AdminElevenLabsInboundCalls.tsx +293 -0
  951. package/web/src/pages/admin/AdminElevenLabsPhoneNumbers.tsx +506 -0
  952. package/web/src/pages/admin/AdminElevenLabsTestChat.tsx +258 -0
  953. package/web/src/pages/admin/AdminElevenLabsWebhooks.tsx +289 -0
  954. package/web/src/pages/admin/AdminEvaluationDashboard.tsx +520 -0
  955. package/web/src/pages/admin/AdminLeads.tsx +339 -0
  956. package/web/src/pages/admin/AdminLogs.tsx +283 -0
  957. package/web/src/pages/admin/AdminMigrations.tsx +247 -0
  958. package/web/src/pages/admin/AdminPlans.tsx +313 -0
  959. package/web/src/pages/admin/AdminSystem.tsx +391 -0
  960. package/web/src/pages/admin/AdminTenantBillableItems.tsx +464 -0
  961. package/web/src/pages/admin/AdminTenantDetail.tsx +1317 -0
  962. package/web/src/pages/admin/AdminTenants.tsx +274 -0
  963. package/web/src/pages/admin/AdminWhatsApp.tsx +618 -0
  964. package/web/src/pages/admin/AdminWhatsAppTestChat.tsx +328 -0
  965. package/web/src/types/index.ts +242 -0
  966. package/web/tsconfig.app.json +32 -0
  967. package/web/tsconfig.json +13 -0
  968. package/web/tsconfig.node.json +26 -0
  969. package/web/vite.config.ts +23 -0
@@ -0,0 +1,942 @@
1
+ # Tektip VoiceAI SaaS Platform - Complete System Overview
2
+
3
+ > Multi-tenant AI-powered voice call platform with ElevenLabs integration, survey campaigns, WhatsApp notifications, and billing.
4
+
5
+ ---
6
+
7
+ ## Table of Contents
8
+
9
+ 1. [Tech Stack](#1-tech-stack)
10
+ 2. [Architecture Overview](#2-architecture-overview)
11
+ 3. [Database Schemas](#3-database-schemas)
12
+ 4. [API Endpoints](#4-api-endpoints)
13
+ 5. [Authentication Flow](#5-authentication-flow)
14
+ 6. [Core Business Flows](#6-core-business-flows)
15
+ 7. [Third-Party Integrations](#7-third-party-integrations)
16
+ 8. [Middleware & Plugins](#8-middleware--plugins)
17
+ 9. [Frontend Pages & Routing](#9-frontend-pages--routing)
18
+ 10. [Frontend State Management](#10-frontend-state-management)
19
+ 11. [Environment Variables](#11-environment-variables)
20
+ 12. [Project Structure](#12-project-structure)
21
+ 13. [Deployment](#13-deployment)
22
+
23
+ ---
24
+
25
+ ## 1. Tech Stack
26
+
27
+ | Layer | Technology |
28
+ |-------|-----------|
29
+ | **Backend** | Fastify 5 + TypeScript 5.9 |
30
+ | **Frontend** | React 19 + Vite 7 + TypeScript 5.9 |
31
+ | **Styling** | Tailwind CSS v4 + shadcn/ui (New York style) |
32
+ | **Database** | MongoDB via Mongoose 8 |
33
+ | **Auth** | JWT dual-token (access + refresh) via @fastify/jwt + jsonwebtoken |
34
+ | **AI** | OpenAI (gpt-5.4-mini) or Google Gemini (configurable) |
35
+ | **Voice** | ElevenLabs (webhook-based post-call processing) |
36
+ | **Messaging** | Twilio WhatsApp API |
37
+ | **Validation** | Zod 4 |
38
+ | **Logging** | Winston |
39
+ | **Process Manager** | PM2 |
40
+ | **Icons** | Lucide React |
41
+ | **Toasts** | Sonner |
42
+ | **HTTP Client** | Axios (frontend) |
43
+
44
+ ---
45
+
46
+ ## 2. Architecture Overview
47
+
48
+ ```
49
+ +-------------------+
50
+ | ElevenLabs AI |
51
+ | (Voice Agents) |
52
+ +--------+----------+
53
+ |
54
+ POST /webhooks/elevenlabs WebSocket (text-only)
55
+ (HMAC-SHA256 signed) (signed URL, 15min)
56
+ | |
57
+ v v
58
+ +------------+ +--------+----------+ +----------+
59
+ | React SPA | <-------> | Fastify API | <-------> | MongoDB |
60
+ | (Vite dev | /api/* | (port 3005) | | |
61
+ | port 5173)| proxy | | +----------+
62
+ +------------+ +---+-----+----+----+
63
+ | | |
64
+ v v v
65
+ +------+-+ +--+------+ +----------+
66
+ | OpenAI | | Twilio | | Unipile |
67
+ | Gemini | | WhatsApp| | WhatsApp |
68
+ +--------+ +---------+ +----------+
69
+ ```
70
+
71
+ **Multi-tenant design**: Every data entity is scoped by `tenant_id`. All queries filter by tenant. Feature flags control which capabilities each tenant can use.
72
+
73
+ **Role hierarchy**: `superadmin` > `admin` > `manager` > `viewer`
74
+
75
+ ---
76
+
77
+ ## 3. Database Schemas
78
+
79
+ ### 3.1 Tenant
80
+
81
+ | Field | Type | Details |
82
+ |-------|------|---------|
83
+ | `name` | String | Required |
84
+ | `plan` | String | `free` / `starter` / `pro` / `premium`, default: `free` |
85
+ | `enabled_features` | [String] | Enum: `inbound_agent`, `outbound_campaigns`, `survey_builder`, `whatsapp_notifications`, `whatsapp_agent` |
86
+ | `settings.whatsapp_agent.unipile_account_id` | String | Unipile WhatsApp account ID |
87
+ | `settings.whatsapp_agent.unipile_account_status` | String | Connection status |
88
+ | `settings.whatsapp_agent.agent_id` | ObjectId → Agent | Reference to the Agent model that handles WhatsApp AI (resolved to ElevenLabs agent ID at runtime, checks is_active) |
89
+ | `settings.whatsapp_agent.connected_at` | Date | When WhatsApp was connected |
90
+ | `settings.whatsapp_agent.connected_phone` | String | Connected phone number |
91
+ | `settings.whatsapp_agent.grace_period_seconds` | Number | Default: 180 (seconds before AI takes over) |
92
+ | `settings.whatsapp_agent.blacklisted_numbers` | [String] | Numbers excluded from AI |
93
+ | `settings.kvkk_consent` | Boolean | Default: false |
94
+ | `settings.notification_recipients` | [String] | Phone numbers |
95
+ | `settings.default_language` | String | Default: `tr` |
96
+ | `createdAt` / `updatedAt` | Date | Auto |
97
+
98
+ ### 3.2 User
99
+
100
+ | Field | Type | Details |
101
+ |-------|------|---------|
102
+ | `tenant_id` | ObjectId → Tenant | Required, indexed |
103
+ | `email` | String | Required, unique, lowercase, trimmed, indexed |
104
+ | `password_hash` | String | Bcrypt, 12 salt rounds |
105
+ | `role` | String | `superadmin` / `admin` / `manager` / `viewer`, default: `viewer` |
106
+ | `name` | String | Required |
107
+ | `createdAt` / `updatedAt` | Date | Auto |
108
+
109
+ ### 3.3 RefreshToken
110
+
111
+ | Field | Type | Details |
112
+ |-------|------|---------|
113
+ | `user_id` | ObjectId → User | Required, indexed |
114
+ | `token` | String | Required, unique |
115
+ | `expires_at` | Date | Required, TTL index (auto-deletes expired tokens) |
116
+ | `createdAt` | Date | Auto |
117
+
118
+ ### 3.4 Agent
119
+
120
+ | Field | Type | Details |
121
+ |-------|------|---------|
122
+ | `tenant_id` | ObjectId → Tenant | Required, indexed |
123
+ | `phone_number` | String | Required |
124
+ | `elevenlabs_agent_id` | String | Required, indexed |
125
+ | `direction` | String | `inbound` / `outbound` / `both` |
126
+ | `agent_template` | String | `receptionist` / `survey` / `custom` |
127
+ | `config.voice_id` | String | Required |
128
+ | `config.language` | String | Default: `tr` |
129
+ | `config.greeting` | String | Default: `''` |
130
+ | `config.template_data` | Mixed | Template-specific data |
131
+ | `post_call_processing.strategy` | String | `summarize` / `extract_survey` / `summarize_and_extract` / `none` |
132
+ | `post_call_processing.llm_provider` | String | `openai` / `gemini` |
133
+ | `post_call_processing.whatsapp_notify` | Boolean | Default: true |
134
+ | `post_call_processing.notification_template` | String | `call_summary` / `survey_progress` / `custom` |
135
+ | `is_active` | Boolean | Default: true |
136
+ | `createdAt` / `updatedAt` | Date | Auto |
137
+
138
+ ### 3.5 Call
139
+
140
+ | Field | Type | Details |
141
+ |-------|------|---------|
142
+ | `tenant_id` | ObjectId → Tenant | Required |
143
+ | `agent_id` | ObjectId → Agent | Required |
144
+ | `campaign_id` | ObjectId → Campaign | Nullable |
145
+ | `direction` | String | `inbound` / `outbound` |
146
+ | `caller_number` | String | Required |
147
+ | `callee_number` | String | Required |
148
+ | `duration_seconds` | Number | Default: 0 |
149
+ | `status` | String | `completed` / `failed` / `no_answer` / `voicemail` / `transferred` |
150
+ | `transcript` | String | Default: `''` |
151
+ | `llm_summary` | String | Nullable |
152
+ | `survey_responses` | Array | `[{ question_id, question_text, answer, parsed_value }]` |
153
+ | `whatsapp_notification_sent` | Boolean | Default: false |
154
+ | `recording_url` | String | Nullable |
155
+ | `createdAt` | Date | Auto |
156
+
157
+ **Indexes**: `(tenant_id, createdAt)`, `(campaign_id, status)`, `(tenant_id, direction, createdAt)`
158
+
159
+ ### 3.6 Survey
160
+
161
+ | Field | Type | Details |
162
+ |-------|------|---------|
163
+ | `tenant_id` | ObjectId → Tenant | Required, indexed |
164
+ | `name` | String | Required |
165
+ | `description` | String | Default: `''` |
166
+ | `questions` | Array | See below |
167
+ | `status` | String | `draft` / `active` / `archived`, default: `draft` |
168
+ | `createdAt` / `updatedAt` | Date | Auto |
169
+
170
+ **Question schema**: `{ id, text, type (open/multiple_choice/rating/yes_no), options: [String], required: Boolean, branch_logic: { condition, go_to } | null }`
171
+
172
+ ### 3.7 Campaign
173
+
174
+ | Field | Type | Details |
175
+ |-------|------|---------|
176
+ | `tenant_id` | ObjectId → Tenant | Required |
177
+ | `survey_id` | ObjectId → Survey | Required |
178
+ | `agent_id` | ObjectId → Agent | Required |
179
+ | `name` | String | Required |
180
+ | `status` | String | `draft` / `scheduled` / `running` / `paused` / `completed` |
181
+ | `phone_list` | Array | `[{ number, status, attempts, last_attempt_at }]` |
182
+ | `schedule.start_date` | Date | Required |
183
+ | `schedule.end_date` | Date | Required |
184
+ | `schedule.daily_start_time` | String | Default: `09:00` |
185
+ | `schedule.daily_end_time` | String | Default: `18:00` |
186
+ | `schedule.days_of_week` | [Number] | Default: `[1,2,3,4,5]` (Mon-Fri) |
187
+ | `schedule.max_concurrent_calls` | Number | Default: 1 |
188
+ | `schedule.max_retries` | Number | Default: 3 |
189
+ | `schedule.retry_delay_minutes` | Number | Default: 60 |
190
+ | `stats` | Object | `{ total, completed, failed, no_answer, voicemail, pending }` |
191
+ | `createdAt` / `updatedAt` | Date | Auto |
192
+
193
+ **Index**: `(tenant_id, status)`
194
+ **State machine**: `draft → scheduled → running → paused/completed`, `paused → running/completed`
195
+
196
+ ### 3.8 BillingEvent
197
+
198
+ | Field | Type | Details |
199
+ |-------|------|---------|
200
+ | `tenant_id` | ObjectId → Tenant | Required |
201
+ | `type` | String | `call_charge` / `subscription` / `top_up` / `refund` |
202
+ | `amount` | Number | Required |
203
+ | `currency` | String | Default: `TRY` |
204
+ | `call_id` | ObjectId → Call | Nullable |
205
+ | `param_transaction_id` | String | Nullable |
206
+ | `description` | String | Default: `''` |
207
+ | `createdAt` | Date | Auto |
208
+
209
+ **Index**: `(tenant_id, createdAt)`
210
+ **Pricing**: 1.5 TRY per minute (rounded up)
211
+
212
+ ### 3.9 WhatsAppChat
213
+
214
+ | Field | Type | Details |
215
+ |-------|------|---------|
216
+ | `tenant_id` | ObjectId → Tenant | Required, indexed |
217
+ | `unipile_chat_id` | String | Required, unique |
218
+ | `unipile_account_id` | String | Unipile account this chat belongs to |
219
+ | `contact_name` | String | Contact's display name |
220
+ | `contact_phone` | String | Contact's phone number |
221
+ | `is_closed` | Boolean | Whether chat has been manually closed (default: false) |
222
+ | `active_session_id` | ObjectId → WhatsAppSession | Current active session (null if no session) |
223
+ | `last_message_at` | Date | Timestamp of most recent message |
224
+ | `last_message_preview` | String | First 100 chars of last message |
225
+ | `message_count` | Number | Total messages in chat |
226
+ | `createdAt` / `updatedAt` | Date | Auto |
227
+
228
+ **Indexes**: `(tenant_id, last_message_at)`, `(unipile_chat_id)` unique
229
+
230
+ ### 3.10 WhatsAppSession
231
+
232
+ Tracks the lifecycle of a human/AI conversation session within a chat. Each new contact interaction starts a session with a grace period where humans get first chance to respond.
233
+
234
+ | Field | Type | Details |
235
+ |-------|------|---------|
236
+ | `chat_id` | ObjectId → WhatsAppChat | Required |
237
+ | `tenant_id` | ObjectId → Tenant | Required |
238
+ | `status` | String | `waiting` / `active` / `resolved` |
239
+ | `resolved_by` | String | `human` / `ai_timeout` / `manual` / `timeout` / null |
240
+ | `started_at` | Date | When session was created |
241
+ | `resolved_at` | Date | When session ended (null if still open) |
242
+ | `grace_deadline` | Date | When AI takes over if human doesn't respond |
243
+ | `taken_over_by` | ObjectId → User | User who took over (null = AI mode) |
244
+ | `taken_over_at` | Date | When takeover happened |
245
+ | `elevenlabs_conversation_id` | String | Active ElevenLabs conversation (null until AI connects) |
246
+ | `elevenlabs_conversation_created_at` | Date | When EL conversation was created |
247
+ | `elevenlabs_last_interaction_at` | Date | Last message sent to EL |
248
+ | `message_count` | Number | Messages in this session |
249
+ | `createdAt` / `updatedAt` | Date | Auto |
250
+
251
+ **Indexes**: `(chat_id, status)`, `(status, grace_deadline)`, `(tenant_id, status)`
252
+
253
+ **Session lifecycle**:
254
+ ```
255
+ Contact sends message
256
+
257
+
258
+ [waiting] ─── grace period timer (e.g. 180s) ───→ [active] (AI takes over)
259
+ │ │
260
+ │ Human responds │ Human takeover button
261
+ ▼ ▼
262
+ [resolved] [active] (human mode)
263
+ resolved_by='human' taken_over_by=<userId>
264
+
265
+ │ Release / Close
266
+
267
+ [resolved]
268
+ resolved_by='manual'
269
+ ```
270
+
271
+ ### 3.11 WhatsAppMessage
272
+
273
+ | Field | Type | Details |
274
+ |-------|------|---------|
275
+ | `chat_id` | ObjectId → WhatsAppChat | Required |
276
+ | `session_id` | ObjectId → WhatsAppSession | Nullable (null for blacklisted/legacy) |
277
+ | `tenant_id` | ObjectId → Tenant | Required |
278
+ | `unipile_message_id` | String | Unipile's message ID (null for AI responses) |
279
+ | `sender` | String | `contact` / `ai` / `human` |
280
+ | `sender_name` | String | Display name of sender |
281
+ | `text` | String | Message content |
282
+ | `sent_via_unipile` | Boolean | Whether sent through Unipile API |
283
+ | `createdAt` | Date | Auto |
284
+
285
+ **Indexes**: `(chat_id, createdAt)`, `(session_id, createdAt)`
286
+
287
+ ### 3.12 Legacy Models (still in codebase)
288
+
289
+ - **Transcription** - Raw ElevenLabs transcription storage with processing pipeline status
290
+ - **Summary** - AI-generated call summaries with sentiment analysis
291
+ - **WhatsAppRecipient** - Notification recipients with agent/duration filters
292
+
293
+ ---
294
+
295
+ ## 4. API Endpoints
296
+
297
+ ### 4.1 Auth (`/auth`)
298
+
299
+ | Method | Path | Auth | Role | Description |
300
+ |--------|------|------|------|-------------|
301
+ | POST | `/auth/register` | - | - | Create tenant + first admin user. Returns tokens. |
302
+ | POST | `/auth/login` | - | - | Email/password login. Returns tokens + user + tenant. |
303
+ | POST | `/auth/refresh` | - | - | Rotate refresh token, get new access token. |
304
+ | POST | `/auth/logout` | Yes | Any | Revoke refresh token. |
305
+ | GET | `/auth/me` | Yes | Any | Current user profile + tenant info. |
306
+
307
+ ### 4.2 Users (`/users`)
308
+
309
+ | Method | Path | Auth | Role | Description |
310
+ |--------|------|------|------|-------------|
311
+ | GET | `/users` | Yes | Any | List users in tenant. |
312
+ | POST | `/users/invite` | Yes | admin | Invite new user (email, password, name, role). |
313
+ | PUT | `/users/:id` | Yes | admin | Update user role/name. |
314
+ | DELETE | `/users/:id` | Yes | admin | Delete user (cannot self-delete). |
315
+
316
+ ### 4.3 Tenants (`/tenants`)
317
+
318
+ | Method | Path | Auth | Role | Description |
319
+ |--------|------|------|------|-------------|
320
+ | GET | `/tenants/me` | Yes | Any | Get current tenant. |
321
+ | PUT | `/tenants/me` | Yes | admin | Update tenant name/settings. |
322
+
323
+ ### 4.4 Agents (`/agents`)
324
+
325
+ | Method | Path | Auth | Role | Description |
326
+ |--------|------|------|------|-------------|
327
+ | GET | `/agents` | Yes | Any | List agents for tenant. |
328
+ | GET | `/agents/:id` | Yes | Any | Get agent detail. |
329
+ | PUT | `/agents/:id/config` | Yes | admin | Update agent config / post-call processing. |
330
+ | POST | `/agents/:id/toggle` | Yes | admin | Enable/disable agent. |
331
+
332
+ ### 4.5 Calls (`/calls`)
333
+
334
+ | Method | Path | Auth | Role | Description |
335
+ |--------|------|------|------|-------------|
336
+ | GET | `/calls` | Yes | Any | Paginated list. Filters: `direction`, `status`, `agent_id`, `from`, `to`. |
337
+ | GET | `/calls/stats` | Yes | Any | Aggregated stats: total, completed, failed, avg duration, etc. |
338
+ | GET | `/calls/:id` | Yes | Any | Call detail with transcript, summary, survey responses. |
339
+
340
+ ### 4.6 Surveys (`/surveys`)
341
+
342
+ | Method | Path | Auth | Role | Feature | Description |
343
+ |--------|------|------|------|---------|-------------|
344
+ | GET | `/surveys` | Yes | Any | `survey_builder` | List surveys. |
345
+ | POST | `/surveys` | Yes | admin/mgr | `survey_builder` | Create survey. |
346
+ | GET | `/surveys/:id` | Yes | Any | `survey_builder` | Survey detail with questions. |
347
+ | PUT | `/surveys/:id` | Yes | admin/mgr | `survey_builder` | Update survey. |
348
+ | DELETE | `/surveys/:id` | Yes | admin/mgr | `survey_builder` | Delete (fails if active campaigns exist). |
349
+ | POST | `/surveys/:id/duplicate` | Yes | admin/mgr | `survey_builder` | Duplicate survey. |
350
+
351
+ ### 4.7 Campaigns (`/campaigns`)
352
+
353
+ | Method | Path | Auth | Role | Feature | Description |
354
+ |--------|------|------|------|---------|-------------|
355
+ | GET | `/campaigns` | Yes | Any | `outbound_campaigns` | Paginated list. Filter: `status`. |
356
+ | POST | `/campaigns` | Yes | admin/mgr | `outbound_campaigns` | Create campaign (name, survey, agent, schedule). |
357
+ | GET | `/campaigns/:id` | Yes | Any | `outbound_campaigns` | Detail with populated survey/agent. |
358
+ | PUT | `/campaigns/:id` | Yes | admin/mgr | `outbound_campaigns` | Update (draft/scheduled only). |
359
+ | POST | `/campaigns/:id/start` | Yes | admin/mgr | `outbound_campaigns` | Start campaign. |
360
+ | POST | `/campaigns/:id/pause` | Yes | admin/mgr | `outbound_campaigns` | Pause campaign. |
361
+ | POST | `/campaigns/:id/resume` | Yes | admin/mgr | `outbound_campaigns` | Resume campaign. |
362
+ | POST | `/campaigns/:id/stop` | Yes | admin/mgr | `outbound_campaigns` | Stop permanently. |
363
+ | POST | `/campaigns/:id/phone-list` | Yes | admin/mgr | `outbound_campaigns` | Upload phone numbers (array or CSV). |
364
+ | GET | `/campaigns/:id/results` | Yes | Any | `outbound_campaigns` | Campaign results with survey responses. |
365
+ | GET | `/campaigns/:id/results/export` | Yes | Any | `outbound_campaigns` | Export results as CSV download. |
366
+
367
+ ### 4.8 Billing (`/billing`)
368
+
369
+ | Method | Path | Auth | Role | Description |
370
+ |--------|------|------|------|-------------|
371
+ | GET | `/billing/usage` | Yes | admin | Current month: total calls, duration, charges. |
372
+ | GET | `/billing/history` | Yes | admin | Paginated billing events. Filter: `type`. |
373
+
374
+ ### 4.9 Admin - SuperAdmin Only (`/admin`)
375
+
376
+ | Method | Path | Auth | Role | Description |
377
+ |--------|------|------|------|-------------|
378
+ | GET | `/admin/tenants` | Yes | superadmin | List all tenants with user_count. Filters: `search`, `page`. |
379
+ | POST | `/admin/tenants` | Yes | superadmin | Create tenant. |
380
+ | GET | `/admin/tenants/:id` | Yes | superadmin | Tenant detail: users, agents, call/campaign counts. |
381
+ | PUT | `/admin/tenants/:id` | Yes | superadmin | Update tenant (name, plan, features, settings). |
382
+ | PUT | `/admin/tenants/:id/features` | Yes | superadmin | Toggle tenant features. |
383
+ | POST | `/admin/agents` | Yes | superadmin | Provision agent for a tenant. |
384
+ | GET | `/admin/system/health` | Yes | superadmin | System: uptime, tenant/user/agent/call counts, revenue. |
385
+ | GET | `/admin/system/usage` | Yes | superadmin | Per-tenant usage this month. |
386
+ | GET | `/admin/templates` | Yes | superadmin | List available agent templates. |
387
+
388
+ ### 4.10 WhatsApp Agent (`/whatsapp`) — Feature: `whatsapp_agent`
389
+
390
+ **Connection Management**:
391
+
392
+ | Method | Path | Auth | Role | Description |
393
+ |--------|------|------|------|-------------|
394
+ | POST | `/whatsapp/connect` | Yes | admin | Initiate WhatsApp QR code connection via Unipile |
395
+ | GET | `/whatsapp/connection-status` | Yes | Any | Check Unipile account connection status |
396
+ | POST | `/whatsapp/disconnect` | Yes | admin | Disconnect WhatsApp account |
397
+ | PUT | `/whatsapp/config` | Yes | admin | Set `agent_id` (ObjectId → Agent) and/or `grace_period_seconds` |
398
+ | GET | `/whatsapp/agents` | Yes | admin | List tenant's agents for selection dropdown |
399
+ | POST | `/whatsapp/register-webhook` | Yes | admin | Register Unipile webhook URL |
400
+
401
+ **Blacklist Management**:
402
+
403
+ | Method | Path | Auth | Role | Description |
404
+ |--------|------|------|------|-------------|
405
+ | GET | `/whatsapp/blacklist` | Yes | admin/mgr | Get blacklisted numbers |
406
+ | POST | `/whatsapp/blacklist` | Yes | admin/mgr | Add phone to blacklist |
407
+ | DELETE | `/whatsapp/blacklist/:phone` | Yes | admin/mgr | Remove phone from blacklist |
408
+
409
+ **Chat Management**:
410
+
411
+ | Method | Path | Auth | Role | Description |
412
+ |--------|------|------|------|-------------|
413
+ | GET | `/whatsapp/stats` | Yes | Any | Chat/session statistics (total, AI, human, waiting, closed) |
414
+ | GET | `/whatsapp/chats` | Yes | Any | Paginated list. Filter: `mode` (ai/human/closed). Enriched with session info. |
415
+ | GET | `/whatsapp/chats/:id` | Yes | Any | Chat detail (enriched with mode/session_status from active session) |
416
+ | GET | `/whatsapp/chats/:id/messages` | Yes | Any | Paginated messages |
417
+ | GET | `/whatsapp/chats/:id/sessions` | Yes | Any | Paginated session history for a chat |
418
+ | POST | `/whatsapp/chats/:id/takeover` | Yes | admin/mgr | Human takes over from AI |
419
+ | POST | `/whatsapp/chats/:id/release` | Yes | admin/mgr | Release back to AI. Body: `{ immediate?: boolean }` |
420
+ | POST | `/whatsapp/chats/:id/close` | Yes | admin/mgr | Close chat (resolves active session) |
421
+ | POST | `/whatsapp/chats/:id/reopen` | Yes | admin/mgr | Reopen closed chat |
422
+ | POST | `/whatsapp/chats/:id/send` | Yes | admin/mgr | Send manual message (human mode only). If session is `waiting`, resolves it as human. |
423
+
424
+ **Note**: The `enrichChat()` function derives backward-compatible virtual fields from the active session:
425
+ - `mode` → `'ai'` (no session or active+no takeover), `'human'` (waiting or taken over), `'closed'` (is_closed)
426
+ - `session_status` → `'waiting'` (grace period) or `'idle'` (all other states)
427
+ - `taken_over_by`, `taken_over_at`, `session_started_at`, `session_grace_deadline`
428
+ - Removes internal fields (`active_session_id`, `is_closed`) and aggregation pipeline temporaries (`_session`, `_activeSession`, `_mode`)
429
+
430
+ ### 4.11 Webhooks
431
+
432
+ | Method | Path | Auth | Description |
433
+ |--------|------|------|-------------|
434
+ | POST | `/webhooks/elevenlabs` | Signature (HMAC-SHA256) | ElevenLabs post-call webhook. Returns 200 immediately, processes async. |
435
+ | POST | `/webhooks/unipile` | Shared secret header | Unipile WhatsApp message webhook. Returns 200 immediately, processes async. |
436
+
437
+ ### 4.11 Health & Legacy
438
+
439
+ | Method | Path | Auth | Description |
440
+ |--------|------|------|-------------|
441
+ | GET | `/health` | - | Health check: `{ status: 'ok', timestamp }` |
442
+ | GET | `/whatsapp/status` | - | WhatsApp service status. |
443
+ | POST | `/legacy-admin/login` | - | Legacy admin auth (password only). |
444
+ | GET/POST/PUT/PATCH/DELETE | `/legacy-admin/*` | JWT | Legacy recipient & transcription CRUD. |
445
+
446
+ ---
447
+
448
+ ## 5. Authentication Flow
449
+
450
+ ### Dual-Token JWT System
451
+
452
+ ```
453
+ Register/Login
454
+ |
455
+ v
456
+ +-----+-------+ +----------+
457
+ | Access Token | | Refresh |
458
+ | (JWT, 15min) | | Token |
459
+ | in-memory / | | (JWT,7d) |
460
+ | localStorage | | DB-stored|
461
+ +--------------+ +----------+
462
+ | |
463
+ | On 401 |
464
+ | +--------+ |
465
+ +->| Retry |<-------+ POST /auth/refresh
466
+ | with | (old token revoked,
467
+ | new AT | new pair issued)
468
+ +--------+
469
+ ```
470
+
471
+ **Access token payload**: `{ id, tenant_id, role, enabled_features }`
472
+ **Refresh token payload**: `{ id, type: 'refresh' }`
473
+
474
+ **Security measures**:
475
+ - Bcrypt (12 rounds) password hashing
476
+ - Token rotation on every refresh (old token revoked)
477
+ - MongoDB TTL index auto-deletes expired refresh tokens
478
+ - `requireFeature` middleware re-fetches tenant from DB (prevents stale JWT features)
479
+ - Users cannot delete themselves or change their own role
480
+
481
+ ---
482
+
483
+ ## 6. Core Business Flows
484
+
485
+ ### 6.1 Inbound Call Flow (Webhook Processing)
486
+
487
+ ```
488
+ 1. Phone call comes in → ElevenLabs AI agent handles it
489
+ 2. Call ends → ElevenLabs sends POST /webhooks/elevenlabs
490
+ 3. Signature validated (HMAC-SHA256, 30-min timestamp tolerance)
491
+ 4. Agent looked up by elevenlabs_agent_id
492
+ 5. Call record created in DB
493
+ 6. Post-call processing (based on agent.post_call_processing.strategy):
494
+ ├── "summarize" → AI generates summary
495
+ ├── "extract_survey" → AI extracts survey responses
496
+ ├── "summarize_and_extract" → Both
497
+ └── "none" → Skip
498
+ 7. WhatsApp notification sent (if whatsapp_notify=true)
499
+ 8. Billing event logged (1.5 TRY/min, rounded up)
500
+ ```
501
+
502
+ ### 6.2 Outbound Campaign Flow
503
+
504
+ ```
505
+ 1. Create Survey → define questions (open/multiple_choice/rating/yes_no)
506
+ 2. Set survey status to "active"
507
+ 3. Create Campaign → link survey + agent + schedule
508
+ 4. Upload phone list (paste numbers or CSV)
509
+ 5. Start campaign (draft → scheduled → running)
510
+ 6. For each phone number:
511
+ ├── ElevenLabs agent calls the number
512
+ ├── Call ends → webhook fires → Call record created
513
+ ├── Survey responses extracted from transcript
514
+ └── Phone list entry status updated
515
+ 7. View results → table with responses per phone number
516
+ 8. Export results as CSV
517
+ ```
518
+
519
+ ### 6.3 Campaign State Machine
520
+
521
+ ```
522
+ draft ──→ scheduled ──→ running ──→ completed
523
+
524
+
525
+ paused ──→ running
526
+
527
+ └──→ completed
528
+ ```
529
+
530
+ ### 6.4 Registration Flow
531
+
532
+ ```
533
+ 1. User submits: email, password, name, tenant_name
534
+ 2. Tenant created: plan=free, features=[inbound_agent, whatsapp_notifications]
535
+ 3. User created: role=admin, linked to tenant
536
+ 4. Access + refresh tokens issued
537
+ 5. User lands on dashboard
538
+ ```
539
+
540
+ ### 6.5 WhatsApp Agent Flow (Session-Based Architecture)
541
+
542
+ The WhatsApp Agent system uses a **grace period** pattern: when a contact sends a message, a session is created in `waiting` state. Humans get first chance to respond. If no human responds before the deadline, AI takes over.
543
+
544
+ ```
545
+ Contact sends WhatsApp message
546
+
547
+ ┌────▼────────────────────────────────────────────────┐
548
+ │ Unipile webhook → POST /webhooks/unipile │
549
+ │ 1. Find/create WhatsAppChat │
550
+ │ 2. Check blacklist (if blacklisted → store only) │
551
+ │ 3. Look up active session │
552
+ └────┬────────────────────────────────────────────────┘
553
+
554
+ ┌────┴───────────────┐
555
+ │ │
556
+ No Active Session Session Exists
557
+ │ │
558
+ ▼ │
559
+ Create WhatsAppSession │
560
+ status='waiting' │
561
+ grace_deadline=now+180s │
562
+ │ │
563
+ ├────────────────────┤
564
+ │ │
565
+ │ ┌─────────────────┴──────────────────┐
566
+ │ │ │
567
+ │ status='waiting' status='active'
568
+ │ Store msg, timer running Forward to AI agent
569
+ │ │ (or skip if human-taken)
570
+ │ │
571
+ │ │ ┌──── Human responds in WhatsApp ────┐
572
+ │ │ │ → resolveSessionAsHuman() │
573
+ │ │ │ → cancel timer, status='resolved' │
574
+ │ │ └─────────────────────────────────────┘
575
+ │ │
576
+ │ │ ┌──── Human clicks "Takeover" in UI ──┐
577
+ │ │ │ → set taken_over_by, close EL WS │
578
+ │ │ │ → session stays 'active' (human) │
579
+ │ │ └──────────────────────────────────────┘
580
+ │ │
581
+ │ └──── Grace period expires (no human response) ───┐
582
+ │ → session status='active' (AI) │
583
+ │ → replayPendingMessages() │
584
+ │ → create ElevenLabs WebSocket (text-only) │
585
+ │ → send context + combined messages │
586
+ │ → AI responds → send via Unipile │
587
+ └─────────────────────────────────────────────────────┘
588
+ ```
589
+
590
+ **Key components**:
591
+ - **WhatsAppAgentService** (`src/services/whatsapp-agent.service.ts`): Manages grace period timers (in-memory `Map<sessionId, Timeout>`), ElevenLabs WebSocket connections, message replay, and session recovery on startup
592
+ - **createSession()** in webhook handler: Creates `WhatsAppSession`, links to chat via `active_session_id`
593
+ - **enrichChat()** in routes: Derives `mode`/`session_status` from active session for backward-compatible API responses
594
+ - **Stuck session sweeper**: Every 5min, finds sessions stuck in `waiting` past deadline without timers
595
+ - **Idle connection cleanup**: Every 1min, closes ElevenLabs WebSocket connections idle > 10min
596
+ - **Conversation timeout**: If ElevenLabs conversation is > 30min old, starts fresh one
597
+
598
+ **Message buffer**: 20-second debounce — contact messages are buffered, timer resets on each new message, combined text sent to AI after 20s of silence.
599
+
600
+ **WebSocket reconnection**: Auto-reconnect with exponential backoff (1.5s, 3s, 6s, max 3 retries) on unexpected WS close.
601
+
602
+ **Inactivity auto-resolve**: Active sessions with no activity for 30 minutes auto-resolve as `timeout`.
603
+
604
+ **Agent reference**: ElevenLabs agent ID is now resolved through the Agent model (checks `is_active`).
605
+
606
+ **Release dialog** (frontend): When releasing a chat back to AI, user can choose:
607
+ - "Hemen Yanit Ver" (Respond Immediately) — replays pending messages to AI
608
+ - "Mesaj Bekle" (Wait for Message) — releases without triggering AI
609
+
610
+ ---
611
+
612
+ ## 7. Third-Party Integrations
613
+
614
+ ### ElevenLabs (Voice AI)
615
+ - **Purpose**: AI voice agents for inbound/outbound calls
616
+ - **Integration**: Webhook-based (POST /webhooks/elevenlabs)
617
+ - **Auth**: HMAC-SHA256 signature validation
618
+ - **Events processed**: `post_call_transcription`
619
+ - **Data received**: conversation_id, agent_id, transcript, metadata, call status
620
+
621
+ ### OpenAI
622
+ - **Purpose**: Call summarization & survey response extraction
623
+ - **Model**: gpt-5.4-mini (configurable via env)
624
+ - **Temperature**: 0.3
625
+ - **Features**: Token usage tracking, custom prompts per agent (via agentPrompts.json)
626
+
627
+ ### Google Gemini
628
+ - **Purpose**: Alternative AI provider for summarization
629
+ - **Model**: gemini-pro (configurable)
630
+ - **Usage**: Swappable with OpenAI via `AI_PROVIDER` env var
631
+
632
+ ### Twilio WhatsApp
633
+ - **Purpose**: Post-call notifications to recipients
634
+ - **Method**: Template-based messages (template SID: HX47645724f174e91c4d90b25ee10fe612)
635
+ - **Variables**: caller_number, call_summary
636
+ - **Features**: Recipient filters (agent_ids, min_call_duration), notification tracking
637
+
638
+ ### Unipile (WhatsApp Messaging)
639
+ - **Purpose**: WhatsApp message relay for the AI agent chat system
640
+ - **Integration**: REST API + webhooks
641
+ - **Auth**: API key (`UNIPILE_API_KEY`)
642
+ - **Connection flow**: `POST /api/v1/accounts` → returns QR code → user scans → account connected
643
+ - **Capabilities**:
644
+ - `connectWhatsApp()` — Create new WhatsApp account (returns QR code checkpoint)
645
+ - `reconnectAccount(id)` — Reconnect existing account
646
+ - `getAccountStatus(id)` — Check connection status
647
+ - `sendMessage(chatId, text)` — Send WhatsApp message
648
+ - `createWebhook(url)` — Register webhook for incoming messages
649
+ - **Webhook payload**: `{ account_id, event, chat_id, message_id, message, is_sender, sender, attendees }`
650
+ - **Webhook secret**: Optional `x-unipile-secret` header validation
651
+
652
+ ### ElevenLabs WebSocket (WhatsApp Chat AI)
653
+ - **Purpose**: Real-time text-only AI conversations for WhatsApp agent
654
+ - **Integration**: Signed WebSocket URL (15min expiry)
655
+ - **Flow**: `getSignedUrl({ agentId })` → WebSocket connect with `?textOnly=true`
656
+ - **Messages**:
657
+ - `conversation_initiation_metadata` — Connection ready, contains conversation_id
658
+ - `user_message` — Send contact's message to AI
659
+ - `agent_response` — AI's reply (forwarded to contact via Unipile)
660
+ - `contextual_update` — Send conversation history for context
661
+ - **First message suppression**: Agent greeting is suppressed (only real responses sent)
662
+ - **Conversation timeout**: 30min idle → new conversation created
663
+
664
+ ---
665
+
666
+ ## 8. Middleware & Plugins
667
+
668
+ | Plugin/Middleware | File | Purpose |
669
+ |-------------------|------|---------|
670
+ | **JWT Plugin** | `src/plugins/jwt.ts` | Registers @fastify/jwt, provides `fastify.authenticate` decorator |
671
+ | **RBAC - requireRole** | `src/plugins/rbac.ts` | Role-based access control. Superadmin bypasses all. Returns 403. |
672
+ | **RBAC - requireFeature** | `src/plugins/rbac.ts` | Feature flag check. Fetches tenant from DB (not JWT). Returns 403. |
673
+ | **CORS** | `src/plugins/cors.ts` | @fastify/cors with defaults |
674
+ | **Raw Body** | `src/plugins/rawBody.ts` | Stores raw body for webhook signature validation |
675
+ | **Webhook Validator** | `src/hooks/webhookValidator.ts` | HMAC-SHA256 signature + timestamp check (30-min window) |
676
+
677
+ ---
678
+
679
+ ## 9. Frontend Pages & Routing
680
+
681
+ ### Route Structure (React Router v6)
682
+
683
+ ```
684
+ / → redirect to /dashboard
685
+ ├── /login Public - email/password login
686
+ ├── /register Public - signup with company name
687
+ └── <ProtectedRoute> + <Layout>
688
+ ├── /dashboard Stats cards, recent calls, usage summary
689
+ ├── /calls Call list with direction/status filters, pagination
690
+ ├── /calls/:id Call detail: transcript, AI summary, survey responses
691
+ ├── /surveys Survey list with duplicate/delete actions
692
+ ├── /surveys/:id Survey builder: add/edit/delete questions
693
+ ├── /surveys/:id/preview Interactive survey preview
694
+ ├── /campaigns Campaign list with status filter, progress bars
695
+ ├── /campaigns/new 3-step wizard: Info → Schedule → Phone list
696
+ ├── /campaigns/:id Campaign detail with start/pause/resume/stop
697
+ ├── /campaigns/:id/results Results table + CSV export
698
+ ├── /whatsapp WhatsApp two-panel layout: chat list + detail
699
+ ├── /whatsapp/:chatId Same WhatsApp component (two-panel), detail panel shows selected chat
700
+ ├── /settings Tabs: Company settings + User management
701
+ ├── /billing Usage summary + transaction history
702
+ ├── /admin/tenants [superadmin] Tenant list with search
703
+ ├── /admin/tenants/:id [superadmin] Tenant detail: users, agents, stats
704
+ └── /admin/system [superadmin] System health, uptime, usage
705
+ ```
706
+
707
+ **Note**: Both `/whatsapp` and `/whatsapp/:chatId` render the same `WhatsApp` component (two-panel layout). The WhatsApp UI is composed of 10 dedicated components in `web/src/components/whatsapp/`.
708
+
709
+ ### Layout Shell
710
+ - Collapsible sidebar with navigation icons
711
+ - User dropdown menu (profile, logout)
712
+ - Conditional nav items based on `enabled_features` and `role`
713
+ - Sonner toast notifications (top-right)
714
+
715
+ ### Shared Components
716
+
717
+ | Component | Props | Purpose |
718
+ |-----------|-------|---------|
719
+ | `PageHeader` | title, description?, children? | Page title + optional action buttons |
720
+ | `StatCard` | label, value, icon?, className? | Metric display card |
721
+ | `PageLoader` | - | Skeleton loading state |
722
+ | `TableLoader` | rows?, cols? | Table skeleton |
723
+ | `EmptyState` | message, icon? | Empty data state |
724
+ | `Pagination` | page, totalPages, onPageChange | Prev/next navigation |
725
+ | `CallStatusBadge` | status | Colored badge for call status |
726
+ | `CampaignStatusBadge` | status | Colored badge for campaign status |
727
+ | `SurveyStatusBadge` | status | Colored badge for survey status |
728
+ | `DirectionBadge` | direction | inbound (sky) / outbound (violet) |
729
+ | `BillingTypeBadge` | type | Badge for billing event type |
730
+ | `ChatModeBadge` | mode | AI (green) / Human (amber) / Closed (gray) |
731
+ | `SessionStatusBadge` | status | Shows "Bekleniyor" badge only when status='waiting' |
732
+
733
+ ---
734
+
735
+ ## 10. Frontend State Management
736
+
737
+ **Approach**: React hooks only (no Redux/Zustand)
738
+
739
+ ### AuthContext (Global)
740
+ ```typescript
741
+ {
742
+ user: User | null
743
+ tenant: Tenant | null
744
+ isLoading: boolean
745
+ login(email, password): Promise<void>
746
+ register(email, password, name, tenantName): Promise<void>
747
+ logout(): Promise<void>
748
+ }
749
+ ```
750
+
751
+ **`useFeature(feature)`** hook: checks `tenant.enabled_features` for conditional rendering.
752
+
753
+ ### API Client (`/lib/api.ts`)
754
+ - Axios instance with baseURL `/api`
755
+ - Request interceptor: attaches `Authorization: Bearer {token}`
756
+ - Response interceptor: on 401 → refresh token → retry request → on failure → redirect to `/login`
757
+
758
+ ### Data Fetching Pattern
759
+ - `useState` + `useEffect` for API calls on mount/param change
760
+ - `useSearchParams` for pagination and filter state in URL
761
+ - No caching layer (direct API calls)
762
+
763
+ ---
764
+
765
+ ## 11. Environment Variables
766
+
767
+ ```bash
768
+ # Server
769
+ PORT=3005 # Backend port
770
+ NODE_ENV=development # development | production
771
+
772
+ # Database
773
+ MONGODB_URI=mongodb://localhost:27017/elevenlabs-webhook
774
+
775
+ # ElevenLabs
776
+ ELEVENLABS_WEBHOOK_SECRET=wsec_... # HMAC-SHA256 webhook signing secret
777
+
778
+ # AI Provider
779
+ AI_PROVIDER=openai # openai | gemini
780
+ SUMMARY_LANGUAGE=tr # tr | en
781
+ SUMMARY_MAX_TOKENS=500
782
+
783
+ # OpenAI
784
+ OPENAI_API_KEY=sk-...
785
+ OPENAI_MODEL=gpt-5.4-mini
786
+
787
+ # Gemini
788
+ GEMINI_API_KEY=...
789
+ GEMINI_MODEL=gemini-pro
790
+
791
+ # Twilio WhatsApp
792
+ TWILIO_ACCOUNT_SID=...
793
+ TWILIO_AUTH_TOKEN=...
794
+ TWILIO_WHATSAPP_NUMBER=+1234567890
795
+
796
+ # Unipile (WhatsApp Agent)
797
+ UNIPILE_API_KEY=... # Unipile API key
798
+ UNIPILE_DSN=https://api.unipile.com # Unipile API base URL
799
+ UNIPILE_WEBHOOK_SECRET=... # Shared secret for webhook validation
800
+
801
+ # JWT
802
+ JWT_SECRET=... # Access token secret
803
+ JWT_REFRESH_SECRET=... # Refresh token secret (separate)
804
+ JWT_ACCESS_EXPIRY=15m
805
+ JWT_REFRESH_EXPIRY=7d
806
+
807
+ # Legacy Admin
808
+ ADMIN_PASSWORD=... # Single password for legacy admin panel
809
+
810
+ # Logging
811
+ LOG_LEVEL=info
812
+ ```
813
+
814
+ ---
815
+
816
+ ## 12. Project Structure
817
+
818
+ ```
819
+ elevenlabs-webhook-nodejs/
820
+ ├── src/
821
+ │ ├── index.ts # Server entry point
822
+ │ ├── app.ts # Fastify app setup & plugin registration
823
+ │ ├── config/
824
+ │ │ ├── index.ts # Config object
825
+ │ │ ├── env.ts # Zod env validation
826
+ │ │ └── database.ts # MongoDB connection
827
+ │ ├── plugins/
828
+ │ │ ├── jwt.ts # JWT auth plugin
829
+ │ │ ├── rbac.ts # Role & feature middleware
830
+ │ │ ├── cors.ts # CORS
831
+ │ │ └── rawBody.ts # Raw body for webhooks
832
+ │ ├── hooks/
833
+ │ │ └── webhookValidator.ts # ElevenLabs signature validation
834
+ │ ├── modules/
835
+ │ │ ├── auth/ # Routes, service, model (User, RefreshToken)
836
+ │ │ ├── users/ # Routes (CRUD)
837
+ │ │ ├── tenants/ # Routes, model
838
+ │ │ ├── agents/ # Routes, model
839
+ │ │ ├── calls/ # Routes, model
840
+ │ │ ├── surveys/ # Routes, model
841
+ │ │ ├── campaigns/ # Routes, service, model
842
+ │ │ ├── billing/ # Routes, service, model
843
+ │ │ ├── whatsapp/ # WhatsApp Agent (chat, session, message models + routes)
844
+ │ │ ├── webhooks/ # ElevenLabs & Unipile webhook routes + services
845
+ │ │ └── admin/ # SuperAdmin routes
846
+ │ ├── models/ # Legacy models (Transcription, Summary, WhatsAppRecipient)
847
+ │ ├── routes/
848
+ │ │ ├── health.routes.ts # Health & WhatsApp status
849
+ │ │ ├── admin.routes.ts # Legacy admin CRUD
850
+ │ │ └── webhook.routes.ts # Generic webhook handler
851
+ │ ├── services/
852
+ │ │ ├── whatsapp.service.ts # Twilio WhatsApp integration
853
+ │ │ ├── unipile.service.ts # Unipile WhatsApp API client
854
+ │ │ ├── elevenlabs.service.ts # ElevenLabs API + signed URL
855
+ │ │ ├── whatsapp-agent.service.ts # Session timers, EL WebSocket, AI responses
856
+ │ │ └── ai/
857
+ │ │ ├── base.ai.ts # Abstract AI service
858
+ │ │ ├── openai.service.ts # OpenAI implementation
859
+ │ │ ├── gemini.service.ts # Gemini implementation
860
+ │ │ └── index.ts # Factory: createAIService()
861
+ │ ├── templates/
862
+ │ │ ├── index.ts # Template exports
863
+ │ │ ├── receptionist.ts # Receptionist agent template
864
+ │ │ └── survey.ts # Survey agent template
865
+ │ ├── types/
866
+ │ │ └── index.ts # TypeScript interfaces
867
+ │ └── utils/
868
+ │ └── logger.ts # Winston logger
869
+
870
+ ├── web/
871
+ │ ├── src/
872
+ │ │ ├── main.tsx # React entry point
873
+ │ │ ├── App.tsx # Router setup
874
+ │ │ ├── index.css # Tailwind v4 imports + theme vars
875
+ │ │ ├── contexts/
876
+ │ │ │ └── AuthContext.tsx # Auth state, login/register/logout, useFeature
877
+ │ │ ├── lib/
878
+ │ │ │ ├── api.ts # Axios instance with interceptors
879
+ │ │ │ └── utils.ts # cn() utility (clsx + tailwind-merge)
880
+ │ │ ├── pages/ # 17 page components (WhatsApp is single page, two-panel)
881
+ │ │ └── components/
882
+ │ │ ├── ui/ # shadcn/ui components
883
+ │ │ ├── whatsapp/ # 10 WhatsApp-specific components
884
+ │ │ ├── stat-card.tsx
885
+ │ │ ├── status-badge.tsx
886
+ │ │ ├── page-header.tsx
887
+ │ │ ├── page-loader.tsx
888
+ │ │ ├── empty-state.tsx
889
+ │ │ └── pagination.tsx
890
+ │ ├── components.json # shadcn/ui config
891
+ │ ├── vite.config.ts # Vite + React + Tailwind + /api proxy
892
+ │ ├── tsconfig.json # TS config with @/* path alias
893
+ │ └── package.json
894
+
895
+ ├── scripts/ # CLI utilities (add recipient, retrigger, migrate-agent-ref, etc.)
896
+ ├── ecosystem.config.js # PM2 production config
897
+ ├── .env.example # Environment template
898
+ ├── .env # Actual env (gitignored)
899
+ ├── tsconfig.json # Backend TS config (CommonJS, ES2022)
900
+ └── package.json # Backend dependencies & scripts
901
+ ```
902
+
903
+ ---
904
+
905
+ ## 13. Deployment
906
+
907
+ ### PM2 Config
908
+ - **App name**: `asistan724-webhook`
909
+ - **Path**: `/var/www/asistan724-webhook-handler/dist/index.js`
910
+ - **Instances**: 1 (single process)
911
+ - **Auto-restart**: enabled
912
+ - **Memory limit**: 500MB
913
+
914
+ ### Build Commands
915
+ ```bash
916
+ # Backend
917
+ npm run build # tsc → dist/ + copy agentPrompts.json
918
+
919
+ # Frontend
920
+ cd web && npm run build # tsc --noEmit && vite build
921
+ ```
922
+
923
+ ### Dev Commands
924
+ ```bash
925
+ npm run dev # tsx watch mode (backend, port 3005)
926
+ cd web && npm run dev # vite dev server (port 5173, proxies /api → :3005)
927
+ ```
928
+
929
+ ### No CI/CD or Docker configured.
930
+
931
+ ---
932
+
933
+ ## Key Notes
934
+
935
+ - **No cron jobs needed**: The WhatsApp agent system is fully event-driven (webhooks + in-memory timers). A stuck session sweeper runs every 5 minutes as a safety net. Campaign execution (placing outbound calls) is not yet automated.
936
+ - **Session-based architecture**: WhatsApp chats use a session model (`WhatsAppSession`) to cleanly track conversation boundaries. Messages are scoped to sessions via `session_id`, eliminating fragile backwards-scanning for message boundaries.
937
+ - **Backward-compatible API**: The `enrichChat()` helper derives `mode`, `session_status`, `taken_over_by` from the active session — frontend types/components remain unchanged.
938
+ - **Migration**: Run `npx tsx scripts/migrate-sessions.ts` to migrate existing chat data to the session model. Supports `--dry-run` flag.
939
+ - **Legacy code**: `src/models/` and `src/routes/admin.routes.ts` contain the original pre-SaaS system (single-tenant, password-only auth). Still functional but separate from the multi-tenant module system.
940
+ - **Billing**: Currently tracks call charges only (1.5 TRY/min). No payment gateway integration - billing events are logged but not collected.
941
+ - **Feature flags**: `inbound_agent`, `outbound_campaigns`, `survey_builder`, `whatsapp_notifications`, `whatsapp_agent` - controlled per-tenant by superadmin.
942
+ - **WebSocket reconnection & message buffering**: Production-ready improvements — auto-reconnect with exponential backoff (1.5s, 3s, 6s, max 3 retries) on unexpected WS close, and 20-second message debounce that buffers contact messages before sending combined text to AI.