django-cfg 1.4.21__py3-none-any.whl → 1.4.24__py3-none-any.whl

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 (793) hide show
  1. django_cfg/__init__.py +4 -4
  2. django_cfg/apps/accounts/__init__.py +1 -1
  3. django_cfg/apps/accounts/__models.py +30 -29
  4. django_cfg/apps/accounts/admin/__init__.py +14 -3
  5. django_cfg/apps/accounts/admin/activity_admin.py +19 -19
  6. django_cfg/apps/accounts/admin/filters.py +7 -6
  7. django_cfg/apps/accounts/admin/group_admin.py +10 -16
  8. django_cfg/apps/accounts/admin/inlines.py +21 -19
  9. django_cfg/apps/accounts/admin/otp_admin.py +12 -12
  10. django_cfg/apps/accounts/admin/registration_admin.py +24 -24
  11. django_cfg/apps/accounts/admin/resources.py +49 -48
  12. django_cfg/apps/accounts/admin/twilio_admin.py +37 -37
  13. django_cfg/apps/accounts/admin/user_admin.py +45 -41
  14. django_cfg/apps/accounts/management/commands/otp_test.py +11 -11
  15. django_cfg/apps/accounts/managers/__init__.py +1 -1
  16. django_cfg/apps/accounts/managers/user_manager.py +6 -7
  17. django_cfg/apps/accounts/migrations/0001_initial.py +3 -2
  18. django_cfg/apps/accounts/models/__init__.py +15 -16
  19. django_cfg/apps/accounts/models/activity.py +5 -5
  20. django_cfg/apps/accounts/models/integrations.py +15 -15
  21. django_cfg/apps/accounts/models/registration.py +3 -2
  22. django_cfg/apps/accounts/models/user.py +3 -2
  23. django_cfg/apps/accounts/serializers/__init__.py +10 -3
  24. django_cfg/apps/accounts/serializers/otp.py +5 -4
  25. django_cfg/apps/accounts/serializers/profile.py +4 -5
  26. django_cfg/apps/accounts/serializers/webhook.py +13 -13
  27. django_cfg/apps/accounts/services/activity_service.py +13 -12
  28. django_cfg/apps/accounts/services/otp_service.py +16 -14
  29. django_cfg/apps/accounts/signals.py +18 -16
  30. django_cfg/apps/accounts/urls.py +10 -5
  31. django_cfg/apps/accounts/utils/notifications.py +22 -22
  32. django_cfg/apps/accounts/views/__init__.py +1 -1
  33. django_cfg/apps/accounts/views/otp.py +15 -14
  34. django_cfg/apps/accounts/views/profile.py +14 -10
  35. django_cfg/apps/accounts/views/webhook.py +46 -48
  36. django_cfg/apps/agents/__init__.py +3 -3
  37. django_cfg/apps/agents/admin/__init__.py +1 -1
  38. django_cfg/apps/agents/admin/execution_admin.py +68 -72
  39. django_cfg/apps/agents/admin/registry_admin.py +50 -54
  40. django_cfg/apps/agents/admin/toolsets_admin.py +63 -67
  41. django_cfg/apps/agents/apps.py +3 -3
  42. django_cfg/apps/agents/core/__init__.py +4 -4
  43. django_cfg/apps/agents/core/dependencies.py +24 -23
  44. django_cfg/apps/agents/core/django_agent.py +41 -39
  45. django_cfg/apps/agents/core/exceptions.py +12 -12
  46. django_cfg/apps/agents/core/models.py +16 -15
  47. django_cfg/apps/agents/core/orchestrator.py +58 -58
  48. django_cfg/apps/agents/examples/simple_example.py +24 -19
  49. django_cfg/apps/agents/integration/__init__.py +1 -1
  50. django_cfg/apps/agents/integration/middleware.py +12 -11
  51. django_cfg/apps/agents/integration/registry.py +52 -49
  52. django_cfg/apps/agents/integration/signals.py +5 -5
  53. django_cfg/apps/agents/management/commands/create_agent.py +39 -38
  54. django_cfg/apps/agents/management/commands/orchestrator_status.py +40 -39
  55. django_cfg/apps/agents/managers/__init__.py +8 -3
  56. django_cfg/apps/agents/managers/execution.py +42 -41
  57. django_cfg/apps/agents/managers/registry.py +40 -39
  58. django_cfg/apps/agents/managers/toolsets.py +87 -86
  59. django_cfg/apps/agents/migrations/0001_initial.py +2 -1
  60. django_cfg/apps/agents/models/__init__.py +2 -2
  61. django_cfg/apps/agents/models/execution.py +43 -42
  62. django_cfg/apps/agents/models/registry.py +46 -45
  63. django_cfg/apps/agents/models/toolsets.py +63 -62
  64. django_cfg/apps/agents/patterns/__init__.py +5 -5
  65. django_cfg/apps/agents/patterns/content_agents.py +17 -16
  66. django_cfg/apps/agents/toolsets/__init__.py +3 -3
  67. django_cfg/apps/agents/toolsets/cache_toolset.py +56 -55
  68. django_cfg/apps/agents/toolsets/django_toolset.py +43 -42
  69. django_cfg/apps/agents/toolsets/file_toolset.py +64 -63
  70. django_cfg/apps/agents/toolsets/orm_toolset.py +75 -74
  71. django_cfg/apps/agents/urls.py +3 -2
  72. django_cfg/apps/api/commands/urls.py +1 -0
  73. django_cfg/apps/api/commands/views.py +23 -26
  74. django_cfg/apps/api/endpoints/checker.py +5 -4
  75. django_cfg/apps/api/endpoints/drf_views.py +2 -2
  76. django_cfg/apps/api/endpoints/tests.py +6 -5
  77. django_cfg/apps/api/endpoints/urls.py +2 -1
  78. django_cfg/apps/api/endpoints/views.py +1 -0
  79. django_cfg/apps/api/health/drf_views.py +6 -6
  80. django_cfg/apps/api/health/urls.py +2 -1
  81. django_cfg/apps/api/health/views.py +41 -41
  82. django_cfg/{modules/django_ipc_client → apps/ipc}/__init__.py +6 -6
  83. django_cfg/apps/ipc/apps.py +28 -0
  84. django_cfg/apps/ipc/serializers/__init__.py +19 -0
  85. django_cfg/apps/ipc/serializers/serializers.py +229 -0
  86. django_cfg/apps/ipc/services/__init__.py +7 -0
  87. django_cfg/apps/ipc/services/client/__init__.py +23 -0
  88. django_cfg/{modules/django_ipc_client → apps/ipc/services/client}/client.py +7 -6
  89. django_cfg/{modules/django_ipc_client → apps/ipc/services/client}/exceptions.py +1 -1
  90. django_cfg/{modules/django_ipc_client/dashboard → apps/ipc/services}/monitor.py +36 -7
  91. django_cfg/{modules/django_ipc_client/dashboard/static/django_ipc_dashboard/js/dashboard.js → apps/ipc/static/django_cfg_ipc/js/dashboard.mjs} +131 -63
  92. django_cfg/{modules/django_ipc_client/dashboard/templates/django_ipc_dashboard → apps/ipc/templates/django_cfg_ipc}/base.html +5 -10
  93. django_cfg/apps/ipc/templates/django_cfg_ipc/dashboard.html +202 -0
  94. django_cfg/apps/ipc/urls.py +21 -0
  95. django_cfg/apps/ipc/urls_admin.py +20 -0
  96. django_cfg/apps/ipc/views/__init__.py +8 -0
  97. django_cfg/apps/ipc/views/dashboard.py +15 -0
  98. django_cfg/apps/ipc/views/viewsets.py +245 -0
  99. django_cfg/apps/knowbase/admin/__init__.py +2 -2
  100. django_cfg/apps/knowbase/admin/actions/__init__.py +1 -1
  101. django_cfg/apps/knowbase/admin/actions/visibility_actions.py +2 -1
  102. django_cfg/apps/knowbase/admin/archive_admin.py +81 -84
  103. django_cfg/apps/knowbase/admin/chat_admin.py +70 -72
  104. django_cfg/apps/knowbase/admin/document_admin.py +10 -11
  105. django_cfg/apps/knowbase/admin/external_data_admin.py +69 -71
  106. django_cfg/apps/knowbase/admin/helpers/__init__.py +1 -1
  107. django_cfg/apps/knowbase/admin/helpers/configs.py +2 -2
  108. django_cfg/apps/knowbase/admin/helpers/statistics.py +1 -1
  109. django_cfg/apps/knowbase/apps.py +13 -13
  110. django_cfg/apps/knowbase/config/__init__.py +7 -6
  111. django_cfg/apps/knowbase/config/constance_fields.py +14 -12
  112. django_cfg/apps/knowbase/config/constance_settings.py +32 -31
  113. django_cfg/apps/knowbase/config/settings.py +28 -28
  114. django_cfg/apps/knowbase/examples/external_data_usage.py +35 -32
  115. django_cfg/apps/knowbase/management/commands/knowbase_stats.py +33 -32
  116. django_cfg/apps/knowbase/management/commands/setup_knowbase.py +11 -13
  117. django_cfg/apps/knowbase/managers/__init__.py +2 -2
  118. django_cfg/apps/knowbase/managers/archive.py +86 -85
  119. django_cfg/apps/knowbase/managers/base.py +5 -5
  120. django_cfg/apps/knowbase/managers/chat.py +29 -28
  121. django_cfg/apps/knowbase/managers/document.py +39 -39
  122. django_cfg/apps/knowbase/managers/external_data.py +74 -73
  123. django_cfg/apps/knowbase/migrations/0001_initial.py +2 -1
  124. django_cfg/apps/knowbase/migrations/0002_archiveitem_archiveitemchunk_documentarchive_and_more.py +2 -1
  125. django_cfg/apps/knowbase/mixins/__init__.py +4 -4
  126. django_cfg/apps/knowbase/mixins/config/__init__.py +1 -1
  127. django_cfg/apps/knowbase/mixins/config/meta_config.py +1 -1
  128. django_cfg/apps/knowbase/mixins/config.py +19 -18
  129. django_cfg/apps/knowbase/mixins/creator.py +7 -7
  130. django_cfg/apps/knowbase/mixins/examples/vehicle_model_example.py +29 -28
  131. django_cfg/apps/knowbase/mixins/external_data_mixin.py +6 -5
  132. django_cfg/apps/knowbase/mixins/generators/__init__.py +1 -1
  133. django_cfg/apps/knowbase/mixins/generators/content_generator.py +2 -2
  134. django_cfg/apps/knowbase/mixins/service.py +47 -45
  135. django_cfg/apps/knowbase/models/__init__.py +7 -7
  136. django_cfg/apps/knowbase/models/archive.py +72 -72
  137. django_cfg/apps/knowbase/models/base.py +12 -13
  138. django_cfg/apps/knowbase/models/chat.py +20 -19
  139. django_cfg/apps/knowbase/models/document.py +37 -35
  140. django_cfg/apps/knowbase/models/external_data.py +41 -42
  141. django_cfg/apps/knowbase/serializers/__init__.py +7 -7
  142. django_cfg/apps/knowbase/serializers/archive_serializers.py +50 -42
  143. django_cfg/apps/knowbase/serializers/chat_serializers.py +16 -15
  144. django_cfg/apps/knowbase/serializers/document_serializers.py +13 -12
  145. django_cfg/apps/knowbase/serializers/external_data_serializers.py +31 -31
  146. django_cfg/apps/knowbase/serializers/public_serializers.py +10 -9
  147. django_cfg/apps/knowbase/services/__init__.py +7 -7
  148. django_cfg/apps/knowbase/services/archive/__init__.py +7 -7
  149. django_cfg/apps/knowbase/services/archive/analyzers/__init__.py +1 -1
  150. django_cfg/apps/knowbase/services/archive/analyzers/tag_generator.py +1 -1
  151. django_cfg/apps/knowbase/services/archive/archive_service.py +109 -112
  152. django_cfg/apps/knowbase/services/archive/chunking/__init__.py +3 -3
  153. django_cfg/apps/knowbase/services/archive/chunking/base.py +1 -0
  154. django_cfg/apps/knowbase/services/archive/chunking/json_chunker.py +4 -3
  155. django_cfg/apps/knowbase/services/archive/chunking/markdown_chunker.py +5 -4
  156. django_cfg/apps/knowbase/services/archive/chunking/python_chunker.py +6 -5
  157. django_cfg/apps/knowbase/services/archive/chunking/text_chunker.py +4 -3
  158. django_cfg/apps/knowbase/services/archive/chunking_service.py +3 -7
  159. django_cfg/apps/knowbase/services/archive/context/__init__.py +1 -1
  160. django_cfg/apps/knowbase/services/archive/context/builders.py +2 -1
  161. django_cfg/apps/knowbase/services/archive/context/models.py +2 -1
  162. django_cfg/apps/knowbase/services/archive/exceptions.py +5 -5
  163. django_cfg/apps/knowbase/services/archive/extraction_service.py +111 -110
  164. django_cfg/apps/knowbase/services/archive/vectorization_service.py +80 -77
  165. django_cfg/apps/knowbase/services/base.py +11 -9
  166. django_cfg/apps/knowbase/services/chat_service.py +40 -39
  167. django_cfg/apps/knowbase/services/document_service.py +28 -27
  168. django_cfg/apps/knowbase/services/embedding/__init__.py +9 -9
  169. django_cfg/apps/knowbase/services/embedding/async_processor.py +38 -40
  170. django_cfg/apps/knowbase/services/embedding/batch_processor.py +45 -42
  171. django_cfg/apps/knowbase/services/embedding/batch_result.py +7 -6
  172. django_cfg/apps/knowbase/services/embedding/models.py +52 -51
  173. django_cfg/apps/knowbase/services/embedding/processors.py +24 -23
  174. django_cfg/apps/knowbase/services/embedding/utils.py +17 -17
  175. django_cfg/apps/knowbase/services/prompt_builder.py +24 -23
  176. django_cfg/apps/knowbase/services/search_service.py +52 -49
  177. django_cfg/apps/knowbase/signals/__init__.py +2 -5
  178. django_cfg/apps/knowbase/signals/archive_signals.py +35 -34
  179. django_cfg/apps/knowbase/signals/chat_signals.py +6 -5
  180. django_cfg/apps/knowbase/signals/document_signals.py +22 -22
  181. django_cfg/apps/knowbase/signals/external_data_signals.py +22 -22
  182. django_cfg/apps/knowbase/tasks/__init__.py +6 -7
  183. django_cfg/apps/knowbase/tasks/archive_tasks.py +41 -41
  184. django_cfg/apps/knowbase/tasks/document_processing.py +49 -44
  185. django_cfg/apps/knowbase/tasks/external_data_tasks.py +46 -44
  186. django_cfg/apps/knowbase/tasks/maintenance.py +26 -24
  187. django_cfg/apps/knowbase/urls.py +3 -2
  188. django_cfg/apps/knowbase/urls_admin.py +6 -3
  189. django_cfg/apps/knowbase/urls_system.py +4 -5
  190. django_cfg/apps/knowbase/utils/chunk_settings.py +22 -20
  191. django_cfg/apps/knowbase/utils/text_processing.py +76 -75
  192. django_cfg/apps/knowbase/utils/validation.py +9 -9
  193. django_cfg/apps/knowbase/views/__init__.py +5 -5
  194. django_cfg/apps/knowbase/views/archive_views.py +90 -87
  195. django_cfg/apps/knowbase/views/base.py +9 -12
  196. django_cfg/apps/knowbase/views/chat_views.py +32 -32
  197. django_cfg/apps/knowbase/views/document_views.py +27 -28
  198. django_cfg/apps/knowbase/views/public_views.py +19 -19
  199. django_cfg/apps/leads/admin/leads_admin.py +41 -45
  200. django_cfg/apps/leads/admin/resources.py +14 -14
  201. django_cfg/apps/leads/admin.py +7 -9
  202. django_cfg/apps/leads/apps.py +1 -1
  203. django_cfg/apps/leads/models.py +17 -17
  204. django_cfg/apps/leads/serializers.py +5 -4
  205. django_cfg/apps/leads/signals.py +7 -7
  206. django_cfg/apps/leads/tests.py +47 -47
  207. django_cfg/apps/leads/urls.py +2 -2
  208. django_cfg/apps/leads/views.py +11 -11
  209. django_cfg/apps/maintenance/__init__.py +3 -3
  210. django_cfg/apps/maintenance/admin/__init__.py +1 -1
  211. django_cfg/apps/maintenance/admin/api_key_admin.py +36 -36
  212. django_cfg/apps/maintenance/admin/log_admin.py +35 -37
  213. django_cfg/apps/maintenance/admin/scheduled_admin.py +47 -51
  214. django_cfg/apps/maintenance/admin/site_admin.py +49 -52
  215. django_cfg/apps/maintenance/apps.py +2 -2
  216. django_cfg/apps/maintenance/management/commands/maintenance.py +53 -52
  217. django_cfg/apps/maintenance/management/commands/process_scheduled_maintenance.py +44 -44
  218. django_cfg/apps/maintenance/management/commands/sync_cloudflare.py +32 -32
  219. django_cfg/apps/maintenance/managers/__init__.py +1 -1
  220. django_cfg/apps/maintenance/managers/cloudflare_site_manager.py +39 -38
  221. django_cfg/apps/maintenance/managers/maintenance_log_manager.py +32 -31
  222. django_cfg/apps/maintenance/migrations/0001_initial.py +1 -0
  223. django_cfg/apps/maintenance/models/__init__.py +2 -2
  224. django_cfg/apps/maintenance/models/cloudflare_api_key.py +15 -15
  225. django_cfg/apps/maintenance/models/cloudflare_site.py +24 -22
  226. django_cfg/apps/maintenance/models/maintenance_log.py +15 -14
  227. django_cfg/apps/maintenance/models/scheduled_maintenance.py +53 -52
  228. django_cfg/apps/maintenance/services/__init__.py +3 -3
  229. django_cfg/apps/maintenance/services/bulk_operations_service.py +68 -68
  230. django_cfg/apps/maintenance/services/maintenance_service.py +59 -58
  231. django_cfg/apps/maintenance/services/scheduled_maintenance_service.py +52 -52
  232. django_cfg/apps/maintenance/services/site_sync_service.py +64 -65
  233. django_cfg/apps/maintenance/utils/__init__.py +1 -1
  234. django_cfg/apps/maintenance/utils/retry_utils.py +17 -17
  235. django_cfg/apps/newsletter/admin/__init__.py +12 -16
  236. django_cfg/apps/newsletter/admin/newsletter_admin.py +90 -87
  237. django_cfg/apps/newsletter/admin/resources.py +29 -29
  238. django_cfg/apps/newsletter/admin.py +39 -32
  239. django_cfg/apps/newsletter/management/commands/test_newsletter.py +3 -3
  240. django_cfg/apps/newsletter/managers/__init__.py +1 -1
  241. django_cfg/apps/newsletter/migrations/0001_initial.py +2 -1
  242. django_cfg/apps/newsletter/models.py +34 -33
  243. django_cfg/apps/newsletter/serializers.py +13 -13
  244. django_cfg/apps/newsletter/services/email_service.py +42 -40
  245. django_cfg/apps/newsletter/signals.py +4 -3
  246. django_cfg/apps/newsletter/urls.py +7 -7
  247. django_cfg/apps/newsletter/views/__init__.py +14 -19
  248. django_cfg/apps/newsletter/views/campaigns.py +19 -19
  249. django_cfg/apps/newsletter/views/emails.py +20 -20
  250. django_cfg/apps/newsletter/views/newsletters.py +5 -5
  251. django_cfg/apps/newsletter/views/subscriptions.py +24 -24
  252. django_cfg/apps/newsletter/views/tracking.py +6 -5
  253. django_cfg/apps/payments/admin/__init__.py +6 -5
  254. django_cfg/apps/payments/admin/api_keys_admin.py +43 -45
  255. django_cfg/apps/payments/admin/balance_admin.py +41 -47
  256. django_cfg/apps/payments/admin/currencies_admin.py +60 -62
  257. django_cfg/apps/payments/admin/endpoint_groups_admin.py +14 -28
  258. django_cfg/apps/payments/admin/filters.py +59 -59
  259. django_cfg/apps/payments/admin/networks_admin.py +36 -50
  260. django_cfg/apps/payments/admin/payments_admin.py +47 -49
  261. django_cfg/apps/payments/admin/subscriptions_admin.py +30 -32
  262. django_cfg/apps/payments/admin/tariffs_admin.py +37 -42
  263. django_cfg/apps/payments/admin_interface/serializers/__init__.py +12 -13
  264. django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +28 -27
  265. django_cfg/apps/payments/admin_interface/serializers/webhook_serializers.py +4 -5
  266. django_cfg/apps/payments/admin_interface/templates/payments/base.html +407 -3
  267. django_cfg/apps/payments/admin_interface/templates/payments/components/ngrok_status.html +13 -13
  268. django_cfg/apps/payments/admin_interface/templates/payments/payment_dashboard.html +5 -1
  269. django_cfg/apps/payments/admin_interface/templates/payments/payment_detail.html +105 -49
  270. django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +4 -1
  271. django_cfg/apps/payments/admin_interface/templates/payments/payment_list.html +16 -8
  272. django_cfg/apps/payments/admin_interface/templates/payments/webhook_dashboard.html +16 -8
  273. django_cfg/apps/payments/admin_interface/views/__init__.py +8 -9
  274. django_cfg/apps/payments/admin_interface/views/api/__init__.py +3 -3
  275. django_cfg/apps/payments/admin_interface/views/api/payments.py +52 -54
  276. django_cfg/apps/payments/admin_interface/views/api/stats.py +33 -30
  277. django_cfg/apps/payments/admin_interface/views/api/users.py +10 -11
  278. django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +46 -51
  279. django_cfg/apps/payments/admin_interface/views/api/webhook_public.py +9 -9
  280. django_cfg/apps/payments/admin_interface/views/base.py +17 -19
  281. django_cfg/apps/payments/admin_interface/views/dashboard.py +10 -10
  282. django_cfg/apps/payments/admin_interface/views/forms.py +21 -20
  283. django_cfg/apps/payments/apps.py +7 -6
  284. django_cfg/apps/payments/config/__init__.py +4 -4
  285. django_cfg/apps/payments/config/django_cfg_integration.py +22 -21
  286. django_cfg/apps/payments/config/helpers.py +14 -12
  287. django_cfg/apps/payments/management/commands/cleanup_expired_data.py +85 -86
  288. django_cfg/apps/payments/management/commands/currency_stats.py +84 -87
  289. django_cfg/apps/payments/management/commands/manage_currencies.py +59 -58
  290. django_cfg/apps/payments/management/commands/manage_providers.py +103 -105
  291. django_cfg/apps/payments/management/commands/process_pending_payments.py +67 -70
  292. django_cfg/apps/payments/management/commands/test_providers.py +83 -84
  293. django_cfg/apps/payments/middleware/__init__.py +1 -1
  294. django_cfg/apps/payments/middleware/api_access.py +77 -78
  295. django_cfg/apps/payments/middleware/rate_limiting.py +72 -72
  296. django_cfg/apps/payments/middleware/usage_tracking.py +66 -64
  297. django_cfg/apps/payments/migrations/0001_initial.py +2 -1
  298. django_cfg/apps/payments/models/__init__.py +11 -12
  299. django_cfg/apps/payments/models/api_keys.py +29 -27
  300. django_cfg/apps/payments/models/balance.py +38 -38
  301. django_cfg/apps/payments/models/base.py +12 -11
  302. django_cfg/apps/payments/models/currencies.py +53 -52
  303. django_cfg/apps/payments/models/managers/__init__.py +13 -14
  304. django_cfg/apps/payments/models/managers/api_key_managers.py +55 -53
  305. django_cfg/apps/payments/models/managers/balance_managers.py +98 -97
  306. django_cfg/apps/payments/models/managers/currency_managers.py +70 -69
  307. django_cfg/apps/payments/models/managers/payment_managers.py +113 -111
  308. django_cfg/apps/payments/models/managers/subscription_managers.py +99 -97
  309. django_cfg/apps/payments/models/payments.py +167 -73
  310. django_cfg/apps/payments/models/subscriptions.py +56 -54
  311. django_cfg/apps/payments/models/tariffs.py +35 -34
  312. django_cfg/apps/payments/services/__init__.py +33 -36
  313. django_cfg/apps/payments/services/cache/__init__.py +7 -1
  314. django_cfg/apps/payments/services/cache_service/__init__.py +22 -20
  315. django_cfg/apps/payments/services/cache_service/api_key_cache.py +6 -5
  316. django_cfg/apps/payments/services/cache_service/interfaces.py +5 -5
  317. django_cfg/apps/payments/services/cache_service/keys.py +8 -8
  318. django_cfg/apps/payments/services/cache_service/rate_limit_cache.py +8 -7
  319. django_cfg/apps/payments/services/cache_service/simple_cache.py +17 -14
  320. django_cfg/apps/payments/services/core/__init__.py +3 -3
  321. django_cfg/apps/payments/services/core/balance_service.py +69 -65
  322. django_cfg/apps/payments/services/core/base.py +25 -22
  323. django_cfg/apps/payments/services/core/currency/__init__.py +1 -1
  324. django_cfg/apps/payments/services/core/currency/currency_converter.py +2 -0
  325. django_cfg/apps/payments/services/core/currency_service.py +68 -66
  326. django_cfg/apps/payments/services/core/operations/__init__.py +1 -1
  327. django_cfg/apps/payments/services/core/operations/payment_canceller.py +2 -1
  328. django_cfg/apps/payments/services/core/operations/payment_creator.py +2 -1
  329. django_cfg/apps/payments/services/core/operations/status_checker.py +2 -1
  330. django_cfg/apps/payments/services/core/payment_service.py +10 -7
  331. django_cfg/apps/payments/services/core/providers/provider_client.py +2 -2
  332. django_cfg/apps/payments/services/core/subscription_service.py +77 -74
  333. django_cfg/apps/payments/services/core/utils/data_converter.py +1 -0
  334. django_cfg/apps/payments/services/core/utils/statistics_calculator.py +1 -0
  335. django_cfg/apps/payments/services/core/webhook_service.py +67 -63
  336. django_cfg/apps/payments/services/integrations/__init__.py +3 -3
  337. django_cfg/apps/payments/services/integrations/ngrok_service.py +1 -0
  338. django_cfg/apps/payments/services/integrations/providers_config.py +3 -2
  339. django_cfg/apps/payments/services/providers/base.py +59 -57
  340. django_cfg/apps/payments/services/providers/models/__init__.py +7 -14
  341. django_cfg/apps/payments/services/providers/models/base.py +15 -15
  342. django_cfg/apps/payments/services/providers/models/providers.py +13 -12
  343. django_cfg/apps/payments/services/providers/models/universal.py +6 -5
  344. django_cfg/apps/payments/services/providers/nowpayments/__init__.py +4 -4
  345. django_cfg/apps/payments/services/providers/nowpayments/config.py +9 -8
  346. django_cfg/apps/payments/services/providers/nowpayments/models.py +15 -15
  347. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/__init__.py +2 -2
  348. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/patterns.py +26 -26
  349. django_cfg/apps/payments/services/providers/nowpayments/parsers/parser.py +3 -2
  350. django_cfg/apps/payments/services/providers/nowpayments/provider.py +95 -99
  351. django_cfg/apps/payments/services/providers/nowpayments/sync.py +41 -40
  352. django_cfg/apps/payments/services/providers/registry.py +65 -63
  353. django_cfg/apps/payments/services/providers/sync_service.py +50 -50
  354. django_cfg/apps/payments/services/types/__init__.py +21 -22
  355. django_cfg/apps/payments/services/types/data.py +14 -13
  356. django_cfg/apps/payments/services/types/requests.py +21 -22
  357. django_cfg/apps/payments/services/types/responses.py +16 -15
  358. django_cfg/apps/payments/services/types/webhooks.py +30 -30
  359. django_cfg/apps/payments/signals/__init__.py +4 -6
  360. django_cfg/apps/payments/signals/api_key_signals.py +33 -32
  361. django_cfg/apps/payments/signals/balance_signals.py +28 -26
  362. django_cfg/apps/payments/signals/payment_signals.py +29 -28
  363. django_cfg/apps/payments/signals/subscription_signals.py +39 -38
  364. django_cfg/apps/payments/static/payments/js/ngrok-status.js +12 -8
  365. django_cfg/apps/payments/static/payments/js/payment-detail.js +1 -1
  366. django_cfg/apps/payments/static/payments/js/payment-form.js +3 -3
  367. django_cfg/apps/payments/static/payments/js/payment-list.js +13 -6
  368. django_cfg/apps/payments/static/payments/js/webhook-dashboard-mjs.js +241 -0
  369. django_cfg/apps/payments/tasks/__init__.py +11 -12
  370. django_cfg/apps/payments/tasks/types.py +10 -9
  371. django_cfg/apps/payments/tasks/usage_tracking.py +44 -46
  372. django_cfg/apps/payments/templatetags/payment_tags.py +27 -27
  373. django_cfg/apps/payments/urls.py +31 -14
  374. django_cfg/apps/payments/urls_admin.py +10 -10
  375. django_cfg/apps/payments/views/api/__init__.py +32 -33
  376. django_cfg/apps/payments/views/api/api_keys.py +62 -62
  377. django_cfg/apps/payments/views/api/balances.py +63 -64
  378. django_cfg/apps/payments/views/api/base.py +52 -52
  379. django_cfg/apps/payments/views/api/currencies.py +75 -63
  380. django_cfg/apps/payments/views/api/payments.py +73 -74
  381. django_cfg/apps/payments/views/api/subscriptions.py +71 -72
  382. django_cfg/apps/payments/views/api/webhooks.py +85 -84
  383. django_cfg/apps/payments/views/overview/__init__.py +7 -7
  384. django_cfg/apps/payments/views/overview/serializers.py +13 -14
  385. django_cfg/apps/payments/views/overview/services.py +66 -67
  386. django_cfg/apps/payments/views/overview/urls.py +2 -1
  387. django_cfg/apps/payments/views/overview/views.py +31 -31
  388. django_cfg/apps/payments/views/serializers/__init__.py +35 -36
  389. django_cfg/apps/payments/views/serializers/api_keys.py +59 -57
  390. django_cfg/apps/payments/views/serializers/balances.py +34 -33
  391. django_cfg/apps/payments/views/serializers/currencies.py +36 -34
  392. django_cfg/apps/payments/views/serializers/payments.py +48 -47
  393. django_cfg/apps/payments/views/serializers/subscriptions.py +50 -45
  394. django_cfg/apps/payments/views/serializers/webhooks.py +17 -16
  395. django_cfg/apps/support/admin/__init__.py +3 -3
  396. django_cfg/apps/support/admin/resources.py +26 -26
  397. django_cfg/apps/support/admin/support_admin.py +44 -48
  398. django_cfg/apps/support/admin.py +16 -15
  399. django_cfg/apps/support/apps.py +1 -1
  400. django_cfg/apps/support/managers/message_manager.py +4 -4
  401. django_cfg/apps/support/managers/ticket_manager.py +13 -12
  402. django_cfg/apps/support/migrations/0001_initial.py +2 -1
  403. django_cfg/apps/support/models.py +3 -1
  404. django_cfg/apps/support/serializers.py +4 -2
  405. django_cfg/apps/support/signals.py +12 -10
  406. django_cfg/apps/support/urls.py +4 -3
  407. django_cfg/apps/support/utils/support_email_service.py +11 -9
  408. django_cfg/apps/support/views/__init__.py +3 -3
  409. django_cfg/apps/support/views/admin.py +9 -9
  410. django_cfg/apps/support/views/api.py +10 -9
  411. django_cfg/apps/support/views/chat.py +14 -14
  412. django_cfg/apps/tasks/admin/tasks_admin.py +65 -74
  413. django_cfg/apps/tasks/apps.py +2 -2
  414. django_cfg/apps/tasks/serializers.py +6 -6
  415. django_cfg/apps/tasks/static/tasks/js/dashboard/main.mjs +44 -20
  416. django_cfg/apps/tasks/static/tasks/js/dashboard/overview.mjs +7 -5
  417. django_cfg/apps/tasks/static/tasks/js/dashboard/queues.mjs +5 -3
  418. django_cfg/apps/tasks/static/tasks/js/dashboard/tasks.mjs +5 -3
  419. django_cfg/apps/tasks/static/tasks/js/dashboard/workers.mjs +5 -3
  420. django_cfg/apps/tasks/tasks/demo_tasks.py +12 -11
  421. django_cfg/apps/tasks/templates/tasks/components/tasks_mjs_integration.html +269 -0
  422. django_cfg/apps/tasks/templates/tasks/pages/dashboard-improved.html +168 -0
  423. django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +21 -2
  424. django_cfg/apps/tasks/urls.py +3 -2
  425. django_cfg/apps/tasks/urls_admin.py +1 -0
  426. django_cfg/apps/tasks/utils/simulator.py +49 -52
  427. django_cfg/apps/tasks/views/api.py +75 -73
  428. django_cfg/apps/tasks/views/dashboard.py +5 -4
  429. django_cfg/apps/urls.py +20 -11
  430. django_cfg/apps.py +6 -5
  431. django_cfg/cli/commands/create_project.py +7 -6
  432. django_cfg/cli/commands/info.py +25 -25
  433. django_cfg/cli/utils.py +27 -27
  434. django_cfg/config.py +1 -1
  435. django_cfg/core/__init__.py +8 -8
  436. django_cfg/core/base/config_model.py +13 -12
  437. django_cfg/core/builders/apps_builder.py +2 -2
  438. django_cfg/core/builders/middleware_builder.py +1 -1
  439. django_cfg/core/builders/security_builder.py +1 -1
  440. django_cfg/core/config.py +2 -2
  441. django_cfg/core/environment/detector.py +27 -28
  442. django_cfg/core/exceptions.py +1 -1
  443. django_cfg/core/generation/core_generators/settings.py +1 -1
  444. django_cfg/core/generation/core_generators/static.py +11 -5
  445. django_cfg/core/generation/core_generators/templates.py +1 -1
  446. django_cfg/core/generation/data_generators/__init__.py +1 -1
  447. django_cfg/core/generation/data_generators/cache.py +1 -1
  448. django_cfg/core/generation/data_generators/database.py +1 -1
  449. django_cfg/core/generation/generation.py +1 -3
  450. django_cfg/core/generation/integration_generators/__init__.py +2 -2
  451. django_cfg/core/generation/integration_generators/api.py +12 -2
  452. django_cfg/core/generation/integration_generators/sessions.py +1 -1
  453. django_cfg/core/generation/integration_generators/tailwind.py +1 -1
  454. django_cfg/core/generation/integration_generators/tasks.py +1 -1
  455. django_cfg/core/generation/integration_generators/third_party.py +1 -1
  456. django_cfg/core/generation/orchestrator.py +1 -1
  457. django_cfg/core/generation/protocols.py +1 -1
  458. django_cfg/core/generation/utility_generators/__init__.py +1 -1
  459. django_cfg/core/generation/utility_generators/email.py +1 -1
  460. django_cfg/core/generation/utility_generators/i18n.py +1 -1
  461. django_cfg/core/generation/utility_generators/limits.py +1 -1
  462. django_cfg/core/generation/utility_generators/logging.py +1 -1
  463. django_cfg/core/generation/utility_generators/security.py +1 -1
  464. django_cfg/core/generation/utils/helpers.py +1 -1
  465. django_cfg/core/integration/__init__.py +5 -5
  466. django_cfg/core/integration/commands_collector.py +38 -39
  467. django_cfg/core/integration/display/__init__.py +2 -2
  468. django_cfg/core/integration/display/base.py +30 -30
  469. django_cfg/core/integration/display/ngrok.py +35 -36
  470. django_cfg/core/integration/display/startup.py +149 -139
  471. django_cfg/core/integration/url_integration.py +10 -10
  472. django_cfg/core/integration/version_checker.py +20 -19
  473. django_cfg/core/services/config_service.py +4 -4
  474. django_cfg/core/state/__init__.py +1 -1
  475. django_cfg/core/state/registry.py +1 -1
  476. django_cfg/core/types/__init__.py +8 -1
  477. django_cfg/core/validation.py +36 -39
  478. django_cfg/management/commands/check_endpoints.py +3 -1
  479. django_cfg/management/commands/check_settings.py +3 -1
  480. django_cfg/management/commands/clear_constance.py +3 -1
  481. django_cfg/management/commands/create_token.py +3 -1
  482. django_cfg/management/commands/generate_clients.py +3 -1
  483. django_cfg/management/commands/migrate_all.py +3 -1
  484. django_cfg/management/commands/rundramatiq.py +3 -1
  485. django_cfg/management/commands/rundramatiq_simulator.py +3 -1
  486. django_cfg/management/commands/runserver_ngrok.py +3 -1
  487. django_cfg/management/commands/show_config.py +3 -1
  488. django_cfg/management/commands/superuser.py +3 -1
  489. django_cfg/management/commands/task_clear.py +3 -1
  490. django_cfg/management/commands/task_status.py +3 -1
  491. django_cfg/management/commands/test_email.py +3 -1
  492. django_cfg/management/commands/test_telegram.py +3 -1
  493. django_cfg/management/commands/test_twilio.py +3 -1
  494. django_cfg/management/commands/validate_openapi.py +3 -1
  495. django_cfg/middleware/pagination.py +8 -8
  496. django_cfg/middleware/public_endpoints.py +24 -23
  497. django_cfg/middleware/user_activity.py +27 -25
  498. django_cfg/models/__init__.py +19 -20
  499. django_cfg/models/api/__init__.py +4 -4
  500. django_cfg/models/api/config.py +23 -21
  501. django_cfg/models/api/cors.py +17 -16
  502. django_cfg/models/api/drf/__init__.py +1 -1
  503. django_cfg/models/api/drf/config.py +2 -1
  504. django_cfg/models/api/drf/redoc.py +2 -1
  505. django_cfg/models/api/drf/spectacular.py +4 -2
  506. django_cfg/models/api/drf/swagger.py +2 -1
  507. django_cfg/models/api/jwt.py +37 -36
  508. django_cfg/models/api/keys.py +13 -12
  509. django_cfg/models/api/limits.py +31 -30
  510. django_cfg/models/base/config.py +40 -41
  511. django_cfg/models/base/module.py +8 -8
  512. django_cfg/models/django/__init__.py +1 -1
  513. django_cfg/models/django/constance.py +8 -7
  514. django_cfg/models/django/environment.py +5 -3
  515. django_cfg/models/django/openapi.py +6 -16
  516. django_cfg/models/django/revolution_legacy.py +17 -16
  517. django_cfg/models/infrastructure/__init__.py +1 -1
  518. django_cfg/models/infrastructure/cache.py +46 -45
  519. django_cfg/models/infrastructure/database/config.py +4 -6
  520. django_cfg/models/infrastructure/database/converters.py +1 -1
  521. django_cfg/models/infrastructure/database/parsers.py +1 -1
  522. django_cfg/models/infrastructure/database/validators.py +1 -1
  523. django_cfg/models/infrastructure/logging.py +59 -57
  524. django_cfg/models/infrastructure/security.py +26 -24
  525. django_cfg/models/ngrok/auth.py +2 -1
  526. django_cfg/models/ngrok/config.py +3 -2
  527. django_cfg/models/ngrok/tunnel.py +2 -1
  528. django_cfg/models/payments/__init__.py +1 -1
  529. django_cfg/models/payments/api_keys.py +3 -1
  530. django_cfg/models/payments/config.py +4 -1
  531. django_cfg/models/payments/providers/base.py +2 -1
  532. django_cfg/models/payments/providers/nowpayments.py +3 -1
  533. django_cfg/models/services/__init__.py +1 -1
  534. django_cfg/models/services/base.py +2 -1
  535. django_cfg/models/services/email.py +28 -26
  536. django_cfg/models/services/telegram.py +2 -1
  537. django_cfg/models/tasks/__init__.py +2 -2
  538. django_cfg/models/tasks/backends.py +4 -3
  539. django_cfg/models/tasks/config.py +6 -4
  540. django_cfg/models/tasks/utils.py +3 -3
  541. django_cfg/modules/base.py +18 -17
  542. django_cfg/modules/django_admin/__init__.py +14 -15
  543. django_cfg/modules/django_admin/decorators/__init__.py +1 -1
  544. django_cfg/modules/django_admin/decorators/actions.py +8 -7
  545. django_cfg/modules/django_admin/decorators/display.py +9 -7
  546. django_cfg/modules/django_admin/icons/__init__.py +1 -1
  547. django_cfg/modules/django_admin/icons/constants.py +27 -27
  548. django_cfg/modules/django_admin/icons/generate_icons.py +54 -54
  549. django_cfg/modules/django_admin/management/commands/check_endpoints.py +5 -3
  550. django_cfg/modules/django_admin/management/commands/check_settings.py +40 -44
  551. django_cfg/modules/django_admin/management/commands/clear_constance.py +29 -30
  552. django_cfg/modules/django_admin/management/commands/create_token.py +42 -42
  553. django_cfg/modules/django_admin/management/commands/list_urls.py +37 -38
  554. django_cfg/modules/django_admin/management/commands/migrate_all.py +13 -15
  555. django_cfg/modules/django_admin/management/commands/migrator.py +17 -17
  556. django_cfg/modules/django_admin/management/commands/script.py +58 -60
  557. django_cfg/modules/django_admin/management/commands/show_config.py +32 -30
  558. django_cfg/modules/django_admin/management/commands/show_urls.py +46 -44
  559. django_cfg/modules/django_admin/management/commands/superuser.py +47 -48
  560. django_cfg/modules/django_admin/management/commands/tree.py +50 -54
  561. django_cfg/modules/django_admin/mixins/display_mixin.py +16 -15
  562. django_cfg/modules/django_admin/mixins/optimization_mixin.py +9 -8
  563. django_cfg/modules/django_admin/mixins/standalone_actions_mixin.py +25 -24
  564. django_cfg/modules/django_admin/models/__init__.py +4 -4
  565. django_cfg/modules/django_admin/models/action_models.py +3 -1
  566. django_cfg/modules/django_admin/models/badge_models.py +4 -2
  567. django_cfg/modules/django_admin/models/base.py +3 -3
  568. django_cfg/modules/django_admin/models/display_models.py +1 -0
  569. django_cfg/modules/django_admin/utils/badges.py +27 -26
  570. django_cfg/modules/django_admin/utils/displays.py +49 -49
  571. django_cfg/modules/django_client/apps.py +21 -3
  572. django_cfg/modules/django_client/core/__init__.py +9 -10
  573. django_cfg/modules/django_client/core/archive/manager.py +2 -2
  574. django_cfg/modules/django_client/core/cli/main.py +1 -3
  575. django_cfg/modules/django_client/core/config/config.py +3 -1
  576. django_cfg/modules/django_client/core/config/group.py +1 -0
  577. django_cfg/modules/django_client/core/config/service.py +2 -1
  578. django_cfg/modules/django_client/core/generator/__init__.py +1 -1
  579. django_cfg/modules/django_client/core/generator/base.py +2 -2
  580. django_cfg/modules/django_client/core/generator/python/async_client_gen.py +1 -1
  581. django_cfg/modules/django_client/core/generator/python/files_generator.py +1 -1
  582. django_cfg/modules/django_client/core/generator/python/generator.py +4 -4
  583. django_cfg/modules/django_client/core/generator/python/models_generator.py +1 -1
  584. django_cfg/modules/django_client/core/generator/python/operations_generator.py +2 -2
  585. django_cfg/modules/django_client/core/generator/python/sync_client_gen.py +1 -1
  586. django_cfg/modules/django_client/core/generator/typescript/client_generator.py +3 -1
  587. django_cfg/modules/django_client/core/generator/typescript/fetchers_generator.py +14 -13
  588. django_cfg/modules/django_client/core/generator/typescript/files_generator.py +1 -0
  589. django_cfg/modules/django_client/core/generator/typescript/generator.py +6 -6
  590. django_cfg/modules/django_client/core/generator/typescript/hooks_generator.py +12 -10
  591. django_cfg/modules/django_client/core/generator/typescript/models_generator.py +2 -1
  592. django_cfg/modules/django_client/core/generator/typescript/naming.py +2 -3
  593. django_cfg/modules/django_client/core/generator/typescript/operations_generator.py +12 -10
  594. django_cfg/modules/django_client/core/generator/typescript/schemas_generator.py +3 -2
  595. django_cfg/modules/django_client/core/generator/typescript/templates/client/client.ts.jinja +14 -6
  596. django_cfg/modules/django_client/core/generator/typescript/templates/main_index.ts.jinja +4 -10
  597. django_cfg/modules/django_client/core/groups/__init__.py +1 -1
  598. django_cfg/modules/django_client/core/groups/detector.py +2 -1
  599. django_cfg/modules/django_client/core/groups/manager.py +2 -1
  600. django_cfg/modules/django_client/core/ir/schema.py +1 -1
  601. django_cfg/modules/django_client/core/parser/base.py +0 -2
  602. django_cfg/modules/django_client/core/parser/models/schema.py +1 -1
  603. django_cfg/modules/django_client/core/validation/__init__.py +1 -1
  604. django_cfg/modules/django_client/core/validation/fixer.py +1 -2
  605. django_cfg/modules/django_client/core/validation/reporter.py +2 -2
  606. django_cfg/modules/django_client/core/validation/safety.py +1 -1
  607. django_cfg/modules/django_client/management/commands/generate_client.py +14 -11
  608. django_cfg/modules/django_client/management/commands/validate_openapi.py +4 -6
  609. django_cfg/modules/django_client/spectacular/__init__.py +1 -1
  610. django_cfg/modules/django_client/spectacular/async_detection.py +3 -2
  611. django_cfg/modules/django_client/spectacular/enum_naming.py +1 -1
  612. django_cfg/modules/django_client/spectacular/schema.py +5 -5
  613. django_cfg/modules/django_client/system/__init__.py +24 -0
  614. django_cfg/modules/django_client/system/base_generator.py +123 -0
  615. django_cfg/modules/django_client/system/generate_mjs_clients.py +174 -0
  616. django_cfg/modules/django_client/system/mjs_generator.py +219 -0
  617. django_cfg/modules/django_client/system/schema_parser.py +195 -0
  618. django_cfg/modules/django_client/system/templates/api_client.js.j2 +87 -0
  619. django_cfg/modules/django_client/system/templates/app_index.js.j2 +13 -0
  620. django_cfg/modules/django_client/system/templates/base_client.js.j2 +166 -0
  621. django_cfg/modules/django_client/system/templates/main_index.js.j2 +80 -0
  622. django_cfg/modules/django_client/system/templates/types.js.j2 +24 -0
  623. django_cfg/modules/django_client/urls.py +3 -2
  624. django_cfg/modules/django_currency/__init__.py +17 -18
  625. django_cfg/modules/django_currency/clients/__init__.py +2 -2
  626. django_cfg/modules/django_currency/clients/coinpaprika_client.py +48 -48
  627. django_cfg/modules/django_currency/clients/hybrid_client.py +76 -75
  628. django_cfg/modules/django_currency/core/__init__.py +7 -13
  629. django_cfg/modules/django_currency/core/converter.py +25 -24
  630. django_cfg/modules/django_currency/core/models.py +9 -8
  631. django_cfg/modules/django_currency/database/__init__.py +4 -4
  632. django_cfg/modules/django_currency/database/database_loader.py +65 -66
  633. django_cfg/modules/django_currency/examples/example_database_usage.py +29 -28
  634. django_cfg/modules/django_currency/utils/cache.py +10 -11
  635. django_cfg/modules/django_dashboard/__init__.py +4 -5
  636. django_cfg/modules/django_dashboard/components.py +11 -7
  637. django_cfg/modules/django_dashboard/debug.py +1 -3
  638. django_cfg/modules/django_dashboard/management/commands/debug_dashboard.py +3 -3
  639. django_cfg/modules/django_dashboard/sections/base.py +2 -1
  640. django_cfg/modules/django_dashboard/sections/commands.py +3 -2
  641. django_cfg/modules/django_dashboard/sections/documentation.py +8 -6
  642. django_cfg/modules/django_dashboard/sections/overview.py +13 -9
  643. django_cfg/modules/django_dashboard/sections/stats.py +2 -2
  644. django_cfg/modules/django_dashboard/sections/system.py +2 -1
  645. django_cfg/modules/django_drf_theme/templatetags/tailwind_tags.py +12 -4
  646. django_cfg/modules/django_email/management/commands/test_email.py +8 -7
  647. django_cfg/modules/django_email/service.py +5 -4
  648. django_cfg/modules/django_health/service.py +46 -44
  649. django_cfg/modules/django_import_export/__init__.py +7 -3
  650. django_cfg/modules/django_llm/__init__.py +3 -2
  651. django_cfg/modules/django_llm/example.py +58 -56
  652. django_cfg/modules/django_llm/llm/__init__.py +1 -1
  653. django_cfg/modules/django_llm/llm/cache.py +21 -20
  654. django_cfg/modules/django_llm/llm/client.py +9 -9
  655. django_cfg/modules/django_llm/llm/costs.py +14 -14
  656. django_cfg/modules/django_llm/llm/embeddings/__init__.py +1 -1
  657. django_cfg/modules/django_llm/llm/embeddings/mock_embedder.py +1 -2
  658. django_cfg/modules/django_llm/llm/embeddings/openai_embedder.py +1 -2
  659. django_cfg/modules/django_llm/llm/extractor.py +8 -8
  660. django_cfg/modules/django_llm/llm/models.py +5 -5
  661. django_cfg/modules/django_llm/llm/models_api/models_query.py +2 -2
  662. django_cfg/modules/django_llm/llm/models_cache.py +91 -92
  663. django_cfg/modules/django_llm/llm/providers/config_builder.py +1 -1
  664. django_cfg/modules/django_llm/llm/providers/provider_manager.py +2 -1
  665. django_cfg/modules/django_llm/llm/requests/cache_manager.py +1 -1
  666. django_cfg/modules/django_llm/llm/requests/chat_handler.py +2 -2
  667. django_cfg/modules/django_llm/llm/requests/embedding_handler.py +1 -1
  668. django_cfg/modules/django_llm/llm/responses/response_builder.py +2 -2
  669. django_cfg/modules/django_llm/llm/stats/stats_manager.py +1 -1
  670. django_cfg/modules/django_llm/llm/tokenizer.py +10 -9
  671. django_cfg/modules/django_llm/translator/__init__.py +1 -1
  672. django_cfg/modules/django_llm/translator/cache.py +36 -35
  673. django_cfg/modules/django_llm/translator/detectors/__init__.py +1 -1
  674. django_cfg/modules/django_llm/translator/detectors/script_detector.py +0 -1
  675. django_cfg/modules/django_llm/translator/stats/stats_tracker.py +1 -1
  676. django_cfg/modules/django_llm/translator/translator.py +5 -4
  677. django_cfg/modules/django_llm/translator/translators/__init__.py +1 -1
  678. django_cfg/modules/django_llm/translator/translators/json_translator.py +1 -1
  679. django_cfg/modules/django_llm/translator/utils/__init__.py +1 -1
  680. django_cfg/modules/django_llm/translator/utils/prompt_builder.py +0 -1
  681. django_cfg/modules/django_logging/__init__.py +1 -1
  682. django_cfg/modules/django_logging/django_logger.py +33 -34
  683. django_cfg/modules/django_logging/logger.py +3 -7
  684. django_cfg/modules/django_ngrok/__init__.py +7 -7
  685. django_cfg/modules/django_ngrok/management/commands/runserver_ngrok.py +33 -30
  686. django_cfg/modules/django_ngrok/service.py +33 -32
  687. django_cfg/modules/django_tailwind/templates/django_tailwind/base.html +4 -36
  688. django_cfg/modules/django_tailwind/templates/django_tailwind/components/navbar.html +1 -1
  689. django_cfg/modules/django_tasks/__init__.py +5 -5
  690. django_cfg/modules/django_tasks/dramatiq_setup.py +1 -1
  691. django_cfg/modules/django_tasks/factory.py +1 -1
  692. django_cfg/modules/django_tasks/management/commands/rundramatiq.py +39 -40
  693. django_cfg/modules/django_tasks/management/commands/rundramatiq_simulator.py +79 -80
  694. django_cfg/modules/django_tasks/management/commands/task_clear.py +34 -34
  695. django_cfg/modules/django_tasks/management/commands/task_status.py +34 -34
  696. django_cfg/modules/django_tasks/service.py +4 -3
  697. django_cfg/modules/django_tasks/settings.py +1 -1
  698. django_cfg/modules/django_telegram/__init__.py +4 -4
  699. django_cfg/modules/django_telegram/management/commands/test_telegram.py +4 -5
  700. django_cfg/modules/django_telegram/service.py +4 -3
  701. django_cfg/modules/django_telegram/utils.py +1 -1
  702. django_cfg/modules/django_twilio/__init__.py +15 -16
  703. django_cfg/modules/django_twilio/_imports.py +1 -1
  704. django_cfg/modules/django_twilio/base.py +9 -5
  705. django_cfg/modules/django_twilio/email_otp.py +4 -3
  706. django_cfg/modules/django_twilio/exceptions.py +36 -36
  707. django_cfg/modules/django_twilio/management/commands/test_twilio.py +6 -7
  708. django_cfg/modules/django_twilio/models.py +54 -53
  709. django_cfg/modules/django_twilio/sendgrid_service.py +70 -72
  710. django_cfg/modules/django_twilio/simple_service.py +42 -41
  711. django_cfg/modules/django_twilio/sms.py +1 -0
  712. django_cfg/modules/django_twilio/twilio_service.py +79 -83
  713. django_cfg/modules/django_twilio/unified.py +6 -5
  714. django_cfg/modules/django_twilio/utils.py +2 -3
  715. django_cfg/modules/django_twilio/whatsapp.py +3 -2
  716. django_cfg/modules/django_unfold/__init__.py +7 -6
  717. django_cfg/modules/django_unfold/callbacks/actions.py +6 -5
  718. django_cfg/modules/django_unfold/callbacks/apizones.py +122 -0
  719. django_cfg/modules/django_unfold/callbacks/base.py +9 -8
  720. django_cfg/modules/django_unfold/callbacks/charts.py +36 -37
  721. django_cfg/modules/django_unfold/callbacks/commands.py +2 -2
  722. django_cfg/modules/django_unfold/callbacks/main.py +27 -27
  723. django_cfg/modules/django_unfold/callbacks/statistics.py +12 -12
  724. django_cfg/modules/django_unfold/callbacks/system.py +5 -5
  725. django_cfg/modules/django_unfold/callbacks/users.py +4 -4
  726. django_cfg/modules/django_unfold/dashboard.py +29 -29
  727. django_cfg/modules/django_unfold/models/__init__.py +23 -8
  728. django_cfg/modules/django_unfold/models/config.py +84 -81
  729. django_cfg/modules/django_unfold/models/dashboard.py +20 -19
  730. django_cfg/modules/django_unfold/models/dropdown.py +6 -4
  731. django_cfg/modules/django_unfold/models/navigation.py +6 -4
  732. django_cfg/modules/django_unfold/models/tabs.py +4 -3
  733. django_cfg/modules/django_unfold/models.py +2 -3
  734. django_cfg/modules/django_unfold/system_monitor.py +27 -25
  735. django_cfg/modules/django_unfold/tailwind.py +12 -14
  736. django_cfg/modules/django_unfold/utils.py +7 -6
  737. django_cfg/pyproject.toml +1 -1
  738. django_cfg/registry/__init__.py +3 -3
  739. django_cfg/registry/core.py +8 -8
  740. django_cfg/registry/modules.py +2 -2
  741. django_cfg/registry/services.py +2 -2
  742. django_cfg/registry/third_party.py +3 -3
  743. django_cfg/routing/__init__.py +3 -3
  744. django_cfg/routing/callbacks.py +27 -26
  745. django_cfg/routing/routers.py +2 -2
  746. django_cfg/static/js/api/accounts/client.mjs +69 -0
  747. django_cfg/static/js/api/accounts/index.mjs +13 -0
  748. django_cfg/static/js/api/base.mjs +166 -0
  749. django_cfg/static/js/api/index.mjs +100 -0
  750. django_cfg/static/js/api/ipc/client.mjs +74 -0
  751. django_cfg/static/js/api/ipc/index.mjs +13 -0
  752. django_cfg/static/js/api/leads/client.mjs +71 -0
  753. django_cfg/static/js/api/leads/index.mjs +13 -0
  754. django_cfg/static/js/api/newsletter/client.mjs +109 -0
  755. django_cfg/static/js/api/newsletter/index.mjs +13 -0
  756. django_cfg/static/js/api/payments/client.mjs +1264 -0
  757. django_cfg/static/js/api/payments/index.mjs +13 -0
  758. django_cfg/static/js/api/support/client.mjs +84 -0
  759. django_cfg/static/js/api/support/index.mjs +13 -0
  760. django_cfg/static/js/api/tasks/client.mjs +74 -0
  761. django_cfg/static/js/api/tasks/index.mjs +13 -0
  762. django_cfg/static/js/api/types.mjs +729 -0
  763. django_cfg/static/js/api-loader.mjs +169 -0
  764. django_cfg/templates/admin/snippets/zones/zones_table.html +4 -3
  765. django_cfg/templatetags/django_cfg.py +4 -4
  766. django_cfg/utils/path_resolution.py +49 -50
  767. django_cfg/utils/smart_defaults.py +27 -29
  768. django_cfg/utils/version_check.py +14 -14
  769. {django_cfg-1.4.21.dist-info → django_cfg-1.4.24.dist-info}/METADATA +1 -1
  770. django_cfg-1.4.24.dist-info/RECORD +1137 -0
  771. django_cfg/apps/payments/static/payments/js/api-client.js +0 -408
  772. django_cfg/modules/django_ipc_client/dashboard/README.md +0 -517
  773. django_cfg/modules/django_ipc_client/dashboard/UNFOLD_INTEGRATION.md +0 -439
  774. django_cfg/modules/django_ipc_client/dashboard/__init__.py +0 -11
  775. django_cfg/modules/django_ipc_client/dashboard/apps.py +0 -22
  776. django_cfg/modules/django_ipc_client/dashboard/templates/django_ipc_dashboard/dashboard.html +0 -200
  777. django_cfg/modules/django_ipc_client/dashboard/urls.py +0 -22
  778. django_cfg/modules/django_ipc_client/dashboard/urls_admin.py +0 -9
  779. django_cfg/modules/django_ipc_client/dashboard/views.py +0 -251
  780. django_cfg/modules/django_rpc_old/POETRY.md +0 -344
  781. django_cfg/modules/django_rpc_old/README.md +0 -397
  782. django_cfg/modules/django_rpc_old/TESTING.md +0 -358
  783. django_cfg/modules/django_rpc_old/__init__.py +0 -39
  784. django_cfg/modules/django_rpc_old/client.py +0 -531
  785. django_cfg/modules/django_rpc_old/config.py +0 -279
  786. django_cfg/modules/django_rpc_old/exceptions.py +0 -172
  787. django_cfg/modules/django_unfold/callbacks/revolution.py +0 -81
  788. django_cfg-1.4.21.dist-info/RECORD +0 -1111
  789. /django_cfg/{modules/django_ipc_client → apps/ipc}/README.md +0 -0
  790. /django_cfg/{modules/django_ipc_client → apps/ipc/services/client}/config.py +0 -0
  791. {django_cfg-1.4.21.dist-info → django_cfg-1.4.24.dist-info}/WHEEL +0 -0
  792. {django_cfg-1.4.21.dist-info → django_cfg-1.4.24.dist-info}/entry_points.txt +0 -0
  793. {django_cfg-1.4.21.dist-info → django_cfg-1.4.24.dist-info}/licenses/LICENSE +0 -0
