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,125 +0,0 @@
1
- """
2
- Validation Module for Django App Agent Generation.
3
-
4
- This module handles validation of generation requirements,
5
- feature compatibility, and generated code quality.
6
- """
7
-
8
- from typing import List, Dict, Any
9
- from pathlib import Path
10
-
11
- from ..base import ServiceDependencies
12
- from ...core.exceptions import ValidationError, FileSystemError
13
- from ...models.responses import ValidationIssue, QualityMetrics
14
- from ...models.enums import ValidationSeverity
15
- from .context import GenerationContext
16
-
17
-
18
- class GenerationValidator:
19
- """Handles validation during application generation process."""
20
-
21
- async def validate_generation_requirements(
22
- self,
23
- context: GenerationContext,
24
- dependencies: ServiceDependencies
25
- ) -> None:
26
- """Validate that generation can proceed."""
27
- # Check if app directory already exists
28
- if context.app_directory.exists():
29
- raise ValidationError(
30
- f"Application directory already exists: {context.app_directory}",
31
- validation_type="directory_exists"
32
- )
33
-
34
- # Check if target directory is writable
35
- if not context.target_directory.exists():
36
- try:
37
- context.target_directory.mkdir(parents=True, exist_ok=True)
38
- except Exception as e:
39
- raise FileSystemError(
40
- f"Cannot create target directory: {e}",
41
- file_path=str(context.target_directory),
42
- operation="create_directory"
43
- )
44
-
45
- # Validate feature compatibility
46
- await self.validate_feature_compatibility(context, dependencies)
47
-
48
- async def validate_feature_compatibility(
49
- self,
50
- context: GenerationContext,
51
- dependencies: ServiceDependencies
52
- ) -> None:
53
- """Validate that requested features are compatible."""
54
- request = context.request
55
-
56
- # Check app type compatibility
57
- for feature in request.features:
58
- if not request.app_type.supports_feature(feature):
59
- raise ValidationError(
60
- f"Feature {feature.value} is not supported by app type {request.app_type.value}",
61
- validation_type="feature_compatibility"
62
- )
63
-
64
- # Check complexity compatibility
65
- recommended_features = request.complexity.get_recommended_features()
66
- missing_recommended = recommended_features - set(request.features)
67
-
68
- if missing_recommended:
69
- dependencies.logger.warning(
70
- f"Missing recommended features for {request.complexity.value} complexity",
71
- missing_features=[f.value for f in missing_recommended]
72
- )
73
-
74
- async def validate_generated_code(
75
- self,
76
- context: GenerationContext,
77
- dependencies: ServiceDependencies
78
- ) -> QualityMetrics:
79
- """Validate generated code quality and return metrics."""
80
- dependencies.log_operation("Validating generated code quality")
81
-
82
- validation_issues = []
83
- total_files = len(context.generated_files)
84
- valid_files = 0
85
-
86
- for generated_file in context.generated_files:
87
- try:
88
- # Basic syntax validation for Python files
89
- if generated_file.file_type == "python":
90
- compile(generated_file.content, generated_file.path, 'exec')
91
- valid_files += 1
92
- else:
93
- valid_files += 1 # Non-Python files are considered valid for now
94
-
95
- except SyntaxError as e:
96
- validation_issues.append(ValidationIssue(
97
- file_path=generated_file.path,
98
- line_number=e.lineno or 1,
99
- severity=ValidationSeverity.ERROR,
100
- message=f"Syntax error: {e.msg}",
101
- rule_id="syntax_error"
102
- ))
103
-
104
- # Calculate quality metrics
105
- syntax_score = (valid_files / total_files * 100) if total_files > 0 else 100
106
-
107
- # Store validation results in context
108
- context.validation_results.update({
109
- "total_files": total_files,
110
- "valid_files": valid_files,
111
- "validation_issues": [issue.model_dump() for issue in validation_issues],
112
- "syntax_score": syntax_score
113
- })
114
-
115
- return QualityMetrics(
116
- overall_score=min(10.0, syntax_score * 0.8), # Weighted average
117
- type_safety_score=8.5, # Placeholder - would need actual type checking
118
- pattern_consistency=9.0, # Placeholder - would need pattern analysis
119
- code_complexity=7.5, # Placeholder - would need complexity analysis
120
- test_coverage=0.0, # No tests generated yet
121
- documentation_coverage=60.0, # Basic docstrings (percentage)
122
- performance_score=8.0, # Placeholder
123
- security_score=8.5, # Placeholder
124
- maintainability_score=min(10.0, syntax_score * 0.9)
125
- )
@@ -1,437 +0,0 @@
1
- """
2
- Base service classes for Django App Agent Module.
3
-
4
- This module provides the foundation for all business logic services,
5
- including common patterns for dependency injection, error handling,
6
- logging, and async operations.
7
- """
8
-
9
- from typing import TypeVar, Generic, Optional, Dict, Any, List, Union
10
- from abc import ABC, abstractmethod
11
- from datetime import datetime, timezone
12
- from pathlib import Path
13
- import asyncio
14
- import uuid
15
-
16
- from pydantic import BaseModel, Field, ConfigDict
17
-
18
- from ..core.config import AgentConfig
19
- from ..core.exceptions import DjangoAppAgentError, ValidationError
20
- from ..utils.logging import StructuredLogger, get_logger
21
-
22
- # Type variables for generic service operations
23
- InputT = TypeVar('InputT')
24
- OutputT = TypeVar('OutputT')
25
-
26
-
27
- class ServiceError(DjangoAppAgentError):
28
- """Base exception for service layer errors."""
29
-
30
- def __init__(
31
- self,
32
- message: str,
33
- service_name: str,
34
- operation: str,
35
- details: Optional[Dict[str, Any]] = None
36
- ):
37
- super().__init__(message, details)
38
- self.service_name = service_name
39
- self.operation = operation
40
-
41
-
42
- class ServiceResult(BaseModel, Generic[OutputT]):
43
- """Standard result wrapper for service operations."""
44
-
45
- model_config = ConfigDict(
46
- extra='forbid',
47
- validate_assignment=True,
48
- arbitrary_types_allowed=True
49
- )
50
-
51
- # Result metadata
52
- operation_id: str = Field(description="Unique operation identifier")
53
- service_name: str = Field(description="Name of the service that produced this result")
54
- operation_name: str = Field(description="Name of the operation performed")
55
-
56
- # Execution information
57
- success: bool = Field(description="Whether the operation was successful")
58
- start_time: datetime = Field(description="Operation start time")
59
- end_time: Optional[datetime] = Field(default=None, description="Operation end time")
60
-
61
- # Result data
62
- data: Optional[OutputT] = Field(default=None, description="Operation result data")
63
- error: Optional[str] = Field(default=None, description="Error message if failed")
64
-
65
- # Performance metrics
66
- execution_time_seconds: float = Field(default=0.0, description="Total execution time")
67
- memory_usage_mb: Optional[float] = Field(default=None, description="Peak memory usage")
68
-
69
- # Context information
70
- metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
71
- warnings: List[str] = Field(default_factory=list, description="Operation warnings")
72
-
73
- @property
74
- def is_successful(self) -> bool:
75
- """Check if operation was successful."""
76
- return self.success and self.error is None
77
-
78
- @property
79
- def is_failed(self) -> bool:
80
- """Check if operation failed."""
81
- return not self.success or self.error is not None
82
-
83
- def mark_completed(self, data: Optional[OutputT] = None) -> None:
84
- """Mark operation as successfully completed."""
85
- self.end_time = datetime.now(timezone.utc)
86
- self.execution_time_seconds = (self.end_time - self.start_time).total_seconds()
87
- self.success = True
88
- if data is not None:
89
- self.data = data
90
-
91
- def mark_failed(self, error: str, details: Optional[Dict[str, Any]] = None) -> None:
92
- """Mark operation as failed."""
93
- self.end_time = datetime.now(timezone.utc)
94
- self.execution_time_seconds = (self.end_time - self.start_time).total_seconds()
95
- self.success = False
96
- self.error = error
97
- if details:
98
- self.metadata.update(details)
99
-
100
- def add_warning(self, warning: str) -> None:
101
- """Add a warning to the result."""
102
- self.warnings.append(warning)
103
-
104
- def get_summary(self) -> Dict[str, Any]:
105
- """Get operation summary."""
106
- return {
107
- "operation_id": self.operation_id,
108
- "service_name": self.service_name,
109
- "operation_name": self.operation_name,
110
- "success": self.success,
111
- "execution_time_seconds": self.execution_time_seconds,
112
- "has_data": self.data is not None,
113
- "has_error": self.error is not None,
114
- "warnings_count": len(self.warnings),
115
- "metadata_keys": list(self.metadata.keys())
116
- }
117
-
118
-
119
- class ServiceDependencies(BaseModel):
120
- """Dependencies for service operations."""
121
-
122
- model_config = ConfigDict(
123
- extra='forbid',
124
- validate_assignment=True,
125
- arbitrary_types_allowed=True
126
- )
127
-
128
- config: AgentConfig = Field(description="Agent configuration")
129
- logger: StructuredLogger = Field(description="Structured logger instance")
130
- operation_id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Unique operation ID")
131
- project_root: Optional[Path] = Field(default=None, description="Project root directory")
132
- output_directory: Optional[Path] = Field(default=None, description="Output directory")
133
- context_data: Dict[str, Any] = Field(default_factory=dict, description="Additional context data")
134
-
135
- def get_project_path(self) -> Path:
136
- """Get project root path."""
137
- return self.project_root or Path.cwd()
138
-
139
- def get_output_path(self) -> Path:
140
- """Get output directory path."""
141
- return self.output_directory or self.get_project_path()
142
-
143
- def log_operation(self, message: str, **kwargs: Any) -> None:
144
- """Log operation with context."""
145
- self.logger.info(
146
- message,
147
- operation_id=self.operation_id,
148
- **kwargs
149
- )
150
-
151
- def log_error(self, message: str, error: Exception, **kwargs: Any) -> None:
152
- """Log error with context."""
153
- self.logger.error(
154
- message,
155
- operation_id=self.operation_id,
156
- error=str(error),
157
- error_type=type(error).__name__,
158
- **kwargs
159
- )
160
-
161
-
162
- class BaseService(ABC, Generic[InputT, OutputT]):
163
- """
164
- Abstract base class for all services in the Django App Agent module.
165
-
166
- Provides common functionality for:
167
- - Dependency injection and configuration
168
- - Structured logging and error handling
169
- - Operation tracking and metrics
170
- - Async operation support
171
- - Type safety with generics
172
- """
173
-
174
- def __init__(self, service_name: str, config: AgentConfig):
175
- """Initialize base service.
176
-
177
- Args:
178
- service_name: Name of the service for logging and identification
179
- config: Agent configuration
180
- """
181
- self.service_name = service_name
182
- self.config = config
183
- self.logger = get_logger(f"services.{service_name}")
184
- self._active_operations: Dict[str, ServiceResult] = {}
185
-
186
- def create_dependencies(
187
- self,
188
- operation_id: Optional[str] = None,
189
- project_root: Optional[Path] = None,
190
- output_directory: Optional[Path] = None,
191
- **context_data: Any
192
- ) -> ServiceDependencies:
193
- """Create service dependencies for an operation.
194
-
195
- Args:
196
- operation_id: Optional operation ID
197
- project_root: Optional project root directory
198
- output_directory: Optional output directory
199
- **context_data: Additional context data
200
-
201
- Returns:
202
- ServiceDependencies instance
203
- """
204
- return ServiceDependencies(
205
- config=self.config,
206
- logger=self.logger,
207
- operation_id=operation_id or str(uuid.uuid4()),
208
- project_root=project_root,
209
- output_directory=output_directory,
210
- context_data=context_data
211
- )
212
-
213
- def create_result(
214
- self,
215
- operation_name: str,
216
- operation_id: Optional[str] = None
217
- ) -> ServiceResult[OutputT]:
218
- """Create a new service result.
219
-
220
- Args:
221
- operation_name: Name of the operation
222
- operation_id: Optional operation ID
223
-
224
- Returns:
225
- ServiceResult instance
226
- """
227
- op_id = operation_id or str(uuid.uuid4())
228
- result = ServiceResult[OutputT](
229
- operation_id=op_id,
230
- service_name=self.service_name,
231
- operation_name=operation_name,
232
- success=False,
233
- start_time=datetime.now(timezone.utc)
234
- )
235
-
236
- # Track active operation
237
- self._active_operations[op_id] = result
238
-
239
- return result
240
-
241
- def complete_operation(self, result: ServiceResult[OutputT]) -> None:
242
- """Complete an operation and remove from active tracking.
243
-
244
- Args:
245
- result: The completed service result
246
- """
247
- # Remove from active operations
248
- self._active_operations.pop(result.operation_id, None)
249
-
250
- # Log completion
251
- self.logger.info(
252
- f"Operation {result.operation_name} completed",
253
- operation_id=result.operation_id,
254
- success=result.success,
255
- execution_time_seconds=result.execution_time_seconds,
256
- has_warnings=len(result.warnings) > 0
257
- )
258
-
259
- async def execute_with_result(
260
- self,
261
- operation_name: str,
262
- operation_func: callable,
263
- dependencies: ServiceDependencies,
264
- *args: Any,
265
- **kwargs: Any
266
- ) -> ServiceResult[OutputT]:
267
- """Execute an operation with automatic result tracking.
268
-
269
- Args:
270
- operation_name: Name of the operation
271
- operation_func: Function to execute
272
- dependencies: Service dependencies
273
- *args: Positional arguments for operation_func
274
- **kwargs: Keyword arguments for operation_func
275
-
276
- Returns:
277
- ServiceResult with operation outcome
278
- """
279
- result = self.create_result(operation_name, dependencies.operation_id)
280
-
281
- try:
282
- # Execute operation
283
- if asyncio.iscoroutinefunction(operation_func):
284
- data = await operation_func(dependencies, *args, **kwargs)
285
- else:
286
- data = operation_func(dependencies, *args, **kwargs)
287
-
288
- # Mark as completed
289
- result.mark_completed(data)
290
-
291
- except Exception as e:
292
- # Mark as failed
293
- error_msg = f"Operation {operation_name} failed: {e}"
294
- result.mark_failed(error_msg, {"exception_type": type(e).__name__})
295
-
296
- # Log error
297
- dependencies.log_error(error_msg, e)
298
-
299
- # Re-raise if it's a service error, otherwise wrap it
300
- if isinstance(e, ServiceError):
301
- raise
302
- else:
303
- raise ServiceError(
304
- error_msg,
305
- service_name=self.service_name,
306
- operation=operation_name,
307
- cause=e
308
- ) from e
309
-
310
- finally:
311
- # Complete operation tracking
312
- self.complete_operation(result)
313
-
314
- return result
315
-
316
- @abstractmethod
317
- async def process(self, input_data: InputT, dependencies: ServiceDependencies) -> OutputT:
318
- """
319
- Process input data and return output.
320
-
321
- This is the main method that subclasses must implement.
322
-
323
- Args:
324
- input_data: Input data for processing
325
- dependencies: Service dependencies
326
-
327
- Returns:
328
- Processed output data
329
- """
330
- pass
331
-
332
- async def run(
333
- self,
334
- input_data: InputT,
335
- operation_id: Optional[str] = None,
336
- project_root: Optional[Path] = None,
337
- output_directory: Optional[Path] = None,
338
- **context_data: Any
339
- ) -> ServiceResult[OutputT]:
340
- """
341
- Run the service with input data and return a result.
342
-
343
- Args:
344
- input_data: Input data for processing
345
- operation_id: Optional operation ID
346
- project_root: Optional project root directory
347
- output_directory: Optional output directory
348
- **context_data: Additional context data
349
-
350
- Returns:
351
- ServiceResult with operation outcome
352
- """
353
- # Create dependencies
354
- dependencies = self.create_dependencies(
355
- operation_id=operation_id,
356
- project_root=project_root,
357
- output_directory=output_directory,
358
- **context_data
359
- )
360
-
361
- # Execute with result tracking
362
- return await self.execute_with_result(
363
- "process",
364
- self.process,
365
- dependencies,
366
- input_data
367
- )
368
-
369
- def get_active_operations(self) -> Dict[str, ServiceResult]:
370
- """Get currently active operations."""
371
- return self._active_operations.copy()
372
-
373
- def get_service_status(self) -> Dict[str, Any]:
374
- """Get service status information."""
375
- return {
376
- "service_name": self.service_name,
377
- "active_operations_count": len(self._active_operations),
378
- "active_operation_ids": list(self._active_operations.keys()),
379
- "config_loaded": self.config is not None,
380
- "logger_configured": self.logger is not None
381
- }
382
-
383
- def validate_input(self, input_data: InputT) -> None:
384
- """
385
- Validate input data before processing.
386
-
387
- Override this method to add custom validation logic.
388
-
389
- Args:
390
- input_data: Input data to validate
391
-
392
- Raises:
393
- ValidationError: If input data is invalid
394
- """
395
- if input_data is None:
396
- raise ValidationError(
397
- "Input data cannot be None",
398
- validation_type="input_validation"
399
- )
400
-
401
- def __repr__(self) -> str:
402
- """String representation of the service."""
403
- return f"{self.__class__.__name__}(service_name='{self.service_name}')"
404
-
405
-
406
- def create_service_dependencies(
407
- config: AgentConfig,
408
- service_name: str,
409
- operation_id: Optional[str] = None,
410
- project_root: Optional[Path] = None,
411
- output_directory: Optional[Path] = None,
412
- **context_data: Any
413
- ) -> ServiceDependencies:
414
- """
415
- Factory function to create service dependencies.
416
-
417
- Args:
418
- config: Agent configuration
419
- service_name: Name of the service
420
- operation_id: Optional operation ID
421
- project_root: Optional project root directory
422
- output_directory: Optional output directory
423
- **context_data: Additional context data
424
-
425
- Returns:
426
- ServiceDependencies instance
427
- """
428
- logger = get_logger(f"services.{service_name}")
429
-
430
- return ServiceDependencies(
431
- config=config,
432
- logger=logger,
433
- operation_id=operation_id or str(uuid.uuid4()),
434
- project_root=project_root,
435
- output_directory=output_directory,
436
- context_data=context_data
437
- )
@@ -1,34 +0,0 @@
1
- """
2
- Context Builder Module for Django App Agent.
3
-
4
- This module provides comprehensive context building capabilities
5
- for AI agents, including project analysis, pattern identification,
6
- and intelligent context optimization.
7
-
8
- Components:
9
- - models: Data models for requests and results
10
- - pattern_analyzer: Architectural pattern analysis
11
- - code_extractor: Code sample extraction
12
- - context_generator: Feature-specific context generation
13
- - main: Main orchestration service
14
- """
15
-
16
- from .main import ContextBuilderService
17
- from .models import ContextBuildRequest, ContextResult
18
- from .pattern_analyzer import PatternAnalyzer
19
- from .code_extractor import CodeExtractor
20
- from .context_generator import ContextGenerator
21
-
22
- __all__ = [
23
- # Main service
24
- "ContextBuilderService",
25
-
26
- # Data models
27
- "ContextBuildRequest",
28
- "ContextResult",
29
-
30
- # Core components
31
- "PatternAnalyzer",
32
- "CodeExtractor",
33
- "ContextGenerator",
34
- ]