django-cfg 1.4.20__py3-none-any.whl → 1.4.23__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 (794) 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 +23 -5
  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/migrations/0003_alter_documentarchive_archive_type.py +29 -0
  126. django_cfg/apps/knowbase/mixins/__init__.py +4 -4
  127. django_cfg/apps/knowbase/mixins/config/__init__.py +1 -1
  128. django_cfg/apps/knowbase/mixins/config/meta_config.py +1 -1
  129. django_cfg/apps/knowbase/mixins/config.py +19 -18
  130. django_cfg/apps/knowbase/mixins/creator.py +7 -7
  131. django_cfg/apps/knowbase/mixins/examples/vehicle_model_example.py +29 -28
  132. django_cfg/apps/knowbase/mixins/external_data_mixin.py +6 -5
  133. django_cfg/apps/knowbase/mixins/generators/__init__.py +1 -1
  134. django_cfg/apps/knowbase/mixins/generators/content_generator.py +2 -2
  135. django_cfg/apps/knowbase/mixins/service.py +47 -45
  136. django_cfg/apps/knowbase/models/__init__.py +7 -7
  137. django_cfg/apps/knowbase/models/archive.py +72 -72
  138. django_cfg/apps/knowbase/models/base.py +12 -13
  139. django_cfg/apps/knowbase/models/chat.py +20 -19
  140. django_cfg/apps/knowbase/models/document.py +37 -35
  141. django_cfg/apps/knowbase/models/external_data.py +41 -42
  142. django_cfg/apps/knowbase/serializers/__init__.py +7 -7
  143. django_cfg/apps/knowbase/serializers/archive_serializers.py +50 -42
  144. django_cfg/apps/knowbase/serializers/chat_serializers.py +16 -15
  145. django_cfg/apps/knowbase/serializers/document_serializers.py +13 -12
  146. django_cfg/apps/knowbase/serializers/external_data_serializers.py +31 -31
  147. django_cfg/apps/knowbase/serializers/public_serializers.py +10 -9
  148. django_cfg/apps/knowbase/services/__init__.py +7 -7
  149. django_cfg/apps/knowbase/services/archive/__init__.py +7 -7
  150. django_cfg/apps/knowbase/services/archive/analyzers/__init__.py +1 -1
  151. django_cfg/apps/knowbase/services/archive/analyzers/tag_generator.py +1 -1
  152. django_cfg/apps/knowbase/services/archive/archive_service.py +109 -112
  153. django_cfg/apps/knowbase/services/archive/chunking/__init__.py +3 -3
  154. django_cfg/apps/knowbase/services/archive/chunking/base.py +1 -0
  155. django_cfg/apps/knowbase/services/archive/chunking/json_chunker.py +4 -3
  156. django_cfg/apps/knowbase/services/archive/chunking/markdown_chunker.py +5 -4
  157. django_cfg/apps/knowbase/services/archive/chunking/python_chunker.py +6 -5
  158. django_cfg/apps/knowbase/services/archive/chunking/text_chunker.py +4 -3
  159. django_cfg/apps/knowbase/services/archive/chunking_service.py +3 -7
  160. django_cfg/apps/knowbase/services/archive/context/__init__.py +1 -1
  161. django_cfg/apps/knowbase/services/archive/context/builders.py +2 -1
  162. django_cfg/apps/knowbase/services/archive/context/models.py +2 -1
  163. django_cfg/apps/knowbase/services/archive/exceptions.py +5 -5
  164. django_cfg/apps/knowbase/services/archive/extraction_service.py +111 -110
  165. django_cfg/apps/knowbase/services/archive/vectorization_service.py +80 -77
  166. django_cfg/apps/knowbase/services/base.py +11 -9
  167. django_cfg/apps/knowbase/services/chat_service.py +40 -39
  168. django_cfg/apps/knowbase/services/document_service.py +28 -27
  169. django_cfg/apps/knowbase/services/embedding/__init__.py +9 -9
  170. django_cfg/apps/knowbase/services/embedding/async_processor.py +38 -40
  171. django_cfg/apps/knowbase/services/embedding/batch_processor.py +45 -42
  172. django_cfg/apps/knowbase/services/embedding/batch_result.py +7 -6
  173. django_cfg/apps/knowbase/services/embedding/models.py +52 -51
  174. django_cfg/apps/knowbase/services/embedding/processors.py +24 -23
  175. django_cfg/apps/knowbase/services/embedding/utils.py +17 -17
  176. django_cfg/apps/knowbase/services/prompt_builder.py +24 -23
  177. django_cfg/apps/knowbase/services/search_service.py +52 -49
  178. django_cfg/apps/knowbase/signals/__init__.py +2 -5
  179. django_cfg/apps/knowbase/signals/archive_signals.py +35 -34
  180. django_cfg/apps/knowbase/signals/chat_signals.py +6 -5
  181. django_cfg/apps/knowbase/signals/document_signals.py +22 -22
  182. django_cfg/apps/knowbase/signals/external_data_signals.py +22 -22
  183. django_cfg/apps/knowbase/tasks/__init__.py +6 -7
  184. django_cfg/apps/knowbase/tasks/archive_tasks.py +41 -41
  185. django_cfg/apps/knowbase/tasks/document_processing.py +49 -44
  186. django_cfg/apps/knowbase/tasks/external_data_tasks.py +46 -44
  187. django_cfg/apps/knowbase/tasks/maintenance.py +26 -24
  188. django_cfg/apps/knowbase/urls.py +3 -2
  189. django_cfg/apps/knowbase/urls_admin.py +6 -3
  190. django_cfg/apps/knowbase/urls_system.py +4 -5
  191. django_cfg/apps/knowbase/utils/chunk_settings.py +22 -20
  192. django_cfg/apps/knowbase/utils/text_processing.py +76 -75
  193. django_cfg/apps/knowbase/utils/validation.py +9 -9
  194. django_cfg/apps/knowbase/views/__init__.py +5 -5
  195. django_cfg/apps/knowbase/views/archive_views.py +90 -87
  196. django_cfg/apps/knowbase/views/base.py +9 -12
  197. django_cfg/apps/knowbase/views/chat_views.py +35 -32
  198. django_cfg/apps/knowbase/views/document_views.py +27 -28
  199. django_cfg/apps/knowbase/views/public_views.py +19 -19
  200. django_cfg/apps/leads/admin/leads_admin.py +41 -45
  201. django_cfg/apps/leads/admin/resources.py +14 -14
  202. django_cfg/apps/leads/admin.py +7 -9
  203. django_cfg/apps/leads/apps.py +1 -1
  204. django_cfg/apps/leads/models.py +17 -17
  205. django_cfg/apps/leads/serializers.py +5 -4
  206. django_cfg/apps/leads/signals.py +7 -7
  207. django_cfg/apps/leads/tests.py +47 -47
  208. django_cfg/apps/leads/urls.py +2 -2
  209. django_cfg/apps/leads/views.py +11 -11
  210. django_cfg/apps/maintenance/__init__.py +3 -3
  211. django_cfg/apps/maintenance/admin/__init__.py +1 -1
  212. django_cfg/apps/maintenance/admin/api_key_admin.py +36 -36
  213. django_cfg/apps/maintenance/admin/log_admin.py +35 -37
  214. django_cfg/apps/maintenance/admin/scheduled_admin.py +47 -51
  215. django_cfg/apps/maintenance/admin/site_admin.py +49 -52
  216. django_cfg/apps/maintenance/apps.py +2 -2
  217. django_cfg/apps/maintenance/management/commands/maintenance.py +53 -52
  218. django_cfg/apps/maintenance/management/commands/process_scheduled_maintenance.py +44 -44
  219. django_cfg/apps/maintenance/management/commands/sync_cloudflare.py +32 -32
  220. django_cfg/apps/maintenance/managers/__init__.py +1 -1
  221. django_cfg/apps/maintenance/managers/cloudflare_site_manager.py +39 -38
  222. django_cfg/apps/maintenance/managers/maintenance_log_manager.py +32 -31
  223. django_cfg/apps/maintenance/migrations/0001_initial.py +1 -0
  224. django_cfg/apps/maintenance/models/__init__.py +2 -2
  225. django_cfg/apps/maintenance/models/cloudflare_api_key.py +15 -15
  226. django_cfg/apps/maintenance/models/cloudflare_site.py +24 -22
  227. django_cfg/apps/maintenance/models/maintenance_log.py +15 -14
  228. django_cfg/apps/maintenance/models/scheduled_maintenance.py +53 -52
  229. django_cfg/apps/maintenance/services/__init__.py +3 -3
  230. django_cfg/apps/maintenance/services/bulk_operations_service.py +68 -68
  231. django_cfg/apps/maintenance/services/maintenance_service.py +59 -58
  232. django_cfg/apps/maintenance/services/scheduled_maintenance_service.py +52 -52
  233. django_cfg/apps/maintenance/services/site_sync_service.py +64 -65
  234. django_cfg/apps/maintenance/utils/__init__.py +1 -1
  235. django_cfg/apps/maintenance/utils/retry_utils.py +17 -17
  236. django_cfg/apps/newsletter/admin/__init__.py +12 -16
  237. django_cfg/apps/newsletter/admin/newsletter_admin.py +90 -87
  238. django_cfg/apps/newsletter/admin/resources.py +29 -29
  239. django_cfg/apps/newsletter/admin.py +39 -32
  240. django_cfg/apps/newsletter/management/commands/test_newsletter.py +3 -3
  241. django_cfg/apps/newsletter/managers/__init__.py +1 -1
  242. django_cfg/apps/newsletter/migrations/0001_initial.py +2 -1
  243. django_cfg/apps/newsletter/models.py +34 -33
  244. django_cfg/apps/newsletter/serializers.py +13 -13
  245. django_cfg/apps/newsletter/services/email_service.py +42 -40
  246. django_cfg/apps/newsletter/signals.py +4 -3
  247. django_cfg/apps/newsletter/urls.py +7 -7
  248. django_cfg/apps/newsletter/views/__init__.py +14 -19
  249. django_cfg/apps/newsletter/views/campaigns.py +19 -19
  250. django_cfg/apps/newsletter/views/emails.py +20 -20
  251. django_cfg/apps/newsletter/views/newsletters.py +5 -5
  252. django_cfg/apps/newsletter/views/subscriptions.py +24 -24
  253. django_cfg/apps/newsletter/views/tracking.py +6 -5
  254. django_cfg/apps/payments/admin/__init__.py +6 -5
  255. django_cfg/apps/payments/admin/api_keys_admin.py +43 -45
  256. django_cfg/apps/payments/admin/balance_admin.py +41 -47
  257. django_cfg/apps/payments/admin/currencies_admin.py +60 -62
  258. django_cfg/apps/payments/admin/endpoint_groups_admin.py +14 -28
  259. django_cfg/apps/payments/admin/filters.py +59 -59
  260. django_cfg/apps/payments/admin/networks_admin.py +36 -50
  261. django_cfg/apps/payments/admin/payments_admin.py +47 -49
  262. django_cfg/apps/payments/admin/subscriptions_admin.py +30 -32
  263. django_cfg/apps/payments/admin/tariffs_admin.py +37 -42
  264. django_cfg/apps/payments/admin_interface/serializers/__init__.py +12 -13
  265. django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +28 -27
  266. django_cfg/apps/payments/admin_interface/serializers/webhook_serializers.py +4 -5
  267. django_cfg/apps/payments/admin_interface/templates/payments/base.html +407 -3
  268. django_cfg/apps/payments/admin_interface/templates/payments/components/ngrok_status.html +13 -13
  269. django_cfg/apps/payments/admin_interface/templates/payments/payment_dashboard.html +5 -1
  270. django_cfg/apps/payments/admin_interface/templates/payments/payment_detail.html +105 -49
  271. django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +4 -1
  272. django_cfg/apps/payments/admin_interface/templates/payments/payment_list.html +16 -8
  273. django_cfg/apps/payments/admin_interface/templates/payments/webhook_dashboard.html +16 -8
  274. django_cfg/apps/payments/admin_interface/views/__init__.py +8 -9
  275. django_cfg/apps/payments/admin_interface/views/api/__init__.py +3 -3
  276. django_cfg/apps/payments/admin_interface/views/api/payments.py +52 -54
  277. django_cfg/apps/payments/admin_interface/views/api/stats.py +33 -30
  278. django_cfg/apps/payments/admin_interface/views/api/users.py +10 -11
  279. django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +46 -51
  280. django_cfg/apps/payments/admin_interface/views/api/webhook_public.py +9 -9
  281. django_cfg/apps/payments/admin_interface/views/base.py +17 -19
  282. django_cfg/apps/payments/admin_interface/views/dashboard.py +10 -10
  283. django_cfg/apps/payments/admin_interface/views/forms.py +21 -20
  284. django_cfg/apps/payments/apps.py +7 -6
  285. django_cfg/apps/payments/config/__init__.py +4 -4
  286. django_cfg/apps/payments/config/django_cfg_integration.py +22 -21
  287. django_cfg/apps/payments/config/helpers.py +14 -12
  288. django_cfg/apps/payments/management/commands/cleanup_expired_data.py +85 -86
  289. django_cfg/apps/payments/management/commands/currency_stats.py +84 -87
  290. django_cfg/apps/payments/management/commands/manage_currencies.py +59 -58
  291. django_cfg/apps/payments/management/commands/manage_providers.py +103 -105
  292. django_cfg/apps/payments/management/commands/process_pending_payments.py +67 -70
  293. django_cfg/apps/payments/management/commands/test_providers.py +83 -84
  294. django_cfg/apps/payments/middleware/__init__.py +1 -1
  295. django_cfg/apps/payments/middleware/api_access.py +77 -78
  296. django_cfg/apps/payments/middleware/rate_limiting.py +72 -72
  297. django_cfg/apps/payments/middleware/usage_tracking.py +66 -64
  298. django_cfg/apps/payments/migrations/0001_initial.py +2 -1
  299. django_cfg/apps/payments/models/__init__.py +11 -12
  300. django_cfg/apps/payments/models/api_keys.py +29 -27
  301. django_cfg/apps/payments/models/balance.py +38 -38
  302. django_cfg/apps/payments/models/base.py +12 -11
  303. django_cfg/apps/payments/models/currencies.py +53 -52
  304. django_cfg/apps/payments/models/managers/__init__.py +13 -14
  305. django_cfg/apps/payments/models/managers/api_key_managers.py +55 -53
  306. django_cfg/apps/payments/models/managers/balance_managers.py +98 -97
  307. django_cfg/apps/payments/models/managers/currency_managers.py +70 -69
  308. django_cfg/apps/payments/models/managers/payment_managers.py +113 -111
  309. django_cfg/apps/payments/models/managers/subscription_managers.py +99 -97
  310. django_cfg/apps/payments/models/payments.py +167 -73
  311. django_cfg/apps/payments/models/subscriptions.py +56 -54
  312. django_cfg/apps/payments/models/tariffs.py +35 -34
  313. django_cfg/apps/payments/services/__init__.py +33 -36
  314. django_cfg/apps/payments/services/cache/__init__.py +7 -1
  315. django_cfg/apps/payments/services/cache_service/__init__.py +22 -20
  316. django_cfg/apps/payments/services/cache_service/api_key_cache.py +6 -5
  317. django_cfg/apps/payments/services/cache_service/interfaces.py +5 -5
  318. django_cfg/apps/payments/services/cache_service/keys.py +8 -8
  319. django_cfg/apps/payments/services/cache_service/rate_limit_cache.py +8 -7
  320. django_cfg/apps/payments/services/cache_service/simple_cache.py +17 -14
  321. django_cfg/apps/payments/services/core/__init__.py +3 -3
  322. django_cfg/apps/payments/services/core/balance_service.py +69 -65
  323. django_cfg/apps/payments/services/core/base.py +25 -22
  324. django_cfg/apps/payments/services/core/currency/__init__.py +1 -1
  325. django_cfg/apps/payments/services/core/currency/currency_converter.py +2 -0
  326. django_cfg/apps/payments/services/core/currency_service.py +68 -66
  327. django_cfg/apps/payments/services/core/operations/__init__.py +1 -1
  328. django_cfg/apps/payments/services/core/operations/payment_canceller.py +2 -1
  329. django_cfg/apps/payments/services/core/operations/payment_creator.py +2 -1
  330. django_cfg/apps/payments/services/core/operations/status_checker.py +2 -1
  331. django_cfg/apps/payments/services/core/payment_service.py +10 -7
  332. django_cfg/apps/payments/services/core/providers/provider_client.py +2 -2
  333. django_cfg/apps/payments/services/core/subscription_service.py +77 -74
  334. django_cfg/apps/payments/services/core/utils/data_converter.py +1 -0
  335. django_cfg/apps/payments/services/core/utils/statistics_calculator.py +1 -0
  336. django_cfg/apps/payments/services/core/webhook_service.py +67 -63
  337. django_cfg/apps/payments/services/integrations/__init__.py +3 -3
  338. django_cfg/apps/payments/services/integrations/ngrok_service.py +1 -0
  339. django_cfg/apps/payments/services/integrations/providers_config.py +3 -2
  340. django_cfg/apps/payments/services/providers/base.py +59 -57
  341. django_cfg/apps/payments/services/providers/models/__init__.py +7 -14
  342. django_cfg/apps/payments/services/providers/models/base.py +15 -15
  343. django_cfg/apps/payments/services/providers/models/providers.py +13 -12
  344. django_cfg/apps/payments/services/providers/models/universal.py +6 -5
  345. django_cfg/apps/payments/services/providers/nowpayments/__init__.py +4 -4
  346. django_cfg/apps/payments/services/providers/nowpayments/config.py +9 -8
  347. django_cfg/apps/payments/services/providers/nowpayments/models.py +15 -15
  348. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/__init__.py +2 -2
  349. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/patterns.py +26 -26
  350. django_cfg/apps/payments/services/providers/nowpayments/parsers/parser.py +3 -2
  351. django_cfg/apps/payments/services/providers/nowpayments/provider.py +95 -99
  352. django_cfg/apps/payments/services/providers/nowpayments/sync.py +41 -40
  353. django_cfg/apps/payments/services/providers/registry.py +65 -63
  354. django_cfg/apps/payments/services/providers/sync_service.py +50 -50
  355. django_cfg/apps/payments/services/types/__init__.py +21 -22
  356. django_cfg/apps/payments/services/types/data.py +14 -13
  357. django_cfg/apps/payments/services/types/requests.py +21 -22
  358. django_cfg/apps/payments/services/types/responses.py +16 -15
  359. django_cfg/apps/payments/services/types/webhooks.py +30 -30
  360. django_cfg/apps/payments/signals/__init__.py +4 -6
  361. django_cfg/apps/payments/signals/api_key_signals.py +36 -35
  362. django_cfg/apps/payments/signals/balance_signals.py +28 -26
  363. django_cfg/apps/payments/signals/payment_signals.py +29 -28
  364. django_cfg/apps/payments/signals/subscription_signals.py +39 -38
  365. django_cfg/apps/payments/static/payments/js/ngrok-status.js +12 -8
  366. django_cfg/apps/payments/static/payments/js/payment-detail.js +1 -1
  367. django_cfg/apps/payments/static/payments/js/payment-form.js +3 -3
  368. django_cfg/apps/payments/static/payments/js/payment-list.js +13 -6
  369. django_cfg/apps/payments/static/payments/js/webhook-dashboard-mjs.js +241 -0
  370. django_cfg/apps/payments/tasks/__init__.py +11 -12
  371. django_cfg/apps/payments/tasks/types.py +10 -9
  372. django_cfg/apps/payments/tasks/usage_tracking.py +44 -46
  373. django_cfg/apps/payments/templatetags/payment_tags.py +27 -27
  374. django_cfg/apps/payments/urls.py +31 -14
  375. django_cfg/apps/payments/urls_admin.py +10 -10
  376. django_cfg/apps/payments/views/api/__init__.py +32 -33
  377. django_cfg/apps/payments/views/api/api_keys.py +62 -62
  378. django_cfg/apps/payments/views/api/balances.py +63 -64
  379. django_cfg/apps/payments/views/api/base.py +52 -52
  380. django_cfg/apps/payments/views/api/currencies.py +75 -63
  381. django_cfg/apps/payments/views/api/payments.py +73 -74
  382. django_cfg/apps/payments/views/api/subscriptions.py +71 -72
  383. django_cfg/apps/payments/views/api/webhooks.py +85 -84
  384. django_cfg/apps/payments/views/overview/__init__.py +7 -7
  385. django_cfg/apps/payments/views/overview/serializers.py +13 -14
  386. django_cfg/apps/payments/views/overview/services.py +66 -67
  387. django_cfg/apps/payments/views/overview/urls.py +2 -1
  388. django_cfg/apps/payments/views/overview/views.py +31 -31
  389. django_cfg/apps/payments/views/serializers/__init__.py +35 -36
  390. django_cfg/apps/payments/views/serializers/api_keys.py +59 -57
  391. django_cfg/apps/payments/views/serializers/balances.py +34 -33
  392. django_cfg/apps/payments/views/serializers/currencies.py +36 -34
  393. django_cfg/apps/payments/views/serializers/payments.py +48 -47
  394. django_cfg/apps/payments/views/serializers/subscriptions.py +50 -45
  395. django_cfg/apps/payments/views/serializers/webhooks.py +17 -16
  396. django_cfg/apps/support/admin/__init__.py +3 -3
  397. django_cfg/apps/support/admin/resources.py +26 -26
  398. django_cfg/apps/support/admin/support_admin.py +44 -48
  399. django_cfg/apps/support/admin.py +16 -15
  400. django_cfg/apps/support/apps.py +1 -1
  401. django_cfg/apps/support/managers/message_manager.py +4 -4
  402. django_cfg/apps/support/managers/ticket_manager.py +13 -12
  403. django_cfg/apps/support/migrations/0001_initial.py +2 -1
  404. django_cfg/apps/support/models.py +3 -1
  405. django_cfg/apps/support/serializers.py +4 -2
  406. django_cfg/apps/support/signals.py +12 -10
  407. django_cfg/apps/support/urls.py +4 -3
  408. django_cfg/apps/support/utils/support_email_service.py +11 -9
  409. django_cfg/apps/support/views/__init__.py +3 -3
  410. django_cfg/apps/support/views/admin.py +9 -9
  411. django_cfg/apps/support/views/api.py +12 -13
  412. django_cfg/apps/support/views/chat.py +14 -14
  413. django_cfg/apps/tasks/admin/tasks_admin.py +65 -74
  414. django_cfg/apps/tasks/apps.py +2 -2
  415. django_cfg/apps/tasks/serializers.py +6 -6
  416. django_cfg/apps/tasks/static/tasks/js/dashboard/main.mjs +44 -20
  417. django_cfg/apps/tasks/static/tasks/js/dashboard/overview.mjs +7 -5
  418. django_cfg/apps/tasks/static/tasks/js/dashboard/queues.mjs +5 -3
  419. django_cfg/apps/tasks/static/tasks/js/dashboard/tasks.mjs +5 -3
  420. django_cfg/apps/tasks/static/tasks/js/dashboard/workers.mjs +5 -3
  421. django_cfg/apps/tasks/tasks/demo_tasks.py +12 -11
  422. django_cfg/apps/tasks/templates/tasks/components/tasks_mjs_integration.html +269 -0
  423. django_cfg/apps/tasks/templates/tasks/pages/dashboard-improved.html +168 -0
  424. django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +21 -2
  425. django_cfg/apps/tasks/urls.py +3 -2
  426. django_cfg/apps/tasks/urls_admin.py +1 -0
  427. django_cfg/apps/tasks/utils/simulator.py +49 -52
  428. django_cfg/apps/tasks/views/api.py +75 -73
  429. django_cfg/apps/tasks/views/dashboard.py +5 -4
  430. django_cfg/apps/urls.py +20 -11
  431. django_cfg/apps.py +6 -5
  432. django_cfg/cli/commands/create_project.py +7 -6
  433. django_cfg/cli/commands/info.py +25 -25
  434. django_cfg/cli/utils.py +27 -27
  435. django_cfg/config.py +1 -1
  436. django_cfg/core/__init__.py +8 -8
  437. django_cfg/core/base/config_model.py +13 -12
  438. django_cfg/core/builders/apps_builder.py +2 -2
  439. django_cfg/core/builders/middleware_builder.py +1 -1
  440. django_cfg/core/builders/security_builder.py +1 -1
  441. django_cfg/core/config.py +2 -2
  442. django_cfg/core/environment/detector.py +27 -28
  443. django_cfg/core/exceptions.py +1 -1
  444. django_cfg/core/generation/core_generators/settings.py +1 -1
  445. django_cfg/core/generation/core_generators/static.py +11 -5
  446. django_cfg/core/generation/core_generators/templates.py +1 -1
  447. django_cfg/core/generation/data_generators/__init__.py +1 -1
  448. django_cfg/core/generation/data_generators/cache.py +1 -1
  449. django_cfg/core/generation/data_generators/database.py +1 -1
  450. django_cfg/core/generation/generation.py +1 -3
  451. django_cfg/core/generation/integration_generators/__init__.py +2 -2
  452. django_cfg/core/generation/integration_generators/api.py +12 -2
  453. django_cfg/core/generation/integration_generators/sessions.py +1 -1
  454. django_cfg/core/generation/integration_generators/tailwind.py +1 -1
  455. django_cfg/core/generation/integration_generators/tasks.py +1 -1
  456. django_cfg/core/generation/integration_generators/third_party.py +1 -1
  457. django_cfg/core/generation/orchestrator.py +1 -1
  458. django_cfg/core/generation/protocols.py +1 -1
  459. django_cfg/core/generation/utility_generators/__init__.py +1 -1
  460. django_cfg/core/generation/utility_generators/email.py +1 -1
  461. django_cfg/core/generation/utility_generators/i18n.py +1 -1
  462. django_cfg/core/generation/utility_generators/limits.py +1 -1
  463. django_cfg/core/generation/utility_generators/logging.py +1 -1
  464. django_cfg/core/generation/utility_generators/security.py +1 -1
  465. django_cfg/core/generation/utils/helpers.py +1 -1
  466. django_cfg/core/integration/__init__.py +5 -5
  467. django_cfg/core/integration/commands_collector.py +38 -39
  468. django_cfg/core/integration/display/__init__.py +2 -2
  469. django_cfg/core/integration/display/base.py +30 -30
  470. django_cfg/core/integration/display/ngrok.py +35 -36
  471. django_cfg/core/integration/display/startup.py +149 -139
  472. django_cfg/core/integration/url_integration.py +10 -10
  473. django_cfg/core/integration/version_checker.py +20 -19
  474. django_cfg/core/services/config_service.py +4 -4
  475. django_cfg/core/state/__init__.py +1 -1
  476. django_cfg/core/state/registry.py +1 -1
  477. django_cfg/core/types/__init__.py +8 -1
  478. django_cfg/core/validation.py +36 -39
  479. django_cfg/management/commands/check_endpoints.py +3 -1
  480. django_cfg/management/commands/check_settings.py +3 -1
  481. django_cfg/management/commands/clear_constance.py +3 -1
  482. django_cfg/management/commands/create_token.py +3 -1
  483. django_cfg/management/commands/generate_clients.py +3 -1
  484. django_cfg/management/commands/migrate_all.py +3 -1
  485. django_cfg/management/commands/rundramatiq.py +3 -1
  486. django_cfg/management/commands/rundramatiq_simulator.py +3 -1
  487. django_cfg/management/commands/runserver_ngrok.py +3 -1
  488. django_cfg/management/commands/show_config.py +3 -1
  489. django_cfg/management/commands/superuser.py +3 -1
  490. django_cfg/management/commands/task_clear.py +3 -1
  491. django_cfg/management/commands/task_status.py +3 -1
  492. django_cfg/management/commands/test_email.py +3 -1
  493. django_cfg/management/commands/test_telegram.py +3 -1
  494. django_cfg/management/commands/test_twilio.py +3 -1
  495. django_cfg/management/commands/validate_openapi.py +3 -1
  496. django_cfg/middleware/pagination.py +8 -8
  497. django_cfg/middleware/public_endpoints.py +24 -23
  498. django_cfg/middleware/user_activity.py +27 -25
  499. django_cfg/models/__init__.py +19 -20
  500. django_cfg/models/api/__init__.py +4 -4
  501. django_cfg/models/api/config.py +23 -21
  502. django_cfg/models/api/cors.py +17 -16
  503. django_cfg/models/api/drf/__init__.py +1 -1
  504. django_cfg/models/api/drf/config.py +2 -1
  505. django_cfg/models/api/drf/redoc.py +2 -1
  506. django_cfg/models/api/drf/spectacular.py +4 -2
  507. django_cfg/models/api/drf/swagger.py +2 -1
  508. django_cfg/models/api/jwt.py +37 -36
  509. django_cfg/models/api/keys.py +13 -12
  510. django_cfg/models/api/limits.py +31 -30
  511. django_cfg/models/base/config.py +40 -41
  512. django_cfg/models/base/module.py +8 -8
  513. django_cfg/models/django/__init__.py +1 -1
  514. django_cfg/models/django/constance.py +8 -7
  515. django_cfg/models/django/environment.py +5 -3
  516. django_cfg/models/django/openapi.py +6 -16
  517. django_cfg/models/django/revolution_legacy.py +17 -16
  518. django_cfg/models/infrastructure/__init__.py +1 -1
  519. django_cfg/models/infrastructure/cache.py +46 -45
  520. django_cfg/models/infrastructure/database/config.py +4 -6
  521. django_cfg/models/infrastructure/database/converters.py +1 -1
  522. django_cfg/models/infrastructure/database/parsers.py +1 -1
  523. django_cfg/models/infrastructure/database/validators.py +1 -1
  524. django_cfg/models/infrastructure/logging.py +59 -57
  525. django_cfg/models/infrastructure/security.py +26 -24
  526. django_cfg/models/ngrok/auth.py +2 -1
  527. django_cfg/models/ngrok/config.py +3 -2
  528. django_cfg/models/ngrok/tunnel.py +2 -1
  529. django_cfg/models/payments/__init__.py +1 -1
  530. django_cfg/models/payments/api_keys.py +3 -1
  531. django_cfg/models/payments/config.py +4 -1
  532. django_cfg/models/payments/providers/base.py +2 -1
  533. django_cfg/models/payments/providers/nowpayments.py +3 -1
  534. django_cfg/models/services/__init__.py +1 -1
  535. django_cfg/models/services/base.py +2 -1
  536. django_cfg/models/services/email.py +28 -26
  537. django_cfg/models/services/telegram.py +2 -1
  538. django_cfg/models/tasks/__init__.py +2 -2
  539. django_cfg/models/tasks/backends.py +4 -3
  540. django_cfg/models/tasks/config.py +6 -4
  541. django_cfg/models/tasks/utils.py +3 -3
  542. django_cfg/modules/base.py +18 -17
  543. django_cfg/modules/django_admin/__init__.py +14 -15
  544. django_cfg/modules/django_admin/decorators/__init__.py +1 -1
  545. django_cfg/modules/django_admin/decorators/actions.py +8 -7
  546. django_cfg/modules/django_admin/decorators/display.py +9 -7
  547. django_cfg/modules/django_admin/icons/__init__.py +1 -1
  548. django_cfg/modules/django_admin/icons/constants.py +27 -27
  549. django_cfg/modules/django_admin/icons/generate_icons.py +54 -54
  550. django_cfg/modules/django_admin/management/commands/check_endpoints.py +5 -3
  551. django_cfg/modules/django_admin/management/commands/check_settings.py +40 -44
  552. django_cfg/modules/django_admin/management/commands/clear_constance.py +29 -30
  553. django_cfg/modules/django_admin/management/commands/create_token.py +42 -42
  554. django_cfg/modules/django_admin/management/commands/list_urls.py +37 -38
  555. django_cfg/modules/django_admin/management/commands/migrate_all.py +13 -15
  556. django_cfg/modules/django_admin/management/commands/migrator.py +17 -17
  557. django_cfg/modules/django_admin/management/commands/script.py +58 -60
  558. django_cfg/modules/django_admin/management/commands/show_config.py +32 -30
  559. django_cfg/modules/django_admin/management/commands/show_urls.py +46 -44
  560. django_cfg/modules/django_admin/management/commands/superuser.py +47 -48
  561. django_cfg/modules/django_admin/management/commands/tree.py +50 -54
  562. django_cfg/modules/django_admin/mixins/display_mixin.py +16 -15
  563. django_cfg/modules/django_admin/mixins/optimization_mixin.py +9 -8
  564. django_cfg/modules/django_admin/mixins/standalone_actions_mixin.py +25 -24
  565. django_cfg/modules/django_admin/models/__init__.py +4 -4
  566. django_cfg/modules/django_admin/models/action_models.py +3 -1
  567. django_cfg/modules/django_admin/models/badge_models.py +4 -2
  568. django_cfg/modules/django_admin/models/base.py +3 -3
  569. django_cfg/modules/django_admin/models/display_models.py +1 -0
  570. django_cfg/modules/django_admin/utils/badges.py +27 -26
  571. django_cfg/modules/django_admin/utils/displays.py +49 -49
  572. django_cfg/modules/django_client/apps.py +21 -3
  573. django_cfg/modules/django_client/core/__init__.py +9 -10
  574. django_cfg/modules/django_client/core/archive/manager.py +2 -2
  575. django_cfg/modules/django_client/core/cli/main.py +1 -3
  576. django_cfg/modules/django_client/core/config/config.py +3 -1
  577. django_cfg/modules/django_client/core/config/group.py +1 -0
  578. django_cfg/modules/django_client/core/config/service.py +2 -1
  579. django_cfg/modules/django_client/core/generator/__init__.py +1 -1
  580. django_cfg/modules/django_client/core/generator/base.py +2 -2
  581. django_cfg/modules/django_client/core/generator/python/async_client_gen.py +1 -1
  582. django_cfg/modules/django_client/core/generator/python/files_generator.py +1 -1
  583. django_cfg/modules/django_client/core/generator/python/generator.py +4 -4
  584. django_cfg/modules/django_client/core/generator/python/models_generator.py +1 -1
  585. django_cfg/modules/django_client/core/generator/python/operations_generator.py +2 -2
  586. django_cfg/modules/django_client/core/generator/python/sync_client_gen.py +1 -1
  587. django_cfg/modules/django_client/core/generator/typescript/client_generator.py +3 -1
  588. django_cfg/modules/django_client/core/generator/typescript/fetchers_generator.py +14 -13
  589. django_cfg/modules/django_client/core/generator/typescript/files_generator.py +1 -0
  590. django_cfg/modules/django_client/core/generator/typescript/generator.py +6 -6
  591. django_cfg/modules/django_client/core/generator/typescript/hooks_generator.py +12 -10
  592. django_cfg/modules/django_client/core/generator/typescript/models_generator.py +2 -1
  593. django_cfg/modules/django_client/core/generator/typescript/naming.py +2 -3
  594. django_cfg/modules/django_client/core/generator/typescript/operations_generator.py +12 -10
  595. django_cfg/modules/django_client/core/generator/typescript/schemas_generator.py +3 -2
  596. django_cfg/modules/django_client/core/generator/typescript/templates/client/client.ts.jinja +14 -6
  597. django_cfg/modules/django_client/core/generator/typescript/templates/main_index.ts.jinja +4 -10
  598. django_cfg/modules/django_client/core/groups/__init__.py +1 -1
  599. django_cfg/modules/django_client/core/groups/detector.py +2 -1
  600. django_cfg/modules/django_client/core/groups/manager.py +2 -1
  601. django_cfg/modules/django_client/core/ir/schema.py +1 -1
  602. django_cfg/modules/django_client/core/parser/base.py +0 -2
  603. django_cfg/modules/django_client/core/parser/models/schema.py +1 -1
  604. django_cfg/modules/django_client/core/validation/__init__.py +1 -1
  605. django_cfg/modules/django_client/core/validation/fixer.py +1 -2
  606. django_cfg/modules/django_client/core/validation/reporter.py +2 -2
  607. django_cfg/modules/django_client/core/validation/safety.py +1 -1
  608. django_cfg/modules/django_client/management/commands/generate_client.py +14 -11
  609. django_cfg/modules/django_client/management/commands/validate_openapi.py +4 -6
  610. django_cfg/modules/django_client/spectacular/__init__.py +1 -1
  611. django_cfg/modules/django_client/spectacular/async_detection.py +3 -2
  612. django_cfg/modules/django_client/spectacular/enum_naming.py +1 -1
  613. django_cfg/modules/django_client/spectacular/schema.py +5 -5
  614. django_cfg/modules/django_client/system/__init__.py +24 -0
  615. django_cfg/modules/django_client/system/base_generator.py +123 -0
  616. django_cfg/modules/django_client/system/generate_mjs_clients.py +174 -0
  617. django_cfg/modules/django_client/system/mjs_generator.py +219 -0
  618. django_cfg/modules/django_client/system/schema_parser.py +195 -0
  619. django_cfg/modules/django_client/system/templates/api_client.js.j2 +87 -0
  620. django_cfg/modules/django_client/system/templates/app_index.js.j2 +13 -0
  621. django_cfg/modules/django_client/system/templates/base_client.js.j2 +166 -0
  622. django_cfg/modules/django_client/system/templates/main_index.js.j2 +80 -0
  623. django_cfg/modules/django_client/system/templates/types.js.j2 +24 -0
  624. django_cfg/modules/django_client/urls.py +3 -2
  625. django_cfg/modules/django_currency/__init__.py +17 -18
  626. django_cfg/modules/django_currency/clients/__init__.py +2 -2
  627. django_cfg/modules/django_currency/clients/coinpaprika_client.py +48 -48
  628. django_cfg/modules/django_currency/clients/hybrid_client.py +76 -75
  629. django_cfg/modules/django_currency/core/__init__.py +7 -13
  630. django_cfg/modules/django_currency/core/converter.py +25 -24
  631. django_cfg/modules/django_currency/core/models.py +9 -8
  632. django_cfg/modules/django_currency/database/__init__.py +4 -4
  633. django_cfg/modules/django_currency/database/database_loader.py +65 -66
  634. django_cfg/modules/django_currency/examples/example_database_usage.py +29 -28
  635. django_cfg/modules/django_currency/utils/cache.py +10 -11
  636. django_cfg/modules/django_dashboard/__init__.py +4 -5
  637. django_cfg/modules/django_dashboard/components.py +11 -7
  638. django_cfg/modules/django_dashboard/debug.py +1 -3
  639. django_cfg/modules/django_dashboard/management/commands/debug_dashboard.py +3 -3
  640. django_cfg/modules/django_dashboard/sections/base.py +2 -1
  641. django_cfg/modules/django_dashboard/sections/commands.py +3 -2
  642. django_cfg/modules/django_dashboard/sections/documentation.py +8 -6
  643. django_cfg/modules/django_dashboard/sections/overview.py +13 -9
  644. django_cfg/modules/django_dashboard/sections/stats.py +2 -2
  645. django_cfg/modules/django_dashboard/sections/system.py +2 -1
  646. django_cfg/modules/django_drf_theme/templatetags/tailwind_tags.py +12 -4
  647. django_cfg/modules/django_email/management/commands/test_email.py +8 -7
  648. django_cfg/modules/django_email/service.py +5 -4
  649. django_cfg/modules/django_health/service.py +46 -44
  650. django_cfg/modules/django_import_export/__init__.py +7 -3
  651. django_cfg/modules/django_llm/__init__.py +3 -2
  652. django_cfg/modules/django_llm/example.py +58 -56
  653. django_cfg/modules/django_llm/llm/__init__.py +1 -1
  654. django_cfg/modules/django_llm/llm/cache.py +21 -20
  655. django_cfg/modules/django_llm/llm/client.py +9 -9
  656. django_cfg/modules/django_llm/llm/costs.py +14 -14
  657. django_cfg/modules/django_llm/llm/embeddings/__init__.py +1 -1
  658. django_cfg/modules/django_llm/llm/embeddings/mock_embedder.py +1 -2
  659. django_cfg/modules/django_llm/llm/embeddings/openai_embedder.py +1 -2
  660. django_cfg/modules/django_llm/llm/extractor.py +8 -8
  661. django_cfg/modules/django_llm/llm/models.py +5 -5
  662. django_cfg/modules/django_llm/llm/models_api/models_query.py +2 -2
  663. django_cfg/modules/django_llm/llm/models_cache.py +91 -92
  664. django_cfg/modules/django_llm/llm/providers/config_builder.py +1 -1
  665. django_cfg/modules/django_llm/llm/providers/provider_manager.py +2 -1
  666. django_cfg/modules/django_llm/llm/requests/cache_manager.py +1 -1
  667. django_cfg/modules/django_llm/llm/requests/chat_handler.py +2 -2
  668. django_cfg/modules/django_llm/llm/requests/embedding_handler.py +1 -1
  669. django_cfg/modules/django_llm/llm/responses/response_builder.py +2 -2
  670. django_cfg/modules/django_llm/llm/stats/stats_manager.py +1 -1
  671. django_cfg/modules/django_llm/llm/tokenizer.py +10 -9
  672. django_cfg/modules/django_llm/translator/__init__.py +1 -1
  673. django_cfg/modules/django_llm/translator/cache.py +36 -35
  674. django_cfg/modules/django_llm/translator/detectors/__init__.py +1 -1
  675. django_cfg/modules/django_llm/translator/detectors/script_detector.py +0 -1
  676. django_cfg/modules/django_llm/translator/stats/stats_tracker.py +1 -1
  677. django_cfg/modules/django_llm/translator/translator.py +5 -4
  678. django_cfg/modules/django_llm/translator/translators/__init__.py +1 -1
  679. django_cfg/modules/django_llm/translator/translators/json_translator.py +1 -1
  680. django_cfg/modules/django_llm/translator/utils/__init__.py +1 -1
  681. django_cfg/modules/django_llm/translator/utils/prompt_builder.py +0 -1
  682. django_cfg/modules/django_logging/__init__.py +1 -1
  683. django_cfg/modules/django_logging/django_logger.py +33 -34
  684. django_cfg/modules/django_logging/logger.py +3 -7
  685. django_cfg/modules/django_ngrok/__init__.py +7 -7
  686. django_cfg/modules/django_ngrok/management/commands/runserver_ngrok.py +33 -30
  687. django_cfg/modules/django_ngrok/service.py +33 -32
  688. django_cfg/modules/django_tailwind/templates/django_tailwind/base.html +4 -36
  689. django_cfg/modules/django_tailwind/templates/django_tailwind/components/navbar.html +1 -1
  690. django_cfg/modules/django_tasks/__init__.py +5 -5
  691. django_cfg/modules/django_tasks/dramatiq_setup.py +1 -1
  692. django_cfg/modules/django_tasks/factory.py +1 -1
  693. django_cfg/modules/django_tasks/management/commands/rundramatiq.py +39 -40
  694. django_cfg/modules/django_tasks/management/commands/rundramatiq_simulator.py +79 -80
  695. django_cfg/modules/django_tasks/management/commands/task_clear.py +34 -34
  696. django_cfg/modules/django_tasks/management/commands/task_status.py +34 -34
  697. django_cfg/modules/django_tasks/service.py +4 -3
  698. django_cfg/modules/django_tasks/settings.py +1 -1
  699. django_cfg/modules/django_telegram/__init__.py +4 -4
  700. django_cfg/modules/django_telegram/management/commands/test_telegram.py +4 -5
  701. django_cfg/modules/django_telegram/service.py +4 -3
  702. django_cfg/modules/django_telegram/utils.py +1 -1
  703. django_cfg/modules/django_twilio/__init__.py +15 -16
  704. django_cfg/modules/django_twilio/_imports.py +1 -1
  705. django_cfg/modules/django_twilio/base.py +9 -5
  706. django_cfg/modules/django_twilio/email_otp.py +4 -3
  707. django_cfg/modules/django_twilio/exceptions.py +36 -36
  708. django_cfg/modules/django_twilio/management/commands/test_twilio.py +6 -7
  709. django_cfg/modules/django_twilio/models.py +54 -53
  710. django_cfg/modules/django_twilio/sendgrid_service.py +70 -72
  711. django_cfg/modules/django_twilio/simple_service.py +42 -41
  712. django_cfg/modules/django_twilio/sms.py +1 -0
  713. django_cfg/modules/django_twilio/twilio_service.py +79 -83
  714. django_cfg/modules/django_twilio/unified.py +6 -5
  715. django_cfg/modules/django_twilio/utils.py +2 -3
  716. django_cfg/modules/django_twilio/whatsapp.py +3 -2
  717. django_cfg/modules/django_unfold/__init__.py +7 -6
  718. django_cfg/modules/django_unfold/callbacks/actions.py +6 -5
  719. django_cfg/modules/django_unfold/callbacks/apizones.py +122 -0
  720. django_cfg/modules/django_unfold/callbacks/base.py +9 -8
  721. django_cfg/modules/django_unfold/callbacks/charts.py +36 -37
  722. django_cfg/modules/django_unfold/callbacks/commands.py +2 -2
  723. django_cfg/modules/django_unfold/callbacks/main.py +27 -27
  724. django_cfg/modules/django_unfold/callbacks/statistics.py +12 -12
  725. django_cfg/modules/django_unfold/callbacks/system.py +5 -5
  726. django_cfg/modules/django_unfold/callbacks/users.py +4 -4
  727. django_cfg/modules/django_unfold/dashboard.py +29 -29
  728. django_cfg/modules/django_unfold/models/__init__.py +23 -8
  729. django_cfg/modules/django_unfold/models/config.py +84 -81
  730. django_cfg/modules/django_unfold/models/dashboard.py +20 -19
  731. django_cfg/modules/django_unfold/models/dropdown.py +6 -4
  732. django_cfg/modules/django_unfold/models/navigation.py +6 -4
  733. django_cfg/modules/django_unfold/models/tabs.py +4 -3
  734. django_cfg/modules/django_unfold/models.py +2 -3
  735. django_cfg/modules/django_unfold/system_monitor.py +27 -25
  736. django_cfg/modules/django_unfold/tailwind.py +12 -14
  737. django_cfg/modules/django_unfold/utils.py +7 -6
  738. django_cfg/pyproject.toml +1 -1
  739. django_cfg/registry/__init__.py +3 -3
  740. django_cfg/registry/core.py +8 -8
  741. django_cfg/registry/modules.py +2 -2
  742. django_cfg/registry/services.py +2 -2
  743. django_cfg/registry/third_party.py +3 -3
  744. django_cfg/routing/__init__.py +3 -3
  745. django_cfg/routing/callbacks.py +27 -26
  746. django_cfg/routing/routers.py +2 -2
  747. django_cfg/static/js/api/accounts/client.mjs +69 -0
  748. django_cfg/static/js/api/accounts/index.mjs +13 -0
  749. django_cfg/static/js/api/base.mjs +166 -0
  750. django_cfg/static/js/api/index.mjs +100 -0
  751. django_cfg/static/js/api/ipc/client.mjs +74 -0
  752. django_cfg/static/js/api/ipc/index.mjs +13 -0
  753. django_cfg/static/js/api/leads/client.mjs +71 -0
  754. django_cfg/static/js/api/leads/index.mjs +13 -0
  755. django_cfg/static/js/api/newsletter/client.mjs +109 -0
  756. django_cfg/static/js/api/newsletter/index.mjs +13 -0
  757. django_cfg/static/js/api/payments/client.mjs +1264 -0
  758. django_cfg/static/js/api/payments/index.mjs +13 -0
  759. django_cfg/static/js/api/support/client.mjs +84 -0
  760. django_cfg/static/js/api/support/index.mjs +13 -0
  761. django_cfg/static/js/api/tasks/client.mjs +74 -0
  762. django_cfg/static/js/api/tasks/index.mjs +13 -0
  763. django_cfg/static/js/api/types.mjs +729 -0
  764. django_cfg/static/js/api-loader.mjs +169 -0
  765. django_cfg/templates/admin/snippets/zones/zones_table.html +4 -3
  766. django_cfg/templatetags/django_cfg.py +4 -4
  767. django_cfg/utils/path_resolution.py +49 -50
  768. django_cfg/utils/smart_defaults.py +27 -29
  769. django_cfg/utils/version_check.py +14 -14
  770. {django_cfg-1.4.20.dist-info → django_cfg-1.4.23.dist-info}/METADATA +1 -1
  771. django_cfg-1.4.23.dist-info/RECORD +1137 -0
  772. django_cfg/apps/payments/static/payments/js/api-client.js +0 -408
  773. django_cfg/modules/django_ipc_client/dashboard/README.md +0 -517
  774. django_cfg/modules/django_ipc_client/dashboard/UNFOLD_INTEGRATION.md +0 -439
  775. django_cfg/modules/django_ipc_client/dashboard/__init__.py +0 -11
  776. django_cfg/modules/django_ipc_client/dashboard/apps.py +0 -22
  777. django_cfg/modules/django_ipc_client/dashboard/templates/django_ipc_dashboard/dashboard.html +0 -200
  778. django_cfg/modules/django_ipc_client/dashboard/urls.py +0 -22
  779. django_cfg/modules/django_ipc_client/dashboard/urls_admin.py +0 -9
  780. django_cfg/modules/django_ipc_client/dashboard/views.py +0 -251
  781. django_cfg/modules/django_rpc_old/POETRY.md +0 -344
  782. django_cfg/modules/django_rpc_old/README.md +0 -397
  783. django_cfg/modules/django_rpc_old/TESTING.md +0 -358
  784. django_cfg/modules/django_rpc_old/__init__.py +0 -39
  785. django_cfg/modules/django_rpc_old/client.py +0 -531
  786. django_cfg/modules/django_rpc_old/config.py +0 -279
  787. django_cfg/modules/django_rpc_old/exceptions.py +0 -172
  788. django_cfg/modules/django_unfold/callbacks/revolution.py +0 -81
  789. django_cfg-1.4.20.dist-info/RECORD +0 -1110
  790. /django_cfg/{modules/django_ipc_client → apps/ipc}/README.md +0 -0
  791. /django_cfg/{modules/django_ipc_client → apps/ipc/services/client}/config.py +0 -0
  792. {django_cfg-1.4.20.dist-info → django_cfg-1.4.23.dist-info}/WHEEL +0 -0
  793. {django_cfg-1.4.20.dist-info → django_cfg-1.4.23.dist-info}/entry_points.txt +0 -0
  794. {django_cfg-1.4.20.dist-info → django_cfg-1.4.23.dist-info}/licenses/LICENSE +0 -0