@@ -5,48 +5,44 @@ Enhanced support ticket management with Material Icons and optimized queries.
5
5
  """
6
6
 
7
7
  from django.contrib import admin, messages
8
- from django.urls import reverse
9
- from django.shortcuts import redirect
8
+ from django.db.models import Count, Q
10
9
  from django.http import HttpRequest
11
- from django.utils.translation import gettext_lazy as _
12
- from django.utils.timesince import timesince
10
+ from django.urls import reverse
13
11
  from django.utils.html import format_html
14
- from django.db import models
15
- from django.db.models import Count, Q
16
12
  from unfold.admin import ModelAdmin, TabularInline
17
- from django_cfg import ExportMixin, ExportForm
18
13
 
14
+ from django_cfg import ExportForm, ExportMixin
19
15
  from django_cfg.modules.django_admin import (
20
- OptimizedModelAdmin,
21
- DisplayMixin,
22
- StatusBadgeConfig,
16
+ ActionVariant,
23
17
  DateTimeDisplayConfig,
18
+ DisplayMixin,
24
19
  Icons,
25
- ActionVariant,
20
+ OptimizedModelAdmin,
21
+ StatusBadgeConfig,
22
+ action,
26
23
  display,
27
- action
28
24
  )
29
25
  from django_cfg.modules.django_admin.utils.badges import StatusBadge
30
26
 
31
- from ..models import Ticket, Message
32
- from .filters import TicketUserEmailFilter, TicketUserNameFilter, MessageSenderEmailFilter
33
- from .resources import TicketResource, MessageResource
27
+ from ..models import Message, Ticket
28
+ from .filters import MessageSenderEmailFilter, TicketUserEmailFilter, TicketUserNameFilter
29
+ from .resources import MessageResource, TicketResource
34
30
 
35
31
 
36
32
  class MessageInline(TabularInline):
37
33
  """Read-only inline for viewing messages. Use Chat interface for replies."""
38
-
34
+
39
35
  model = Message
40
36
  extra = 0
41
37
  fields = ["sender_display", "created_at", "text_preview"]
42
38
  readonly_fields = ["sender_display", "created_at", "text_preview"]
43
39
  show_change_link = False
44
40
  classes = ('collapse',)
45
-
41
+
46
42
  def has_add_permission(self, request, obj=None):
47
43
  """Disable adding messages through admin - use chat interface instead."""
48
44
  return False
49
-
45
+
50
46
  def has_delete_permission(self, request, obj=None):
51
47
  """Disable deleting messages through admin."""
52
48
  return False
@@ -56,7 +52,7 @@ class MessageInline(TabularInline):
56
52
  """Display sender with badge."""
57
53
  if not obj.sender:
58
54
  return "—"
59
-
55
+
60
56
  # Determine sender type and variant
61
57
  if obj.sender.is_superuser:
62
58
  variant = "danger"
@@ -67,40 +63,40 @@ class MessageInline(TabularInline):
67
63
  else:
68
64
  variant = "info"
69
65
  icon = Icons.PERSON
70
-
66
+
71
67
  config = StatusBadgeConfig(show_icons=True, icon=icon)
72
68
  return StatusBadge.create(
73
69
  text=obj.sender.get_full_name() or obj.sender.username,
74
70
  variant=variant,
75
71
  config=config
76
72
  )
77
-
73
+
78
74
  @display(description="Message")
79
75
  def text_preview(self, obj):
80
76
  """Display message preview."""
81
77
  if not obj.text:
82
78
  return "—"
83
-
79
+
84
80
  preview = obj.text[:100]
85
81
  if len(obj.text) > 100:
86
82
  preview += "..."
87
-
83
+
88
84
  return preview
89
85
 
90
86
 
91
87
  @admin.register(Ticket)
92
88
  class TicketAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin, ExportMixin):
93
89
  """Admin interface for Ticket using Django Admin Utilities."""
94
-
90
+
95
91
  # Performance optimization
96
92
  select_related_fields = ['user']
97
-
93
+
98
94
  # Export-only configuration
99
95
  resource_class = TicketResource
100
96
  export_form_class = ExportForm
101
-
97
+
102
98
  list_display = [
103
- "user_display", "uuid_display", "subject_display", "status_display",
99
+ "user_display", "uuid_display", "subject_display", "status_display",
104
100
  "last_message_display", "last_message_ago_display", "chat_link_display", "created_at_display"
105
101
  ]
106
102
  list_display_links = ["subject_display"]
@@ -109,16 +105,16 @@ class TicketAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin, ExportMixin):
109
105
  list_filter = ["status", "created_at", TicketUserEmailFilter, TicketUserNameFilter]
110
106
  inlines = [MessageInline]
111
107
  autocomplete_fields = ["user"]
112
-
108
+
113
109
  actions = ["mark_as_open", "mark_as_waiting_for_user", "mark_as_waiting_for_admin", "mark_as_resolved", "mark_as_closed"]
114
-
110
+
115
111
  def get_readonly_fields(self, request, obj=None):
116
112
  """Different readonly fields for add/change forms."""
117
113
  if obj is None: # Adding new ticket
118
114
  return ("uuid", "created_at")
119
115
  else: # Editing existing ticket
120
116
  return ("uuid", "user", "created_at")
121
-
117
+
122
118
  def get_fieldsets(self, request, obj=None):
123
119
  """Different fieldsets for add/change forms."""
124
120
  if obj is None: # Adding new ticket
@@ -265,7 +261,7 @@ class TicketAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin, ExportMixin):
265
261
  def changelist_view(self, request, extra_context=None):
266
262
  """Add ticket statistics to changelist."""
267
263
  extra_context = extra_context or {}
268
-
264
+
269
265
  queryset = self.get_queryset(request)
270
266
  stats = queryset.aggregate(
271
267
  total_tickets=Count('uuid'),
@@ -275,7 +271,7 @@ class TicketAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin, ExportMixin):
275
271
  resolved_tickets=Count('uuid', filter=Q(status='resolved')),
276
272
  closed_tickets=Count('uuid', filter=Q(status='closed'))
277
273
  )
278
-
274
+
279
275
  extra_context['ticket_stats'] = {
280
276
  'total_tickets': stats['total_tickets'] or 0,
281
277
  'open_tickets': stats['open_tickets'] or 0,
@@ -284,21 +280,21 @@ class TicketAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin, ExportMixin):
284
280
  'resolved_tickets': stats['resolved_tickets'] or 0,
285
281
  'closed_tickets': stats['closed_tickets'] or 0
286
282
  }
287
-
283
+
288
284
  return super().changelist_view(request, extra_context)
289
285
 
290
286
 
291
287
  @admin.register(Message)
292
288
  class MessageAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin, ExportMixin):
293
289
  """Admin interface for Message using Django Admin Utilities."""
294
-
290
+
295
291
  # Performance optimization
296
292
  select_related_fields = ['ticket', 'sender']
297
-
293
+
298
294
  # Export-only configuration
299
295
  resource_class = MessageResource
300
296
  export_form_class = ExportForm
301
-
297
+
302
298
  list_display = [
303
299
  "ticket_display", "sender_display", "text_preview", "created_at_display"
304
300
  ]
@@ -307,7 +303,7 @@ class MessageAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin, ExportMixin):
307
303
  search_fields = ["ticket__uuid", "ticket__subject", "sender__username", "sender__email", "text"]
308
304
  list_filter = ["created_at", "ticket__status", MessageSenderEmailFilter]
309
305
  readonly_fields = ["ticket", "sender", "created_at"]
310
-
306
+
311
307
  fieldsets = [
312
308
  ('💬 Message Information', {
313
309
  'fields': ['ticket', 'sender', 'text'],
@@ -318,11 +314,11 @@ class MessageAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin, ExportMixin):
318
314
  'classes': ('tab', 'collapse')
319
315
  })
320
316
  ]
321
-
317
+
322
318
  def has_add_permission(self, request):
323
319
  """Disable adding messages through admin - use chat interface instead."""
324
320
  return False
325
-
321
+
326
322
  def has_change_permission(self, request, obj=None):
327
323
  """Disable editing messages through admin."""
328
324
  return False
@@ -332,7 +328,7 @@ class MessageAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin, ExportMixin):
332
328
  """Display ticket information."""
333
329
  if not obj.ticket:
334
330
  return "—"
335
-
331
+
336
332
  config = StatusBadgeConfig(show_icons=True, icon=Icons.CONFIRMATION_NUMBER)
337
333
  return StatusBadge.create(
338
334
  text=f"{obj.ticket.subject} ({str(obj.ticket.uuid)[:8]}...)",
@@ -345,7 +341,7 @@ class MessageAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin, ExportMixin):
345
341
  """Display sender with role indication."""
346
342
  if not obj.sender:
347
343
  return "—"
348
-
344
+
349
345
  # Determine sender type and variant
350
346
  if obj.sender.is_superuser:
351
347
  variant = "danger"
@@ -356,7 +352,7 @@ class MessageAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin, ExportMixin):
356
352
  else:
357
353
  variant = "info"
358
354
  icon = Icons.PERSON
359
-
355
+
360
356
  config = StatusBadgeConfig(show_icons=True, icon=icon)
361
357
  return StatusBadge.create(
362
358
  text=obj.sender.get_full_name() or obj.sender.username,
@@ -369,11 +365,11 @@ class MessageAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin, ExportMixin):
369
365
  """Display message text preview."""
370
366
  if not obj.text:
371
367
  return "—"
372
-
368
+
373
369
  preview = obj.text[:100]
374
370
  if len(obj.text) > 100:
375
371
  preview += "..."
376
-
372
+
377
373
  return preview
378
374
 
379
375
  @display(description="Created")
@@ -385,26 +381,26 @@ class MessageAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin, ExportMixin):
385
381
  def changelist_view(self, request, extra_context=None):
386
382
  """Add message statistics to changelist."""
387
383
  extra_context = extra_context or {}
388
-
384
+
389
385
  queryset = self.get_queryset(request)
390
386
  stats = queryset.aggregate(
391
387
  total_messages=Count('uuid'),
392
388
  staff_messages=Count('uuid', filter=Q(sender__is_staff=True)),
393
389
  user_messages=Count('uuid', filter=Q(sender__is_staff=False))
394
390
  )
395
-
391
+
396
392
  # Messages by ticket status
397
393
  ticket_status_counts = dict(
398
394
  queryset.values_list('ticket__status').annotate(
399
395
  count=Count('uuid')
400
396
  )
401
397
  )
402
-
398
+
403
399
  extra_context['message_stats'] = {
404
400
  'total_messages': stats['total_messages'] or 0,
405
401
  'staff_messages': stats['staff_messages'] or 0,
406
402
  'user_messages': stats['user_messages'] or 0,
407
403
  'ticket_status_counts': ticket_status_counts
408
404
  }
409
-
405
+
410
406
  return super().changelist_view(request, extra_context)
@@ -1,30 +1,31 @@
1
1
  from django.contrib import admin
2
- from unfold.admin import ModelAdmin, TabularInline
3
- from unfold.decorators import action
4
- from django.utils.timesince import timesince
5
- from django.utils.html import format_html
6
- from django.urls import reverse
7
- from django.shortcuts import redirect
8
2
  from django.http import HttpRequest
3
+ from django.shortcuts import redirect
4
+ from django.urls import reverse
5
+ from django.utils.html import format_html
6
+ from django.utils.timesince import timesince
9
7
  from django.utils.translation import gettext_lazy as _
10
- from .models import Ticket, Message
11
- from .admin_filters import TicketUserEmailFilter, TicketUserNameFilter, MessageSenderEmailFilter
12
- from django import forms
8
+ from unfold.admin import ModelAdmin, TabularInline
9
+ from unfold.decorators import action
10
+
11
+ from .admin_filters import MessageSenderEmailFilter, TicketUserEmailFilter, TicketUserNameFilter
12
+ from .models import Message, Ticket
13
+
13
14
 
14
15
  class MessageInline(TabularInline):
15
16
  """Read-only inline for viewing messages. Use Chat interface for replies."""
16
-
17
+
17
18
  model = Message
18
19
  extra = 0
19
20
  fields = ("sender_avatar", "created_at", "text")
20
21
  readonly_fields = ("sender_avatar", "created_at", "text")
21
22
  show_change_link = False
22
23
  classes = ('collapse',)
23
-
24
+
24
25
  def has_add_permission(self, request, obj=None):
25
26
  """Disable adding messages through admin - use chat interface instead."""
26
27
  return False
27
-
28
+
28
29
  def has_delete_permission(self, request, obj=None):
29
30
  """Disable deleting messages through admin."""
30
31
  return False
@@ -39,7 +40,7 @@ class MessageInline(TabularInline):
39
40
  else:
40
41
  initials = obj.sender.__class__.objects.get_initials(obj.sender)
41
42
  bg_color = '#0d6efd' if obj.sender.is_staff else '#6f42c1' if obj.sender.is_superuser else '#198754'
42
-
43
+
43
44
  return format_html(
44
45
  '<div style="width: 24px; height: 24px; border-radius: 50%; background: {}; '
45
46
  'color: white; display: flex; align-items: center; justify-content: center; '
@@ -97,7 +98,7 @@ class TicketAdmin(ModelAdmin):
97
98
  else:
98
99
  initials = obj.user.__class__.objects.get_initials(obj.user)
99
100
  bg_color = '#0d6efd' if obj.user.is_staff else '#6f42c1' if obj.user.is_superuser else '#198754'
100
-
101
+
101
102
  return format_html(
102
103
  '<div style="width: 32px; height: 32px; border-radius: 50%; background: {}; '
103
104
  'color: white; display: flex; align-items: center; justify-content: center; '
@@ -181,7 +182,7 @@ class MessageAdmin(ModelAdmin):
181
182
  else:
182
183
  initials = obj.sender.__class__.objects.get_initials(obj.sender)
183
184
  bg_color = '#0d6efd' if obj.sender.is_staff else '#6f42c1' if obj.sender.is_superuser else '#198754'
184
-
185
+
185
186
  return format_html(
186
187
  '<div style="width: 32px; height: 32px; border-radius: 50%; background: {}; '
187
188
  'color: white; display: flex; align-items: center; justify-content: center; '
@@ -8,4 +8,4 @@ class SupportConfig(AppConfig):
8
8
  verbose_name = 'Django CFG Support'
9
9
 
10
10
  def ready(self):
11
- import django_cfg.apps.support.signals
11
+ pass
@@ -1,8 +1,8 @@
1
- from django.db import models
2
1
  import threading
3
-
4
2
  from typing import TYPE_CHECKING
5
3
 
4
+ from django.db import models
5
+
6
6
  if TYPE_CHECKING:
7
7
  # Only for type checking
8
8
  from django_cfg.apps.support.models import Message
@@ -12,10 +12,10 @@ class MessageManager(models.Manager):
12
12
  def send_support_reply_email(self, message: "Message"):
13
13
  """Send email notification when support replies to a ticket."""
14
14
  from ..utils.support_email_service import SupportEmailService
15
-
15
+
16
16
  ticket = message.ticket
17
17
  user = ticket.user
18
-
18
+
19
19
  # Don't send email to yourself
20
20
  if message.sender == ticket.user:
21
21
  return
@@ -1,10 +1,11 @@
1
+ from typing import TYPE_CHECKING
2
+
1
3
  from django.db import models
2
4
  from django.db.models import QuerySet
3
- from typing import TYPE_CHECKING
4
5
 
5
6
  if TYPE_CHECKING:
6
7
  # Only for type checking
7
- from django_cfg.apps.support.models import Ticket, Message
8
+ pass
8
9
 
9
10
  class TicketManager(models.Manager):
10
11
  def _count_unanswered_messages_for_user_in_tickets(self, user, tickets) -> int:
@@ -16,30 +17,30 @@ class TicketManager(models.Manager):
16
17
  2. Check if there's an admin message after the last user message
17
18
  """
