django-cfg 1.3.9__py3-none-any.whl → 1.3.11__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 (187) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/payments/admin/networks_admin.py +12 -1
  3. django_cfg/apps/payments/admin/payments_admin.py +13 -0
  4. django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +62 -14
  5. django_cfg/apps/payments/admin_interface/templates/payments/components/payment_card.html +121 -0
  6. django_cfg/apps/payments/admin_interface/templates/payments/components/payment_qr_code.html +95 -0
  7. django_cfg/apps/payments/admin_interface/templates/payments/components/progress_bar.html +37 -0
  8. django_cfg/apps/payments/admin_interface/templates/payments/components/provider_stats.html +60 -0
  9. django_cfg/apps/payments/admin_interface/templates/payments/components/status_badge.html +41 -0
  10. django_cfg/apps/payments/admin_interface/templates/payments/components/status_overview.html +83 -0
  11. django_cfg/apps/payments/admin_interface/templates/payments/payment_detail.html +363 -0
  12. django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +33 -3
  13. django_cfg/apps/payments/admin_interface/views/api/payments.py +102 -0
  14. django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +96 -45
  15. django_cfg/apps/payments/admin_interface/views/forms.py +5 -1
  16. django_cfg/apps/payments/config/__init__.py +14 -15
  17. django_cfg/apps/payments/config/django_cfg_integration.py +59 -1
  18. django_cfg/apps/payments/config/helpers.py +8 -13
  19. django_cfg/apps/payments/migrations/0001_initial.py +33 -46
  20. django_cfg/apps/payments/migrations/0002_rename_payments_un_user_id_7f6e79_idx_payments_un_user_id_8ce187_idx_and_more.py +46 -0
  21. django_cfg/apps/payments/migrations/0003_universalpayment_status_changed_at.py +25 -0
  22. django_cfg/apps/payments/models/managers/payment_managers.py +142 -25
  23. django_cfg/apps/payments/models/payments.py +94 -0
  24. django_cfg/apps/payments/services/core/base.py +4 -4
  25. django_cfg/apps/payments/services/core/payment_service.py +265 -38
  26. django_cfg/apps/payments/services/providers/base.py +209 -3
  27. django_cfg/apps/payments/services/providers/models/__init__.py +2 -0
  28. django_cfg/apps/payments/services/providers/models/base.py +25 -2
  29. django_cfg/apps/payments/services/providers/nowpayments/models.py +2 -2
  30. django_cfg/apps/payments/services/providers/nowpayments/provider.py +57 -9
  31. django_cfg/apps/payments/services/providers/registry.py +5 -5
  32. django_cfg/apps/payments/services/types/requests.py +19 -7
  33. django_cfg/apps/payments/signals/payment_signals.py +31 -2
  34. django_cfg/apps/payments/static/payments/js/api-client.js +6 -1
  35. django_cfg/apps/payments/static/payments/js/payment-detail.js +167 -0
  36. django_cfg/apps/payments/static/payments/js/payment-form.js +35 -26
  37. django_cfg/apps/payments/templatetags/payment_tags.py +8 -0
  38. django_cfg/apps/payments/urls.py +3 -2
  39. django_cfg/apps/payments/views/api/currencies.py +3 -0
  40. django_cfg/apps/payments/views/serializers/currencies.py +18 -5
  41. django_cfg/apps/tasks/admin/tasks_admin.py +2 -2
  42. django_cfg/apps/tasks/static/tasks/css/dashboard.css +68 -217
  43. django_cfg/apps/tasks/static/tasks/js/api.js +40 -84
  44. django_cfg/apps/tasks/static/tasks/js/components/DataManager.js +24 -0
  45. django_cfg/apps/tasks/static/tasks/js/components/TabManager.js +85 -0
  46. django_cfg/apps/tasks/static/tasks/js/components/TaskRenderer.js +216 -0
  47. django_cfg/apps/tasks/static/tasks/js/dashboard/main.mjs +245 -0
  48. django_cfg/apps/tasks/static/tasks/js/dashboard/overview.mjs +123 -0
  49. django_cfg/apps/tasks/static/tasks/js/dashboard/queues.mjs +120 -0
  50. django_cfg/apps/tasks/static/tasks/js/dashboard/tasks.mjs +350 -0
  51. django_cfg/apps/tasks/static/tasks/js/dashboard/workers.mjs +169 -0
  52. django_cfg/apps/tasks/tasks/__init__.py +10 -0
  53. django_cfg/apps/tasks/tasks/demo_tasks.py +133 -0
  54. django_cfg/apps/tasks/templates/tasks/components/management_actions.html +42 -45
  55. django_cfg/apps/tasks/templates/tasks/components/{status_cards.html → overview_content.html} +30 -11
  56. django_cfg/apps/tasks/templates/tasks/components/queues_content.html +19 -0
  57. django_cfg/apps/tasks/templates/tasks/components/tab_navigation.html +16 -10
  58. django_cfg/apps/tasks/templates/tasks/components/tasks_content.html +51 -0
  59. django_cfg/apps/tasks/templates/tasks/components/workers_content.html +30 -0
  60. django_cfg/apps/tasks/templates/tasks/layout/base.html +117 -0
  61. django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +82 -0
  62. django_cfg/apps/tasks/templates/tasks/partials/task_row_template.html +40 -0
  63. django_cfg/apps/tasks/templates/tasks/widgets/task_filters.html +37 -0
  64. django_cfg/apps/tasks/templates/tasks/widgets/task_footer.html +41 -0
  65. django_cfg/apps/tasks/templates/tasks/widgets/task_table.html +50 -0
  66. django_cfg/apps/tasks/urls.py +2 -2
  67. django_cfg/apps/tasks/urls_admin.py +2 -2
  68. django_cfg/apps/tasks/utils/__init__.py +1 -0
  69. django_cfg/apps/tasks/utils/simulator.py +356 -0
  70. django_cfg/apps/tasks/views/__init__.py +16 -0
  71. django_cfg/apps/tasks/views/api.py +569 -0
  72. django_cfg/apps/tasks/views/dashboard.py +58 -0
  73. django_cfg/core/integration/__init__.py +21 -0
  74. django_cfg/management/commands/rundramatiq_simulator.py +430 -0
  75. django_cfg/models/constance.py +0 -11
  76. django_cfg/models/payments.py +137 -3
  77. django_cfg/modules/django_tasks.py +54 -21
  78. django_cfg/registry/core.py +4 -9
  79. django_cfg/template_archive/django_sample.zip +0 -0
  80. {django_cfg-1.3.9.dist-info → django_cfg-1.3.11.dist-info}/METADATA +2 -2
  81. {django_cfg-1.3.9.dist-info → django_cfg-1.3.11.dist-info}/RECORD +84 -152
  82. django_cfg/apps/payments/config/constance/__init__.py +0 -22
  83. django_cfg/apps/payments/config/constance/config_service.py +0 -123
  84. django_cfg/apps/payments/config/constance/fields.py +0 -69
  85. django_cfg/apps/payments/config/constance/settings.py +0 -160
  86. django_cfg/apps/payments/migrations/0002_currency_usd_rate_currency_usd_rate_updated_at.py +0 -26
  87. django_cfg/apps/payments/migrations/0003_remove_provider_currency_fields.py +0 -28
  88. django_cfg/apps/payments/migrations/0004_add_reserved_usd_field.py +0 -30
  89. django_cfg/apps/tasks/static/tasks/js/dashboard.js +0 -614
  90. django_cfg/apps/tasks/static/tasks/js/modals.js +0 -452
  91. django_cfg/apps/tasks/static/tasks/js/notifications.js +0 -144
  92. django_cfg/apps/tasks/static/tasks/js/task-monitor.js +0 -454
  93. django_cfg/apps/tasks/static/tasks/js/theme.js +0 -77
  94. django_cfg/apps/tasks/templates/tasks/base.html +0 -96
  95. django_cfg/apps/tasks/templates/tasks/components/info_cards.html +0 -85
  96. django_cfg/apps/tasks/templates/tasks/components/overview_tab.html +0 -22
  97. django_cfg/apps/tasks/templates/tasks/components/queues_tab.html +0 -19
  98. django_cfg/apps/tasks/templates/tasks/components/task_details_modal.html +0 -103
  99. django_cfg/apps/tasks/templates/tasks/components/tasks_tab.html +0 -32
  100. django_cfg/apps/tasks/templates/tasks/components/workers_tab.html +0 -29
  101. django_cfg/apps/tasks/templates/tasks/dashboard.html +0 -29
  102. django_cfg/apps/tasks/views.py +0 -461
  103. django_cfg/management/commands/app_agent_diagnose.py +0 -470
  104. django_cfg/management/commands/app_agent_generate.py +0 -342
  105. django_cfg/management/commands/app_agent_info.py +0 -308
  106. django_cfg/management/commands/auto_generate.py +0 -486
  107. django_cfg/modules/django_app_agent/__init__.py +0 -87
  108. django_cfg/modules/django_app_agent/agents/__init__.py +0 -40
  109. django_cfg/modules/django_app_agent/agents/base/__init__.py +0 -24
  110. django_cfg/modules/django_app_agent/agents/base/agent.py +0 -354
  111. django_cfg/modules/django_app_agent/agents/base/context.py +0 -236
  112. django_cfg/modules/django_app_agent/agents/base/executor.py +0 -430
  113. django_cfg/modules/django_app_agent/agents/generation/__init__.py +0 -12
  114. django_cfg/modules/django_app_agent/agents/generation/app_generator/__init__.py +0 -15
  115. django_cfg/modules/django_app_agent/agents/generation/app_generator/config_validator.py +0 -147
  116. django_cfg/modules/django_app_agent/agents/generation/app_generator/main.py +0 -99
  117. django_cfg/modules/django_app_agent/agents/generation/app_generator/models.py +0 -32
  118. django_cfg/modules/django_app_agent/agents/generation/app_generator/prompt_manager.py +0 -290
  119. django_cfg/modules/django_app_agent/agents/interfaces.py +0 -376
  120. django_cfg/modules/django_app_agent/core/__init__.py +0 -33
  121. django_cfg/modules/django_app_agent/core/config.py +0 -300
  122. django_cfg/modules/django_app_agent/core/exceptions.py +0 -359
  123. django_cfg/modules/django_app_agent/models/__init__.py +0 -71
  124. django_cfg/modules/django_app_agent/models/base.py +0 -283
  125. django_cfg/modules/django_app_agent/models/context.py +0 -496
  126. django_cfg/modules/django_app_agent/models/enums.py +0 -481
  127. django_cfg/modules/django_app_agent/models/requests.py +0 -500
  128. django_cfg/modules/django_app_agent/models/responses.py +0 -585
  129. django_cfg/modules/django_app_agent/pytest.ini +0 -6
  130. django_cfg/modules/django_app_agent/services/__init__.py +0 -42
  131. django_cfg/modules/django_app_agent/services/app_generator/__init__.py +0 -30
  132. django_cfg/modules/django_app_agent/services/app_generator/ai_integration.py +0 -133
  133. django_cfg/modules/django_app_agent/services/app_generator/context.py +0 -40
  134. django_cfg/modules/django_app_agent/services/app_generator/main.py +0 -202
  135. django_cfg/modules/django_app_agent/services/app_generator/structure.py +0 -316
  136. django_cfg/modules/django_app_agent/services/app_generator/validation.py +0 -125
  137. django_cfg/modules/django_app_agent/services/base.py +0 -437
  138. django_cfg/modules/django_app_agent/services/context_builder/__init__.py +0 -34
  139. django_cfg/modules/django_app_agent/services/context_builder/code_extractor.py +0 -141
  140. django_cfg/modules/django_app_agent/services/context_builder/context_generator.py +0 -276
  141. django_cfg/modules/django_app_agent/services/context_builder/main.py +0 -272
  142. django_cfg/modules/django_app_agent/services/context_builder/models.py +0 -40
  143. django_cfg/modules/django_app_agent/services/context_builder/pattern_analyzer.py +0 -85
  144. django_cfg/modules/django_app_agent/services/project_scanner/__init__.py +0 -31
  145. django_cfg/modules/django_app_agent/services/project_scanner/app_discovery.py +0 -311
  146. django_cfg/modules/django_app_agent/services/project_scanner/main.py +0 -221
  147. django_cfg/modules/django_app_agent/services/project_scanner/models.py +0 -59
  148. django_cfg/modules/django_app_agent/services/project_scanner/pattern_detection.py +0 -94
  149. django_cfg/modules/django_app_agent/services/questioning_service/__init__.py +0 -28
  150. django_cfg/modules/django_app_agent/services/questioning_service/main.py +0 -273
  151. django_cfg/modules/django_app_agent/services/questioning_service/models.py +0 -111
  152. django_cfg/modules/django_app_agent/services/questioning_service/question_generator.py +0 -251
  153. django_cfg/modules/django_app_agent/services/questioning_service/response_processor.py +0 -347
  154. django_cfg/modules/django_app_agent/services/questioning_service/session_manager.py +0 -356
  155. django_cfg/modules/django_app_agent/services/report_service.py +0 -332
  156. django_cfg/modules/django_app_agent/services/template_manager/__init__.py +0 -18
  157. django_cfg/modules/django_app_agent/services/template_manager/jinja_engine.py +0 -236
  158. django_cfg/modules/django_app_agent/services/template_manager/main.py +0 -159
  159. django_cfg/modules/django_app_agent/services/template_manager/models.py +0 -36
  160. django_cfg/modules/django_app_agent/services/template_manager/template_loader.py +0 -100
  161. django_cfg/modules/django_app_agent/services/template_manager/templates/admin.py.j2 +0 -105
  162. django_cfg/modules/django_app_agent/services/template_manager/templates/apps.py.j2 +0 -31
  163. django_cfg/modules/django_app_agent/services/template_manager/templates/cfg_config.py.j2 +0 -44
  164. django_cfg/modules/django_app_agent/services/template_manager/templates/cfg_module.py.j2 +0 -81
  165. django_cfg/modules/django_app_agent/services/template_manager/templates/forms.py.j2 +0 -107
  166. django_cfg/modules/django_app_agent/services/template_manager/templates/models.py.j2 +0 -139
  167. django_cfg/modules/django_app_agent/services/template_manager/templates/serializers.py.j2 +0 -91
  168. django_cfg/modules/django_app_agent/services/template_manager/templates/tests.py.j2 +0 -195
  169. django_cfg/modules/django_app_agent/services/template_manager/templates/urls.py.j2 +0 -35
  170. django_cfg/modules/django_app_agent/services/template_manager/templates/views.py.j2 +0 -211
  171. django_cfg/modules/django_app_agent/services/template_manager/variable_processor.py +0 -200
  172. django_cfg/modules/django_app_agent/services/validation_service/__init__.py +0 -25
  173. django_cfg/modules/django_app_agent/services/validation_service/django_validator.py +0 -333
  174. django_cfg/modules/django_app_agent/services/validation_service/main.py +0 -242
  175. django_cfg/modules/django_app_agent/services/validation_service/models.py +0 -66
  176. django_cfg/modules/django_app_agent/services/validation_service/quality_validator.py +0 -352
  177. django_cfg/modules/django_app_agent/services/validation_service/security_validator.py +0 -272
  178. django_cfg/modules/django_app_agent/services/validation_service/syntax_validator.py +0 -203
  179. django_cfg/modules/django_app_agent/ui/__init__.py +0 -25
  180. django_cfg/modules/django_app_agent/ui/cli.py +0 -419
  181. django_cfg/modules/django_app_agent/ui/rich_components.py +0 -622
  182. django_cfg/modules/django_app_agent/utils/__init__.py +0 -38
  183. django_cfg/modules/django_app_agent/utils/logging.py +0 -360
  184. django_cfg/modules/django_app_agent/utils/validation.py +0 -417
  185. {django_cfg-1.3.9.dist-info → django_cfg-1.3.11.dist-info}/WHEEL +0 -0
  186. {django_cfg-1.3.9.dist-info → django_cfg-1.3.11.dist-info}/entry_points.txt +0 -0
  187. {django_cfg-1.3.9.dist-info → django_cfg-1.3.11.dist-info}/licenses/LICENSE +0 -0