@@ -4,24 +4,21 @@ CloudflareSite admin using Django Admin Utilities.
4
4
  Enhanced site management with Material Icons and optimized queries.
5
5
  """
6
6
 
7
+
7
8
  from django.contrib import admin, messages
8
- from django.urls import reverse
9
- from django.http import HttpRequest
10
- from django.shortcuts import redirect
11
- from django.db import models
12
9
  from django.db.models import Count, Q
13
- from typing import Any
10
+ from django.http import HttpRequest
14
11
  from unfold.admin import ModelAdmin, TabularInline
15
12
 
16
13
  from django_cfg.modules.django_admin import (
17
- OptimizedModelAdmin,
18
- DisplayMixin,
19
- StatusBadgeConfig,
14
+ ActionVariant,
20
15
  DateTimeDisplayConfig,
16
+ DisplayMixin,
21
17
  Icons,
22
- ActionVariant,
18
+ OptimizedModelAdmin,
19
+ StatusBadgeConfig,
20
+ action,
23
21
  display,
24
- action
25
22
  )
26
23
  from django_cfg.modules.django_admin.utils.badges import StatusBadge
27
24
 
@@ -31,7 +28,7 @@ from ..services import MaintenanceService
31
28
 
32
29
  class MaintenanceLogInline(TabularInline):
33
30
  """Inline for recent maintenance logs."""
34
-
31
+
35
32
  model = MaintenanceLog
36
33
  verbose_name = "Recent Log"
37
34
  verbose_name_plural = "📋 Recent Maintenance Logs"
@@ -39,16 +36,16 @@ class MaintenanceLogInline(TabularInline):
39
36
  max_num = 5
40
37
  can_delete = False
41
38
  show_change_link = True
42
-
39
+
43
40
  fields = ['status_display', 'action', 'created_at', 'duration_seconds', 'error_preview']
44
41
  readonly_fields = ['status_display', 'action', 'created_at', 'duration_seconds', 'error_preview']
45
-
42
+
46
43
  def has_add_permission(self, request, obj=None):
47
44
  return False
48
-
45
+
49
46
  def has_change_permission(self, request, obj=None):
50
47
  return False
51
-
48
+
52
49
  @display(description="Status")
53
50
  def status_display(self, obj):
54
51
  """Display status with badge."""
@@ -58,44 +55,44 @@ class MaintenanceLogInline(TabularInline):
58
55
  MaintenanceLog.Status.PENDING: 'warning'
59
56
  }
60
57
  variant = status_variants.get(obj.status, 'secondary')
61
-
58
+
62
59
  status_icons = {
63
60
  MaintenanceLog.Status.SUCCESS: Icons.CHECK_CIRCLE,
64
61
  MaintenanceLog.Status.FAILED: Icons.CANCEL,
65
62
  MaintenanceLog.Status.PENDING: Icons.SCHEDULE
66
63
  }
67
64
  icon = status_icons.get(obj.status, Icons.HELP)
68
-
65
+
69
66
  config = StatusBadgeConfig(show_icons=True, icon=icon)
70
67
  return StatusBadge.create(
71
68
  text=obj.get_status_display(),
72
69
  variant=variant,
73
70
  config=config
74
71
  )
75
-
72
+
76
73
  @display(description="Error")
77
74
  def error_preview(self, obj):
78
75
  """Show error message preview."""
79
76
  if not obj.error_message:
80
77
  return "—"
81
-
78
+
82
79
  preview = obj.error_message[:50]
83
80
  if len(obj.error_message) > 50:
84
81
  preview += "..."
85
-
82
+
86
83
  return preview
87
84
 
88
85
 
89
86
  @admin.register(CloudflareSite)
90
87
  class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
91
88
  """Admin for CloudflareSite using Django Admin Utilities."""
92
-
89
+
93
90
  # Performance optimization
94
91
  select_related_fields = ['api_key']
95
-
92
+
96
93
  list_display = [
97
94
  'status_display',
98
- 'name_display',
95
+ 'name_display',
99
96
  'domain_display',
100
97
  'subdomain_config_display',
101
98
  'maintenance_display',
@@ -120,7 +117,7 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
120
117
  'last_maintenance_at',
121
118
  'logs_preview'
122
119
  ]
123
-
120
+
124
121
  fieldsets = [
125
122
  ('🌐 Site Information', {
126
123
  'fields': ['name', 'domain', 'zone_id'],
@@ -147,9 +144,9 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
147
144
  'classes': ('tab', 'collapse')
148
145
  })
149
146
  ]
150
-
147
+
151
148
  inlines = [MaintenanceLogInline]
152
-
149
+
153
150
  actions = [
154
151
  'enable_maintenance_action',
155
152
  'disable_maintenance_action',
@@ -157,7 +154,7 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
157
154
  'deactivate_sites_action',
158
155
  'sync_with_cloudflare_action'
159
156
  ]
160
-
157
+
161
158
  @display(description="Status")
162
159
  def status_display(self, obj: CloudflareSite) -> str:
163
160
  """Display site status with maintenance indicator."""
@@ -182,7 +179,7 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
182
179
  variant="secondary",
183
180
  config=config
184
181
  )
185
-
182
+
186
183
  @display(description="Name", ordering="name")
187
184
  def name_display(self, obj: CloudflareSite) -> str:
188
185
  """Display site name."""
@@ -192,7 +189,7 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
192
189
  variant="primary",
193
190
  config=config
194
191
  )
195
-
192
+
196
193
  @display(description="Domain", ordering="domain")
197
194
  def domain_display(self, obj: CloudflareSite) -> str:
198
195
  """Display domain."""
@@ -202,7 +199,7 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
202
199
  variant="info",
203
200
  config=config
204
201
  )
205
-
202
+
206
203
  @display(description="Subdomains")
207
204
  def subdomain_config_display(self, obj: CloudflareSite) -> str:
208
205
  """Display subdomain configuration."""
@@ -211,7 +208,7 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
211
208
  return StatusBadge.create(text="Includes Subdomains", variant="info", config=config)
212
209
  else:
213
210
  return "Domain Only"
214
-
211
+
215
212
  @display(description="Maintenance")
216
213
  def maintenance_display(self, obj: CloudflareSite) -> str:
217
214
  """Display maintenance status."""
@@ -221,7 +218,7 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
221
218
  else:
222
219
  config = StatusBadgeConfig(show_icons=True, icon=Icons.CHECK_CIRCLE)
223
220
  return StatusBadge.create(text="Inactive", variant="success", config=config)
224
-
221
+
225
222
  @display(description="Active")
226
223
  def active_display(self, obj: CloudflareSite) -> str:
227
224
  """Display active status."""
@@ -231,7 +228,7 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
231
228
  else:
232
229
  config = StatusBadgeConfig(show_icons=True, icon=Icons.CANCEL)
233
230
  return StatusBadge.create(text="Inactive", variant="secondary", config=config)
234
-
231
+
235
232
  @display(description="Last Maintenance")
236
233
  def last_maintenance_display(self, obj: CloudflareSite) -> str:
237
234
  """Display last maintenance time."""
@@ -239,7 +236,7 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
239
236
  return "Never"
240
237
  config = DateTimeDisplayConfig(show_relative=True)
241
238
  return self.display_datetime_relative(obj, 'last_maintenance_at', config)
242
-
239
+
243
240
  @display(description="Logs")
244
241
  def logs_count(self, obj: CloudflareSite) -> str:
245
242
  """Display count of maintenance logs."""
@@ -247,35 +244,35 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
247
244
  if count > 0:
248
245
  return f"{count} logs"
249
246
  return "No logs"
250
-
247
+
251
248
  @display(description="API Key")
252
249
  def api_key_display(self, obj: CloudflareSite) -> str:
253
250
  """Display API key."""
254
251
  if not obj.api_key:
255
252
  return "—"
256
253
  return self.display_user_simple(obj.api_key, field_name='name')
257
-
254
+
258
255
  def logs_preview(self, obj: CloudflareSite) -> str:
259
256
  """Show recent maintenance logs."""
260
257
  logs = obj.maintenancelog_set.all()[:5]
261
-
258
+
262
259
  if not logs:
263
260
  return "No maintenance logs yet"
264
-
261
+
265
262
  log_list = []
266
263
  for log in logs:
267
264
  status_emoji = "✅" if log.status == MaintenanceLog.Status.SUCCESS else "❌" if log.status == MaintenanceLog.Status.FAILED else "⏳"
268
265
  log_list.append(f"{status_emoji} {log.action} - {log.created_at.strftime('%Y-%m-%d %H:%M')}")
269
-
266
+
270
267
  return "\n".join(log_list)
271
-
268
+
272
269
  @action(description="Enable maintenance mode", variant=ActionVariant.WARNING)
273
270
  def enable_maintenance_action(self, request: HttpRequest, queryset) -> None:
274
271
  """Enable maintenance mode for selected sites."""
275
272
  service = MaintenanceService()
276
273
  success_count = 0
277
274
  error_count = 0
278
-
275
+
279
276
  for site in queryset:
280
277
  try:
281
278
  service.enable_maintenance(site)
@@ -283,19 +280,19 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
283
280
  except Exception as e:
284
281
  error_count += 1
285
282
  messages.error(request, f"Failed to enable maintenance for {site.name}: {str(e)}")
286
-
283
+
287
284
  if success_count > 0:
288
285
  messages.success(request, f"Successfully enabled maintenance for {success_count} sites.")
289
286
  if error_count > 0:
290
287
  messages.error(request, f"Failed to enable maintenance for {error_count} sites.")
291
-
288
+
292
289
  @action(description="Disable maintenance mode", variant=ActionVariant.SUCCESS)
293
290
  def disable_maintenance_action(self, request: HttpRequest, queryset) -> None:
294
291
  """Disable maintenance mode for selected sites."""
295
292
  service = MaintenanceService()
296
293
  success_count = 0
297
294
  error_count = 0
298
-
295
+
299
296
  for site in queryset:
300
297
  try:
301
298
  service.disable_maintenance(site)
@@ -303,33 +300,33 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
303
300
  except Exception as e:
304
301
  error_count += 1
305
302
  messages.error(request, f"Failed to disable maintenance for {site.name}: {str(e)}")
306
-
303
+
307
304
  if success_count > 0:
308
305
  messages.success(request, f"Successfully disabled maintenance for {success_count} sites.")
309
306
  if error_count > 0:
310
307
  messages.error(request, f"Failed to disable maintenance for {error_count} sites.")
311
-
308
+
312
309
  @action(description="Activate sites", variant=ActionVariant.SUCCESS)
313
310
  def activate_sites_action(self, request: HttpRequest, queryset) -> None:
314
311
  """Activate selected sites."""
315
312
  count = queryset.update(is_active=True)
316
313
  messages.success(request, f"Successfully activated {count} sites.")
317
-
314
+
318
315
  @action(description="Deactivate sites", variant=ActionVariant.DANGER)
319
316
  def deactivate_sites_action(self, request: HttpRequest, queryset) -> None:
320
317
  """Deactivate selected sites."""
321
318
  count = queryset.update(is_active=False)
322
319
  messages.warning(request, f"Successfully deactivated {count} sites.")
323
-
320
+
324
321
  @action(description="Sync with Cloudflare", variant=ActionVariant.INFO)
325
322
  def sync_with_cloudflare_action(self, request: HttpRequest, queryset) -> None:
326
323
  """Sync selected sites with Cloudflare."""
327
324
  messages.info(request, f"Cloudflare sync initiated for {queryset.count()} sites.")
328
-
325
+
329
326
  def changelist_view(self, request, extra_context=None):
330
327
  """Add site statistics to changelist."""
331
328
  extra_context = extra_context or {}
332
-
329
+
333
330
  queryset = self.get_queryset(request)
334
331
  stats = queryset.aggregate(
335
332
  total_sites=Count('id'),
@@ -337,12 +334,12 @@ class CloudflareSiteAdmin(OptimizedModelAdmin, DisplayMixin, ModelAdmin):
337
334
  maintenance_sites=Count('id', filter=Q(maintenance_active=True)),
338
335
  subdomain_sites=Count('id', filter=Q(include_subdomains=True))
339
336
  )
340
-
337
+
341
338
  extra_context['site_stats'] = {
342
339
  'total_sites': stats['total_sites'] or 0,
343
340
  'active_sites': stats['active_sites'] or 0,
344
341
  'maintenance_sites': stats['maintenance_sites'] or 0,
345
342
  'subdomain_sites': stats['subdomain_sites'] or 0
346
343
  }
347
-
344
+
348
345
  return super().changelist_view(request, extra_context)
@@ -7,11 +7,11 @@ from django.apps import AppConfig
7
7
 
8
8
  class MaintenanceConfig(AppConfig):
9
9
  """Configuration for the simplified maintenance app."""
10
-
10
+
11
11
  default_auto_field = 'django.db.models.BigAutoField'
12
12
  name = 'django_cfg.apps.maintenance'
13
13
  verbose_name = 'Maintenance Mode'
14
-
14
+
15
15
  def ready(self):
16
16
  """Initialize app when Django starts."""
17
17
  # No complex signals or initialization needed
@@ -5,9 +5,10 @@ Single command instead of 2+ complex commands.
5
5
  Usage: python manage.py maintenance enable/disable/status/sync domain.com
6
6
  """