18
19
  from django_cfg.apps.support.models import Message
19
-
20
+
20
21
  unanswered_count = 0
21
-
22
+
22
23
  for ticket in tickets:
23
24
  messages: QuerySet[Message] = ticket.messages.order_by('created_at')
24
-
25
+
25
26
  # Find the last user message in this ticket
26
27
  last_user_message = messages.filter(sender=user).order_by('-created_at').first()
27
-
28
+
28
29
  print(f"DEBUG: Ticket {ticket.uuid}")
29
30
  print(f"DEBUG: Last user message: {last_user_message}")
30
-
31
+
31
32
  if last_user_message:
32
33
  # Check if there's an admin message after the last user message
33
34
  admin_message_after = messages.filter(
34
35
  sender__is_staff=True, # Admin messages
35
36
  created_at__gt=last_user_message.created_at
36
37
  ).order_by('-created_at').first()
37
-
38
+
38
39
  if admin_message_after:
39
40
  print(f"DEBUG: Latest admin message after user: {admin_message_after.sender.username}: {admin_message_after.text[:50]}... ({admin_message_after.created_at})")
40
41
  unanswered_count += 1
41
42
  else:
42
- print(f"DEBUG: No admin messages after user message")
43
+ print("DEBUG: No admin messages after user message")
43
44
  else:
