django-cfg 1.3.9__py3-none-any.whl → 1.3.13__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 (188) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/accounts/admin/inlines.py +11 -5
  3. django_cfg/apps/payments/admin/networks_admin.py +12 -1
  4. django_cfg/apps/payments/admin/payments_admin.py +13 -0
  5. django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +62 -14
  6. django_cfg/apps/payments/admin_interface/templates/payments/components/payment_card.html +121 -0
  7. django_cfg/apps/payments/admin_interface/templates/payments/components/payment_qr_code.html +95 -0
  8. django_cfg/apps/payments/admin_interface/templates/payments/components/progress_bar.html +37 -0
  9. django_cfg/apps/payments/admin_interface/templates/payments/components/provider_stats.html +60 -0
  10. django_cfg/apps/payments/admin_interface/templates/payments/components/status_badge.html +41 -0
  11. django_cfg/apps/payments/admin_interface/templates/payments/components/status_overview.html +83 -0
  12. django_cfg/apps/payments/admin_interface/templates/payments/payment_detail.html +363 -0
  13. django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +33 -3
  14. django_cfg/apps/payments/admin_interface/views/api/payments.py +102 -0
  15. django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +96 -45
  16. django_cfg/apps/payments/admin_interface/views/forms.py +5 -1
  17. django_cfg/apps/payments/config/__init__.py +14 -15
  18. django_cfg/apps/payments/config/django_cfg_integration.py +59 -1
  19. django_cfg/apps/payments/config/helpers.py +8 -13
  20. django_cfg/apps/payments/migrations/0001_initial.py +33 -46
  21. django_cfg/apps/payments/migrations/0002_rename_payments_un_user_id_7f6e79_idx_payments_un_user_id_8ce187_idx_and_more.py +46 -0
  22. django_cfg/apps/payments/migrations/0003_universalpayment_status_changed_at.py +25 -0
  23. django_cfg/apps/payments/models/managers/payment_managers.py +142 -25
  24. django_cfg/apps/payments/models/payments.py +94 -0
  25. django_cfg/apps/payments/services/core/base.py +4 -4
  26. django_cfg/apps/payments/services/core/payment_service.py +265 -38
  27. django_cfg/apps/payments/services/providers/base.py +209 -3
  28. django_cfg/apps/payments/services/providers/models/__init__.py +2 -0
  29. django_cfg/apps/payments/services/providers/models/base.py +25 -2
  30. django_cfg/apps/payments/services/providers/nowpayments/models.py +2 -2
  31. django_cfg/apps/payments/services/providers/nowpayments/provider.py +57 -9
  32. django_cfg/apps/payments/services/providers/registry.py +5 -5
  33. django_cfg/apps/payments/services/types/requests.py +19 -7
  34. django_cfg/apps/payments/signals/payment_signals.py +31 -2
  35. django_cfg/apps/payments/static/payments/js/api-client.js +6 -1
  36. django_cfg/apps/payments/static/payments/js/payment-detail.js +167 -0
  37. django_cfg/apps/payments/static/payments/js/payment-form.js +35 -26
  38. django_cfg/apps/payments/templatetags/payment_tags.py +8 -0
  39. django_cfg/apps/payments/urls.py +3 -2
  40. django_cfg/apps/payments/views/api/currencies.py +3 -0
  41. django_cfg/apps/payments/views/serializers/currencies.py +18 -5
  42. django_cfg/apps/tasks/admin/tasks_admin.py +2 -2
  43. django_cfg/apps/tasks/static/tasks/css/dashboard.css +68 -217
  44. django_cfg/apps/tasks/static/tasks/js/api.js +40 -84
  45. django_cfg/apps/tasks/static/tasks/js/components/DataManager.js +24 -0
  46. django_cfg/apps/tasks/static/tasks/js/components/TabManager.js +85 -0
  47. django_cfg/apps/tasks/static/tasks/js/components/TaskRenderer.js +216 -0
  48. django_cfg/apps/tasks/static/tasks/js/dashboard/main.mjs +245 -0
  49. django_cfg/apps/tasks/static/tasks/js/dashboard/overview.mjs +123 -0
  50. django_cfg/apps/tasks/static/tasks/js/dashboard/queues.mjs +120 -0
  51. django_cfg/apps/tasks/static/tasks/js/dashboard/tasks.mjs +350 -0
  52. django_cfg/apps/tasks/static/tasks/js/dashboard/workers.mjs +169 -0
  53. django_cfg/apps/tasks/tasks/__init__.py +10 -0
  54. django_cfg/apps/tasks/tasks/demo_tasks.py +133 -0
  55. django_cfg/apps/tasks/templates/tasks/components/management_actions.html +42 -45
  56. django_cfg/apps/tasks/templates/tasks/components/{status_cards.html → overview_content.html} +30 -11
  57. django_cfg/apps/tasks/templates/tasks/components/queues_content.html +19 -0
  58. django_cfg/apps/tasks/templates/tasks/components/tab_navigation.html +16 -10
  59. django_cfg/apps/tasks/templates/tasks/components/tasks_content.html +51 -0
  60. django_cfg/apps/tasks/templates/tasks/components/workers_content.html +30 -0
  61. django_cfg/apps/tasks/templates/tasks/layout/base.html +117 -0
  62. django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +82 -0
  63. django_cfg/apps/tasks/templates/tasks/partials/task_row_template.html +40 -0
  64. django_cfg/apps/tasks/templates/tasks/widgets/task_filters.html +37 -0
  65. django_cfg/apps/tasks/templates/tasks/widgets/task_footer.html +41 -0
  66. django_cfg/apps/tasks/templates/tasks/widgets/task_table.html +50 -0
  67. django_cfg/apps/tasks/urls.py +2 -2
  68. django_cfg/apps/tasks/urls_admin.py +2 -2
  69. django_cfg/apps/tasks/utils/__init__.py +1 -0
  70. django_cfg/apps/tasks/utils/simulator.py +356 -0
  71. django_cfg/apps/tasks/views/__init__.py +16 -0
  72. django_cfg/apps/tasks/views/api.py +569 -0
  73. django_cfg/apps/tasks/views/dashboard.py +58 -0
  74. django_cfg/core/integration/__init__.py +21 -0
  75. django_cfg/management/commands/rundramatiq_simulator.py +430 -0
  76. django_cfg/models/constance.py +0 -11
  77. django_cfg/models/payments.py +137 -3
  78. django_cfg/modules/django_tasks.py +54 -21
  79. django_cfg/registry/core.py +4 -9
  80. django_cfg/template_archive/django_sample.zip +0 -0
  81. {django_cfg-1.3.9.dist-info → django_cfg-1.3.13.dist-info}/METADATA +2 -2
  82. {django_cfg-1.3.9.dist-info → django_cfg-1.3.13.dist-info}/RECORD +85 -153
  83. django_cfg/apps/payments/config/constance/__init__.py +0 -22
  84. django_cfg/apps/payments/config/constance/config_service.py +0 -123
  85. django_cfg/apps/payments/config/constance/fields.py +0 -69
  86. django_cfg/apps/payments/config/constance/settings.py +0 -160
  87. django_cfg/apps/payments/migrations/0002_currency_usd_rate_currency_usd_rate_updated_at.py +0 -26
  88. django_cfg/apps/payments/migrations/0003_remove_provider_currency_fields.py +0 -28
  89. django_cfg/apps/payments/migrations/0004_add_reserved_usd_field.py +0 -30
  90. django_cfg/apps/tasks/static/tasks/js/dashboard.js +0 -614
  91. django_cfg/apps/tasks/static/tasks/js/modals.js +0 -452
  92. django_cfg/apps/tasks/static/tasks/js/notifications.js +0 -144
  93. django_cfg/apps/tasks/static/tasks/js/task-monitor.js +0 -454
  94. django_cfg/apps/tasks/static/tasks/js/theme.js +0 -77
  95. django_cfg/apps/tasks/templates/tasks/base.html +0 -96
  96. django_cfg/apps/tasks/templates/tasks/components/info_cards.html +0 -85
  97. django_cfg/apps/tasks/templates/tasks/components/overview_tab.html +0 -22
  98. django_cfg/apps/tasks/templates/tasks/components/queues_tab.html +0 -19
  99. django_cfg/apps/tasks/templates/tasks/components/task_details_modal.html +0 -103
  100. django_cfg/apps/tasks/templates/tasks/components/tasks_tab.html +0 -32
  101. django_cfg/apps/tasks/templates/tasks/components/workers_tab.html +0 -29
  102. django_cfg/apps/tasks/templates/tasks/dashboard.html +0 -29
  103. django_cfg/apps/tasks/views.py +0 -461
  104. django_cfg/management/commands/app_agent_diagnose.py +0 -470
  105. django_cfg/management/commands/app_agent_generate.py +0 -342
  106. django_cfg/management/commands/app_agent_info.py +0 -308
  107. django_cfg/management/commands/auto_generate.py +0 -486
  108. django_cfg/modules/django_app_agent/__init__.py +0 -87
  109. django_cfg/modules/django_app_agent/agents/__init__.py +0 -40
  110. django_cfg/modules/django_app_agent/agents/base/__init__.py +0 -24
  111. django_cfg/modules/django_app_agent/agents/base/agent.py +0 -354
  112. django_cfg/modules/django_app_agent/agents/base/context.py +0 -236
  113. django_cfg/modules/django_app_agent/agents/base/executor.py +0 -430
  114. django_cfg/modules/django_app_agent/agents/generation/__init__.py +0 -12
  115. django_cfg/modules/django_app_agent/agents/generation/app_generator/__init__.py +0 -15
  116. django_cfg/modules/django_app_agent/agents/generation/app_generator/config_validator.py +0 -147
  117. django_cfg/modules/django_app_agent/agents/generation/app_generator/main.py +0 -99
  118. django_cfg/modules/django_app_agent/agents/generation/app_generator/models.py +0 -32
  119. django_cfg/modules/django_app_agent/agents/generation/app_generator/prompt_manager.py +0 -290
  120. django_cfg/modules/django_app_agent/agents/interfaces.py +0 -376
  121. django_cfg/modules/django_app_agent/core/__init__.py +0 -33
  122. django_cfg/modules/django_app_agent/core/config.py +0 -300
  123. django_cfg/modules/django_app_agent/core/exceptions.py +0 -359
  124. django_cfg/modules/django_app_agent/models/__init__.py +0 -71
  125. django_cfg/modules/django_app_agent/models/base.py +0 -283
  126. django_cfg/modules/django_app_agent/models/context.py +0 -496
  127. django_cfg/modules/django_app_agent/models/enums.py +0 -481
  128. django_cfg/modules/django_app_agent/models/requests.py +0 -500
  129. django_cfg/modules/django_app_agent/models/responses.py +0 -585
  130. django_cfg/modules/django_app_agent/pytest.ini +0 -6
  131. django_cfg/modules/django_app_agent/services/__init__.py +0 -42
  132. django_cfg/modules/django_app_agent/services/app_generator/__init__.py +0 -30
  133. django_cfg/modules/django_app_agent/services/app_generator/ai_integration.py +0 -133
  134. django_cfg/modules/django_app_agent/services/app_generator/context.py +0 -40
  135. django_cfg/modules/django_app_agent/services/app_generator/main.py +0 -202
  136. django_cfg/modules/django_app_agent/services/app_generator/structure.py +0 -316
  137. django_cfg/modules/django_app_agent/services/app_generator/validation.py +0 -125
  138. django_cfg/modules/django_app_agent/services/base.py +0 -437
  139. django_cfg/modules/django_app_agent/services/context_builder/__init__.py +0 -34
  140. django_cfg/modules/django_app_agent/services/context_builder/code_extractor.py +0 -141
  141. django_cfg/modules/django_app_agent/services/context_builder/context_generator.py +0 -276
  142. django_cfg/modules/django_app_agent/services/context_builder/main.py +0 -272
  143. django_cfg/modules/django_app_agent/services/context_builder/models.py +0 -40
  144. django_cfg/modules/django_app_agent/services/context_builder/pattern_analyzer.py +0 -85
  145. django_cfg/modules/django_app_agent/services/project_scanner/__init__.py +0 -31
  146. django_cfg/modules/django_app_agent/services/project_scanner/app_discovery.py +0 -311
  147. django_cfg/modules/django_app_agent/services/project_scanner/main.py +0 -221
  148. django_cfg/modules/django_app_agent/services/project_scanner/models.py +0 -59
  149. django_cfg/modules/django_app_agent/services/project_scanner/pattern_detection.py +0 -94
  150. django_cfg/modules/django_app_agent/services/questioning_service/__init__.py +0 -28
  151. django_cfg/modules/django_app_agent/services/questioning_service/main.py +0 -273
  152. django_cfg/modules/django_app_agent/services/questioning_service/models.py +0 -111
  153. django_cfg/modules/django_app_agent/services/questioning_service/question_generator.py +0 -251
  154. django_cfg/modules/django_app_agent/services/questioning_service/response_processor.py +0 -347
  155. django_cfg/modules/django_app_agent/services/questioning_service/session_manager.py +0 -356
  156. django_cfg/modules/django_app_agent/services/report_service.py +0 -332
  157. django_cfg/modules/django_app_agent/services/template_manager/__init__.py +0 -18
  158. django_cfg/modules/django_app_agent/services/template_manager/jinja_engine.py +0 -236
  159. django_cfg/modules/django_app_agent/services/template_manager/main.py +0 -159
  160. django_cfg/modules/django_app_agent/services/template_manager/models.py +0 -36
  161. django_cfg/modules/django_app_agent/services/template_manager/template_loader.py +0 -100
  162. django_cfg/modules/django_app_agent/services/template_manager/templates/admin.py.j2 +0 -105
  163. django_cfg/modules/django_app_agent/services/template_manager/templates/apps.py.j2 +0 -31
  164. django_cfg/modules/django_app_agent/services/template_manager/templates/cfg_config.py.j2 +0 -44
  165. django_cfg/modules/django_app_agent/services/template_manager/templates/cfg_module.py.j2 +0 -81
  166. django_cfg/modules/django_app_agent/services/template_manager/templates/forms.py.j2 +0 -107
  167. django_cfg/modules/django_app_agent/services/template_manager/templates/models.py.j2 +0 -139
  168. django_cfg/modules/django_app_agent/services/template_manager/templates/serializers.py.j2 +0 -91
  169. django_cfg/modules/django_app_agent/services/template_manager/templates/tests.py.j2 +0 -195
  170. django_cfg/modules/django_app_agent/services/template_manager/templates/urls.py.j2 +0 -35
  171. django_cfg/modules/django_app_agent/services/template_manager/templates/views.py.j2 +0 -211
  172. django_cfg/modules/django_app_agent/services/template_manager/variable_processor.py +0 -200
  173. django_cfg/modules/django_app_agent/services/validation_service/__init__.py +0 -25
  174. django_cfg/modules/django_app_agent/services/validation_service/django_validator.py +0 -333
  175. django_cfg/modules/django_app_agent/services/validation_service/main.py +0 -242
  176. django_cfg/modules/django_app_agent/services/validation_service/models.py +0 -66
  177. django_cfg/modules/django_app_agent/services/validation_service/quality_validator.py +0 -352
  178. django_cfg/modules/django_app_agent/services/validation_service/security_validator.py +0 -272
  179. django_cfg/modules/django_app_agent/services/validation_service/syntax_validator.py +0 -203
  180. django_cfg/modules/django_app_agent/ui/__init__.py +0 -25
  181. django_cfg/modules/django_app_agent/ui/cli.py +0 -419
  182. django_cfg/modules/django_app_agent/ui/rich_components.py +0 -622
  183. django_cfg/modules/django_app_agent/utils/__init__.py +0 -38
  184. django_cfg/modules/django_app_agent/utils/logging.py +0 -360
  185. django_cfg/modules/django_app_agent/utils/validation.py +0 -417
  186. {django_cfg-1.3.9.dist-info → django_cfg-1.3.13.dist-info}/WHEEL +0 -0
  187. {django_cfg-1.3.9.dist-info → django_cfg-1.3.13.dist-info}/entry_points.txt +0 -0
  188. {django_cfg-1.3.9.dist-info → django_cfg-1.3.13.dist-info}/licenses/LICENSE +0 -0
