django-cfg 1.4.107__py3-none-any.whl → 1.4.108__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.

Potentially problematic release.


This version of django-cfg might be problematic. Click here for more details.

Files changed (130) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/accounts/views/profile.py +19 -9
  3. django_cfg/apps/centrifugo/views/admin_api.py +4 -7
  4. django_cfg/apps/centrifugo/views/monitoring.py +3 -6
  5. django_cfg/apps/centrifugo/views/testing_api.py +3 -6
  6. django_cfg/apps/dashboard/services/system_health_service.py +16 -11
  7. django_cfg/apps/dashboard/views/activity_views.py +3 -5
  8. django_cfg/apps/dashboard/views/apizones_views.py +4 -5
  9. django_cfg/apps/dashboard/views/charts_views.py +4 -5
  10. django_cfg/apps/dashboard/views/overview_views.py +4 -5
  11. django_cfg/apps/dashboard/views/statistics_views.py +4 -5
  12. django_cfg/apps/dashboard/views/system_views.py +4 -5
  13. django_cfg/apps/knowbase/__init__.py +2 -2
  14. django_cfg/apps/knowbase/apps.py +2 -8
  15. django_cfg/apps/knowbase/views/base.py +9 -4
  16. django_cfg/apps/support/views/api.py +16 -7
  17. django_cfg/apps/tasks/__init__.py +61 -2
  18. django_cfg/apps/tasks/admin/__init__.py +3 -10
  19. django_cfg/apps/tasks/admin/config.py +98 -0
  20. django_cfg/apps/tasks/admin/task_log.py +265 -0
  21. django_cfg/apps/tasks/apps.py +7 -9
  22. django_cfg/apps/tasks/filters/__init__.py +10 -0
  23. django_cfg/apps/tasks/filters/task_log.py +121 -0
  24. django_cfg/apps/tasks/migrations/0001_initial.py +196 -0
  25. django_cfg/apps/tasks/models/__init__.py +4 -0
  26. django_cfg/apps/tasks/models/task_log.py +246 -0
  27. django_cfg/apps/tasks/serializers/__init__.py +28 -0
  28. django_cfg/apps/tasks/serializers/task_log.py +249 -0
  29. django_cfg/apps/tasks/services/__init__.py +10 -0
  30. django_cfg/apps/tasks/services/client/__init__.py +7 -0
  31. django_cfg/apps/tasks/services/client/client.py +234 -0
  32. django_cfg/apps/tasks/services/config_helper.py +63 -0
  33. django_cfg/apps/tasks/services/sync.py +204 -0
  34. django_cfg/apps/tasks/urls.py +7 -13
  35. django_cfg/apps/tasks/views/__init__.py +4 -10
  36. django_cfg/apps/tasks/views/task_log.py +41 -0
  37. django_cfg/apps/tasks/views/task_log_base.py +41 -0
  38. django_cfg/apps/tasks/views/task_log_overview.py +100 -0
  39. django_cfg/apps/tasks/views/task_log_related.py +41 -0
  40. django_cfg/apps/tasks/views/task_log_stats.py +91 -0
  41. django_cfg/apps/tasks/views/task_log_timeline.py +81 -0
  42. django_cfg/apps/urls.py +0 -1
  43. django_cfg/cli/commands/info.py +1 -1
  44. django_cfg/cli/utils.py +1 -1
  45. django_cfg/core/base/config_model.py +1 -1
  46. django_cfg/core/builders/apps_builder.py +1 -1
  47. django_cfg/core/generation/integration_generators/__init__.py +1 -1
  48. django_cfg/core/generation/integration_generators/tasks.py +14 -18
  49. django_cfg/core/generation/security_generators/crypto_fields.py +2 -1
  50. django_cfg/core/integration/display/startup.py +1 -1
  51. django_cfg/mixins/__init__.py +12 -0
  52. django_cfg/mixins/admin_api.py +37 -0
  53. django_cfg/mixins/client_api.py +39 -0
  54. django_cfg/models/django/constance.py +2 -8
  55. django_cfg/models/django/crypto_fields.py +13 -48
  56. django_cfg/models/tasks/__init__.py +8 -10
  57. django_cfg/models/tasks/backends.py +76 -207
  58. django_cfg/models/tasks/config.py +20 -127
  59. django_cfg/models/tasks/utils.py +17 -29
  60. django_cfg/modules/django_client/management/commands/generate_client.py +13 -1
  61. django_cfg/modules/django_unfold/navigation.py +121 -22
  62. django_cfg/pyproject.toml +2 -2
  63. django_cfg/registry/core.py +1 -1
  64. django_cfg/static/frontend/admin.zip +0 -0
  65. {django_cfg-1.4.107.dist-info → django_cfg-1.4.108.dist-info}/METADATA +3 -3
  66. {django_cfg-1.4.107.dist-info → django_cfg-1.4.108.dist-info}/RECORD +70 -107
  67. django_cfg/apps/tasks/admin/actions.py +0 -29
  68. django_cfg/apps/tasks/admin/tasks_admin.py +0 -154
  69. django_cfg/apps/tasks/api/serializers.py +0 -82
  70. django_cfg/apps/tasks/api/views.py +0 -571
  71. django_cfg/apps/tasks/serializers.py +0 -82
  72. django_cfg/apps/tasks/static/tasks/css/dashboard-alpine.css +0 -299
  73. django_cfg/apps/tasks/static/tasks/css/dashboard.css +0 -120
  74. django_cfg/apps/tasks/static/tasks/js/alpine/README.md +0 -47
  75. django_cfg/apps/tasks/static/tasks/js/alpine/actions/index.js +0 -8
  76. django_cfg/apps/tasks/static/tasks/js/alpine/actions/management.js +0 -123
  77. django_cfg/apps/tasks/static/tasks/js/alpine/actions/pagination.js +0 -21
  78. django_cfg/apps/tasks/static/tasks/js/alpine/actions/tasks.js +0 -101
  79. django_cfg/apps/tasks/static/tasks/js/alpine/actions/workers.js +0 -59
  80. django_cfg/apps/tasks/static/tasks/js/alpine/computed.js +0 -35
  81. django_cfg/apps/tasks/static/tasks/js/alpine/index.js +0 -148
  82. django_cfg/apps/tasks/static/tasks/js/alpine/loaders/index.js +0 -36
  83. django_cfg/apps/tasks/static/tasks/js/alpine/loaders/overview.js +0 -37
  84. django_cfg/apps/tasks/static/tasks/js/alpine/loaders/queues.js +0 -27
  85. django_cfg/apps/tasks/static/tasks/js/alpine/loaders/tasks.js +0 -32
  86. django_cfg/apps/tasks/static/tasks/js/alpine/loaders/workers.js +0 -21
  87. django_cfg/apps/tasks/static/tasks/js/alpine/state.js +0 -36
  88. django_cfg/apps/tasks/static/tasks/js/alpine/utils/formatters.js +0 -42
  89. django_cfg/apps/tasks/static/tasks/js/alpine/utils/helpers.js +0 -68
  90. django_cfg/apps/tasks/static/tasks/js/dashboard-alpine.js +0 -725
  91. django_cfg/apps/tasks/tasks/__init__.py +0 -10
  92. django_cfg/apps/tasks/tasks/demo_tasks.py +0 -127
  93. django_cfg/apps/tasks/templates/tasks/components/management_actions.html +0 -71
  94. django_cfg/apps/tasks/templates/tasks/components/overview_content.html +0 -94
  95. django_cfg/apps/tasks/templates/tasks/components/queues_content.html +0 -44
  96. django_cfg/apps/tasks/templates/tasks/components/tab_navigation.html +0 -45
  97. django_cfg/apps/tasks/templates/tasks/components/task_details_modal.html +0 -151
  98. django_cfg/apps/tasks/templates/tasks/components/tasks_content.html +0 -61
  99. django_cfg/apps/tasks/templates/tasks/components/tasks_mjs_integration.html +0 -269
  100. django_cfg/apps/tasks/templates/tasks/components/workers_content.html +0 -60
  101. django_cfg/apps/tasks/templates/tasks/layout/base.html +0 -20
  102. django_cfg/apps/tasks/templates/tasks/pages/dashboard-improved.html +0 -168
  103. django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +0 -77
  104. django_cfg/apps/tasks/templates/tasks/partials/task_row_template.html +0 -40
  105. django_cfg/apps/tasks/templates/tasks/widgets/task_filters.html +0 -40
  106. django_cfg/apps/tasks/templates/tasks/widgets/task_footer.html +0 -86
  107. django_cfg/apps/tasks/templates/tasks/widgets/task_table.html +0 -90
  108. django_cfg/apps/tasks/urls_admin.py +0 -15
  109. django_cfg/apps/tasks/utils/__init__.py +0 -1
  110. django_cfg/apps/tasks/utils/simulator.py +0 -353
  111. django_cfg/apps/tasks/views/api.py +0 -571
  112. django_cfg/apps/tasks/views/dashboard.py +0 -89
  113. django_cfg/management/commands/rundramatiq.py +0 -24
  114. django_cfg/management/commands/rundramatiq_simulator.py +0 -22
  115. django_cfg/management/commands/task_clear.py +0 -25
  116. django_cfg/management/commands/task_status.py +0 -24
  117. django_cfg/modules/django_tasks/__init__.py +0 -29
  118. django_cfg/modules/django_tasks/dramatiq_setup.py +0 -20
  119. django_cfg/modules/django_tasks/factory.py +0 -127
  120. django_cfg/modules/django_tasks/management/commands/__init__.py +0 -0
  121. django_cfg/modules/django_tasks/management/commands/rundramatiq.py +0 -253
  122. django_cfg/modules/django_tasks/management/commands/rundramatiq_simulator.py +0 -436
  123. django_cfg/modules/django_tasks/management/commands/task_clear.py +0 -226
  124. django_cfg/modules/django_tasks/management/commands/task_status.py +0 -257
  125. django_cfg/modules/django_tasks/service.py +0 -281
  126. django_cfg/modules/django_tasks/settings.py +0 -107
  127. /django_cfg/{modules/django_tasks/management → apps/tasks/migrations}/__init__.py +0 -0
  128. {django_cfg-1.4.107.dist-info → django_cfg-1.4.108.dist-info}/WHEEL +0 -0
  129. {django_cfg-1.4.107.dist-info → django_cfg-1.4.108.dist-info}/entry_points.txt +0 -0
  130. {django_cfg-1.4.107.dist-info → django_cfg-1.4.108.dist-info}/licenses/LICENSE +0 -0