44
45
  # If user never sent a message, check if there are any admin messages
45
46
  admin_messages_count = messages.filter(sender__is_staff=True).count()
@@ -47,8 +48,8 @@ class TicketManager(models.Manager):
47
48
  print(f"DEBUG: User never sent message, but there are {admin_messages_count} admin messages")
48
49
  unanswered_count += 1
49
50
  else:
50
- print(f"DEBUG: User never sent message, no admin messages")
51
-
51
+ print("DEBUG: User never sent message, no admin messages")
52
+
52
53
  print(f"DEBUG: Total unanswered count: {unanswered_count}")
53
54
  return unanswered_count
54
55
 
@@ -64,4 +65,4 @@ class TicketManager(models.Manager):
64
65
  """
65
66
  Count unanswered messages for a specific ticket.
66
67
  """
67
- return self._count_unanswered_messages_for_user_in_tickets(ticket.user, [ticket])
68
+ return self._count_unanswered_messages_for_user_in_tickets(ticket.user, [ticket])
@@ -1,7 +1,8 @@
1
1
  # Generated by Django 5.2.4 on 2025-07-24 13:44
2
2
 
3
- import django.db.models.deletion
4
3
  import uuid
4
+
5
+ import django.db.models.deletion
5
6
  from django.conf import settings