@@ -1,496 +0,0 @@
1
- """
2
- Context models for Django App Agent Module.
3
-
4
- This module defines context models for:
5
- - Project structure analysis
6
- - Django app information
7
- - Architectural patterns
8
- - Infrastructure context
9
- """
10
-
11
- from typing import List, Optional, Dict, Any, Set
12
- from pathlib import Path
13
- from pydantic import Field, field_validator, computed_field
14
-
15
- from .base import BaseAgentModel, ValidationMixin
16
- from .enums import AppType, AppFeature
17
-
18
-
19
- class ArchitecturalPattern(BaseAgentModel):
20
- """Information about an architectural pattern found in the project."""
21
-
22
- name: str = Field(
23
- description="Name of the architectural pattern",
24
- min_length=1,
25
- max_length=100
26
- )
27
-
28
- description: str = Field(
29
- description="Description of the pattern and its purpose",
30
- min_length=10,
31
- max_length=500
32
- )
33
-
34
- confidence: float = Field(
35
- ge=0.0,
36
- le=1.0,
37
- description="Confidence level in pattern detection (0-1)"
38
- )
39
-
40
- evidence: List[str] = Field(
41
- default_factory=list,
42
- description="Evidence supporting the presence of this pattern"
43
- )
44
-
45
- files_using_pattern: List[str] = Field(
46
- default_factory=list,
47
- description="Files that implement this pattern"
48
- )
49
-
50
- benefits: List[str] = Field(
51
- default_factory=list,
52
- description="Benefits of using this pattern"
53
- )
54
-
55
- implementation_notes: List[str] = Field(
56
- default_factory=list,
57
- description="Notes on how the pattern is implemented"
58
- )
59
-
60
- @computed_field
61
- @property
62
- def is_high_confidence(self) -> bool:
63
- """Check if this pattern detection has high confidence."""
64
- return self.confidence >= 0.8
65
-
66
- @computed_field
67
- @property
68
- def usage_score(self) -> float:
69
- """Calculate usage score based on evidence and files."""
70
- evidence_score = min(1.0, len(self.evidence) / 3.0) # Reduced threshold
71
- files_score = min(1.0, len(self.files_using_pattern) / 2.0) # Reduced threshold
72
- return (evidence_score + files_score + self.confidence) / 3.0
73
-
74
-
75
- class DjangoAppInfo(BaseAgentModel, ValidationMixin):
76
- """Information about a Django application in the project."""
77
-
78
- name: str = Field(
79
- description="Name of the Django app",
80
- min_length=1,
81
- max_length=50
82
- )
83
-
84
- path: Path = Field(
85
- description="Path to the app directory"
86
- )
87
-
88
- # App structure information
89
- has_models: bool = Field(
90
- default=False,
91
- description="Whether the app has models"
92
- )
93
-
94
- has_views: bool = Field(
95
- default=False,
96
- description="Whether the app has views"
97
- )
98
-
99
- has_admin: bool = Field(
100
- default=False,
101
- description="Whether the app has admin configuration"
102
- )
103
-
104
- has_tests: bool = Field(
105
- default=False,
106
- description="Whether the app has tests"
107
- )
108
-
109
- has_services: bool = Field(
110
- default=False,
111
- description="Whether the app uses service layer pattern"
112
- )
113
-
114
- has_async_views: bool = Field(
115
- default=False,
116
- description="Whether the app has async views"
117
- )
118
-
119
- # Pattern information
120
- model_patterns: List[str] = Field(
121
- default_factory=list,
122
- description="Patterns used in models"
123
- )
124
-
125
- view_patterns: List[str] = Field(
126
- default_factory=list,
127
- description="Patterns used in views"
128
- )
129
-
130
- service_patterns: List[str] = Field(
131
- default_factory=list,
132
- description="Patterns used in services"
133
- )
134
-
135
- test_patterns: List[str] = Field(
136
- default_factory=list,
137
- description="Patterns used in tests"
138
- )
139
-
140
- # Metrics
141
- dependencies: List[str] = Field(
142
- default_factory=list,
143
- description="External dependencies used by this app"
144
- )
145
-
146
- lines_of_code: int = Field(
147
- ge=0,
148
- default=0,
149
- description="Total lines of code in the app"
150
- )
151
-
152
- complexity_score: float = Field(
153
- ge=0.0,
154
- le=10.0,
155
- default=5.0,
156
- description="Complexity score of the app (0-10)"
157
- )
158
-
159
- quality_score: float = Field(
160
- ge=0.0,
161
- le=10.0,
162
- default=7.0,
163
- description="Quality score of the app (0-10)"
164
- )
165
-
166
- @field_validator('name')
167
- @classmethod
168
- def validate_app_name(cls, v: str) -> str:
169
- """Validate Django app name."""
170
- from ..utils.validation import validate_app_name
171
- return validate_app_name(v, check_reserved=False)
172
-
173
- @computed_field
174
- @property
175
- def features_implemented(self) -> Set[AppFeature]:
176
- """Get set of features implemented by this app."""
177
- features = set()
178
-
179
- if self.has_models:
180
- features.add(AppFeature.MODELS)
181
- if self.has_views:
182
- features.add(AppFeature.VIEWS)
183
- if self.has_admin:
184
- features.add(AppFeature.ADMIN)
185
- if self.has_tests:
186
- features.add(AppFeature.TESTS)
187
-
188
- return features
189
-
190
- @computed_field
191
- @property
192
- def all_patterns(self) -> Set[str]:
193
- """Get all patterns used in this app."""
194
- all_patterns = set()
195
- all_patterns.update(self.model_patterns)
196
- all_patterns.update(self.view_patterns)
197
- all_patterns.update(self.service_patterns)
198
- all_patterns.update(self.test_patterns)
199
- return all_patterns
200
-
201
- @computed_field
202
- @property
203
- def is_well_structured(self) -> bool:
204
- """Check if app follows good structure practices."""
205
- return (
206
- self.has_models and
207
- self.has_views and
208
- self.has_tests and
209
- self.quality_score >= 7.0
210
- )
211
-
212
- def get_integration_compatibility(self, other_app: "DjangoAppInfo") -> float:
213
- """Calculate compatibility score with another app."""
214
- # Compare patterns
215
- common_patterns = self.all_patterns & other_app.all_patterns
216
- total_patterns = self.all_patterns | other_app.all_patterns
217
-
218
- if not total_patterns:
219
- return 0.5 # Neutral if no patterns
220
-
221
- pattern_similarity = len(common_patterns) / len(total_patterns)
222
-
223
- # Compare dependencies
224
- common_deps = set(self.dependencies) & set(other_app.dependencies)
225
- total_deps = set(self.dependencies) | set(other_app.dependencies)
226
-
227
- if total_deps:
228
- dep_similarity = len(common_deps) / len(total_deps)
229
- else:
230
- dep_similarity = 1.0 # Perfect if no dependencies
231
-
232
- # Weighted average
233
- return (pattern_similarity * 0.7 + dep_similarity * 0.3)
234
-
235
-
236
- class ProjectContext(BaseAgentModel):
237
- """Context information about the Django project."""
238
-
239
- project_path: Path = Field(
240
- description="Path to the Django project root"
241
- )
242
-
243
- project_type: str = Field(
244
- default="django",
245
- description="Type of Django project (django, django_cfg)"
246
- )
247
-
248
- # Project structure
249
- django_apps: List[DjangoAppInfo] = Field(
250
- default_factory=list,
251
- description="Information about Django apps in the project"
252
- )
253
-
254
- # Architectural information
255
- architectural_patterns: List[str] = Field(
256
- default_factory=list,
257
- description="Architectural patterns used across the project"
258
- )
259
-
260
- security_features: List[str] = Field(
261
- default_factory=list,
262
- description="Security features implemented in the project"
263
- )
264
-
265
- performance_features: List[str] = Field(
266
- default_factory=list,
267
- description="Performance optimization features"
268
- )
269
-
270
- testing_patterns: List[str] = Field(
271
- default_factory=list,
272
- description="Testing patterns and frameworks used"
273
- )
274
-
275
- # Quality metrics
276
- documentation_level: str = Field(
277
- default="basic",
278
- description="Level of documentation (basic, good, comprehensive)"
279
- )
280
-
281
- code_quality_score: float = Field(
282
- ge=0.0,
283
- le=10.0,
284
- default=7.0,
285
- description="Overall code quality score"
286
- )
287
-
288
- type_safety_percentage: float = Field(
289
- ge=0.0,
290
- le=100.0,
291
- default=70.0,
292
- description="Percentage of code that is type-safe"
293
- )
294
-
295
- @field_validator('project_path')
296
- @classmethod
297
- def validate_project_path(cls, v: Path) -> Path:
298
- """Validate project path exists."""
299
- from ..utils.validation import validate_file_path
300
- return validate_file_path(v, must_exist=True, must_be_dir=True)
301
-
302
- @computed_field
303
- @property
304
- def total_apps_count(self) -> int:
305
- """Get total number of Django apps."""
306
- return len(self.django_apps)
307
-
308
- @computed_field
309
- @property
310
- def apps_with_tests_count(self) -> int:
311
- """Get number of apps with tests."""
312
- return sum(1 for app in self.django_apps if app.has_tests)
313
-
314
- @computed_field
315
- @property
316
- def test_coverage_percentage(self) -> float:
317
- """Calculate test coverage percentage."""
318
- if not self.django_apps:
319
- return 0.0
320
- return (self.apps_with_tests_count / self.total_apps_count) * 100
321
-
322
- @computed_field
323
- @property
324
- def common_patterns(self) -> Set[str]:
325
- """Get patterns that are common across multiple apps."""
326
- if len(self.django_apps) < 2:
327
- return set()
328
-
329
- pattern_counts: Dict[str, int] = {}
330
- for app in self.django_apps:
331
- for pattern in app.all_patterns:
332
- pattern_counts[pattern] = pattern_counts.get(pattern, 0) + 1
333
-
334
- # Patterns used in at least 50% of apps
335
- threshold = max(1, len(self.django_apps) // 2)
336
- return {pattern for pattern, count in pattern_counts.items() if count >= threshold}
337
-
338
- def get_app_by_name(self, name: str) -> Optional[DjangoAppInfo]:
339
- """Get app information by name."""
340
- for app in self.django_apps:
341
- if app.name == name:
342
- return app
343
- return None
344
-
345
- def get_apps_using_pattern(self, pattern: str) -> List[DjangoAppInfo]:
346
- """Get apps that use a specific pattern."""
347
- return [app for app in self.django_apps if pattern in app.all_patterns]
348
-
349
- def get_recommended_patterns_for_new_app(self) -> List[str]:
350
- """Get recommended patterns for a new app based on existing patterns."""
351
- # Prioritize common patterns
352
- common = list(self.common_patterns)
353
-
354
- # Add project-level architectural patterns
355
- project_patterns = [p for p in self.architectural_patterns if p not in common]
356
-
357
- return common + project_patterns
358
-
359
- def analyze_integration_opportunities(self, app_name: str) -> Dict[str, Any]:
360
- """Analyze integration opportunities for a new app."""
361
- similar_apps = []
362
- potential_dependencies = set()
363
-
364
- # Find apps with similar patterns
365
- for app in self.django_apps:
366
- if len(app.all_patterns) > 0:
367
- similar_apps.append({
368
- "name": app.name,
369
- "similarity_score": len(app.all_patterns & self.common_patterns) / len(app.all_patterns),
370
- "patterns": list(app.all_patterns)
371
- })
372
-
373
- # Sort by similarity
374
- similar_apps.sort(key=lambda x: x["similarity_score"], reverse=True)
375
-
376
- # Identify potential dependencies
377
- for app in self.django_apps:
378
- if app.has_models and "user" in app.name.lower():
379
- potential_dependencies.add(f"{app.name}.models")
380
-
381
- return {
382
- "similar_apps": similar_apps[:3], # Top 3 similar apps
383
- "potential_dependencies": list(potential_dependencies),
384
- "recommended_patterns": self.get_recommended_patterns_for_new_app(),
385
- "integration_complexity": "low" if len(similar_apps) > 0 else "medium"
386
- }
387
-
388
-
389
- class InfrastructureContext(BaseAgentModel):
390
- """Infrastructure context for code generation."""
391
-
392
- project_context: ProjectContext = Field(
393
- description="Project-level context information"
394
- )
395
-
396
- target_app_type: AppType = Field(
397
- description="Type of app being generated"
398
- )
399
-
400
- integration_targets: List[str] = Field(
401
- default_factory=list,
402
- description="Apps to integrate with"
403
- )
404
-
405
- # Generation constraints
406
- must_follow_patterns: List[str] = Field(
407
- default_factory=list,
408
- description="Patterns that must be followed"
409
- )
410
-
411
- avoid_patterns: List[str] = Field(
412
- default_factory=list,
413
- description="Patterns to avoid"
414
- )
415
-
416
- # Quality requirements
417
- minimum_quality_score: float = Field(
418
- ge=0.0,
419
- le=10.0,
420
- default=8.0,
421
- description="Minimum required quality score"
422
- )
423
-
424
- require_type_safety: bool = Field(
425
- default=True,
426
- description="Whether type safety is required"
427
- )
428
-
429
- require_tests: bool = Field(
430
- default=True,
431
- description="Whether tests are required"
432
- )
433
-
434
- # Infrastructure preferences
435
- preferred_async_style: str = Field(
436
- default="async_await",
437
- description="Preferred async programming style"
438
- )
439
-
440
- database_preferences: List[str] = Field(
441
- default_factory=list,
442
- description="Database-related preferences"
443
- )
444
-
445
- @computed_field
446
- @property
447
- def effective_patterns(self) -> List[str]:
448
- """Get effective patterns after applying constraints."""
449
- # Start with project patterns
450
- base_patterns = self.project_context.get_recommended_patterns_for_new_app()
451
-
452
- # Add must-follow patterns
453
- effective = list(set(base_patterns + self.must_follow_patterns))
454
-
455
- # Remove avoided patterns
456
- effective = [p for p in effective if p not in self.avoid_patterns]
457
-
458
- return effective
459
-
460
- @computed_field
461
- @property
462
- def integration_complexity(self) -> str:
463
- """Assess integration complexity."""
464
- if not self.integration_targets:
465
- return "none"
466
-
467
- if len(self.integration_targets) == 1:
468
- return "simple"
469
- elif len(self.integration_targets) <= 3:
470
- return "moderate"
471
- else:
472
- return "complex"
473
-
474
- def get_integration_requirements(self) -> Dict[str, Any]:
475
- """Get specific integration requirements."""
476
- requirements = {
477
- "imports_needed": [],
478
- "model_relationships": [],
479
- "service_dependencies": [],
480
- "url_integrations": []
481
- }
482
-
483
- for target_app_name in self.integration_targets:
484
- target_app = self.project_context.get_app_by_name(target_app_name)
485
- if target_app:
486
- if target_app.has_models:
487
- requirements["imports_needed"].append(f"{target_app_name}.models")
488
-
489
- if target_app.has_services:
490
- requirements["service_dependencies"].append(f"{target_app_name}.services")
491
-
492
- # Check for user model integration
493
- if "user" in target_app_name.lower():
494
- requirements["model_relationships"].append("User foreign key relationships")
495
-
496
- return requirements