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,141 +0,0 @@
1
- """
2
- Code Extraction Module for Context Builder.
3
-
4
- This module handles extraction of relevant code samples
5
- and examples from existing project files.
6
- """
7
-
8
- from typing import Dict, Optional
9
- from pathlib import Path
10
-
11
- from ..base import ServiceDependencies
12
- from .models import ContextBuildRequest, ContextResult
13
-
14
-
15
- class CodeExtractor:
16
- """Handles extraction of code samples for context building."""
17
-
18
- def __init__(self):
19
- """Initialize code extractor."""
20
- # Map features to their corresponding files
21
- self.feature_files = {
22
- "models": "models.py",
23
- "views": "views.py",
24
- "urls": "urls.py",
25
- "admin": "admin.py",
26
- "forms": "forms.py",
27
- "tests": "tests.py",
28
- "serializers": "serializers.py",
29
- "viewsets": "viewsets.py",
30
- "filters": "filters.py",
31
- "pagination": "pagination.py",
32
- "tasks": "tasks.py",
33
- "signals": "signals.py",
34
- "middleware": "middleware.py"
35
- }
36
-
37
- async def extract_code_samples(
38
- self,
39
- request: ContextBuildRequest,
40
- result: ContextResult,
41
- dependencies: ServiceDependencies
42
- ) -> None:
43
- """Extract relevant code samples for context."""
44
- if not request.generation_request:
45
- return
46
-
47
- samples = {}
48
-
49
- # Extract samples for each requested feature
50
- for feature in request.generation_request.features:
51
- feature_samples = await self._extract_feature_samples(
52
- feature.value, request, result, dependencies
53
- )
54
- if feature_samples:
55
- samples[feature.value] = feature_samples
56
-
57
- result.code_samples = samples
58
-
59
- async def _extract_feature_samples(
60
- self,
61
- feature: str,
62
- request: ContextBuildRequest,
63
- result: ContextResult,
64
- dependencies: ServiceDependencies
65
- ) -> Optional[str]:
66
- """Extract code samples for a specific feature."""
67
- # Find the best example of this feature in existing apps
68
- best_sample = None
69
- max_complexity = 0
70
-
71
- for app in result.project_context.apps:
72
- app_path = Path(app.path)
73
-
74
- filename = self.feature_files.get(feature)
75
- if not filename:
76
- continue
77
-
78
- file_path = app_path / filename
79
- if not file_path.exists():
80
- continue
81
-
82
- try:
83
- content = file_path.read_text()
84
-
85
- # Simple complexity measure (lines of meaningful code)
86
- lines = [line.strip() for line in content.split('\n')]
87
- meaningful_lines = [line for line in lines if line and not line.startswith('#')]
88
- complexity = len(meaningful_lines)
89
-
90
- if complexity > max_complexity:
91
- max_complexity = complexity
92
- # Truncate sample if too long
93
- if len(content) > 2000:
94
- content = content[:2000] + "\n# ... (truncated)"
95
- best_sample = content
96
-
97
- except Exception:
98
- continue
99
-
100
- return best_sample
101
-
102
- def extract_specific_patterns(
103
- self,
104
- project_root: Path,
105
- pattern_type: str,
106
- max_samples: int = 3
107
- ) -> Dict[str, str]:
108
- """Extract specific code patterns from the project."""
109
- samples = {}
110
-
111
- pattern_searches = {
112
- "model_definitions": ["models.py"],
113
- "view_classes": ["views.py"],
114
- "url_patterns": ["urls.py"],
115
- "admin_configs": ["admin.py"],
116
- "serializer_classes": ["serializers.py"],
117
- "test_cases": ["tests.py", "test_*.py"]
118
- }
119
-
120
- search_files = pattern_searches.get(pattern_type, [])
121
-
122
- for search_pattern in search_files:
123
- for file_path in project_root.rglob(search_pattern):
124
- if file_path.is_file():
125
- try:
126
- content = file_path.read_text()
127
- relative_path = file_path.relative_to(project_root)
128
-
129
- # Truncate if too long
130
- if len(content) > 1500:
131
- content = content[:1500] + "\n# ... (truncated)"
132
-
133
- samples[str(relative_path)] = content
134
-
135
- # Limit number of samples
136
- if len(samples) >= max_samples:
137
- break
138
- except Exception:
139
- continue
140
-
141
- return samples
@@ -1,276 +0,0 @@
1
- """
2
- Context Generation Module for Context Builder.
3
-
4
- This module handles generation of specific context for different
5
- Django features and components.
6
- """
7
-
8
- from typing import List, Dict, Any
9
- from pathlib import Path
10
- import re
11
-
12
- from ..base import ServiceDependencies
13
- from .models import ContextBuildRequest, ContextResult
14
-
15
-
16
- class ContextGenerator:
17
- """Handles generation of feature-specific context."""
18
-
19
- def __init__(self):
20
- """Initialize context generator."""
21
- # Map features to their context building strategies
22
- self.context_strategies = {
23
- "models": self._build_models_context,
24
- "views": self._build_views_context,
25
- "urls": self._build_urls_context,
26
- "admin": self._build_admin_context,
27
- "api": self._build_api_context,
28
- "tests": self._build_tests_context,
29
- "serializers": self._build_api_context,
30
- "viewsets": self._build_api_context,
31
- "forms": self._build_forms_context
32
- }
33
-
34
- async def build_generation_context(
35
- self,
36
- request: ContextBuildRequest,
37
- result: ContextResult,
38
- dependencies: ServiceDependencies
39
- ) -> None:
40
- """Build context specific to the generation request."""
41
- gen_request = request.generation_request
42
- if not gen_request:
43
- return
44
-
45
- # Build context for each requested feature
46
- for feature in gen_request.features:
47
- feature_name = feature.value
48
-
49
- if feature_name in self.context_strategies:
50
- strategy = self.context_strategies[feature_name]
51
- await strategy(request, result, dependencies)
52
-
53
- async def _build_models_context(
54
- self,
55
- request: ContextBuildRequest,
56
- result: ContextResult,
57
- dependencies: ServiceDependencies
58
- ) -> None:
59
- """Build context for models generation."""
60
- # Find existing models in the project
61
- existing_models = []
62
-
63
- for app in result.project_context.apps:
64
- if app.models_count > 0:
65
- app_path = Path(app.path)
66
- models_file = app_path / "models.py"
67
-
68
- if models_file.exists():
69
- try:
70
- content = models_file.read_text()
71
- # Extract model class names
72
- model_classes = re.findall(r'class\s+(\w+)\s*\([^)]*Model[^)]*\):', content)
73
- existing_models.extend([(app.name, model) for model in model_classes])
74
- except Exception:
75
- pass
76
-
77
- # Add to context summary
78
- result.context_summary["existing_models"] = existing_models
79
- result.context_summary["model_patterns"] = [
80
- p for p in result.relevant_patterns
81
- if "model" in p.name.lower() or "data" in p.name.lower()
82
- ]
83
-
84
- async def _build_views_context(
85
- self,
86
- request: ContextBuildRequest,
87
- result: ContextResult,
88
- dependencies: ServiceDependencies
89
- ) -> None:
90
- """Build context for views generation."""
91
- # Find existing view patterns
92
- view_patterns = []
93
-
94
- for app in result.project_context.apps:
95
- if app.views_count > 0:
96
- app_path = Path(app.path)
97
- views_file = app_path / "views.py"
98
-
99
- if views_file.exists():
100
- try:
101
- content = views_file.read_text()
102
-
103
- # Detect view types
104
- if "class" in content and "View" in content:
105
- view_patterns.append("class_based_views")
106
- if "def " in content and "request" in content:
107
- view_patterns.append("function_based_views")
108
- if "async def" in content:
109
- view_patterns.append("async_views")
110
-
111
- except Exception:
112
- pass
113
-
114
- result.context_summary["view_patterns"] = list(set(view_patterns))
115
-
116
- async def _build_urls_context(
117
- self,
118
- request: ContextBuildRequest,
119
- result: ContextResult,
120
- dependencies: ServiceDependencies
121
- ) -> None:
122
- """Build context for URLs generation."""
123
- # Analyze URL patterns in existing apps
124
- url_patterns = []
125
-
126
- for app in result.project_context.apps:
127
- app_path = Path(app.path)
128
- urls_file = app_path / "urls.py"
129
-
130
- if urls_file.exists():
131
- try:
132
- content = urls_file.read_text()
133
-
134
- # Detect URL pattern styles
135
- if "path(" in content:
136
- url_patterns.append("django_path")
137
- if "re_path(" in content:
138
- url_patterns.append("regex_path")
139
- if "include(" in content:
140
- url_patterns.append("url_include")
141
-
142
- except Exception:
143
- pass
144
-
145
- result.context_summary["url_patterns"] = list(set(url_patterns))
146
-
147
- async def _build_admin_context(
148
- self,
149
- request: ContextBuildRequest,
150
- result: ContextResult,
151
- dependencies: ServiceDependencies
152
- ) -> None:
153
- """Build context for admin generation."""
154
- # Find admin registration patterns
155
- admin_patterns = []
156
-
157
- for app in result.project_context.apps:
158
- if app.admin_registered_models > 0:
159
- app_path = Path(app.path)
160
- admin_file = app_path / "admin.py"
161
-
162
- if admin_file.exists():
163
- try:
164
- content = admin_file.read_text()
165
-
166
- # Detect admin patterns
167
- if "@admin.register" in content:
168
- admin_patterns.append("decorator_registration")
169
- if "admin.site.register" in content:
170
- admin_patterns.append("function_registration")
171
- if "ModelAdmin" in content:
172
- admin_patterns.append("custom_admin_classes")
173
-
174
- except Exception:
175
- pass
176
-
177
- result.context_summary["admin_patterns"] = list(set(admin_patterns))
178
-
179
- async def _build_api_context(
180
- self,
181
- request: ContextBuildRequest,
182
- result: ContextResult,
183
- dependencies: ServiceDependencies
184
- ) -> None:
185
- """Build context for API generation."""
186
- # Find API patterns
187
- api_patterns = []
188
-
189
- for app in result.project_context.apps:
190
- app_path = Path(app.path)
191
-
192
- # Check for DRF patterns
193
- for api_file in ["serializers.py", "viewsets.py", "views.py"]:
194
- file_path = app_path / api_file
195
- if file_path.exists():
196
- try:
197
- content = file_path.read_text()
198
-
199
- if "rest_framework" in content:
200
- api_patterns.append("django_rest_framework")
201
- if "Serializer" in content:
202
- api_patterns.append("serializers")
203
- if "ViewSet" in content:
204
- api_patterns.append("viewsets")
205
- if "APIView" in content:
206
- api_patterns.append("api_views")
207
-
208
- except Exception:
209
- pass
210
-
211
- result.context_summary["api_patterns"] = list(set(api_patterns))
212
-
213
- async def _build_tests_context(
214
- self,
215
- request: ContextBuildRequest,
216
- result: ContextResult,
217
- dependencies: ServiceDependencies
218
- ) -> None:
219
- """Build context for tests generation."""
220
- # Find testing patterns
221
- test_patterns = []
222
-
223
- for app in result.project_context.apps:
224
- app_path = Path(app.path)
225
-
226
- # Check for test files
227
- test_files = list(app_path.glob("test*.py")) + [app_path / "tests.py"]
228
-
229
- for test_file in test_files:
230
- if test_file.exists():
231
- try:
232
- content = test_file.read_text()
233
-
234
- if "TestCase" in content:
235
- test_patterns.append("django_testcase")
236
- if "pytest" in content or "def test_" in content:
237
- test_patterns.append("pytest")
238
- if "Client" in content:
239
- test_patterns.append("test_client")
240
- if "factory" in content.lower():
241
- test_patterns.append("factory_boy")
242
-
243
- except Exception:
244
- pass
245
-
246
- result.context_summary["test_patterns"] = list(set(test_patterns))
247
-
248
- async def _build_forms_context(
249
- self,
250
- request: ContextBuildRequest,
251
- result: ContextResult,
252
- dependencies: ServiceDependencies
253
- ) -> None:
254
- """Build context for forms generation."""
255
- # Find form patterns
256
- form_patterns = []
257
-
258
- for app in result.project_context.apps:
259
- app_path = Path(app.path)
260
- forms_file = app_path / "forms.py"
261
-
262
- if forms_file.exists():
263
- try:
264
- content = forms_file.read_text()
265
-
266
- if "ModelForm" in content:
267
- form_patterns.append("model_forms")
268
- if "Form" in content and "ModelForm" not in content:
269
- form_patterns.append("regular_forms")
270
- if "widgets" in content:
271
- form_patterns.append("custom_widgets")
272
-
273
- except Exception:
274
- pass
275
-
276
- result.context_summary["form_patterns"] = list(set(form_patterns))
@@ -1,272 +0,0 @@
1
- """
2
- Main Context Builder Service for Django App Agent Module.
3
-
4
- This service builds comprehensive development context for AI agents,
5
- coordinating project analysis, pattern identification, and context optimization.
6
- """
7
-
8
- from typing import Dict, Any, List
9
-
10
- from ..base import BaseService, ServiceDependencies
11
- from ..project_scanner import ProjectScannerService, ProjectScanRequest
12
- from ...models.context import ProjectContext
13
- from ...core.exceptions import ValidationError
14
-
15
- from .models import ContextBuildRequest, ContextResult
16
- from .pattern_analyzer import PatternAnalyzer
17
- from .code_extractor import CodeExtractor
18
- from .context_generator import ContextGenerator
19
-
20
-
21
- class ContextBuilderService(BaseService[ContextBuildRequest, ContextResult]):
22
- """
23
- Service for building comprehensive development context for AI agents.
24
-
25
- Capabilities:
26
- - Project structure analysis and pattern identification
27
- - Code sample extraction and context building
28
- - Integration point identification
29
- - Context optimization for AI consumption
30
- """
31
-
32
- def __init__(self, config):
33
- """Initialize context builder service."""
34
- super().__init__("context_builder", config)
35
-
36
- # Initialize sub-components
37
- self.pattern_analyzer = PatternAnalyzer()
38
- self.code_extractor = CodeExtractor()
39
- self.context_generator = ContextGenerator()
40
-
41
- # Initialize project scanner
42
- self.project_scanner = ProjectScannerService(config)
43
-
44
- async def process(
45
- self,
46
- request: ContextBuildRequest,
47
- dependencies: ServiceDependencies
48
- ) -> ContextResult:
49
- """
50
- Process context building request.
51
-
52
- Args:
53
- request: Context building request
54
- dependencies: Service dependencies for logging and operations
55
-
56
- Returns:
57
- ContextResult with comprehensive development context
58
- """
59
- try:
60
- dependencies.log_operation(
61
- f"Building development context for '{request.project_root}'",
62
- project_root=str(request.project_root),
63
- target_app=request.target_app_name
64
- )
65
-
66
- # Initialize result
67
- result = ContextResult(
68
- project_context=ProjectContext(
69
- project_root=str(request.project_root),
70
- project_name=request.project_root.name,
71
- django_version="Unknown",
72
- is_django_cfg_project=False,
73
- apps=[],
74
- architectural_patterns=[],
75
- integration_opportunities=[]
76
- )
77
- )
78
-
79
- # Scan project structure
80
- scan_request = ProjectScanRequest(
81
- project_root=request.project_root,
82
- analyze_dependencies=True,
83
- detect_patterns=True
84
- )
85
-
86
- scan_result = await self.project_scanner.process(scan_request, dependencies)
87
- result.project_context = scan_result.project_context
88
-
89
- # Identify relevant architectural patterns
90
- await self.pattern_analyzer.identify_relevant_patterns(
91
- request, scan_result, result, dependencies
92
- )
93
-
94
- # Build generation-specific context
95
- await self.context_generator.build_generation_context(
96
- request, result, dependencies
97
- )
98
-
99
- # Extract code samples if requested
100
- if request.include_code_samples:
101
- await self.code_extractor.extract_code_samples(
102
- request, result, dependencies
103
- )
104
-
105
- # Identify integration points
106
- await self._identify_integration_points(request, result, dependencies)
107
-
108
- # Generate recommendations
109
- await self._generate_recommendations(request, result, dependencies)
110
-
111
- # Optimize context size if needed
112
- await self._optimize_context_size(request, result, dependencies)
113
-
114
- dependencies.log_operation(
115
- "Context building completed successfully",
116
- patterns_found=len(result.relevant_patterns),
117
- code_samples=len(result.code_samples),
118
- recommendations=len(result.recommendations)
119
- )
120
-
121
- return result
122
-
123
- except Exception as e:
124
- raise ValidationError(
125
- f"Failed to build development context: {e}",
126
- validation_type="context_building"
127
- )
128
-
129
- async def _identify_integration_points(
130
- self,
131
- request: ContextBuildRequest,
132
- result: ContextResult,
133
- dependencies: ServiceDependencies
134
- ) -> None:
135
- """Identify potential integration points with existing code."""
136
- integration_points = []
137
-
138
- if not request.generation_request:
139
- return
140
-
141
- # Check for potential integrations based on requested features
142
- for feature in request.generation_request.features:
143
- feature_name = feature.value
144
-
145
- if feature_name == "models":
146
- # Look for existing models that could be related
147
- for app in result.project_context.apps:
148
- if app.models_count > 0:
149
- integration_points.append({
150
- "type": "model_relationships",
151
- "app": app.name,
152
- "description": f"Consider relationships with models in {app.name}",
153
- "confidence": 0.7
154
- })
155
-
156
- elif feature_name == "api":
157
- # Look for existing API patterns
158
- api_apps = [app for app in result.project_context.apps if "api" in app.name.lower()]
159
- for app in api_apps:
160
- integration_points.append({
161
- "type": "api_integration",
162
- "app": app.name,
163
- "description": f"Consider API consistency with {app.name}",
164
- "confidence": 0.8
165
- })
166
-
167
- elif feature_name == "admin":
168
- # Look for existing admin customizations
169
- admin_apps = [app for app in result.project_context.apps if app.admin_registered_models > 0]
170
- for app in admin_apps:
171
- integration_points.append({
172
- "type": "admin_consistency",
173
- "app": app.name,
174
- "description": f"Follow admin patterns from {app.name}",
175
- "confidence": 0.6
176
- })
177
-
178
- result.integration_points = integration_points
179
-
180
- async def _generate_recommendations(
181
- self,
182
- request: ContextBuildRequest,
183
- result: ContextResult,
184
- dependencies: ServiceDependencies
185
- ) -> None:
186
- """Generate development recommendations based on context."""
187
- recommendations = []
188
-
189
- # Analyze project patterns for recommendations
190
- if result.relevant_patterns:
191
- high_confidence_patterns = [p for p in result.relevant_patterns if p.confidence >= 0.8]
192
- if high_confidence_patterns:
193
- pattern_names = [p.name for p in high_confidence_patterns]
194
- recommendations.append(
195
- f"Follow established patterns: {', '.join(pattern_names)}"
196
- )
197
-
198
- # Check for django-cfg specific recommendations
199
- if result.project_context.is_django_cfg_project:
200
- recommendations.extend([
201
- "Use django-cfg configuration patterns for settings",
202
- "Leverage django-cfg modules for better organization",
203
- "Consider using BaseCfgModule for configuration management"
204
- ])
205
-
206
- # Feature-specific recommendations
207
- if request.generation_request:
208
- for feature in request.generation_request.features:
209
- feature_name = feature.value
210
-
211
- if feature_name == "models":
212
- recommendations.append("Use proper field types and validation")
213
- recommendations.append("Add meaningful __str__ methods")
214
- recommendations.append("Consider adding Meta class with ordering")
215
-
216
- elif feature_name == "api":
217
- recommendations.append("Use DRF serializers for consistent API responses")
218
- recommendations.append("Implement proper pagination")
219
- recommendations.append("Add API documentation with drf-spectacular")
220
-
221
- elif feature_name == "tests":
222
- recommendations.append("Aim for high test coverage")
223
- recommendations.append("Use factory_boy for test data generation")
224
- recommendations.append("Test both positive and negative scenarios")
225
-
226
- # Context size recommendations
227
- context_size = sum(len(str(v)) for v in result.code_samples.values())
228
- if context_size > request.max_context_size:
229
- recommendations.append("Consider reducing context size for better AI performance")
230
-
231
- result.recommendations = recommendations
232
-
233
- async def _optimize_context_size(
234
- self,
235
- request: ContextBuildRequest,
236
- result: ContextResult,
237
- dependencies: ServiceDependencies
238
- ) -> None:
239
- """Optimize context size to fit within limits."""
240
- # Calculate current context size
241
- context_size = 0
242
- context_size += len(str(result.project_context))
243
- context_size += sum(len(str(p)) for p in result.relevant_patterns)
244
- context_size += sum(len(sample) for sample in result.code_samples.values())
245
-
246
- if context_size <= request.max_context_size:
247
- return
248
-
249
- dependencies.log_operation(
250
- f"Optimizing context size from {context_size} to {request.max_context_size}"
251
- )
252
-
253
- # Prioritize and truncate content
254
- # 1. Keep most relevant patterns (highest confidence)
255
- result.relevant_patterns = sorted(
256
- result.relevant_patterns,
257
- key=lambda p: p.confidence,
258
- reverse=True
259
- )[:5] # Keep top 5 patterns
260
-
261
- # 2. Truncate code samples
262
- max_sample_size = request.max_context_size // (len(result.code_samples) + 1) if result.code_samples else 1000
263
-
264
- for feature, sample in result.code_samples.items():
265
- if len(sample) > max_sample_size:
266
- result.code_samples[feature] = sample[:max_sample_size] + "\n# ... (truncated for context)"
267
-
268
- # 3. Limit integration points
269
- result.integration_points = result.integration_points[:10]
270
-
271
- # 4. Limit recommendations
272
- result.recommendations = result.recommendations[:15]