6
7
  from django.db import migrations, models
7
8
 
@@ -1,6 +1,8 @@
1
1
  import uuid
2
- from django.db import models
2
+
3
3
  from django.conf import settings
4
+ from django.db import models
5
+
4
6
  from .managers.message_manager import MessageManager
5
7
  from .managers.ticket_manager import TicketManager
6
8
 
@@ -1,7 +1,9 @@
1
1
  from typing import Optional
2
- from rest_framework import serializers
2
+
3
3
  from django.contrib.auth import get_user_model
4
- from .models import Ticket, Message
4
+ from rest_framework import serializers
5
+
6
+ from .models import Message, Ticket
5
7
 
6
8
  User = get_user_model()
7
9
 
@@ -1,13 +1,15 @@
1
- from django.db.models.signals import post_save
2
- from django.dispatch import receiver
3
- import traceback
4
1
  import logging
5
2
  import socket
3
+ import traceback
6
4
  from smtplib import SMTPException
7
5
 
6
+ from django.db.models.signals import post_save
7
+ from django.dispatch import receiver
8
+
9
+ from django_cfg.modules.django_telegram import DjangoTelegram
10
+
8
11
  from .models import Message, Ticket
9
12
  from .utils.support_email_service import SupportEmailService
10
- from django_cfg.modules.django_telegram import DjangoTelegram
11
13
 