7
7
 
8
+ from typing import Any
9
+
8
10
  from django.core.management.base import BaseCommand, CommandError
9
11
  from django.db import transaction
10
- from typing import Any, Optional
11
12
 
12
13
  from ...models import CloudflareSite, MaintenanceLog
13
14
  from ...services import MaintenanceService
@@ -15,9 +16,9 @@ from ...services import MaintenanceService
15
16
 
16
17
  class Command(BaseCommand):
17
18
  """Simple maintenance management command."""
18
-
19
+
19
20
  help = 'Manage maintenance mode for Cloudflare sites'
20
-
21
+
21
22
  def add_arguments(self, parser) -> None:
22
23
  """Add command arguments."""
23
24
  parser.add_argument(
@@ -25,31 +26,31 @@ class Command(BaseCommand):
25
26
  choices=['enable', 'disable', 'status', 'sync', 'list'],
26
27
  help='Action to perform'
27
28
  )
28
-
29
+
29
30
  parser.add_argument(
30
31
  'domain',
31
32
  nargs='?',
32
33
  help='Domain to operate on (required for enable/disable/status/sync)'
33
34
  )
34
-
35
+
35
36
  parser.add_argument(
36
37
  '--reason',
37
38
  default='Maintenance via CLI',
38
39
  help='Reason for enabling maintenance (default: "Maintenance via CLI")'
39
40
  )