django_cfg/__init__.py CHANGED
@@ -32,7 +32,7 @@ Example:
32
32
  default_app_config = "django_cfg.apps.DjangoCfgConfig"
33
33
 
34
34
  # Version information
35
- __version__ = "1.4.107"
35
+ __version__ = "1.4.108"
36
36
  __license__ = "MIT"
37
37
 
38
38
  # Import registry for organized lazy loading
@@ -4,6 +4,7 @@ from rest_framework import generics, permissions, status
4
4
  from rest_framework.decorators import api_view, permission_classes
5
5
  from rest_framework.response import Response
6
6
 
7
+ from django_cfg.mixins import ClientAPIMixin
7
8
  from ..serializers.profile import (
8
9
  AvatarUploadSerializer,
9
10
  UserProfileUpdateSerializer,
@@ -22,10 +23,13 @@ User = get_user_model()
22
23
  401: {"description": "Authentication credentials were not provided."}
23
24
  }
24
25
  )
25
- class UserProfileView(generics.RetrieveAPIView):
26
- """Get current user profile details."""
26
+ class UserProfileView(ClientAPIMixin, generics.RetrieveAPIView):
27
+ """
28
+ Get current user profile details.
29
+
30
+ Requires authenticated user (JWT or Session).
31
+ """
27
32
  serializer_class = UserSerializer