@@ -1,470 +0,0 @@
1
- """
2
- Django management command for project diagnosis.
3
-
4
- This command provides AI-powered diagnosis of Django/Django-cfg projects
5
- to help identify and solve common problems.
6
- """
7
-
8
- import asyncio
9
- import sys
10
- from pathlib import Path
11
- from typing import List, Optional
12
-
13
- from django.core.management.base import BaseCommand, CommandError
14
- from django.conf import settings
15
-
16
- try:
17
- from django_cfg.modules.django_app_agent.services import (
18
- ProjectScannerService,
19
- ContextBuilderService
20
- )
21
- from django_cfg.modules.django_app_agent.models.requests import (
22
- ProjectScanRequest,
23
- ContextBuildRequest
24
- )
25
- from django_cfg.modules.django_app_agent.core.exceptions import DjangoAppAgentError
26
- from django_cfg.modules.django_app_agent.core.config import AgentConfig
27
- from django_cfg.modules.django_app_agent.utils.logging import get_logger
28
- from django_cfg.modules.django_app_agent.ui.rich_components import (
29
- RichProgressTracker,
30
- InteractiveQuestioningUI
31
- )
32
- except ImportError as e:
33
- print(f"Error importing django_app_agent module: {e}")
34
- print("Make sure the django_app_agent module is properly installed.")
35
- sys.exit(1)
36
-
37
-
38
- class Command(BaseCommand):
39
- """Django management command for project diagnosis."""
40
-
41
- help = "Diagnose problems in Django/Django-cfg projects using AI (Django App Agent)"
42
-
43
- def add_arguments(self, parser):
44
- """Add command line arguments."""
45
-
46
- parser.add_argument(
47
- '--app',
48
- type=str,
49
- help='Specific application name to diagnose'
50
- )
51
-
52
- parser.add_argument(
53
- '--category',
54
- choices=[
55
- 'database', 'views', 'templates', 'static',
56
- 'admin', 'auth', 'performance', 'deployment',
57
- 'config', 'security', 'testing', 'other'
58
- ],
59
- help='Problem category to focus on'
60
- )
61
-
62
- parser.add_argument(
63
- '--description',
64
- type=str,
65
- help='Description of the problem you are experiencing'
66
- )
67
-
68
- parser.add_argument(
69
- '--severity',
70
- choices=['low', 'medium', 'high', 'critical'],
71
- default='medium',
72
- help='Problem severity level (default: medium)'
73
- )
74
-
75
- parser.add_argument(
76
- '--interactive',
77
- action='store_true',
78
- default=True,
79
- help='Enable interactive diagnosis mode (default: True)'
80
- )
81
-
82
- parser.add_argument(
83
- '--non-interactive',
84
- action='store_true',
85
- help='Disable interactive mode'
86
- )
87
-
88
- parser.add_argument(
89
- '--scan-only',
90
- action='store_true',
91
- help='Only scan the project without AI diagnosis'
92
- )
93
-
94
- parser.add_argument(
95
- '--output-format',
96
- choices=['text', 'json', 'markdown'],
97
- default='text',
98
- help='Output format for diagnosis results (default: text)'
99
- )
100
-
101
- parser.add_argument(
102
- '--save-report',
103
- type=str,
104
- help='Save diagnosis report to specified file'
105
- )
106
-
107
- parser.add_argument(
108
- '--verbose',
109
- action='store_true',
110
- help='Enable verbose output'
111
- )
112
-
113
- def handle(self, *args, **options):
114
- """Handle the command execution."""
115
-
116
- try:
117
- # Initialize logger
118
- logger = get_logger("management.commands.diagnose_project")
119
-
120
- # Determine interactive mode
121
- interactive = options.get('interactive', True) and not options.get('non_interactive', False)
122
-
123
- # Show welcome message
124
- self.stdout.write(
125
- self.style.SUCCESS("šŸ” Django Project Diagnostic Tool")
126
- )
127
- self.stdout.write("Analyzing your project for potential issues...\n")
128
-
129
- # Run diagnosis
130
- if interactive and not options.get('description'):
131
- return self._run_interactive_diagnosis(options)
132
- else:
133
- return self._run_direct_diagnosis(options)
134
-
135
- except DjangoAppAgentError as e:
136
- logger.error(f"Diagnosis failed: {e}")
137
- raise CommandError(f"Diagnosis failed: {e}")
138
- except Exception as e:
139
- logger.error(f"Unexpected error: {e}")
140
- raise CommandError(f"Unexpected error: {e}")
141
-
142
- def _run_interactive_diagnosis(self, options):
143
- """Run interactive diagnosis with user prompts."""
144
- try:
145
- self.stdout.write("šŸ¤– Starting interactive diagnosis...\n")
146
-
147
- # Gather information interactively
148
- problem_info = self._gather_problem_info()
149
-
150
- # Merge with command line options
151
- diagnosis_options = {**options, **problem_info}
152
-
153
- # Run diagnosis
154
- return self._run_diagnosis_process(diagnosis_options)
155
-
156
- except KeyboardInterrupt:
157
- self.stdout.write("\nšŸ›‘ Diagnosis cancelled by user")
158
- except Exception as e:
159
- raise CommandError(f"Interactive diagnosis failed: {e}")
160
-
161
- def _run_direct_diagnosis(self, options):
162
- """Run diagnosis with provided parameters."""
163
- return self._run_diagnosis_process(options)
164
-
165
- def _gather_problem_info(self):
166
- """Gather problem information interactively."""
167
- problem_info = {}
168
-
169
- # Ask for problem description
170
- self.stdout.write("šŸ“ Please describe the problem you're experiencing:")
171
- description = input("Description: ").strip()
172
- if description:
173
- problem_info['description'] = description
174
-
175
- # Ask for category
176
- self.stdout.write("\nšŸ“‚ What category best describes your problem?")
177
- categories = [
178
- 'database', 'views', 'templates', 'static',
179
- 'admin', 'auth', 'performance', 'deployment',
180
- 'config', 'security', 'testing', 'other'
181
- ]
182
-
183
- for i, category in enumerate(categories, 1):
184
- self.stdout.write(f" {i}. {category}")
185
-
186
- try:
187
- choice = input("\nEnter number (or press Enter to skip): ").strip()
188
- if choice and choice.isdigit():
189
- idx = int(choice) - 1
190
- if 0 <= idx < len(categories):
191
- problem_info['category'] = categories[idx]
192
- except (ValueError, IndexError):
193
- pass
194
-
195
- # Ask for specific app
196
- self.stdout.write("\nšŸŽÆ Is this problem specific to a particular app?")
197
- app_name = input("App name (or press Enter to skip): ").strip()
198
- if app_name:
199
- problem_info['app'] = app_name
200
-
201
- # Ask for severity
202
- self.stdout.write("\nāš ļø How severe is this problem?")
203
- severities = ['low', 'medium', 'high', 'critical']
204
- for i, severity in enumerate(severities, 1):
205
- self.stdout.write(f" {i}. {severity}")
206
-
207
- try:
208
- choice = input("\nEnter number (default: 2 for medium): ").strip()
209
- if choice and choice.isdigit():
210
- idx = int(choice) - 1
211
- if 0 <= idx < len(severities):
212
- problem_info['severity'] = severities[idx]
213
- else:
214
- problem_info['severity'] = 'medium'
215
- except (ValueError, IndexError):
216
- problem_info['severity'] = 'medium'
217
-
218
- return problem_info
219
-
220
- def _run_diagnosis_process(self, options):
221
- """Run the actual diagnosis process."""
222
- try:
223
- # Initialize configuration
224
- config = AgentConfig()
225
- logger = get_logger("management.commands.diagnose_project")
226
-
227
- # Show current configuration
228
- if options.get('verbose'):
229
- self.stdout.write(f"šŸ”§ Project root: {settings.BASE_DIR}")
230
- if options.get('app'):
231
- self.stdout.write(f"šŸŽÆ Target app: {options['app']}")
232
- if options.get('category'):
233
- self.stdout.write(f"šŸ“‚ Category: {options['category']}")
234
- if options.get('description'):
235
- self.stdout.write(f"šŸ“ Problem: {options['description']}")
236
- self.stdout.write("")
237
-
238
- # Step 1: Scan project
239
- self.stdout.write("šŸ” Step 1: Scanning project structure...")
240
- scan_result = self._scan_project(options)
241
-
242
- if options.get('scan_only'):
243
- return self._display_scan_results(scan_result, options)
244
-
245
- # Step 2: Build context
246
- self.stdout.write("🧠 Step 2: Building project context...")
247
- context = self._build_context(scan_result, options)
248
-
249
- # Step 3: AI Diagnosis (placeholder for now)
250
- self.stdout.write("šŸ¤– Step 3: Running AI diagnosis...")
251
- diagnosis = self._run_ai_diagnosis(context, options)
252
-
253
- # Step 4: Display results
254
- self.stdout.write("šŸ“Š Step 4: Generating diagnosis report...")
255
- return self._display_diagnosis_results(diagnosis, options)
256
-
257
- except Exception as e:
258
- raise CommandError(f"Diagnosis process failed: {e}")
259
-
260
- def _scan_project(self, options):
261
- """Scan the project structure."""
262
- try:
263
- # Initialize scanner service
264
- config = AgentConfig()
265
- logger = get_logger("project_scanner")
266
-
267
- scanner = ProjectScannerService(config, logger)
268
-
269
- # Create scan request
270
- request = ProjectScanRequest(
271
- project_root=str(settings.BASE_DIR),
272
- target_app=options.get('app'),
273
- scan_depth=3,
274
- include_tests=True,
275
- include_migrations=True
276
- )
277
-
278
- # Run scan (async)
279
- if sys.platform == 'win32':
280
- asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
281
-
282
- result = asyncio.run(scanner.process(request))
283
- return result
284
-
285
- except Exception as e:
286
- raise CommandError(f"Project scan failed: {e}")
287
-
288
- def _build_context(self, scan_result, options):
289
- """Build project context for diagnosis."""
290
- try:
291
- # Initialize context builder
292
- config = AgentConfig()
293
- logger = get_logger("context_builder")
294
-
295
- builder = ContextBuilderService(config, logger)
296
-
297
- # Create context request
298
- request = ContextBuildRequest(
299
- project_root=str(settings.BASE_DIR),
300
- scan_result=scan_result,
301
- focus_area=options.get('category'),
302
- target_app=options.get('app')
303
- )
304
-
305
- # Build context (async)
306
- result = asyncio.run(builder.process(request))
307
- return result
308
-
309
- except Exception as e:
310
- raise CommandError(f"Context building failed: {e}")
311
-
312
- def _run_ai_diagnosis(self, context, options):
313
- """Run AI-powered diagnosis (placeholder implementation)."""
314
- # This is a placeholder implementation
315
- # In the real implementation, this would use AI agents
316
-
317
- diagnosis = {
318
- 'status': 'completed',
319
- 'findings': [
320
- {
321
- 'category': options.get('category', 'general'),
322
- 'severity': options.get('severity', 'medium'),
323
- 'title': 'Project Structure Analysis',
324
- 'description': 'Basic project structure appears to be well-organized.',
325
- 'recommendations': [
326
- 'Consider adding more comprehensive tests',
327
- 'Review security settings for production deployment',
328
- 'Optimize database queries for better performance'
329
- ]
330
- }
331
- ],
332
- 'summary': 'Project analysis completed. No critical issues found.',
333
- 'confidence': 0.75
334
- }
335
-
336
- return diagnosis
337
-
338
- def _display_scan_results(self, scan_result, options):
339
- """Display project scan results."""
340
- self.stdout.write(self.style.SUCCESS("\nšŸ“Š Project Scan Results"))
341
- self.stdout.write("=" * 50)
342
-
343
- if hasattr(scan_result, 'project_info'):
344
- info = scan_result.project_info
345
- self.stdout.write(f"Project Name: {info.get('name', 'Unknown')}")
346
- self.stdout.write(f"Django Version: {info.get('django_version', 'Unknown')}")
347
- self.stdout.write(f"Total Apps: {info.get('total_apps', 0)}")
348
-
349
- if hasattr(scan_result, 'apps') and scan_result.apps:
350
- self.stdout.write(f"\nšŸ“± Applications ({len(scan_result.apps)}):")
351
- for app in scan_result.apps:
352
- self.stdout.write(f" • {app.name} ({app.path})")
353
-
354
- self.stdout.write(f"\nāœ… Scan completed successfully!")
355
-
356
- def _display_diagnosis_results(self, diagnosis, options):
357
- """Display diagnosis results."""
358
- self.stdout.write(self.style.SUCCESS("\nšŸŽÆ Diagnosis Results"))
359
- self.stdout.write("=" * 50)
360
-
361
- # Summary
362
- self.stdout.write(f"Status: {diagnosis['status']}")
363
- self.stdout.write(f"Summary: {diagnosis['summary']}")
364
- self.stdout.write(f"Confidence: {diagnosis['confidence']:.0%}")
365
-
366
- # Findings
367
- if diagnosis.get('findings'):
368
- self.stdout.write(f"\nšŸ” Findings ({len(diagnosis['findings'])}):")
369
-
370
- for i, finding in enumerate(diagnosis['findings'], 1):
371
- severity_style = {
372
- 'low': self.style.SUCCESS,
373
- 'medium': self.style.WARNING,
374
- 'high': self.style.ERROR,
375
- 'critical': self.style.ERROR
376
- }.get(finding['severity'], self.style.WARNING)
377
-
378
- self.stdout.write(f"\n{i}. {finding['title']}")
379
- self.stdout.write(severity_style(f" Severity: {finding['severity'].upper()}"))
380
- self.stdout.write(f" Category: {finding['category']}")
381
- self.stdout.write(f" Description: {finding['description']}")
382
-
383
- if finding.get('recommendations'):
384
- self.stdout.write(" Recommendations:")
385
- for rec in finding['recommendations']:
386
- self.stdout.write(f" • {rec}")
387
-
388
- # Save report if requested
389
- if options.get('save_report'):
390
- self._save_diagnosis_report(diagnosis, options)
391
-
392
- self.stdout.write(f"\nāœ… Diagnosis completed!")
393
-
394
- def _save_diagnosis_report(self, diagnosis, options):
395
- """Save diagnosis report to file."""
396
- try:
397
- report_path = Path(options['save_report'])
398
-
399
- # Generate report content based on format
400
- format_type = options.get('output_format', 'text')
401
-
402
- if format_type == 'json':
403
- import json
404
- content = json.dumps(diagnosis, indent=2)
405
- elif format_type == 'markdown':
406
- content = self._generate_markdown_report(diagnosis)
407
- else: # text
408
- content = self._generate_text_report(diagnosis)
409
-
410
- # Write to file
411
- report_path.write_text(content, encoding='utf-8')
412
-
413
- self.stdout.write(f"šŸ“„ Report saved to: {report_path}")
414
-
415
- except Exception as e:
416
- self.stdout.write(
417
- self.style.WARNING(f"Failed to save report: {e}")
418
- )
419
-
420
- def _generate_markdown_report(self, diagnosis):
421
- """Generate markdown format report."""
422
- content = f"""# Project Diagnosis Report
423
-
424
- ## Summary
425
- - **Status**: {diagnosis['status']}
426
- - **Confidence**: {diagnosis['confidence']:.0%}
427
- - **Summary**: {diagnosis['summary']}
428
-
429
- ## Findings
430
- """
431
-
432
- for i, finding in enumerate(diagnosis.get('findings', []), 1):
433
- content += f"""
434
- ### {i}. {finding['title']}
435
- - **Severity**: {finding['severity'].upper()}
436
- - **Category**: {finding['category']}
437
- - **Description**: {finding['description']}
438
-
439
- **Recommendations**:
440
- """
441
- for rec in finding.get('recommendations', []):
442
- content += f"- {rec}\n"
443
-
444
- return content
445
-
446
- def _generate_text_report(self, diagnosis):
447
- """Generate plain text report."""
448
- content = f"""PROJECT DIAGNOSIS REPORT
449
- {'=' * 50}
450
-
451
- STATUS: {diagnosis['status']}
452
- CONFIDENCE: {diagnosis['confidence']:.0%}
453
- SUMMARY: {diagnosis['summary']}
454
-
455
- FINDINGS:
456
- """
457
-
458
- for i, finding in enumerate(diagnosis.get('findings', []), 1):
459
- content += f"""
460
- {i}. {finding['title']}
461
- Severity: {finding['severity'].upper()}
462
- Category: {finding['category']}
463
- Description: {finding['description']}
464
-
465
- Recommendations:
466
- """
467
- for rec in finding.get('recommendations', []):
468
- content += f" • {rec}\n"
469
-
470
- return content