40
-
41
+
41
42
  parser.add_argument(
42
43
  '--force',
43
44
  action='store_true',
44
45
  help='Skip confirmation prompts'
45
46
  )
46
-
47
+
47
48
  parser.add_argument(
48
49
  '--verbose',
49
50
  action='store_true',
50
51
  help='Show detailed output'
51
52
  )
52
-
53
+
53
54
  def handle(self, *args: Any, **options: Any) -> None:
54
55
  """Handle the command."""
55
56
  action = options['action']
@@ -57,11 +58,11 @@ class Command(BaseCommand):
57
58
  reason = options['reason']
58
59
  force = options['force']
59
60
  verbose = options['verbose']
60
-
61
+
61
62
  # Validate arguments
62
63
  if action in ['enable', 'disable', 'status', 'sync'] and not domain:
63
64
  raise CommandError(f"Domain is required for '{action}' action")
64
-
65
+
65
66
  try:
66
67
  if action == 'list':
67
68
  self._handle_list(verbose)
@@ -73,36 +74,36 @@ class Command(BaseCommand):
73
74
  self._handle_disable(domain, force, verbose)
74
75
  elif action == 'sync':
75
76
  self._handle_sync(domain, verbose)
76
-
77
+
77
78
  except CloudflareSite.DoesNotExist:
78
79
  raise CommandError(f"Site '{domain}' not found. Use 'list' action to see available sites.")
79
80
  except Exception as e:
80
81
  raise CommandError(f"Operation failed: {str(e)}")
81
-
82
+
82
83
  def _handle_list(self, verbose: bool) -> None:
83
84
  """List all sites."""
84
85
  sites = CloudflareSite.objects.all().order_by('name')
85
-
86
+
86
87
  if not sites:
87
88
  self.stdout.write(self.style.WARNING("No sites configured"))
88
89
  return
89
-
90
+
90
91
  self.stdout.write(self.style.SUCCESS(f"Found {sites.count()} sites:"))
91
92
  self.stdout.write("")
92
-
93
+
93
94
  for site in sites:
94
95
  status_style = self.style.WARNING if site.maintenance_active else self.style.SUCCESS
95
96
  status_text = "🔧 MAINTENANCE" if site.maintenance_active else "🟢 ACTIVE"
96
-
97
+
97
98
  self.stdout.write(f" {status_style(status_text)} {site.name} ({site.domain})")
98
-
99
+
99
100
  if verbose:
100
101
  self.stdout.write(f" Zone ID: {site.zone_id}")
101
102
  self.stdout.write(f" Account ID: {site.account_id}")
102
103
  self.stdout.write(f" Created: {site.created_at.strftime('%Y-%m-%d %H:%M')}")