12
14
  logger = logging.getLogger(__name__)
13
15
 
@@ -15,14 +17,14 @@ logger = logging.getLogger(__name__)
15
17
  def notify_on_message(sender, instance: Message, created: bool, **kwargs):
16
18
  """Send notifications when a new message is created."""
17
19
  logger.info(f"🔔 Signal triggered: Message {instance.uuid} created={created}")
18
-
20
+
19
21
  if not created:
20
22
  logger.info(" ⏭️ Not a new message, skipping")
21
23
  return
22
24
 
23
25
  ticket = instance.ticket
24
26
  user = ticket.user
25
-
27
+
26
28
  logger.info(f" 📝 Message from: {instance.sender.username} (is_staff: {instance.sender.is_staff})")
27
29
  logger.info(f" 🎫 Ticket author: {user.username}")
28
30
  logger.info(f" 📧 Is from author: {instance.is_from_author}")
@@ -33,10 +35,10 @@ def notify_on_message(sender, instance: Message, created: bool, **kwargs):
33
35
  try:
34
36
  email_service = SupportEmailService(user)
35
37
  email_service.send_support_reply_email(instance)
36
- logger.info(f" 📬 Email sent successfully!")
38
+ logger.info(" 📬 Email sent successfully!")
37
39
  except (socket.timeout, TimeoutError, SMTPException) as e:
38
40
  logger.warning(f" ⚠️ Email service timeout/error: {e}")
39
- logger.info(f" 📝 Message processed successfully, email notification failed")
41
+ logger.info(" 📝 Message processed successfully, email notification failed")
40
42
  # Do not re-raise to prevent blocking the main process
41
43
  except Exception as e:
42
44
  logger.error(f" ❌ Failed to send email notification: {e}")
@@ -75,10 +77,10 @@ def notify_on_ticket_created(sender, instance: Ticket, created: bool, **kwargs):
75
77
  try:
76
78
  email_service = SupportEmailService(instance.user)
77
79
  email_service.send_ticket_created_email(instance)
78
- logger.info(f" 📬 Ticket creation email sent successfully!")
80
+ logger.info(" 📬 Ticket creation email sent successfully!")
79
81
  except (socket.timeout, TimeoutError, SMTPException) as e:
80
82
  logger.warning(f" ⚠️ Email service timeout/error for ticket creation: {e}")
81
- logger.info(f" 📝 Ticket created successfully, email notification failed")
83
+ logger.info(" 📝 Ticket created successfully, email notification failed")
82
84
  except Exception as e:
83
85
  logger.error(f" ❌ Failed to send ticket creation email: {e}")
84
86
  logger.debug(f" 🔍 Exception details: {traceback.format_exc()}")