28
- permission_classes = [permissions.IsAuthenticated]
29
33
 
30
34
  def get_object(self):
31
35
  return self.request.user
@@ -56,10 +60,13 @@ class UserProfileView(generics.RetrieveAPIView):
56
60
  )
57
61
  ]
58
62
  )
59
- class UserProfileUpdateView(generics.UpdateAPIView):
60
- """Update current user profile."""
63
+ class UserProfileUpdateView(ClientAPIMixin, generics.UpdateAPIView):
64
+ """
65
+ Update current user profile.
66
+
67
+ Requires authenticated user (JWT or Session).
68
+ """
61
69
  serializer_class = UserProfileUpdateSerializer
62
- permission_classes = [permissions.IsAuthenticated]
63
70
 
64
71
  def get_object(self):
65
72
  return self.request.user
@@ -102,10 +109,13 @@ class UserProfileUpdateView(generics.UpdateAPIView):
102
109
  )
103
110
  ]
104
111
  )
105
- class UserProfilePartialUpdateView(generics.UpdateAPIView):
106
- """Partially update current user profile."""
112
+ class UserProfilePartialUpdateView(ClientAPIMixin, generics.UpdateAPIView):
113
+ """
114
+ Partially update current user profile.
115
+
116
+ Requires authenticated user (JWT or Session).
117
+ """
107
118
  serializer_class = UserProfileUpdateSerializer
108
- permission_classes = [permissions.IsAuthenticated]
109
119
 
110
120
  def get_object(self):
111
121
  return self.request.user
@@ -11,11 +11,10 @@ from django.http import JsonResponse
11
11
  from django_cfg.modules.django_logging import get_logger