103
104
  if site.last_maintenance_at:
104
105
  self.stdout.write(f" Last Maintenance: {site.last_maintenance_at.strftime('%Y-%m-%d %H:%M')}")
105
-
106
+
106
107
  # Show recent logs
107
108
  recent_logs = site.logs.all()[:3]
108
109
  if recent_logs:
@@ -113,30 +114,30 @@ class Command(BaseCommand):
113
114
  MaintenanceLog.Status.FAILED: "❌",
114
115
  MaintenanceLog.Status.PENDING: "⏳"
115
116
  }.get(log.status, "❓")
116
-
117
+
117
118
  self.stdout.write(f" {status_emoji} {log.get_action_display()} - {log.created_at.strftime('%m-%d %H:%M')}")
118
-
119
+
119
120
  self.stdout.write("")
120
-
121
+
121
122
  def _handle_status(self, domain: str, verbose: bool) -> None:
122
123
  """Show status for specific site."""
123
124
  site = CloudflareSite.objects.get(domain=domain)
124
-
125
+
125
126
  status_style = self.style.WARNING if site.maintenance_active else self.style.SUCCESS
126
127
  status_text = "🔧 MAINTENANCE ACTIVE" if site.maintenance_active else "🟢 ACTIVE"
127
-
128
+
128
129
  self.stdout.write(f"Status for {site.name} ({domain}):")