@@ -1,8 +1,9 @@
1
1
  from django.urls import path
2
2
  from rest_framework_nested import routers
3
- from .views import TicketViewSet, MessageViewSet
4
- from .views.chat import ticket_chat_view, send_message_ajax
3
+
4
+ from .views import MessageViewSet, TicketViewSet
5
5
  from .views.admin import ticket_admin_chat_view
6
+ from .views.chat import send_message_ajax, ticket_chat_view
6
7
 
7
8
  app_name = 'cfg_support'
8
9
 
@@ -20,4 +21,4 @@ chat_urlpatterns = [
20
21
  path('admin/chat/<uuid:ticket_uuid>/', ticket_admin_chat_view, name='ticket-admin-chat'),
21
22
  ]
22
23
 
23
- urlpatterns = router.urls + tickets_router.urls + chat_urlpatterns
24
+ urlpatterns = router.urls + tickets_router.urls + chat_urlpatterns
@@ -3,7 +3,9 @@ Support Email Service - Email notifications for support operations
3
3
  """
4
4
 
5
5
  import logging
6
+
6
7
  from django.contrib.auth import get_user_model
8
+
7
9
  from django_cfg.modules.django_email import DjangoEmailService
8
10
 
9
11
  User = get_user_model()
@@ -15,7 +17,7 @@ class SupportEmailService:
15
17
 
16
18
  def __init__(self, user: User):
17
19
  self.user = user
18
-
20
+
19
21
  def _get_ticket_url(self, ticket_uuid: str) -> str:
20
22
  """Get ticket URL from configuration."""
21
23
  try:
@@ -42,7 +44,7 @@ class SupportEmailService:
42
44
  ):
43
45
  """Private method for sending templated emails."""
44
46
  email_service = DjangoEmailService()
45
-
47
+
46
48
  # Prepare context for template
47
49
  context = {
48
50
  "user": self.user,
@@ -54,7 +56,7 @@ class SupportEmailService:
54
56
  "button_text": button_text,
55
57
  "button_url": button_url,
56
58
  }
57
-
59
+
58
60
  email_service.send_template(
59
61
  subject=subject,
60
62
  template_name=template_name,
@@ -76,11 +78,11 @@ class SupportEmailService:
76
78
  def send_support_reply_email(self, message):
77
79
  """Send email notification when support replies to a ticket."""
78
80
  ticket = message.ticket
79
-
81
+
80
82
  # Don't send email to yourself
81
83
  if message.sender == ticket.user:
82
84
  return
83
-
85
+
84
86
  self._send_email(
85
87
  subject=f"Support Reply: {ticket.subject}",
86
88
  main_text="You have received a reply from our support team.",
@@ -94,13 +96,13 @@ class SupportEmailService:
94
96
  """Send email notification when ticket status changes."""
95
97
  status_colors = {
96
98
  'open': '#28a745',
97
- 'in_progress': '#ffc107',
99
+ 'in_progress': '#ffc107',
98
100
  'resolved': '#17a2b8',
99
101
  'closed': '#6c757d',
100
102
  }
101
-
103
+
102
104
  color = status_colors.get(new_status, '#6c757d')
103
-
105
+
104
106
  self._send_email(
105
107
  subject=f"Ticket Status Updated: {ticket.subject}",
106
108
  main_text=f"Your ticket status has been updated from '{old_status}' to '{new_status}'.",
@@ -115,7 +117,7 @@ class SupportEmailService:
115
117
  self._send_email(
116
118
  subject=f"Ticket Resolved: {ticket.subject}",
117
119
  main_text="Great news! Your support ticket has been resolved.",
118
- main_html_content=f'<div style="background: #e8f5e8; padding: 15px; border-left: 4px solid #28a745; margin: 15px 0;"><strong>✅ Ticket Resolved</strong><br>Your issue has been successfully resolved by our support team.</div>',
120
+ main_html_content='<div style="background: #e8f5e8; padding: 15px; border-left: 4px solid #28a745; margin: 15px 0;"><strong>✅ Ticket Resolved</strong><br>Your issue has been successfully resolved by our support team.</div>',
119
121
  secondary_text="If you're satisfied with the resolution, no further action is needed. If you need additional help, feel free to reply to reopen the ticket.",
120
122
  button_text="View Resolution",
121
123
  button_url=self._get_ticket_url(ticket.uuid),
@@ -7,13 +7,13 @@ Decomposed views for better organization:
7
7
  - admin.py: Admin-specific views
8
8
  """
9
9
 
10
- from .api import TicketViewSet, MessageViewSet
11
- from .chat import ticket_chat_view, send_message_ajax
12
10
  from .admin import ticket_admin_chat_view
11
+ from .api import MessageViewSet, TicketViewSet
12
+ from .chat import send_message_ajax, ticket_chat_view
13
13
 
14
14
  __all__ = [
15
15
  'TicketViewSet',
16
- 'MessageViewSet',
16
+ 'MessageViewSet',
17
17
  'ticket_chat_view',
18
18
  'send_message_ajax',
19
19
  'ticket_admin_chat_view',