12
12
  from drf_spectacular.utils import OpenApiParameter, extend_schema
13
13
  from rest_framework import status, viewsets
14
- from rest_framework.authentication import SessionAuthentication
15
14
  from rest_framework.decorators import action
16
- from rest_framework.permissions import IsAdminUser
17
15
  from rest_framework.response import Response
18
16
 
17
+ from django_cfg.mixins import AdminAPIMixin
19
18
  from ..serializers import (
20
19
  CentrifugoInfoRequest,
21
20
  CentrifugoInfoResponse,
@@ -33,17 +32,15 @@ from ..services import get_centrifugo_config
33
32
  logger = get_logger("centrifugo.admin_api")
34
33
 
35
34
 
36
- class CentrifugoAdminAPIViewSet(viewsets.ViewSet):
35
+ class CentrifugoAdminAPIViewSet(AdminAPIMixin, viewsets.ViewSet):
37
36
  """
38
37
  Centrifugo Admin API Proxy ViewSet.
39
38
 
40
39
  Provides type-safe proxy endpoints to Centrifugo server API.
41
- All requests are authenticated via Django session and proxied to Centrifugo.
40
+ All requests are authenticated via Django session/JWT and proxied to Centrifugo.
41
+ Requires admin authentication (JWT, Session, or Basic Auth).
42
42
  """
43
43
 
44
- # authentication_classes = [SessionAuthentication]
45
- permission_classes = [IsAdminUser]
46
-
47
44
  def __init__(self, *args, **kwargs):
48
45
  super().__init__(*args, **kwargs)
49
46
  self._http_client = None
@@ -13,11 +13,10 @@ from django_cfg.modules.django_logging import get_logger
13
13
  from drf_spectacular.types import OpenApiTypes
14
14
  from drf_spectacular.utils import OpenApiParameter, extend_schema
15
15
  from rest_framework import status, viewsets
16
- from rest_framework.authentication import SessionAuthentication
17
16
  from rest_framework.decorators import action
18
- from rest_framework.permissions import IsAdminUser
19
17
  from rest_framework.response import Response
20
18
 
19
+ from django_cfg.mixins import AdminAPIMixin
21
20
  from ..models import CentrifugoLog
22
21
  from ..serializers import (
23
22
  ChannelListSerializer,
@@ -31,7 +30,7 @@ from ..services import get_centrifugo_config
31
30
  logger = get_logger("centrifugo.monitoring")
32
31
 
33
32
 
34
- class CentrifugoMonitorViewSet(viewsets.ViewSet):
33
+ class CentrifugoMonitorViewSet(AdminAPIMixin, viewsets.ViewSet):
35
34
  """
36
35
  ViewSet for Centrifugo monitoring and statistics.
37
36
 
@@ -40,11 +39,9 @@ class CentrifugoMonitorViewSet(viewsets.ViewSet):
40
39
  - Overview statistics
41
40
  - Recent publishes
42
41
  - Channel-level statistics
42
+ Requires admin authentication (JWT, Session, or Basic Auth).
43
43
  """
44
44
 
45
- # authentication_classes = [SessionAuthentication]
46
- permission_classes = [IsAdminUser]
47
-
48
45
  @extend_schema(
49
46
  tags=["Centrifugo Monitoring"],
50
47
  summary="Get Centrifugo health status",
@@ -17,11 +17,10 @@ from django_cfg.modules.django_logging import get_logger
17
17
  from drf_spectacular.utils import extend_schema
18
18
  from pydantic import BaseModel, Field
19
19
  from rest_framework import status, viewsets
20
- from rest_framework.authentication import SessionAuthentication
21
20
  from rest_framework.decorators import action
22
- from rest_framework.permissions import IsAdminUser
23
21
  from rest_framework.response import Response
24
22
 
23
+ from django_cfg.mixins import AdminAPIMixin
25
24
  from ..services import get_centrifugo_config
26
25
  from ..services.client import CentrifugoClient
27
26
 
@@ -94,18 +93,16 @@ class ManualAckResponse(BaseModel):
94
93
  # ========================================================================
95
94
 
96
95
 
97
- class CentrifugoTestingAPIViewSet(viewsets.ViewSet):
96
+ class CentrifugoTestingAPIViewSet(AdminAPIMixin, viewsets.ViewSet):
98
97
  """
99
98
  Centrifugo Testing API ViewSet.
100
99
 
101
100
  Provides endpoints for interactive testing of Centrifugo integration
102
101
  from the dashboard. Includes connection token generation, test message
103
102
  publishing, and manual ACK management.
103
+ Requires admin authentication (JWT, Session, or Basic Auth).
104
104
  """
105
105
 
106
- # authentication_classes = [SessionAuthentication]
107
- permission_classes = [IsAdminUser]
108
-
109
106
  def __init__(self, *args, **kwargs):
110
107
  super().__init__(*args, **kwargs)
111
108
  self._http_client = None
@@ -105,34 +105,39 @@ class SystemHealthService:
105
105
 
106
106
  def check_queue_health(self) -> Dict[str, Any]:
107
107
  """
108
- Check task queue (Celery/Dramatiq) health.
108
+ Check task queue (ReArq) health via Redis connection.
109
109
 
110
110
  Returns:
111
111
  Health status dictionary
112
112
  """
113
113
  try:
114
- # TODO: Add real queue health check
115
- # Example: Check Redis connection, queue sizes, worker status
116
- from django_cfg.modules.django_tasks import DjangoTasks
114
+ # Check Redis connection directly (used by task queue)
115
+ from django.core.cache import cache
116
+
117
+ # Try to ping Redis through cache backend
118
+ cache_backend = cache._cache if hasattr(cache, '_cache') else cache
117
119
 
118
- tasks = DjangoTasks()
119
- redis_client = tasks.get_redis_client()
120
+ # Simple check - if cache works, Redis is available
121
+ test_key = 'queue_health_check'
122
+ cache.set(test_key, 'ok', timeout=5)
123
+ result = cache.get(test_key)
120
124
 
121
- if redis_client and redis_client.ping():
125
+ if result == 'ok':
126
+ cache.delete(test_key)
122
127
  return {
123
128
  'component': 'queue',
124
129
  'status': 'healthy',
125
- 'description': 'Queue system is operational',
130
+ 'description': 'Queue system (Redis) is operational',
126
131
  'last_check': datetime.now().isoformat(),
127
132
  'health_percentage': 100,
128
133
  }
129
134
  else:
130
135
  return {
131
136
  'component': 'queue',
132
- 'status': 'error',
133
- 'description': 'Queue system unavailable',
137
+ 'status': 'warning',
138
+ 'description': 'Queue system check inconclusive',
134
139
  'last_check': datetime.now().isoformat(),
135
- 'health_percentage': 0,
140
+ 'health_percentage': 50,
136
141
  }
137
142
 
138
143
  except Exception as e:
@@ -10,26 +10,24 @@ import logging
10
10
 
11
11
  from drf_spectacular.utils import OpenApiParameter, extend_schema
12
12
  from rest_framework import status, viewsets
13
- from rest_framework.authentication import BasicAuthentication, SessionAuthentication
14
13
  from rest_framework.decorators import action
15
- from rest_framework.permissions import IsAdminUser
16
14
  from rest_framework.response import Response
17
15
 
16
+ from django_cfg.mixins import AdminAPIMixin
18
17
  from ..services import StatisticsService, SystemHealthService
19
18
  from ..serializers import ActivityEntrySerializer, QuickActionSerializer
20
19
 
21
20
  logger = logging.getLogger(__name__)
22
21
 
23
22
 
24
- class ActivityViewSet(viewsets.GenericViewSet):
23
+ class ActivityViewSet(AdminAPIMixin, viewsets.GenericViewSet):
25
24
  """
26
25
  Activity Tracking ViewSet
27
26
 
28
27
  Provides endpoints for recent activity and quick actions.
28
+ Requires admin authentication (JWT, Session, or Basic Auth).
29
29
  """
30
30
 
31
- authentication_classes = [SessionAuthentication, BasicAuthentication]
32
- permission_classes = [IsAdminUser]
33
31
  serializer_class = ActivityEntrySerializer
34
32
 
35
33
  @extend_schema(
@@ -10,9 +10,9 @@ import logging
10
10
 
11
11
  from drf_spectacular.utils import extend_schema
12
12
  from rest_framework import status, viewsets
13
- from rest_framework.authentication import BasicAuthentication, SessionAuthentication
13
+
14
+ from django_cfg.mixins import AdminAPIMixin
14
15
  from rest_framework.decorators import action
15
- from rest_framework.permissions import IsAdminUser
16
16
  from rest_framework.response import Response
17
17
 
18
18
  from ..services import APIZonesService
@@ -21,15 +21,14 @@ from ..serializers import APIZoneSerializer, APIZonesSummarySerializer
21
21
  logger = logging.getLogger(__name__)
22
22
 
23
23
 
24
- class APIZonesViewSet(viewsets.GenericViewSet):
24
+ class APIZonesViewSet(AdminAPIMixin, viewsets.GenericViewSet):
25
25
  """
26
26
  API Zones ViewSet
27
27
 
28
28
  Provides endpoints for OpenAPI zones (groups) management.
29
+ Requires admin authentication (JWT, Session, or Basic Auth).
29
30
  """
30
31
 
31
- authentication_classes = [SessionAuthentication, BasicAuthentication]
32
- permission_classes = [IsAdminUser]
33
32
  serializer_class = APIZoneSerializer
34
33
  pagination_class = None # Disable pagination for zones list
35
34
 
@@ -12,9 +12,9 @@ import logging
12
12
 
13
13
  from drf_spectacular.utils import OpenApiParameter, extend_schema
14
14
  from rest_framework import status, viewsets
15
- from rest_framework.authentication import BasicAuthentication, SessionAuthentication
15
+
16
+ from django_cfg.mixins import AdminAPIMixin
16
17
  from rest_framework.decorators import action
17
- from rest_framework.permissions import IsAdminUser
18
18
  from rest_framework.response import Response
19
19
 
20
20
  from ..services import ChartsService, StatisticsService
@@ -27,15 +27,14 @@ from ..serializers import (
27
27
  logger = logging.getLogger(__name__)
28
28
 
29
29
 
30
- class ChartsViewSet(viewsets.GenericViewSet):
30
+ class ChartsViewSet(AdminAPIMixin, viewsets.GenericViewSet):
31
31
  """
32
32
  Charts ViewSet
33
33
 
34
34
  Provides endpoints for dashboard charts and analytics.
35
+ Requires admin authentication (JWT, Session, or Basic Auth).
35
36
  """
36
37
 
37
- authentication_classes = [SessionAuthentication, BasicAuthentication]
38
- permission_classes = [IsAdminUser]
39
38
  serializer_class = ChartDataSerializer
40
39
 
41
40
  @extend_schema(
@@ -10,9 +10,9 @@ from datetime import datetime
10
10
 
11
11
  from drf_spectacular.utils import extend_schema
12
12
  from rest_framework import status, viewsets
13
- from rest_framework.authentication import BasicAuthentication, SessionAuthentication
13
+
14
+ from django_cfg.mixins import AdminAPIMixin
14
15
  from rest_framework.decorators import action
15
- from rest_framework.permissions import IsAdminUser
16
16
  from rest_framework.response import Response
17
17
 
18
18
  from ..services import StatisticsService, SystemHealthService, ChartsService
@@ -21,16 +21,15 @@ from ..serializers import DashboardOverviewSerializer
21
21
  logger = logging.getLogger(__name__)
22
22
 
23
23
 
24
- class OverviewViewSet(viewsets.GenericViewSet):
24
+ class OverviewViewSet(AdminAPIMixin, viewsets.GenericViewSet):
25
25
  """
26
26
  Dashboard Overview ViewSet
27
27
 
28
28
  Provides a single endpoint that returns all dashboard data at once.
29
29
  Useful for initial page load.
30
+ Requires admin authentication (JWT, Session, or Basic Auth).
30
31
  """
31
32
 
32
- authentication_classes = [SessionAuthentication, BasicAuthentication]
33
- permission_classes = [IsAdminUser]
34
33
  serializer_class = DashboardOverviewSerializer
35
34
 
36
35
  @extend_schema(
@@ -11,9 +11,9 @@ import logging
11
11
 
12
12
  from drf_spectacular.utils import extend_schema
13
13
  from rest_framework import status, viewsets
14
- from rest_framework.authentication import BasicAuthentication, SessionAuthentication
14
+
15
+ from django_cfg.mixins import AdminAPIMixin
15
16
  from rest_framework.decorators import action
16
- from rest_framework.permissions import IsAdminUser
17
17
  from rest_framework.response import Response
18
18
 
19
19
  from ..services import StatisticsService
@@ -26,15 +26,14 @@ from ..serializers import (
26
26
  logger = logging.getLogger(__name__)
27
27
 
28
28
 
29
- class StatisticsViewSet(viewsets.GenericViewSet):
29
+ class StatisticsViewSet(AdminAPIMixin, viewsets.GenericViewSet):
30
30
  """
31
31
  Statistics ViewSet
32
32
 
33
33
  Provides endpoints for retrieving various dashboard statistics.
34
+ Requires admin authentication (JWT, Session, or Basic Auth).
34
35
  """
35
36
 
36
- authentication_classes = [SessionAuthentication, BasicAuthentication]
37
- permission_classes = [IsAdminUser]
38
37
  serializer_class = StatCardSerializer
39
38
 
40
39
  @extend_schema(
@@ -10,9 +10,9 @@ import logging
10
10
 
11
11
  from drf_spectacular.utils import extend_schema
12
12
  from rest_framework import status, viewsets
13
- from rest_framework.authentication import BasicAuthentication, SessionAuthentication
13
+
14
+ from django_cfg.mixins import AdminAPIMixin
14
15
  from rest_framework.decorators import action
15
- from rest_framework.permissions import IsAdminUser
16
16
  from rest_framework.response import Response
17
17
 
18
18
  from ..services import SystemHealthService, StatisticsService
@@ -21,15 +21,14 @@ from ..serializers import SystemHealthSerializer, SystemMetricsSerializer
21
21
  logger = logging.getLogger(__name__)
22
22
 
23
23
 
24
- class SystemViewSet(viewsets.GenericViewSet):
24
+ class SystemViewSet(AdminAPIMixin, viewsets.GenericViewSet):
25
25
  """
26
26
  System Monitoring ViewSet
27
27
 
28
28
  Provides endpoints for system health and performance metrics.
29
+ Requires admin authentication (JWT, Session, or Basic Auth).
29
30
  """
30
31
 
31
- authentication_classes = [SessionAuthentication, BasicAuthentication]
32
- permission_classes = [IsAdminUser]
33
32
  serializer_class = SystemHealthSerializer
34
33
 
35
34
  @extend_schema(
@@ -2,7 +2,7 @@
2
2
  Django SaaS Knowledge Assistant
3
3
 
4
4
  Enterprise-grade RAG (Retrieval-Augmented Generation) application built on Django 5.2
5
- with pgvector semantic search, Dramatiq background processing, and comprehensive
5
+ with pgvector semantic search, ReArq background processing, and comprehensive
6
6
  API endpoints for document management and AI-powered chat.
7
7
 
8
8
  Key Features:
@@ -10,7 +10,7 @@ Key Features:
10
10
  - Semantic search using pgvector cosine similarity
11
11
  - RAG-powered chat with context retrieval
12
12
  - Multi-tenant user isolation
13
- - Background processing with Dramatiq
13
+ - Background processing with ReArq
14
14
  - Cost tracking for LLM usage monitoring
15
15
  - Comprehensive admin interface with Unfold styling
16
16
  - Type-safe APIs with Pydantic v2 validation
@@ -21,14 +21,8 @@ class KnowbaseConfig(AppConfig):
21
21
  # Connect post-migrate signal for database setup
22
22
  post_migrate.connect(self.create_pgvector_extension, sender=self)
23
23
 
24
- # Initialize task system and auto-start worker if configured
25
- try:
26
- from django_cfg.modules.django_tasks import initialize_task_system
27
- initialize_task_system()
28
- except Exception as e:
29
- import logging
30
- logger = logging.getLogger(__name__)
31
- logger.warning(f"Failed to initialize task system: {e}")
24
+ # Note: Task system initialization removed - ReArq doesn't need it
25
+ # Tasks are auto-discovered from decorated functions
32
26
 
33
27
  def create_pgvector_extension(self, sender, **kwargs):
34
28
  """Create pgvector extension and indexes if they don't exist."""
@@ -5,15 +5,20 @@ Base views for knowledge base API.
5
5
  import logging
6
6
 
7
7
  from rest_framework import viewsets
8
- from rest_framework.permissions import IsAuthenticated
8
+
9
+ from django_cfg.mixins import ClientAPIMixin
9
10
 
10
11
  logger = logging.getLogger(__name__)
11
12
 
12
13
 
13
- class BaseKnowledgeViewSet(viewsets.ModelViewSet):
14
- """Base ViewSet with common knowledge base functionality."""
14
+ class BaseKnowledgeViewSet(ClientAPIMixin, viewsets.ModelViewSet):
15
+ """
16
+ Base ViewSet with common knowledge base functionality.
17
+
18
+ Requires authenticated user (JWT or Session).
19
+ Automatically filters queryset by user and sets user on creation.
20
+ """
15
21
 
16
- permission_classes = [IsAuthenticated]
17
22
  lookup_field = 'pk'
18
23
 
19
24
  def get_queryset(self):
@@ -5,17 +5,22 @@ REST API ViewSets for tickets and messages.
5
5
  """
6
6
 
7
7
  from drf_spectacular.utils import OpenApiParameter, OpenApiTypes, extend_schema
8
- from rest_framework import permissions, viewsets
8
+ from rest_framework import viewsets
9
9
 
10
+ from django_cfg.mixins import ClientAPIMixin
10
11
  from ..models import Message, Ticket
11
12
  from ..serializers import MessageCreateSerializer, MessageSerializer, TicketSerializer
12
13
 
13
14
 
14
- class TicketViewSet(viewsets.ModelViewSet):
15
- """ViewSet for managing support tickets."""
15
+ class TicketViewSet(ClientAPIMixin, viewsets.ModelViewSet):
16
+ """
17
+ ViewSet for managing support tickets.
18
+
19
+ Requires authenticated user (JWT or Session).
20
+ Staff users can see all tickets, regular users see only their own.
21
+ """
16
22
 
17
23
  serializer_class = TicketSerializer
18
- permission_classes = [permissions.IsAuthenticated]
19
24
  lookup_field = 'uuid'
20
25
  lookup_url_kwarg = 'uuid'
21
26
 
@@ -32,11 +37,15 @@ class TicketViewSet(viewsets.ModelViewSet):
32
37
  serializer.save(user=self.request.user)
33
38
 
34
39
 
35
- class MessageViewSet(viewsets.ModelViewSet):
36
- """ViewSet for managing support messages."""
40
+ class MessageViewSet(ClientAPIMixin, viewsets.ModelViewSet):
41
+ """
42
+ ViewSet for managing support messages.
43
+
44
+ Requires authenticated user (JWT or Session).
45
+ Users can only access messages for their own tickets.
46
+ """
37
47
 
38
48
  serializer_class = MessageSerializer
39
- permission_classes = [permissions.IsAuthenticated]
40
49
  lookup_field = 'uuid'
41
50
  lookup_url_kwarg = 'uuid'
42
51
 
@@ -1,5 +1,64 @@
1
1
  """
2
- Django CFG Tasks App
2
+ ReArq tasks app for Django-CFG.
3
3
 
4
- Provides admin interface for Dramatiq task management.
4
+ Provides async background task processing with Redis queue.
5
5
  """
6
+
7
+ __all__ = [
8
+ "ReArqClient",
9
+ "get_rearq_client",
10
+ "get_tasks_config",
11
+ "get_tasks_config_or_default",
12
+ "task",
13
+ "cron_task",
14
+ ]
15
+
16
+
17
+ def __getattr__(name):
18
+ """Lazy imports to avoid loading ReArq at Django startup."""
19
+ if name in ("ReArqClient", "get_rearq_client"):
20
+ from .services.client import ReArqClient, get_rearq_client
21
+ return ReArqClient if name == "ReArqClient" else get_rearq_client
22
+ elif name in ("get_tasks_config", "get_tasks_config_or_default"):
23
+ from .services.config_helper import get_tasks_config, get_tasks_config_or_default
24
+ return get_tasks_config if name == "get_tasks_config" else get_tasks_config_or_default
25
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
26
+
27
+
28
+ def task(queue: str = "default", **kwargs):
29
+ """
30
+ Task decorator shortcut.
31
+
32
+ Example:
33
+ >>> from django_cfg.apps.tasks import task
34
+ >>>
35
+ >>> @task(queue="default")
36
+ >>> async def my_task(data: str):
37
+ ... return f"Processed {data}"
38
+ >>>
39
+ >>> # Execute task
40
+ >>> job = await my_task.delay(data="test")
41
+ >>> result = await job.result(timeout=30)
42
+ """
43
+ from .services.client import get_rearq_client
44
+ client = get_rearq_client()
45
+ return client.task(queue=queue, **kwargs)
46
+
47
+
48
+ def cron_task(cron: str, **kwargs):
49
+ """
50
+ Cron task decorator shortcut.
51
+
52
+ Args:
53
+ cron: Cron expression (e.g., "0 * * * *" for hourly)
54
+
55
+ Example:
56
+ >>> from django_cfg.apps.tasks import cron_task
57
+ >>>
58
+ >>> @cron_task(cron="0 0 * * *") # Daily at midnight
59
+ >>> async def daily_cleanup():
60
+ ... return "Cleanup complete"
61
+ """
62
+ from .services.client import get_rearq_client
63
+ client = get_rearq_client()
64
+ return client.cron_task(cron=cron, **kwargs)
@@ -1,11 +1,4 @@
1
- """
2
- Tasks admin interfaces using Django-CFG admin system.
1
+ """Admin configuration for tasks app."""
2
+ from .config import tasklog_config
3
3
 
4
- Enhanced Dramatiq task management with Material Icons and optimized queries.
5
- """
6
-
7
- from .tasks_admin import TaskAdmin
8
-
9
- __all__ = [
10
- 'TaskAdmin',
11
- ]
4
+ __all__ = ["tasklog_config"]