django-cfg 1.1.81__py3-none-any.whl → 1.2.0__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 (246) hide show
  1. django_cfg/__init__.py +20 -448
  2. django_cfg/apps/accounts/README.md +3 -3
  3. django_cfg/apps/accounts/admin/__init__.py +0 -2
  4. django_cfg/apps/accounts/admin/activity.py +2 -9
  5. django_cfg/apps/accounts/admin/filters.py +0 -42
  6. django_cfg/apps/accounts/admin/inlines.py +8 -8
  7. django_cfg/apps/accounts/admin/otp.py +5 -5
  8. django_cfg/apps/accounts/admin/registration_source.py +1 -8
  9. django_cfg/apps/accounts/admin/user.py +12 -20
  10. django_cfg/apps/accounts/managers/user_manager.py +2 -129
  11. django_cfg/apps/accounts/migrations/0006_remove_twilioresponse_otp_secret_and_more.py +46 -0
  12. django_cfg/apps/accounts/models.py +3 -123
  13. django_cfg/apps/accounts/serializers/otp.py +40 -44
  14. django_cfg/apps/accounts/serializers/profile.py +0 -2
  15. django_cfg/apps/accounts/services/otp_service.py +98 -186
  16. django_cfg/apps/accounts/signals.py +25 -15
  17. django_cfg/apps/accounts/utils/auth_email_service.py +84 -0
  18. django_cfg/apps/accounts/views/otp.py +35 -36
  19. django_cfg/apps/agents/README.md +129 -0
  20. django_cfg/apps/agents/__init__.py +68 -0
  21. django_cfg/apps/agents/admin/__init__.py +17 -0
  22. django_cfg/apps/agents/admin/execution_admin.py +460 -0
  23. django_cfg/apps/agents/admin/registry_admin.py +360 -0
  24. django_cfg/apps/agents/admin/toolsets_admin.py +482 -0
  25. django_cfg/apps/agents/apps.py +29 -0
  26. django_cfg/apps/agents/core/__init__.py +20 -0
  27. django_cfg/apps/agents/core/agent.py +281 -0
  28. django_cfg/apps/agents/core/dependencies.py +154 -0
  29. django_cfg/apps/agents/core/exceptions.py +66 -0
  30. django_cfg/apps/agents/core/models.py +106 -0
  31. django_cfg/apps/agents/core/orchestrator.py +391 -0
  32. django_cfg/apps/agents/examples/__init__.py +3 -0
  33. django_cfg/apps/agents/examples/simple_example.py +161 -0
  34. django_cfg/apps/agents/integration/__init__.py +14 -0
  35. django_cfg/apps/agents/integration/middleware.py +80 -0
  36. django_cfg/apps/agents/integration/registry.py +345 -0
  37. django_cfg/apps/agents/integration/signals.py +50 -0
  38. django_cfg/apps/agents/management/__init__.py +3 -0
  39. django_cfg/apps/agents/management/commands/__init__.py +3 -0
  40. django_cfg/apps/agents/management/commands/create_agent.py +365 -0
  41. django_cfg/apps/agents/management/commands/orchestrator_status.py +191 -0
  42. django_cfg/apps/agents/managers/__init__.py +23 -0
  43. django_cfg/apps/agents/managers/execution.py +236 -0
  44. django_cfg/apps/agents/managers/registry.py +254 -0
  45. django_cfg/apps/agents/managers/toolsets.py +496 -0
  46. django_cfg/apps/agents/migrations/0001_initial.py +286 -0
  47. django_cfg/apps/agents/migrations/__init__.py +5 -0
  48. django_cfg/apps/agents/models/__init__.py +15 -0
  49. django_cfg/apps/agents/models/execution.py +215 -0
  50. django_cfg/apps/agents/models/registry.py +220 -0
  51. django_cfg/apps/agents/models/toolsets.py +305 -0
  52. django_cfg/apps/agents/patterns/__init__.py +24 -0
  53. django_cfg/apps/agents/patterns/content_agents.py +234 -0
  54. django_cfg/apps/agents/toolsets/__init__.py +15 -0
  55. django_cfg/apps/agents/toolsets/cache_toolset.py +285 -0
  56. django_cfg/apps/agents/toolsets/django_toolset.py +220 -0
  57. django_cfg/apps/agents/toolsets/file_toolset.py +324 -0
  58. django_cfg/apps/agents/toolsets/orm_toolset.py +319 -0
  59. django_cfg/apps/agents/urls.py +46 -0
  60. django_cfg/apps/knowbase/README.md +150 -0
  61. django_cfg/apps/knowbase/__init__.py +27 -0
  62. django_cfg/apps/knowbase/admin/__init__.py +23 -0
  63. django_cfg/apps/knowbase/admin/archive_admin.py +857 -0
  64. django_cfg/apps/knowbase/admin/chat_admin.py +386 -0
  65. django_cfg/apps/knowbase/admin/document_admin.py +650 -0
  66. django_cfg/apps/knowbase/admin/external_data_admin.py +685 -0
  67. django_cfg/apps/knowbase/apps.py +81 -0
  68. django_cfg/apps/knowbase/config/README.md +176 -0
  69. django_cfg/apps/knowbase/config/__init__.py +51 -0
  70. django_cfg/apps/knowbase/config/constance_fields.py +186 -0
  71. django_cfg/apps/knowbase/config/constance_settings.py +200 -0
  72. django_cfg/apps/knowbase/config/settings.py +444 -0
  73. django_cfg/apps/knowbase/examples/__init__.py +3 -0
  74. django_cfg/apps/knowbase/examples/external_data_usage.py +191 -0
  75. django_cfg/apps/knowbase/management/__init__.py +0 -0
  76. django_cfg/apps/knowbase/management/commands/__init__.py +0 -0
  77. django_cfg/apps/knowbase/management/commands/knowbase_stats.py +158 -0
  78. django_cfg/apps/knowbase/management/commands/setup_knowbase.py +59 -0
  79. django_cfg/apps/knowbase/managers/__init__.py +22 -0
  80. django_cfg/apps/knowbase/managers/archive.py +426 -0
  81. django_cfg/apps/knowbase/managers/base.py +32 -0
  82. django_cfg/apps/knowbase/managers/chat.py +141 -0
  83. django_cfg/apps/knowbase/managers/document.py +203 -0
  84. django_cfg/apps/knowbase/managers/external_data.py +471 -0
  85. django_cfg/apps/knowbase/migrations/0001_initial.py +427 -0
  86. django_cfg/apps/knowbase/migrations/0002_archiveitem_archiveitemchunk_documentarchive_and_more.py +434 -0
  87. django_cfg/apps/knowbase/migrations/__init__.py +5 -0
  88. django_cfg/apps/knowbase/mixins/__init__.py +15 -0
  89. django_cfg/apps/knowbase/mixins/config.py +108 -0
  90. django_cfg/apps/knowbase/mixins/creator.py +81 -0
  91. django_cfg/apps/knowbase/mixins/examples/vehicle_model_example.py +199 -0
  92. django_cfg/apps/knowbase/mixins/external_data_mixin.py +813 -0
  93. django_cfg/apps/knowbase/mixins/service.py +362 -0
  94. django_cfg/apps/knowbase/models/__init__.py +41 -0
  95. django_cfg/apps/knowbase/models/archive.py +599 -0
  96. django_cfg/apps/knowbase/models/base.py +58 -0
  97. django_cfg/apps/knowbase/models/chat.py +157 -0
  98. django_cfg/apps/knowbase/models/document.py +267 -0
  99. django_cfg/apps/knowbase/models/external_data.py +376 -0
  100. django_cfg/apps/knowbase/serializers/__init__.py +68 -0
  101. django_cfg/apps/knowbase/serializers/archive_serializers.py +386 -0
  102. django_cfg/apps/knowbase/serializers/chat_serializers.py +137 -0
  103. django_cfg/apps/knowbase/serializers/document_serializers.py +94 -0
  104. django_cfg/apps/knowbase/serializers/external_data_serializers.py +256 -0
  105. django_cfg/apps/knowbase/serializers/public_serializers.py +74 -0
  106. django_cfg/apps/knowbase/services/__init__.py +40 -0
  107. django_cfg/apps/knowbase/services/archive/__init__.py +42 -0
  108. django_cfg/apps/knowbase/services/archive/archive_service.py +541 -0
  109. django_cfg/apps/knowbase/services/archive/chunking_service.py +791 -0
  110. django_cfg/apps/knowbase/services/archive/exceptions.py +52 -0
  111. django_cfg/apps/knowbase/services/archive/extraction_service.py +508 -0
  112. django_cfg/apps/knowbase/services/archive/vectorization_service.py +362 -0
  113. django_cfg/apps/knowbase/services/base.py +53 -0
  114. django_cfg/apps/knowbase/services/chat_service.py +239 -0
  115. django_cfg/apps/knowbase/services/document_service.py +144 -0
  116. django_cfg/apps/knowbase/services/embedding/__init__.py +43 -0
  117. django_cfg/apps/knowbase/services/embedding/async_processor.py +244 -0
  118. django_cfg/apps/knowbase/services/embedding/batch_processor.py +250 -0
  119. django_cfg/apps/knowbase/services/embedding/batch_result.py +61 -0
  120. django_cfg/apps/knowbase/services/embedding/models.py +229 -0
  121. django_cfg/apps/knowbase/services/embedding/processors.py +148 -0
  122. django_cfg/apps/knowbase/services/embedding/utils.py +176 -0
  123. django_cfg/apps/knowbase/services/prompt_builder.py +191 -0
  124. django_cfg/apps/knowbase/services/search_service.py +293 -0
  125. django_cfg/apps/knowbase/signals/__init__.py +21 -0
  126. django_cfg/apps/knowbase/signals/archive_signals.py +211 -0
  127. django_cfg/apps/knowbase/signals/chat_signals.py +37 -0
  128. django_cfg/apps/knowbase/signals/document_signals.py +143 -0
  129. django_cfg/apps/knowbase/signals/external_data_signals.py +157 -0
  130. django_cfg/apps/knowbase/tasks/__init__.py +39 -0
  131. django_cfg/apps/knowbase/tasks/archive_tasks.py +316 -0
  132. django_cfg/apps/knowbase/tasks/document_processing.py +341 -0
  133. django_cfg/apps/knowbase/tasks/external_data_tasks.py +341 -0
  134. django_cfg/apps/knowbase/tasks/maintenance.py +195 -0
  135. django_cfg/apps/knowbase/urls.py +43 -0
  136. django_cfg/apps/knowbase/utils/__init__.py +12 -0
  137. django_cfg/apps/knowbase/utils/chunk_settings.py +261 -0
  138. django_cfg/apps/knowbase/utils/text_processing.py +375 -0
  139. django_cfg/apps/knowbase/utils/validation.py +99 -0
  140. django_cfg/apps/knowbase/views/__init__.py +28 -0
  141. django_cfg/apps/knowbase/views/archive_views.py +469 -0
  142. django_cfg/apps/knowbase/views/base.py +49 -0
  143. django_cfg/apps/knowbase/views/chat_views.py +181 -0
  144. django_cfg/apps/knowbase/views/document_views.py +183 -0
  145. django_cfg/apps/knowbase/views/public_views.py +129 -0
  146. django_cfg/apps/leads/admin.py +70 -0
  147. django_cfg/apps/newsletter/admin.py +234 -0
  148. django_cfg/apps/newsletter/admin_filters.py +124 -0
  149. django_cfg/apps/support/admin.py +196 -0
  150. django_cfg/apps/support/admin_filters.py +71 -0
  151. django_cfg/apps/support/templates/support/chat/ticket_chat.html +1 -1
  152. django_cfg/apps/urls.py +5 -4
  153. django_cfg/cli/README.md +1 -1
  154. django_cfg/cli/commands/create_project.py +2 -2
  155. django_cfg/cli/commands/info.py +1 -1
  156. django_cfg/config.py +44 -0
  157. django_cfg/core/config.py +29 -82
  158. django_cfg/core/environment.py +1 -1
  159. django_cfg/core/generation.py +19 -107
  160. django_cfg/{integration.py → core/integration.py} +18 -16
  161. django_cfg/core/validation.py +1 -1
  162. django_cfg/management/__init__.py +1 -1
  163. django_cfg/management/commands/__init__.py +1 -1
  164. django_cfg/management/commands/auto_generate.py +482 -0
  165. django_cfg/management/commands/migrator.py +19 -101
  166. django_cfg/management/commands/test_email.py +1 -1
  167. django_cfg/middleware/README.md +0 -158
  168. django_cfg/middleware/__init__.py +0 -2
  169. django_cfg/middleware/user_activity.py +3 -3
  170. django_cfg/models/api.py +145 -0
  171. django_cfg/models/base.py +287 -0
  172. django_cfg/models/cache.py +4 -4
  173. django_cfg/models/constance.py +25 -88
  174. django_cfg/models/database.py +9 -9
  175. django_cfg/models/drf.py +3 -36
  176. django_cfg/models/email.py +163 -0
  177. django_cfg/models/environment.py +276 -0
  178. django_cfg/models/limits.py +1 -1
  179. django_cfg/models/logging.py +366 -0
  180. django_cfg/models/revolution.py +41 -2
  181. django_cfg/models/security.py +125 -0
  182. django_cfg/models/services.py +1 -1
  183. django_cfg/modules/__init__.py +2 -56
  184. django_cfg/modules/base.py +78 -52
  185. django_cfg/modules/django_currency/service.py +2 -2
  186. django_cfg/modules/django_email.py +2 -2
  187. django_cfg/modules/django_health.py +267 -0
  188. django_cfg/modules/django_llm/llm/client.py +79 -17
  189. django_cfg/modules/django_llm/translator/translator.py +2 -2
  190. django_cfg/modules/django_logger.py +2 -2
  191. django_cfg/modules/django_ngrok.py +2 -2
  192. django_cfg/modules/django_tasks.py +68 -3
  193. django_cfg/modules/django_telegram.py +3 -3
  194. django_cfg/modules/django_twilio/sendgrid_service.py +2 -2
  195. django_cfg/modules/django_twilio/service.py +2 -2
  196. django_cfg/modules/django_twilio/simple_service.py +2 -2
  197. django_cfg/modules/django_twilio/templates/guide.md +266 -0
  198. django_cfg/modules/django_twilio/twilio_service.py +2 -2
  199. django_cfg/modules/django_unfold/__init__.py +69 -0
  200. django_cfg/modules/{unfold → django_unfold}/callbacks.py +23 -22
  201. django_cfg/modules/django_unfold/dashboard.py +278 -0
  202. django_cfg/modules/django_unfold/icons/README.md +145 -0
  203. django_cfg/modules/django_unfold/icons/__init__.py +12 -0
  204. django_cfg/modules/django_unfold/icons/constants.py +2851 -0
  205. django_cfg/modules/django_unfold/icons/generate_icons.py +486 -0
  206. django_cfg/modules/django_unfold/models/__init__.py +42 -0
  207. django_cfg/modules/django_unfold/models/config.py +601 -0
  208. django_cfg/modules/django_unfold/models/dashboard.py +206 -0
  209. django_cfg/modules/django_unfold/models/dropdown.py +40 -0
  210. django_cfg/modules/django_unfold/models/navigation.py +73 -0
  211. django_cfg/modules/django_unfold/models/tabs.py +25 -0
  212. django_cfg/modules/{unfold → django_unfold}/system_monitor.py +2 -2
  213. django_cfg/modules/django_unfold/utils.py +140 -0
  214. django_cfg/registry/__init__.py +23 -0
  215. django_cfg/registry/core.py +61 -0
  216. django_cfg/registry/exceptions.py +11 -0
  217. django_cfg/registry/modules.py +12 -0
  218. django_cfg/registry/services.py +26 -0
  219. django_cfg/registry/third_party.py +52 -0
  220. django_cfg/routing/__init__.py +19 -0
  221. django_cfg/routing/callbacks.py +198 -0
  222. django_cfg/routing/routers.py +48 -0
  223. django_cfg/templates/admin/layouts/dashboard_with_tabs.html +8 -9
  224. django_cfg/templatetags/__init__.py +0 -0
  225. django_cfg/templatetags/django_cfg.py +33 -0
  226. django_cfg/urls.py +33 -0
  227. django_cfg/utils/path_resolution.py +1 -1
  228. django_cfg/utils/smart_defaults.py +7 -61
  229. django_cfg/utils/toolkit.py +663 -0
  230. {django_cfg-1.1.81.dist-info → django_cfg-1.2.0.dist-info}/METADATA +83 -86
  231. django_cfg-1.2.0.dist-info/RECORD +441 -0
  232. django_cfg/apps/tasks/@docs/README.md +0 -195
  233. django_cfg/archive/django_sample.zip +0 -0
  234. django_cfg/models/unfold.py +0 -271
  235. django_cfg/modules/unfold/__init__.py +0 -29
  236. django_cfg/modules/unfold/dashboard.py +0 -318
  237. django_cfg/pyproject.toml +0 -370
  238. django_cfg/routers.py +0 -83
  239. django_cfg-1.1.81.dist-info/RECORD +0 -278
  240. /django_cfg/{exceptions.py → core/exceptions.py} +0 -0
  241. /django_cfg/modules/{unfold → django_unfold}/models.py +0 -0
  242. /django_cfg/modules/{unfold → django_unfold}/tailwind.py +0 -0
  243. /django_cfg/{version_check.py → utils/version_check.py} +0 -0
  244. {django_cfg-1.1.81.dist-info → django_cfg-1.2.0.dist-info}/WHEEL +0 -0
  245. {django_cfg-1.1.81.dist-info → django_cfg-1.2.0.dist-info}/entry_points.txt +0 -0
  246. {django_cfg-1.1.81.dist-info → django_cfg-1.2.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,266 @@
1
+ # 🚀 Django CFG Twilio Integration - Complete Setup Guide
2
+
3
+ ## 📋 Overview
4
+
5
+ Django CFG Twilio provides seamless integration for:
6
+ - 📱 **WhatsApp OTP** via Twilio Verify API
7
+ - 📱 **SMS OTP** via Twilio Verify API
8
+ - 📧 **Email OTP** via SendGrid
9
+ - 🔧 **Testing Suite** with management commands
10
+ - 📧 **HTML Email Templates** with customization
11
+
12
+ ## 🛠️ Quick Setup (5 minutes)
13
+
14
+ ### 1. Install Dependencies
15
+ ```bash
16
+ pip install django-cfg[twilio]
17
+ # or
18
+ poetry add django-cfg[twilio]
19
+ ```
20
+
21
+ ### 2. Configure Twilio Services
22
+
23
+ #### A. Create Twilio Verify Service
24
+ 1. Go to [Twilio Console > Verify > Services](https://console.twilio.com/us1/develop/verify/services)
25
+ 2. Click **Create new Service**
26
+ 3. Name: `YourApp OTP Service`
27
+ 4. **Enable channels**: WhatsApp ✅, SMS ✅
28
+ 5. Copy the **Service SID** (starts with `VA...`)
29
+
30
+ #### B. Get SendGrid API Key (Optional)
31
+ 1. Go to [SendGrid Console > API Keys](https://app.sendgrid.com/settings/api_keys)
32
+ 2. Create new API key with **Mail Send** permissions
33
+ 3. Copy the API key (starts with `SG.`)
34
+
35
+ ### 3. Update Configuration Files
36
+
37
+ #### `config.dev.yaml`
38
+ ```yaml
39
+ twilio:
40
+ account_sid: "AC_YOUR_ACCOUNT_SID"
41
+ auth_token: "YOUR_AUTH_TOKEN"
42
+ whatsapp_from: "+14155238886" # Twilio sandbox
43
+ sms_from: "+YOUR_SMS_NUMBER"
44
+ sendgrid_api_key: "SG.YOUR_SENDGRID_API_KEY"
45
+ verify_service_sid: "VA_YOUR_VERIFY_SERVICE_SID"
46
+ ```
47
+
48
+ #### `config.py`
49
+ ```python
50
+ from django_cfg.modules.django_twilio.models import SendGridConfig, TwilioVerifyConfig, TwilioChannelType
51
+
52
+ class YourProjectConfig(DjangoConfig):
53
+ # Admin emails for testing
54
+ admin_emails: List[str] = ["admin@yourdomain.com"]
55
+
56
+ # Twilio configuration
57
+ twilio: Optional[TwilioConfig] = TwilioConfig(
58
+ account_sid=env.twilio.account_sid,
59
+ auth_token=SecretStr(env.twilio.auth_token),
60
+
61
+ # Verify API for OTP
62
+ verify=TwilioVerifyConfig(
63
+ service_sid=env.twilio.verify_service_sid,
64
+ service_name=env.app.name,
65
+ default_channel=TwilioChannelType.WHATSAPP,
66
+ fallback_channels=[TwilioChannelType.SMS],
67
+ code_length=6,
68
+ ttl_seconds=600, # 10 minutes
69
+ max_attempts=5,
70
+ ) if env.twilio.verify_service_sid else None,
71
+
72
+ # SendGrid for email
73
+ sendgrid=SendGridConfig(
74
+ api_key=SecretStr(env.twilio.sendgrid_api_key),
75
+ from_email="noreply@yourdomain.com",
76
+ from_name=env.app.name,
77
+ default_subject=f"Your {env.app.name} verification code",
78
+ ) if env.twilio.sendgrid_api_key else None,
79
+ ) if env.twilio.account_sid and env.twilio.auth_token else None
80
+ ```
81
+
82
+ ## 🧪 Testing Everything
83
+
84
+ ### Quick Test Command
85
+ ```bash
86
+ # Test all services
87
+ python manage.py test_twilio --mode=all
88
+
89
+ # Test OTP only
90
+ python manage.py test_twilio --mode=test-otp --phone="+1234567890"
91
+
92
+ # Interactive mode
93
+ python manage.py test_twilio --interactive
94
+
95
+ # Check configuration
96
+ python manage.py test_twilio --mode=setup
97
+ ```
98
+
99
+ ### Expected Output
100
+ ```
101
+ 🚀 Django CFG Twilio Test Suite
102
+ ==================================================
103
+ 📧 Using admin email from config: admin@yourdomain.com
104
+
105
+ 🔧 Configuration Check
106
+ ------------------------------
107
+ ✅ Admin emails configured
108
+ ✅ Twilio configuration found
109
+ ✅ Verify API configured
110
+ ✅ SendGrid configured
111
+ ✅ Email configuration found
112
+
113
+ 🔐 Testing OTP Functionality
114
+ ------------------------------
115
+ 📱 Testing WhatsApp OTP to +1234567890...
116
+ ✅ OTP sent via WhatsApp to ***7890
117
+
118
+ 📧 Testing Email OTP to admin@yourdomain.com...
119
+ ✅ Email OTP sent (code: 123456)
120
+
121
+ 🎉 All tests completed!
122
+ ```
123
+
124
+ ## 🔌 API Usage
125
+
126
+ ### Basic OTP Request
127
+ ```python
128
+ from django_cfg.modules.django_twilio import send_whatsapp_otp, verify_otp
129
+
130
+ # Send WhatsApp OTP
131
+ success, message = send_whatsapp_otp("+1234567890")
132
+
133
+ # Verify OTP
134
+ is_valid, message = verify_otp("+1234567890", "123456")
135
+ ```
136
+
137
+ ### Email OTP
138
+ ```python
139
+ from django_cfg.modules.django_twilio import send_otp_email
140
+
141
+ # Send email OTP
142
+ success, message, otp_code = send_otp_email("user@example.com")
143
+ ```
144
+
145
+ ### REST API Endpoints
146
+ ```bash
147
+ # Request OTP
148
+ curl -X POST http://localhost:8000/api/accounts/otp/request/ \
149
+ -H "Content-Type: application/json" \
150
+ -d '{"identifier": "+1234567890", "channel": "phone"}'
151
+
152
+ # Verify OTP
153
+ curl -X POST http://localhost:8000/api/accounts/otp/verify/ \
154
+ -H "Content-Type: application/json" \
155
+ -d '{"identifier": "+1234567890", "otp": "123456", "channel": "phone"}'
156
+ ```
157
+
158
+ ## 📧 Email Templates
159
+
160
+ ### Template Structure
161
+ ```
162
+ django_cfg/modules/django_twilio/templates/
163
+ ├── email_otp_template.html # Main HTML template
164
+ ├── email_otp_test_data.json # Test data
165
+ └── email_otp_rendered.html # Generated preview
166
+ ```
167
+
168
+ ### Template Variables
169
+ - `{{app_name}}` - Your app name
170
+ - `{{user_name}}` - User's name
171
+ - `{{otp_code}}` - 6-digit OTP code
172
+ - `{{otp_link}}` - Verification link
173
+ - `{{expires_minutes}}` - Expiry time
174
+
175
+ ### Generate Templates
176
+ ```bash
177
+ python manage.py test_twilio --mode=generate-templates
178
+ ```
179
+
180
+ ## 🚨 Troubleshooting
181
+
182
+ ### Common Issues
183
+
184
+ #### 1. WhatsApp Not Working
185
+ ```
186
+ ❌ Error: Unable to create record: Delivery channel disabled: WHATSAPP
187
+ ```
188
+ **Solution**: Enable WhatsApp channel in [Twilio Console > Verify > Services](https://console.twilio.com/us1/develop/verify/services)
189
+
190
+ #### 2. SMS to International Numbers
191
+ ```
192
+ ❌ Error: Message cannot be sent with current 'To' and 'From' parameters
193
+ ```
194
+ **Solution**: Use Verify API (automatic) or upgrade Twilio account for international SMS
195
+
196
+ #### 3. SendGrid Not Working
197
+ ```
198
+ ❌ Error: SendGrid configuration not found
199
+ ```
200
+ **Solution**: Add `sendgrid_api_key` to your YAML config and enable in `config.py`
201
+
202
+ #### 4. Email Not Sending
203
+ ```
204
+ ❌ Error: Email backend not configured
205
+ ```
206
+ **Solution**: Check email configuration in `config.py` and ensure SMTP settings are correct
207
+
208
+ ### Debug Mode
209
+ ```python
210
+ # Enable detailed logging
211
+ twilio: TwilioConfig = TwilioConfig(
212
+ debug_logging=True, # Shows all API requests/responses
213
+ test_mode=True, # Uses test credentials
214
+ )
215
+ ```
216
+
217
+ ## 📱 Production Checklist
218
+
219
+ ### Before Going Live:
220
+
221
+ #### Twilio Setup
222
+ - [ ] **Account verified** and upgraded from trial
223
+ - [ ] **Phone numbers verified** for SMS
224
+ - [ ] **WhatsApp Business approved** (if using production WhatsApp)
225
+ - [ ] **Verify Service** created and channels enabled
226
+ - [ ] **Webhook URLs** configured (optional)
227
+
228
+ #### SendGrid Setup
229
+ - [ ] **Domain authentication** completed
230
+ - [ ] **Sender identity** verified
231
+ - [ ] **API key** with proper permissions
232
+ - [ ] **Email templates** tested and approved
233
+
234
+ #### Security
235
+ - [ ] **Environment variables** for sensitive data
236
+ - [ ] **Rate limiting** configured
237
+ - [ ] **Admin emails** updated for production
238
+ - [ ] **Error monitoring** setup (Sentry, etc.)
239
+
240
+ #### Testing
241
+ - [ ] **All OTP channels** tested with real numbers
242
+ - [ ] **Email delivery** tested with real addresses
243
+ - [ ] **Error handling** tested with invalid inputs
244
+ - [ ] **Load testing** completed for expected volume
245
+
246
+ ## 🔗 Useful Links
247
+
248
+ - [Twilio Console](https://console.twilio.com/)
249
+ - [Twilio Verify API Docs](https://www.twilio.com/docs/verify/api)
250
+ - [SendGrid Console](https://app.sendgrid.com/)
251
+ - [Django CFG Documentation](https://github.com/your-repo/django-cfg)
252
+
253
+ ## 💡 Pro Tips
254
+
255
+ 1. **Use Verify API** for professional OTP instead of custom solutions
256
+ 2. **Enable both WhatsApp and SMS** for better delivery rates
257
+ 3. **Test with real numbers** in different countries
258
+ 4. **Monitor delivery rates** in Twilio Console
259
+ 5. **Use admin_emails** for easy testing configuration
260
+ 6. **Keep templates simple** for better email client compatibility
261
+
262
+ ---
263
+
264
+ 🎉 **You're all set!** Your Django CFG Twilio integration is ready for production use.
265
+
266
+ For support, check the troubleshooting section or create an issue on GitHub.
@@ -17,7 +17,7 @@ from twilio.rest import Client
17
17
  from twilio.base.exceptions import TwilioException
18
18
  from asgiref.sync import sync_to_async
19
19
 
20
- from django_cfg.modules.base import BaseModule
20
+ from django_cfg.modules.base import BaseCfgModule
21
21
  from django_cfg.modules.django_twilio.models import TwilioConfig, TwilioVerifyConfig
22
22
  from django_cfg.modules.django_twilio.exceptions import (
23
23
  TwilioConfigurationError,
@@ -27,7 +27,7 @@ from django_cfg.modules.django_twilio.exceptions import (
27
27
  logger = logging.getLogger(__name__)
28
28
 
29
29
 
30
- class TwilioService(BaseModule):
30
+ class TwilioService(BaseCfgModule):
31
31
  """
32
32
  Unified Twilio service for WhatsApp, SMS, and OTP.
33
33
 
@@ -0,0 +1,69 @@
1
+ """
2
+ Django CFG Unfold Module
3
+
4
+ Provides complete Unfold admin interface integration with dashboard,
5
+ navigation, theming, and callback support.
6
+ """
7
+
8
+ from .dashboard import DashboardManager, get_dashboard_manager
9
+ from .callbacks import UnfoldCallbacks
10
+ from .system_monitor import SystemMonitor
11
+ from .tailwind import get_unfold_colors, get_css_variables
12
+ from .models import *
13
+
14
+ # Lazy initialization functions to avoid circular imports
15
+ def get_system_monitor() -> SystemMonitor:
16
+ """Get the global system monitor instance."""
17
+ global _system_monitor
18
+ if '_system_monitor' not in globals():
19
+ globals()['_system_monitor'] = SystemMonitor()
20
+ return globals()['_system_monitor']
21
+
22
+ def get_unfold_callbacks() -> UnfoldCallbacks:
23
+ """Get the global unfold callbacks instance."""
24
+ global _unfold_callbacks
25
+ if '_unfold_callbacks' not in globals():
26
+ globals()['_unfold_callbacks'] = UnfoldCallbacks()
27
+ return globals()['_unfold_callbacks']
28
+
29
+ # Export main components
30
+ __all__ = [
31
+ 'DashboardManager',
32
+ 'get_dashboard_manager',
33
+ 'UnfoldCallbacks',
34
+ 'get_unfold_callbacks',
35
+ 'SystemMonitor',
36
+ 'get_system_monitor',
37
+ 'get_unfold_colors',
38
+ 'get_css_variables',
39
+ # Models
40
+ 'UnfoldConfig',
41
+ 'UnfoldTheme',
42
+ 'UnfoldColors',
43
+ 'UnfoldSidebar',
44
+ 'UnfoldThemeConfig',
45
+ 'UnfoldDashboardConfig',
46
+ 'NavigationItem',
47
+ 'NavigationSection',
48
+ 'NavigationItemType',
49
+ 'SiteDropdownItem',
50
+ 'StatCard',
51
+ 'SystemHealthItem',
52
+ 'QuickAction',
53
+ 'DashboardWidget',
54
+ 'DashboardData',
55
+ 'ChartDataset',
56
+ 'ChartData',
57
+ 'TabConfiguration',
58
+ 'TabItem',
59
+ ]
60
+
61
+ # Version info
62
+ __version__ = '1.0.0'
63
+ __author__ = 'Django CFG Team'
64
+ __email__ = 'team@djangocfg.com'
65
+
66
+ # Module metadata
67
+ __title__ = 'Django CFG Unfold'
68
+ __description__ = 'Complete Unfold admin interface integration'
69
+ __url__ = 'https://github.com/djangocfg/django-cfg'
@@ -21,8 +21,9 @@ from django.db import connection
21
21
  from django.core.cache import cache
22
22
  from django.apps import apps
23
23
 
24
- from ..base import BaseModule
25
- from .models import DashboardData, StatCard, SystemHealthItem, QuickAction
24
+ from ..base import BaseCfgModule
25
+ from .models.dashboard import DashboardData, StatCard, SystemHealthItem, QuickAction
26
+ from .icons import Icons
26
27
 
27
28
  logger = logging.getLogger(__name__)
28
29
 
@@ -119,7 +120,7 @@ def get_user_admin_urls():
119
120
  }
120
121
 
121
122
 
122
- class UnfoldCallbacks(BaseModule):
123
+ class UnfoldCallbacks(BaseCfgModule):
123
124
  """
124
125
  Base Unfold dashboard callbacks with full system monitoring.
125
126
 
@@ -148,7 +149,7 @@ class UnfoldCallbacks(BaseModule):
148
149
  StatCard(
149
150
  title="Total Users",
150
151
  value=f"{total_users:,}",
151
- icon="people",
152
+ icon=Icons.PEOPLE,
152
153
  change=f"+{new_users_7d}" if new_users_7d > 0 else None,
153
154
  change_type="positive" if new_users_7d > 0 else "neutral",
154
155
  description="Registered users",
@@ -156,7 +157,7 @@ class UnfoldCallbacks(BaseModule):
156
157
  StatCard(
157
158
  title="Active Users",
158
159
  value=f"{active_users:,}",
159
- icon="person",
160
+ icon=Icons.PERSON,
160
161
  change=(
161
162
  f"{(active_users/total_users*100):.1f}%"
162
163
  if total_users > 0
@@ -170,14 +171,14 @@ class UnfoldCallbacks(BaseModule):
170
171
  StatCard(
171
172
  title="New This Week",
172
173
  value=f"{new_users_7d:,}",
173
- icon="person_add",
174
+ icon=Icons.PERSON_ADD,
174
175
  change_type="positive" if new_users_7d > 0 else "neutral",
175
176
  description="Last 7 days",
176
177
  ),
177
178
  StatCard(
178
179
  title="Staff Members",
179
180
  value=f"{staff_users:,}",
180
- icon="admin_panel_settings",
181
+ icon=Icons.ADMIN_PANEL_SETTINGS,
181
182
  change=(
182
183
  f"{(staff_users/total_users*100):.1f}%" if total_users > 0 else "0%"
183
184
  ),
@@ -191,7 +192,7 @@ class UnfoldCallbacks(BaseModule):
191
192
  StatCard(
192
193
  title="Users",
193
194
  value="N/A",
194
- icon="people",
195
+ icon=Icons.PEOPLE,
195
196
  description="Data unavailable",
196
197
  )
197
198
  ]
@@ -316,7 +317,7 @@ class UnfoldCallbacks(BaseModule):
316
317
  QuickAction(
317
318
  title="Add User",
318
319
  description="Create new user account",
319
- icon="person_add",
320
+ icon=Icons.PERSON_ADD,
320
321
  link=user_admin_urls["add"],
321
322
  color="primary",
322
323
  category="admin",
@@ -324,16 +325,16 @@ class UnfoldCallbacks(BaseModule):
324
325
  QuickAction(
325
326
  title="Support Tickets",
326
327
  description="Manage support tickets",
327
- icon="support_agent",
328
+ icon=Icons.SUPPORT_AGENT,
328
329
  link="admin:django_cfg_support_ticket_changelist",
329
- color="info",
330
+ color="primary",
330
331
  category="support",
331
332
  ),
332
333
  QuickAction(
333
334
  title="Health Check",
334
335
  description="System health status",
335
- icon="health_and_safety",
336
- link="django_cfg_health",
336
+ icon=Icons.HEALTH_AND_SAFETY,
337
+ link="/cfg/health/",
337
338
  color="success",
338
339
  category="system",
339
340
  ),
@@ -382,7 +383,7 @@ class UnfoldCallbacks(BaseModule):
382
383
  StatCard(
383
384
  title="Total Tickets",
384
385
  value=f"{total_tickets:,}",
385
- icon="support_agent",
386
+ icon=Icons.SUPPORT_AGENT,
386
387
  change=f"+{new_tickets_7d}" if new_tickets_7d > 0 else None,
387
388
  change_type="positive" if new_tickets_7d > 0 else "neutral",
388
389
  description="All support tickets",
@@ -390,7 +391,7 @@ class UnfoldCallbacks(BaseModule):
390
391
  StatCard(
391
392
  title="Open Tickets",
392
393
  value=f"{open_tickets:,}",
393
- icon="pending",
394
+ icon=Icons.PENDING,
394
395
  change=(
395
396
  f"{(open_tickets/total_tickets*100):.1f}%"
396
397
  if total_tickets > 0
@@ -406,7 +407,7 @@ class UnfoldCallbacks(BaseModule):
406
407
  StatCard(
407
408
  title="Resolved",
408
409
  value=f"{resolved_tickets:,}",
409
- icon="check_circle",
410
+ icon=Icons.CHECK_CIRCLE,
410
411
  change=(
411
412
  f"{(resolved_tickets/total_tickets*100):.1f}%"
412
413
  if total_tickets > 0
@@ -418,7 +419,7 @@ class UnfoldCallbacks(BaseModule):
418
419
  StatCard(
419
420
  title="New This Week",
420
421
  value=f"{new_tickets_7d:,}",
421
- icon="new_releases",
422
+ icon=Icons.NEW_RELEASES,
422
423
  change_type="positive" if new_tickets_7d > 0 else "neutral",
423
424
  description="Last 7 days",
424
425
  ),
@@ -429,7 +430,7 @@ class UnfoldCallbacks(BaseModule):
429
430
  StatCard(
430
431
  title="Support",
431
432
  value="N/A",
432
- icon="support_agent",
433
+ icon=Icons.SUPPORT_AGENT,
433
434
  description="Data unavailable",
434
435
  )
435
436
  ]
@@ -707,14 +708,14 @@ class UnfoldCallbacks(BaseModule):
707
708
  environment=getattr(settings, "ENVIRONMENT", "development"),
708
709
  )
709
710
 
710
- # Convert to template context (keeping Pydantic validation)
711
- cards_data = [card.model_dump() for card in dashboard_data.stat_cards]
711
+ # Convert to template context (using to_dict for Unfold compatibility)
712
+ cards_data = [card.to_dict() for card in dashboard_data.stat_cards]
712
713
 
713
714
  context.update({
714
715
  # Statistics cards
715
716
  "cards": cards_data,
716
- "user_stats": [card.model_dump() for card in user_stats],
717
- "support_stats": [card.model_dump() for card in support_stats],
717
+ "user_stats": [card.to_dict() for card in user_stats],
718
+ "support_stats": [card.to_dict() for card in support_stats],
718
719
  # System health (convert to dict for template)
719
720
  "system_health": {
720
721
  item.component + "_status": item.status