129
130
  self.stdout.write(f" {status_style(status_text)}")
130
-
131
+
131
132
  if verbose:
132
133
  self.stdout.write(f" Zone ID: {site.zone_id}")
133
134
  self.stdout.write(f" Account ID: {site.account_id}")
134
135
  self.stdout.write(f" Created: {site.created_at.strftime('%Y-%m-%d %H:%M')}")
135
136
  self.stdout.write(f" Updated: {site.updated_at.strftime('%Y-%m-%d %H:%M')}")
136
-
137
+
137
138
  if site.last_maintenance_at:
138
139
  self.stdout.write(f" Last Maintenance: {site.last_maintenance_at.strftime('%Y-%m-%d %H:%M')}")
139
-
140
+
140
141
  # Show recent logs
141
142
  recent_logs = site.logs.all()[:5]
142
143
  if recent_logs:
@@ -147,115 +148,115 @@ class Command(BaseCommand):
147
148
  MaintenanceLog.Status.FAILED: "❌",
148
149
  MaintenanceLog.Status.PENDING: "⏳"
149
150
  }.get(log.status, "❓")
150
-
151
+
151
152
  duration_text = f" ({log.duration_seconds}s)" if log.duration_seconds else ""
152
153
  self.stdout.write(f" {status_emoji} {log.get_action_display()}{duration_text} - {log.created_at.strftime('%Y-%m-%d %H:%M')}")
153
-
154
+
154
155
  if log.error_message and verbose:
155
156
  self.stdout.write(f" Error: {log.error_message[:100]}")
156
-
157
+
157
158
  def _handle_enable(self, domain: str, reason: str, force: bool, verbose: bool) -> None:
158
159
  """Enable maintenance for site."""
159
160
  site = CloudflareSite.objects.get(domain=domain)
160
-
161
+
161
162
  if site.maintenance_active:
162
163
  self.stdout.write(self.style.WARNING(f"Maintenance is already active for {domain}"))
163
164
  return
164
-
165
+
165
166
  # Confirmation
166
167
  if not force:
167
168
  confirm = input(f"Enable maintenance for {site.name} ({domain})? [y/N]: ")
168
169
  if confirm.lower() not in ['y', 'yes']:
169
170
  self.stdout.write("Cancelled")
170
171
  return
171
-
172
+
172
173
  self.stdout.write(f"Enabling maintenance for {domain}...")
173
174
  if verbose:
174
175
  self.stdout.write(f"Reason: {reason}")
175
-
176
+
176
177
  try:
177
178
  with transaction.atomic():
178
179
  service = MaintenanceService(site)
179
180
  log_entry = service.enable_maintenance(reason)
180
-
181
+
181
182
  if log_entry.status == MaintenanceLog.Status.SUCCESS:
182
183
  duration_text = f" ({log_entry.duration_seconds}s)" if log_entry.duration_seconds else ""
183
184
  self.stdout.write(self.style.SUCCESS(f"✅ Maintenance enabled successfully{duration_text}"))
184
-
185
+
185
186
  if verbose and log_entry.cloudflare_response:
186
187
  self.stdout.write("Cloudflare response:")
187
188
  import json
188
189
  self.stdout.write(json.dumps(log_entry.cloudflare_response, indent=2))
189
190
  else:
190
191
  self.stdout.write(self.style.ERROR(f"❌ Failed to enable maintenance: {log_entry.error_message}"))
191
-
192
+
192
193
  except Exception as e:
193
194
  self.stdout.write(self.style.ERROR(f"❌ Error: {str(e)}"))
194
-
195
+
195
196
  def _handle_disable(self, domain: str, force: bool, verbose: bool) -> None:
196
197
  """Disable maintenance for site."""
197
198
  site = CloudflareSite.objects.get(domain=domain)
198
-
199
+
199
200
  if not site.maintenance_active:
200
201
  self.stdout.write(self.style.WARNING(f"Maintenance is not active for {domain}"))
201
202
  return
202
-
203
+
203
204
  # Confirmation
204
205
  if not force:
205
206
  confirm = input(f"Disable maintenance for {site.name} ({domain})? [y/N]: ")
206
207
  if confirm.lower() not in ['y', 'yes']:
207
208
  self.stdout.write("Cancelled")
208
209
  return
209
-
210
+
210
211
  self.stdout.write(f"Disabling maintenance for {domain}...")
211
-
212
+
212
213
  try:
213
214
  with transaction.atomic():
214
215
  service = MaintenanceService(site)
215
216
  log_entry = service.disable_maintenance()
216
-
217
+
217
218
  if log_entry.status == MaintenanceLog.Status.SUCCESS:
218
219
  duration_text = f" ({log_entry.duration_seconds}s)" if log_entry.duration_seconds else ""
219
220
  self.stdout.write(self.style.SUCCESS(f"✅ Maintenance disabled successfully{duration_text}"))
220
-
221
+
221
222
  if verbose and log_entry.cloudflare_response:
222
223
  self.stdout.write("Cloudflare response:")
223
224
  import json
224
225
  self.stdout.write(json.dumps(log_entry.cloudflare_response, indent=2))
225
226
  else:
226
227
  self.stdout.write(self.style.ERROR(f"❌ Failed to disable maintenance: {log_entry.error_message}"))
227
-
228
+
228
229
  except Exception as e:
229
230
  self.stdout.write(self.style.ERROR(f"❌ Error: {str(e)}"))
230
-
231
+
231
232
  def _handle_sync(self, domain: str, verbose: bool) -> None:
232
233
  """Sync site from Cloudflare."""
233
234
  site = CloudflareSite.objects.get(domain=domain)
234
-
235
+
235
236
  self.stdout.write(f"Syncing {domain} from Cloudflare...")
236
-
237
+
237
238
  try:
238
239
  service = MaintenanceService(site)
239
240
  log_entry = service.sync_site_from_cloudflare()
240
-
241
+
241
242
  if log_entry.status == MaintenanceLog.Status.SUCCESS:
242
243
  duration_text = f" ({log_entry.duration_seconds}s)" if log_entry.duration_seconds else ""
243
244
  self.stdout.write(self.style.SUCCESS(f"✅ Sync completed successfully{duration_text}"))
244
-
245
+
245
246
  if verbose and log_entry.cloudflare_response:
246
247
  response = log_entry.cloudflare_response
247
248
  if 'updated_fields' in response and response['updated_fields']:
248
249
  self.stdout.write(f"Updated fields: {', '.join(response['updated_fields'])}")
249
-
250
+
250
251
  maintenance_status = response.get('maintenance_active', 'unknown')
251
252
  self.stdout.write(f"Current maintenance status: {maintenance_status}")
252
-
253
+
253
254
  if verbose:
254
255
  import json
255
256
  self.stdout.write("Full Cloudflare response:")
256
257
  self.stdout.write(json.dumps(response, indent=2))
257
258
  else:
258
259
  self.stdout.write(self.style.ERROR(f"❌ Sync failed: {log_entry.error_message}"))
259
-
260
+
260
261
  except Exception as e:
261
262
  self.stdout.write(self.style.ERROR(f"❌ Error: {str(e)}"))