django-cfg 1.4.20__py3-none-any.whl → 1.4.23__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.
- django_cfg/__init__.py +4 -4
- django_cfg/apps/accounts/__init__.py +1 -1
- django_cfg/apps/accounts/__models.py +30 -29
- django_cfg/apps/accounts/admin/__init__.py +14 -3
- django_cfg/apps/accounts/admin/activity_admin.py +19 -19
- django_cfg/apps/accounts/admin/filters.py +7 -6
- django_cfg/apps/accounts/admin/group_admin.py +10 -16
- django_cfg/apps/accounts/admin/inlines.py +21 -19
- django_cfg/apps/accounts/admin/otp_admin.py +12 -12
- django_cfg/apps/accounts/admin/registration_admin.py +24 -24
- django_cfg/apps/accounts/admin/resources.py +49 -48
- django_cfg/apps/accounts/admin/twilio_admin.py +37 -37
- django_cfg/apps/accounts/admin/user_admin.py +45 -41
- django_cfg/apps/accounts/management/commands/otp_test.py +11 -11
- django_cfg/apps/accounts/managers/__init__.py +1 -1
- django_cfg/apps/accounts/managers/user_manager.py +6 -7
- django_cfg/apps/accounts/migrations/0001_initial.py +3 -2
- django_cfg/apps/accounts/models/__init__.py +15 -16
- django_cfg/apps/accounts/models/activity.py +5 -5
- django_cfg/apps/accounts/models/integrations.py +15 -15
- django_cfg/apps/accounts/models/registration.py +3 -2
- django_cfg/apps/accounts/models/user.py +3 -2
- django_cfg/apps/accounts/serializers/__init__.py +10 -3
- django_cfg/apps/accounts/serializers/otp.py +5 -4
- django_cfg/apps/accounts/serializers/profile.py +4 -5
- django_cfg/apps/accounts/serializers/webhook.py +13 -13
- django_cfg/apps/accounts/services/activity_service.py +13 -12
- django_cfg/apps/accounts/services/otp_service.py +16 -14
- django_cfg/apps/accounts/signals.py +18 -16
- django_cfg/apps/accounts/urls.py +10 -5
- django_cfg/apps/accounts/utils/notifications.py +22 -22
- django_cfg/apps/accounts/views/__init__.py +1 -1
- django_cfg/apps/accounts/views/otp.py +15 -14
- django_cfg/apps/accounts/views/profile.py +14 -10
- django_cfg/apps/accounts/views/webhook.py +46 -48
- django_cfg/apps/agents/__init__.py +3 -3
- django_cfg/apps/agents/admin/__init__.py +1 -1
- django_cfg/apps/agents/admin/execution_admin.py +68 -72
- django_cfg/apps/agents/admin/registry_admin.py +50 -54
- django_cfg/apps/agents/admin/toolsets_admin.py +63 -67
- django_cfg/apps/agents/apps.py +3 -3
- django_cfg/apps/agents/core/__init__.py +4 -4
- django_cfg/apps/agents/core/dependencies.py +24 -23
- django_cfg/apps/agents/core/django_agent.py +41 -39
- django_cfg/apps/agents/core/exceptions.py +12 -12
- django_cfg/apps/agents/core/models.py +16 -15
- django_cfg/apps/agents/core/orchestrator.py +58 -58
- django_cfg/apps/agents/examples/simple_example.py +24 -19
- django_cfg/apps/agents/integration/__init__.py +1 -1
- django_cfg/apps/agents/integration/middleware.py +12 -11
- django_cfg/apps/agents/integration/registry.py +52 -49
- django_cfg/apps/agents/integration/signals.py +5 -5
- django_cfg/apps/agents/management/commands/create_agent.py +39 -38
- django_cfg/apps/agents/management/commands/orchestrator_status.py +40 -39
- django_cfg/apps/agents/managers/__init__.py +8 -3
- django_cfg/apps/agents/managers/execution.py +42 -41
- django_cfg/apps/agents/managers/registry.py +40 -39
- django_cfg/apps/agents/managers/toolsets.py +87 -86
- django_cfg/apps/agents/migrations/0001_initial.py +2 -1
- django_cfg/apps/agents/models/__init__.py +2 -2
- django_cfg/apps/agents/models/execution.py +43 -42
- django_cfg/apps/agents/models/registry.py +46 -45
- django_cfg/apps/agents/models/toolsets.py +63 -62
- django_cfg/apps/agents/patterns/__init__.py +5 -5
- django_cfg/apps/agents/patterns/content_agents.py +17 -16
- django_cfg/apps/agents/toolsets/__init__.py +3 -3
- django_cfg/apps/agents/toolsets/cache_toolset.py +56 -55
- django_cfg/apps/agents/toolsets/django_toolset.py +43 -42
- django_cfg/apps/agents/toolsets/file_toolset.py +64 -63
- django_cfg/apps/agents/toolsets/orm_toolset.py +75 -74
- django_cfg/apps/agents/urls.py +3 -2
- django_cfg/apps/api/commands/urls.py +1 -0
- django_cfg/apps/api/commands/views.py +23 -26
- django_cfg/apps/api/endpoints/checker.py +5 -4
- django_cfg/apps/api/endpoints/drf_views.py +2 -2
- django_cfg/apps/api/endpoints/tests.py +6 -5
- django_cfg/apps/api/endpoints/urls.py +2 -1
- django_cfg/apps/api/endpoints/views.py +1 -0
- django_cfg/apps/api/health/drf_views.py +6 -6
- django_cfg/apps/api/health/urls.py +2 -1
- django_cfg/apps/api/health/views.py +41 -41
- django_cfg/{modules/django_ipc_client → apps/ipc}/__init__.py +6 -6
- django_cfg/apps/ipc/apps.py +28 -0
- django_cfg/apps/ipc/serializers/__init__.py +19 -0
- django_cfg/apps/ipc/serializers/serializers.py +229 -0
- django_cfg/apps/ipc/services/__init__.py +7 -0
- django_cfg/apps/ipc/services/client/__init__.py +23 -0
- django_cfg/{modules/django_ipc_client → apps/ipc/services/client}/client.py +7 -6
- django_cfg/{modules/django_ipc_client → apps/ipc/services/client}/exceptions.py +1 -1
- django_cfg/{modules/django_ipc_client/dashboard → apps/ipc/services}/monitor.py +23 -5
- django_cfg/{modules/django_ipc_client/dashboard/static/django_ipc_dashboard/js/dashboard.js → apps/ipc/static/django_cfg_ipc/js/dashboard.mjs} +131 -63
- django_cfg/{modules/django_ipc_client/dashboard/templates/django_ipc_dashboard → apps/ipc/templates/django_cfg_ipc}/base.html +5 -10
- django_cfg/apps/ipc/templates/django_cfg_ipc/dashboard.html +202 -0
- django_cfg/apps/ipc/urls.py +21 -0
- django_cfg/apps/ipc/urls_admin.py +20 -0
- django_cfg/apps/ipc/views/__init__.py +8 -0
- django_cfg/apps/ipc/views/dashboard.py +15 -0
- django_cfg/apps/ipc/views/viewsets.py +245 -0
- django_cfg/apps/knowbase/admin/__init__.py +2 -2
- django_cfg/apps/knowbase/admin/actions/__init__.py +1 -1
- django_cfg/apps/knowbase/admin/actions/visibility_actions.py +2 -1
- django_cfg/apps/knowbase/admin/archive_admin.py +81 -84
- django_cfg/apps/knowbase/admin/chat_admin.py +70 -72
- django_cfg/apps/knowbase/admin/document_admin.py +10 -11
- django_cfg/apps/knowbase/admin/external_data_admin.py +69 -71
- django_cfg/apps/knowbase/admin/helpers/__init__.py +1 -1
- django_cfg/apps/knowbase/admin/helpers/configs.py +2 -2
- django_cfg/apps/knowbase/admin/helpers/statistics.py +1 -1
- django_cfg/apps/knowbase/apps.py +13 -13
- django_cfg/apps/knowbase/config/__init__.py +7 -6
- django_cfg/apps/knowbase/config/constance_fields.py +14 -12
- django_cfg/apps/knowbase/config/constance_settings.py +32 -31
- django_cfg/apps/knowbase/config/settings.py +28 -28
- django_cfg/apps/knowbase/examples/external_data_usage.py +35 -32
- django_cfg/apps/knowbase/management/commands/knowbase_stats.py +33 -32
- django_cfg/apps/knowbase/management/commands/setup_knowbase.py +11 -13
- django_cfg/apps/knowbase/managers/__init__.py +2 -2
- django_cfg/apps/knowbase/managers/archive.py +86 -85
- django_cfg/apps/knowbase/managers/base.py +5 -5
- django_cfg/apps/knowbase/managers/chat.py +29 -28
- django_cfg/apps/knowbase/managers/document.py +39 -39
- django_cfg/apps/knowbase/managers/external_data.py +74 -73
- django_cfg/apps/knowbase/migrations/0001_initial.py +2 -1
- django_cfg/apps/knowbase/migrations/0002_archiveitem_archiveitemchunk_documentarchive_and_more.py +2 -1
- django_cfg/apps/knowbase/migrations/0003_alter_documentarchive_archive_type.py +29 -0
- django_cfg/apps/knowbase/mixins/__init__.py +4 -4
- django_cfg/apps/knowbase/mixins/config/__init__.py +1 -1
- django_cfg/apps/knowbase/mixins/config/meta_config.py +1 -1
- django_cfg/apps/knowbase/mixins/config.py +19 -18
- django_cfg/apps/knowbase/mixins/creator.py +7 -7
- django_cfg/apps/knowbase/mixins/examples/vehicle_model_example.py +29 -28
- django_cfg/apps/knowbase/mixins/external_data_mixin.py +6 -5
- django_cfg/apps/knowbase/mixins/generators/__init__.py +1 -1
- django_cfg/apps/knowbase/mixins/generators/content_generator.py +2 -2
- django_cfg/apps/knowbase/mixins/service.py +47 -45
- django_cfg/apps/knowbase/models/__init__.py +7 -7
- django_cfg/apps/knowbase/models/archive.py +72 -72
- django_cfg/apps/knowbase/models/base.py +12 -13
- django_cfg/apps/knowbase/models/chat.py +20 -19
- django_cfg/apps/knowbase/models/document.py +37 -35
- django_cfg/apps/knowbase/models/external_data.py +41 -42
- django_cfg/apps/knowbase/serializers/__init__.py +7 -7
- django_cfg/apps/knowbase/serializers/archive_serializers.py +50 -42
- django_cfg/apps/knowbase/serializers/chat_serializers.py +16 -15
- django_cfg/apps/knowbase/serializers/document_serializers.py +13 -12
- django_cfg/apps/knowbase/serializers/external_data_serializers.py +31 -31
- django_cfg/apps/knowbase/serializers/public_serializers.py +10 -9
- django_cfg/apps/knowbase/services/__init__.py +7 -7
- django_cfg/apps/knowbase/services/archive/__init__.py +7 -7
- django_cfg/apps/knowbase/services/archive/analyzers/__init__.py +1 -1
- django_cfg/apps/knowbase/services/archive/analyzers/tag_generator.py +1 -1
- django_cfg/apps/knowbase/services/archive/archive_service.py +109 -112
- django_cfg/apps/knowbase/services/archive/chunking/__init__.py +3 -3
- django_cfg/apps/knowbase/services/archive/chunking/base.py +1 -0
- django_cfg/apps/knowbase/services/archive/chunking/json_chunker.py +4 -3
- django_cfg/apps/knowbase/services/archive/chunking/markdown_chunker.py +5 -4
- django_cfg/apps/knowbase/services/archive/chunking/python_chunker.py +6 -5
- django_cfg/apps/knowbase/services/archive/chunking/text_chunker.py +4 -3
- django_cfg/apps/knowbase/services/archive/chunking_service.py +3 -7
- django_cfg/apps/knowbase/services/archive/context/__init__.py +1 -1
- django_cfg/apps/knowbase/services/archive/context/builders.py +2 -1
- django_cfg/apps/knowbase/services/archive/context/models.py +2 -1
- django_cfg/apps/knowbase/services/archive/exceptions.py +5 -5
- django_cfg/apps/knowbase/services/archive/extraction_service.py +111 -110
- django_cfg/apps/knowbase/services/archive/vectorization_service.py +80 -77
- django_cfg/apps/knowbase/services/base.py +11 -9
- django_cfg/apps/knowbase/services/chat_service.py +40 -39
- django_cfg/apps/knowbase/services/document_service.py +28 -27
- django_cfg/apps/knowbase/services/embedding/__init__.py +9 -9
- django_cfg/apps/knowbase/services/embedding/async_processor.py +38 -40
- django_cfg/apps/knowbase/services/embedding/batch_processor.py +45 -42
- django_cfg/apps/knowbase/services/embedding/batch_result.py +7 -6
- django_cfg/apps/knowbase/services/embedding/models.py +52 -51
- django_cfg/apps/knowbase/services/embedding/processors.py +24 -23
- django_cfg/apps/knowbase/services/embedding/utils.py +17 -17
- django_cfg/apps/knowbase/services/prompt_builder.py +24 -23
- django_cfg/apps/knowbase/services/search_service.py +52 -49
- django_cfg/apps/knowbase/signals/__init__.py +2 -5
- django_cfg/apps/knowbase/signals/archive_signals.py +35 -34
- django_cfg/apps/knowbase/signals/chat_signals.py +6 -5
- django_cfg/apps/knowbase/signals/document_signals.py +22 -22
- django_cfg/apps/knowbase/signals/external_data_signals.py +22 -22
- django_cfg/apps/knowbase/tasks/__init__.py +6 -7
- django_cfg/apps/knowbase/tasks/archive_tasks.py +41 -41
- django_cfg/apps/knowbase/tasks/document_processing.py +49 -44
- django_cfg/apps/knowbase/tasks/external_data_tasks.py +46 -44
- django_cfg/apps/knowbase/tasks/maintenance.py +26 -24
- django_cfg/apps/knowbase/urls.py +3 -2
- django_cfg/apps/knowbase/urls_admin.py +6 -3
- django_cfg/apps/knowbase/urls_system.py +4 -5
- django_cfg/apps/knowbase/utils/chunk_settings.py +22 -20
- django_cfg/apps/knowbase/utils/text_processing.py +76 -75
- django_cfg/apps/knowbase/utils/validation.py +9 -9
- django_cfg/apps/knowbase/views/__init__.py +5 -5
- django_cfg/apps/knowbase/views/archive_views.py +90 -87
- django_cfg/apps/knowbase/views/base.py +9 -12
- django_cfg/apps/knowbase/views/chat_views.py +35 -32
- django_cfg/apps/knowbase/views/document_views.py +27 -28
- django_cfg/apps/knowbase/views/public_views.py +19 -19
- django_cfg/apps/leads/admin/leads_admin.py +41 -45
- django_cfg/apps/leads/admin/resources.py +14 -14
- django_cfg/apps/leads/admin.py +7 -9
- django_cfg/apps/leads/apps.py +1 -1
- django_cfg/apps/leads/models.py +17 -17
- django_cfg/apps/leads/serializers.py +5 -4
- django_cfg/apps/leads/signals.py +7 -7
- django_cfg/apps/leads/tests.py +47 -47
- django_cfg/apps/leads/urls.py +2 -2
- django_cfg/apps/leads/views.py +11 -11
- django_cfg/apps/maintenance/__init__.py +3 -3
- django_cfg/apps/maintenance/admin/__init__.py +1 -1
- django_cfg/apps/maintenance/admin/api_key_admin.py +36 -36
- django_cfg/apps/maintenance/admin/log_admin.py +35 -37
- django_cfg/apps/maintenance/admin/scheduled_admin.py +47 -51
- django_cfg/apps/maintenance/admin/site_admin.py +49 -52
- django_cfg/apps/maintenance/apps.py +2 -2
- django_cfg/apps/maintenance/management/commands/maintenance.py +53 -52
- django_cfg/apps/maintenance/management/commands/process_scheduled_maintenance.py +44 -44
- django_cfg/apps/maintenance/management/commands/sync_cloudflare.py +32 -32
- django_cfg/apps/maintenance/managers/__init__.py +1 -1
- django_cfg/apps/maintenance/managers/cloudflare_site_manager.py +39 -38
- django_cfg/apps/maintenance/managers/maintenance_log_manager.py +32 -31
- django_cfg/apps/maintenance/migrations/0001_initial.py +1 -0
- django_cfg/apps/maintenance/models/__init__.py +2 -2
- django_cfg/apps/maintenance/models/cloudflare_api_key.py +15 -15
- django_cfg/apps/maintenance/models/cloudflare_site.py +24 -22
- django_cfg/apps/maintenance/models/maintenance_log.py +15 -14
- django_cfg/apps/maintenance/models/scheduled_maintenance.py +53 -52
- django_cfg/apps/maintenance/services/__init__.py +3 -3
- django_cfg/apps/maintenance/services/bulk_operations_service.py +68 -68
- django_cfg/apps/maintenance/services/maintenance_service.py +59 -58
- django_cfg/apps/maintenance/services/scheduled_maintenance_service.py +52 -52
- django_cfg/apps/maintenance/services/site_sync_service.py +64 -65
- django_cfg/apps/maintenance/utils/__init__.py +1 -1
- django_cfg/apps/maintenance/utils/retry_utils.py +17 -17
- django_cfg/apps/newsletter/admin/__init__.py +12 -16
- django_cfg/apps/newsletter/admin/newsletter_admin.py +90 -87
- django_cfg/apps/newsletter/admin/resources.py +29 -29
- django_cfg/apps/newsletter/admin.py +39 -32
- django_cfg/apps/newsletter/management/commands/test_newsletter.py +3 -3
- django_cfg/apps/newsletter/managers/__init__.py +1 -1
- django_cfg/apps/newsletter/migrations/0001_initial.py +2 -1
- django_cfg/apps/newsletter/models.py +34 -33
- django_cfg/apps/newsletter/serializers.py +13 -13
- django_cfg/apps/newsletter/services/email_service.py +42 -40
- django_cfg/apps/newsletter/signals.py +4 -3
- django_cfg/apps/newsletter/urls.py +7 -7
- django_cfg/apps/newsletter/views/__init__.py +14 -19
- django_cfg/apps/newsletter/views/campaigns.py +19 -19
- django_cfg/apps/newsletter/views/emails.py +20 -20
- django_cfg/apps/newsletter/views/newsletters.py +5 -5
- django_cfg/apps/newsletter/views/subscriptions.py +24 -24
- django_cfg/apps/newsletter/views/tracking.py +6 -5
- django_cfg/apps/payments/admin/__init__.py +6 -5
- django_cfg/apps/payments/admin/api_keys_admin.py +43 -45
- django_cfg/apps/payments/admin/balance_admin.py +41 -47
- django_cfg/apps/payments/admin/currencies_admin.py +60 -62
- django_cfg/apps/payments/admin/endpoint_groups_admin.py +14 -28
- django_cfg/apps/payments/admin/filters.py +59 -59
- django_cfg/apps/payments/admin/networks_admin.py +36 -50
- django_cfg/apps/payments/admin/payments_admin.py +47 -49
- django_cfg/apps/payments/admin/subscriptions_admin.py +30 -32
- django_cfg/apps/payments/admin/tariffs_admin.py +37 -42
- django_cfg/apps/payments/admin_interface/serializers/__init__.py +12 -13
- django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +28 -27
- django_cfg/apps/payments/admin_interface/serializers/webhook_serializers.py +4 -5
- django_cfg/apps/payments/admin_interface/templates/payments/base.html +407 -3
- django_cfg/apps/payments/admin_interface/templates/payments/components/ngrok_status.html +13 -13
- django_cfg/apps/payments/admin_interface/templates/payments/payment_dashboard.html +5 -1
- django_cfg/apps/payments/admin_interface/templates/payments/payment_detail.html +105 -49
- django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +4 -1
- django_cfg/apps/payments/admin_interface/templates/payments/payment_list.html +16 -8
- django_cfg/apps/payments/admin_interface/templates/payments/webhook_dashboard.html +16 -8
- django_cfg/apps/payments/admin_interface/views/__init__.py +8 -9
- django_cfg/apps/payments/admin_interface/views/api/__init__.py +3 -3
- django_cfg/apps/payments/admin_interface/views/api/payments.py +52 -54
- django_cfg/apps/payments/admin_interface/views/api/stats.py +33 -30
- django_cfg/apps/payments/admin_interface/views/api/users.py +10 -11
- django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +46 -51
- django_cfg/apps/payments/admin_interface/views/api/webhook_public.py +9 -9
- django_cfg/apps/payments/admin_interface/views/base.py +17 -19
- django_cfg/apps/payments/admin_interface/views/dashboard.py +10 -10
- django_cfg/apps/payments/admin_interface/views/forms.py +21 -20
- django_cfg/apps/payments/apps.py +7 -6
- django_cfg/apps/payments/config/__init__.py +4 -4
- django_cfg/apps/payments/config/django_cfg_integration.py +22 -21
- django_cfg/apps/payments/config/helpers.py +14 -12
- django_cfg/apps/payments/management/commands/cleanup_expired_data.py +85 -86
- django_cfg/apps/payments/management/commands/currency_stats.py +84 -87
- django_cfg/apps/payments/management/commands/manage_currencies.py +59 -58
- django_cfg/apps/payments/management/commands/manage_providers.py +103 -105
- django_cfg/apps/payments/management/commands/process_pending_payments.py +67 -70
- django_cfg/apps/payments/management/commands/test_providers.py +83 -84
- django_cfg/apps/payments/middleware/__init__.py +1 -1
- django_cfg/apps/payments/middleware/api_access.py +77 -78
- django_cfg/apps/payments/middleware/rate_limiting.py +72 -72
- django_cfg/apps/payments/middleware/usage_tracking.py +66 -64
- django_cfg/apps/payments/migrations/0001_initial.py +2 -1
- django_cfg/apps/payments/models/__init__.py +11 -12
- django_cfg/apps/payments/models/api_keys.py +29 -27
- django_cfg/apps/payments/models/balance.py +38 -38
- django_cfg/apps/payments/models/base.py +12 -11
- django_cfg/apps/payments/models/currencies.py +53 -52
- django_cfg/apps/payments/models/managers/__init__.py +13 -14
- django_cfg/apps/payments/models/managers/api_key_managers.py +55 -53
- django_cfg/apps/payments/models/managers/balance_managers.py +98 -97
- django_cfg/apps/payments/models/managers/currency_managers.py +70 -69
- django_cfg/apps/payments/models/managers/payment_managers.py +113 -111
- django_cfg/apps/payments/models/managers/subscription_managers.py +99 -97
- django_cfg/apps/payments/models/payments.py +167 -73
- django_cfg/apps/payments/models/subscriptions.py +56 -54
- django_cfg/apps/payments/models/tariffs.py +35 -34
- django_cfg/apps/payments/services/__init__.py +33 -36
- django_cfg/apps/payments/services/cache/__init__.py +7 -1
- django_cfg/apps/payments/services/cache_service/__init__.py +22 -20
- django_cfg/apps/payments/services/cache_service/api_key_cache.py +6 -5
- django_cfg/apps/payments/services/cache_service/interfaces.py +5 -5
- django_cfg/apps/payments/services/cache_service/keys.py +8 -8
- django_cfg/apps/payments/services/cache_service/rate_limit_cache.py +8 -7
- django_cfg/apps/payments/services/cache_service/simple_cache.py +17 -14
- django_cfg/apps/payments/services/core/__init__.py +3 -3
- django_cfg/apps/payments/services/core/balance_service.py +69 -65
- django_cfg/apps/payments/services/core/base.py +25 -22
- django_cfg/apps/payments/services/core/currency/__init__.py +1 -1
- django_cfg/apps/payments/services/core/currency/currency_converter.py +2 -0
- django_cfg/apps/payments/services/core/currency_service.py +68 -66
- django_cfg/apps/payments/services/core/operations/__init__.py +1 -1
- django_cfg/apps/payments/services/core/operations/payment_canceller.py +2 -1
- django_cfg/apps/payments/services/core/operations/payment_creator.py +2 -1
- django_cfg/apps/payments/services/core/operations/status_checker.py +2 -1
- django_cfg/apps/payments/services/core/payment_service.py +10 -7
- django_cfg/apps/payments/services/core/providers/provider_client.py +2 -2
- django_cfg/apps/payments/services/core/subscription_service.py +77 -74
- django_cfg/apps/payments/services/core/utils/data_converter.py +1 -0
- django_cfg/apps/payments/services/core/utils/statistics_calculator.py +1 -0
- django_cfg/apps/payments/services/core/webhook_service.py +67 -63
- django_cfg/apps/payments/services/integrations/__init__.py +3 -3
- django_cfg/apps/payments/services/integrations/ngrok_service.py +1 -0
- django_cfg/apps/payments/services/integrations/providers_config.py +3 -2
- django_cfg/apps/payments/services/providers/base.py +59 -57
- django_cfg/apps/payments/services/providers/models/__init__.py +7 -14
- django_cfg/apps/payments/services/providers/models/base.py +15 -15
- django_cfg/apps/payments/services/providers/models/providers.py +13 -12
- django_cfg/apps/payments/services/providers/models/universal.py +6 -5
- django_cfg/apps/payments/services/providers/nowpayments/__init__.py +4 -4
- django_cfg/apps/payments/services/providers/nowpayments/config.py +9 -8
- django_cfg/apps/payments/services/providers/nowpayments/models.py +15 -15
- django_cfg/apps/payments/services/providers/nowpayments/parsers/data/__init__.py +2 -2
- django_cfg/apps/payments/services/providers/nowpayments/parsers/data/patterns.py +26 -26
- django_cfg/apps/payments/services/providers/nowpayments/parsers/parser.py +3 -2
- django_cfg/apps/payments/services/providers/nowpayments/provider.py +95 -99
- django_cfg/apps/payments/services/providers/nowpayments/sync.py +41 -40
- django_cfg/apps/payments/services/providers/registry.py +65 -63
- django_cfg/apps/payments/services/providers/sync_service.py +50 -50
- django_cfg/apps/payments/services/types/__init__.py +21 -22
- django_cfg/apps/payments/services/types/data.py +14 -13
- django_cfg/apps/payments/services/types/requests.py +21 -22
- django_cfg/apps/payments/services/types/responses.py +16 -15
- django_cfg/apps/payments/services/types/webhooks.py +30 -30
- django_cfg/apps/payments/signals/__init__.py +4 -6
- django_cfg/apps/payments/signals/api_key_signals.py +36 -35
- django_cfg/apps/payments/signals/balance_signals.py +28 -26
- django_cfg/apps/payments/signals/payment_signals.py +29 -28
- django_cfg/apps/payments/signals/subscription_signals.py +39 -38
- django_cfg/apps/payments/static/payments/js/ngrok-status.js +12 -8
- django_cfg/apps/payments/static/payments/js/payment-detail.js +1 -1
- django_cfg/apps/payments/static/payments/js/payment-form.js +3 -3
- django_cfg/apps/payments/static/payments/js/payment-list.js +13 -6
- django_cfg/apps/payments/static/payments/js/webhook-dashboard-mjs.js +241 -0
- django_cfg/apps/payments/tasks/__init__.py +11 -12
- django_cfg/apps/payments/tasks/types.py +10 -9
- django_cfg/apps/payments/tasks/usage_tracking.py +44 -46
- django_cfg/apps/payments/templatetags/payment_tags.py +27 -27
- django_cfg/apps/payments/urls.py +31 -14
- django_cfg/apps/payments/urls_admin.py +10 -10
- django_cfg/apps/payments/views/api/__init__.py +32 -33
- django_cfg/apps/payments/views/api/api_keys.py +62 -62
- django_cfg/apps/payments/views/api/balances.py +63 -64
- django_cfg/apps/payments/views/api/base.py +52 -52
- django_cfg/apps/payments/views/api/currencies.py +75 -63
- django_cfg/apps/payments/views/api/payments.py +73 -74
- django_cfg/apps/payments/views/api/subscriptions.py +71 -72
- django_cfg/apps/payments/views/api/webhooks.py +85 -84
- django_cfg/apps/payments/views/overview/__init__.py +7 -7
- django_cfg/apps/payments/views/overview/serializers.py +13 -14
- django_cfg/apps/payments/views/overview/services.py +66 -67
- django_cfg/apps/payments/views/overview/urls.py +2 -1
- django_cfg/apps/payments/views/overview/views.py +31 -31
- django_cfg/apps/payments/views/serializers/__init__.py +35 -36
- django_cfg/apps/payments/views/serializers/api_keys.py +59 -57
- django_cfg/apps/payments/views/serializers/balances.py +34 -33
- django_cfg/apps/payments/views/serializers/currencies.py +36 -34
- django_cfg/apps/payments/views/serializers/payments.py +48 -47
- django_cfg/apps/payments/views/serializers/subscriptions.py +50 -45
- django_cfg/apps/payments/views/serializers/webhooks.py +17 -16
- django_cfg/apps/support/admin/__init__.py +3 -3
- django_cfg/apps/support/admin/resources.py +26 -26
- django_cfg/apps/support/admin/support_admin.py +44 -48
- django_cfg/apps/support/admin.py +16 -15
- django_cfg/apps/support/apps.py +1 -1
- django_cfg/apps/support/managers/message_manager.py +4 -4
- django_cfg/apps/support/managers/ticket_manager.py +13 -12
- django_cfg/apps/support/migrations/0001_initial.py +2 -1
- django_cfg/apps/support/models.py +3 -1
- django_cfg/apps/support/serializers.py +4 -2
- django_cfg/apps/support/signals.py +12 -10
- django_cfg/apps/support/urls.py +4 -3
- django_cfg/apps/support/utils/support_email_service.py +11 -9
- django_cfg/apps/support/views/__init__.py +3 -3
- django_cfg/apps/support/views/admin.py +9 -9
- django_cfg/apps/support/views/api.py +12 -13
- django_cfg/apps/support/views/chat.py +14 -14
- django_cfg/apps/tasks/admin/tasks_admin.py +65 -74
- django_cfg/apps/tasks/apps.py +2 -2
- django_cfg/apps/tasks/serializers.py +6 -6
- django_cfg/apps/tasks/static/tasks/js/dashboard/main.mjs +44 -20
- django_cfg/apps/tasks/static/tasks/js/dashboard/overview.mjs +7 -5
- django_cfg/apps/tasks/static/tasks/js/dashboard/queues.mjs +5 -3
- django_cfg/apps/tasks/static/tasks/js/dashboard/tasks.mjs +5 -3
- django_cfg/apps/tasks/static/tasks/js/dashboard/workers.mjs +5 -3
- django_cfg/apps/tasks/tasks/demo_tasks.py +12 -11
- django_cfg/apps/tasks/templates/tasks/components/tasks_mjs_integration.html +269 -0
- django_cfg/apps/tasks/templates/tasks/pages/dashboard-improved.html +168 -0
- django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +21 -2
- django_cfg/apps/tasks/urls.py +3 -2
- django_cfg/apps/tasks/urls_admin.py +1 -0
- django_cfg/apps/tasks/utils/simulator.py +49 -52
- django_cfg/apps/tasks/views/api.py +75 -73
- django_cfg/apps/tasks/views/dashboard.py +5 -4
- django_cfg/apps/urls.py +20 -11
- django_cfg/apps.py +6 -5
- django_cfg/cli/commands/create_project.py +7 -6
- django_cfg/cli/commands/info.py +25 -25
- django_cfg/cli/utils.py +27 -27
- django_cfg/config.py +1 -1
- django_cfg/core/__init__.py +8 -8
- django_cfg/core/base/config_model.py +13 -12
- django_cfg/core/builders/apps_builder.py +2 -2
- django_cfg/core/builders/middleware_builder.py +1 -1
- django_cfg/core/builders/security_builder.py +1 -1
- django_cfg/core/config.py +2 -2
- django_cfg/core/environment/detector.py +27 -28
- django_cfg/core/exceptions.py +1 -1
- django_cfg/core/generation/core_generators/settings.py +1 -1
- django_cfg/core/generation/core_generators/static.py +11 -5
- django_cfg/core/generation/core_generators/templates.py +1 -1
- django_cfg/core/generation/data_generators/__init__.py +1 -1
- django_cfg/core/generation/data_generators/cache.py +1 -1
- django_cfg/core/generation/data_generators/database.py +1 -1
- django_cfg/core/generation/generation.py +1 -3
- django_cfg/core/generation/integration_generators/__init__.py +2 -2
- django_cfg/core/generation/integration_generators/api.py +12 -2
- django_cfg/core/generation/integration_generators/sessions.py +1 -1
- django_cfg/core/generation/integration_generators/tailwind.py +1 -1
- django_cfg/core/generation/integration_generators/tasks.py +1 -1
- django_cfg/core/generation/integration_generators/third_party.py +1 -1
- django_cfg/core/generation/orchestrator.py +1 -1
- django_cfg/core/generation/protocols.py +1 -1
- django_cfg/core/generation/utility_generators/__init__.py +1 -1
- django_cfg/core/generation/utility_generators/email.py +1 -1
- django_cfg/core/generation/utility_generators/i18n.py +1 -1
- django_cfg/core/generation/utility_generators/limits.py +1 -1
- django_cfg/core/generation/utility_generators/logging.py +1 -1
- django_cfg/core/generation/utility_generators/security.py +1 -1
- django_cfg/core/generation/utils/helpers.py +1 -1
- django_cfg/core/integration/__init__.py +5 -5
- django_cfg/core/integration/commands_collector.py +38 -39
- django_cfg/core/integration/display/__init__.py +2 -2
- django_cfg/core/integration/display/base.py +30 -30
- django_cfg/core/integration/display/ngrok.py +35 -36
- django_cfg/core/integration/display/startup.py +149 -139
- django_cfg/core/integration/url_integration.py +10 -10
- django_cfg/core/integration/version_checker.py +20 -19
- django_cfg/core/services/config_service.py +4 -4
- django_cfg/core/state/__init__.py +1 -1
- django_cfg/core/state/registry.py +1 -1
- django_cfg/core/types/__init__.py +8 -1
- django_cfg/core/validation.py +36 -39
- django_cfg/management/commands/check_endpoints.py +3 -1
- django_cfg/management/commands/check_settings.py +3 -1
- django_cfg/management/commands/clear_constance.py +3 -1
- django_cfg/management/commands/create_token.py +3 -1
- django_cfg/management/commands/generate_clients.py +3 -1
- django_cfg/management/commands/migrate_all.py +3 -1
- django_cfg/management/commands/rundramatiq.py +3 -1
- django_cfg/management/commands/rundramatiq_simulator.py +3 -1
- django_cfg/management/commands/runserver_ngrok.py +3 -1
- django_cfg/management/commands/show_config.py +3 -1
- django_cfg/management/commands/superuser.py +3 -1
- django_cfg/management/commands/task_clear.py +3 -1
- django_cfg/management/commands/task_status.py +3 -1
- django_cfg/management/commands/test_email.py +3 -1
- django_cfg/management/commands/test_telegram.py +3 -1
- django_cfg/management/commands/test_twilio.py +3 -1
- django_cfg/management/commands/validate_openapi.py +3 -1
- django_cfg/middleware/pagination.py +8 -8
- django_cfg/middleware/public_endpoints.py +24 -23
- django_cfg/middleware/user_activity.py +27 -25
- django_cfg/models/__init__.py +19 -20
- django_cfg/models/api/__init__.py +4 -4
- django_cfg/models/api/config.py +23 -21
- django_cfg/models/api/cors.py +17 -16
- django_cfg/models/api/drf/__init__.py +1 -1
- django_cfg/models/api/drf/config.py +2 -1
- django_cfg/models/api/drf/redoc.py +2 -1
- django_cfg/models/api/drf/spectacular.py +4 -2
- django_cfg/models/api/drf/swagger.py +2 -1
- django_cfg/models/api/jwt.py +37 -36
- django_cfg/models/api/keys.py +13 -12
- django_cfg/models/api/limits.py +31 -30
- django_cfg/models/base/config.py +40 -41
- django_cfg/models/base/module.py +8 -8
- django_cfg/models/django/__init__.py +1 -1
- django_cfg/models/django/constance.py +8 -7
- django_cfg/models/django/environment.py +5 -3
- django_cfg/models/django/openapi.py +6 -16
- django_cfg/models/django/revolution_legacy.py +17 -16
- django_cfg/models/infrastructure/__init__.py +1 -1
- django_cfg/models/infrastructure/cache.py +46 -45
- django_cfg/models/infrastructure/database/config.py +4 -6
- django_cfg/models/infrastructure/database/converters.py +1 -1
- django_cfg/models/infrastructure/database/parsers.py +1 -1
- django_cfg/models/infrastructure/database/validators.py +1 -1
- django_cfg/models/infrastructure/logging.py +59 -57
- django_cfg/models/infrastructure/security.py +26 -24
- django_cfg/models/ngrok/auth.py +2 -1
- django_cfg/models/ngrok/config.py +3 -2
- django_cfg/models/ngrok/tunnel.py +2 -1
- django_cfg/models/payments/__init__.py +1 -1
- django_cfg/models/payments/api_keys.py +3 -1
- django_cfg/models/payments/config.py +4 -1
- django_cfg/models/payments/providers/base.py +2 -1
- django_cfg/models/payments/providers/nowpayments.py +3 -1
- django_cfg/models/services/__init__.py +1 -1
- django_cfg/models/services/base.py +2 -1
- django_cfg/models/services/email.py +28 -26
- django_cfg/models/services/telegram.py +2 -1
- django_cfg/models/tasks/__init__.py +2 -2
- django_cfg/models/tasks/backends.py +4 -3
- django_cfg/models/tasks/config.py +6 -4
- django_cfg/models/tasks/utils.py +3 -3
- django_cfg/modules/base.py +18 -17
- django_cfg/modules/django_admin/__init__.py +14 -15
- django_cfg/modules/django_admin/decorators/__init__.py +1 -1
- django_cfg/modules/django_admin/decorators/actions.py +8 -7
- django_cfg/modules/django_admin/decorators/display.py +9 -7
- django_cfg/modules/django_admin/icons/__init__.py +1 -1
- django_cfg/modules/django_admin/icons/constants.py +27 -27
- django_cfg/modules/django_admin/icons/generate_icons.py +54 -54
- django_cfg/modules/django_admin/management/commands/check_endpoints.py +5 -3
- django_cfg/modules/django_admin/management/commands/check_settings.py +40 -44
- django_cfg/modules/django_admin/management/commands/clear_constance.py +29 -30
- django_cfg/modules/django_admin/management/commands/create_token.py +42 -42
- django_cfg/modules/django_admin/management/commands/list_urls.py +37 -38
- django_cfg/modules/django_admin/management/commands/migrate_all.py +13 -15
- django_cfg/modules/django_admin/management/commands/migrator.py +17 -17
- django_cfg/modules/django_admin/management/commands/script.py +58 -60
- django_cfg/modules/django_admin/management/commands/show_config.py +32 -30
- django_cfg/modules/django_admin/management/commands/show_urls.py +46 -44
- django_cfg/modules/django_admin/management/commands/superuser.py +47 -48
- django_cfg/modules/django_admin/management/commands/tree.py +50 -54
- django_cfg/modules/django_admin/mixins/display_mixin.py +16 -15
- django_cfg/modules/django_admin/mixins/optimization_mixin.py +9 -8
- django_cfg/modules/django_admin/mixins/standalone_actions_mixin.py +25 -24
- django_cfg/modules/django_admin/models/__init__.py +4 -4
- django_cfg/modules/django_admin/models/action_models.py +3 -1
- django_cfg/modules/django_admin/models/badge_models.py +4 -2
- django_cfg/modules/django_admin/models/base.py +3 -3
- django_cfg/modules/django_admin/models/display_models.py +1 -0
- django_cfg/modules/django_admin/utils/badges.py +27 -26
- django_cfg/modules/django_admin/utils/displays.py +49 -49
- django_cfg/modules/django_client/apps.py +21 -3
- django_cfg/modules/django_client/core/__init__.py +9 -10
- django_cfg/modules/django_client/core/archive/manager.py +2 -2
- django_cfg/modules/django_client/core/cli/main.py +1 -3
- django_cfg/modules/django_client/core/config/config.py +3 -1
- django_cfg/modules/django_client/core/config/group.py +1 -0
- django_cfg/modules/django_client/core/config/service.py +2 -1
- django_cfg/modules/django_client/core/generator/__init__.py +1 -1
- django_cfg/modules/django_client/core/generator/base.py +2 -2
- django_cfg/modules/django_client/core/generator/python/async_client_gen.py +1 -1
- django_cfg/modules/django_client/core/generator/python/files_generator.py +1 -1
- django_cfg/modules/django_client/core/generator/python/generator.py +4 -4
- django_cfg/modules/django_client/core/generator/python/models_generator.py +1 -1
- django_cfg/modules/django_client/core/generator/python/operations_generator.py +2 -2
- django_cfg/modules/django_client/core/generator/python/sync_client_gen.py +1 -1
- django_cfg/modules/django_client/core/generator/typescript/client_generator.py +3 -1
- django_cfg/modules/django_client/core/generator/typescript/fetchers_generator.py +14 -13
- django_cfg/modules/django_client/core/generator/typescript/files_generator.py +1 -0
- django_cfg/modules/django_client/core/generator/typescript/generator.py +6 -6
- django_cfg/modules/django_client/core/generator/typescript/hooks_generator.py +12 -10
- django_cfg/modules/django_client/core/generator/typescript/models_generator.py +2 -1
- django_cfg/modules/django_client/core/generator/typescript/naming.py +2 -3
- django_cfg/modules/django_client/core/generator/typescript/operations_generator.py +12 -10
- django_cfg/modules/django_client/core/generator/typescript/schemas_generator.py +3 -2
- django_cfg/modules/django_client/core/generator/typescript/templates/client/client.ts.jinja +14 -6
- django_cfg/modules/django_client/core/generator/typescript/templates/main_index.ts.jinja +4 -10
- django_cfg/modules/django_client/core/groups/__init__.py +1 -1
- django_cfg/modules/django_client/core/groups/detector.py +2 -1
- django_cfg/modules/django_client/core/groups/manager.py +2 -1
- django_cfg/modules/django_client/core/ir/schema.py +1 -1
- django_cfg/modules/django_client/core/parser/base.py +0 -2
- django_cfg/modules/django_client/core/parser/models/schema.py +1 -1
- django_cfg/modules/django_client/core/validation/__init__.py +1 -1
- django_cfg/modules/django_client/core/validation/fixer.py +1 -2
- django_cfg/modules/django_client/core/validation/reporter.py +2 -2
- django_cfg/modules/django_client/core/validation/safety.py +1 -1
- django_cfg/modules/django_client/management/commands/generate_client.py +14 -11
- django_cfg/modules/django_client/management/commands/validate_openapi.py +4 -6
- django_cfg/modules/django_client/spectacular/__init__.py +1 -1
- django_cfg/modules/django_client/spectacular/async_detection.py +3 -2
- django_cfg/modules/django_client/spectacular/enum_naming.py +1 -1
- django_cfg/modules/django_client/spectacular/schema.py +5 -5
- django_cfg/modules/django_client/system/__init__.py +24 -0
- django_cfg/modules/django_client/system/base_generator.py +123 -0
- django_cfg/modules/django_client/system/generate_mjs_clients.py +174 -0
- django_cfg/modules/django_client/system/mjs_generator.py +219 -0
- django_cfg/modules/django_client/system/schema_parser.py +195 -0
- django_cfg/modules/django_client/system/templates/api_client.js.j2 +87 -0
- django_cfg/modules/django_client/system/templates/app_index.js.j2 +13 -0
- django_cfg/modules/django_client/system/templates/base_client.js.j2 +166 -0
- django_cfg/modules/django_client/system/templates/main_index.js.j2 +80 -0
- django_cfg/modules/django_client/system/templates/types.js.j2 +24 -0
- django_cfg/modules/django_client/urls.py +3 -2
- django_cfg/modules/django_currency/__init__.py +17 -18
- django_cfg/modules/django_currency/clients/__init__.py +2 -2
- django_cfg/modules/django_currency/clients/coinpaprika_client.py +48 -48
- django_cfg/modules/django_currency/clients/hybrid_client.py +76 -75
- django_cfg/modules/django_currency/core/__init__.py +7 -13
- django_cfg/modules/django_currency/core/converter.py +25 -24
- django_cfg/modules/django_currency/core/models.py +9 -8
- django_cfg/modules/django_currency/database/__init__.py +4 -4
- django_cfg/modules/django_currency/database/database_loader.py +65 -66
- django_cfg/modules/django_currency/examples/example_database_usage.py +29 -28
- django_cfg/modules/django_currency/utils/cache.py +10 -11
- django_cfg/modules/django_dashboard/__init__.py +4 -5
- django_cfg/modules/django_dashboard/components.py +11 -7
- django_cfg/modules/django_dashboard/debug.py +1 -3
- django_cfg/modules/django_dashboard/management/commands/debug_dashboard.py +3 -3
- django_cfg/modules/django_dashboard/sections/base.py +2 -1
- django_cfg/modules/django_dashboard/sections/commands.py +3 -2
- django_cfg/modules/django_dashboard/sections/documentation.py +8 -6
- django_cfg/modules/django_dashboard/sections/overview.py +13 -9
- django_cfg/modules/django_dashboard/sections/stats.py +2 -2
- django_cfg/modules/django_dashboard/sections/system.py +2 -1
- django_cfg/modules/django_drf_theme/templatetags/tailwind_tags.py +12 -4
- django_cfg/modules/django_email/management/commands/test_email.py +8 -7
- django_cfg/modules/django_email/service.py +5 -4
- django_cfg/modules/django_health/service.py +46 -44
- django_cfg/modules/django_import_export/__init__.py +7 -3
- django_cfg/modules/django_llm/__init__.py +3 -2
- django_cfg/modules/django_llm/example.py +58 -56
- django_cfg/modules/django_llm/llm/__init__.py +1 -1
- django_cfg/modules/django_llm/llm/cache.py +21 -20
- django_cfg/modules/django_llm/llm/client.py +9 -9
- django_cfg/modules/django_llm/llm/costs.py +14 -14
- django_cfg/modules/django_llm/llm/embeddings/__init__.py +1 -1
- django_cfg/modules/django_llm/llm/embeddings/mock_embedder.py +1 -2
- django_cfg/modules/django_llm/llm/embeddings/openai_embedder.py +1 -2
- django_cfg/modules/django_llm/llm/extractor.py +8 -8
- django_cfg/modules/django_llm/llm/models.py +5 -5
- django_cfg/modules/django_llm/llm/models_api/models_query.py +2 -2
- django_cfg/modules/django_llm/llm/models_cache.py +91 -92
- django_cfg/modules/django_llm/llm/providers/config_builder.py +1 -1
- django_cfg/modules/django_llm/llm/providers/provider_manager.py +2 -1
- django_cfg/modules/django_llm/llm/requests/cache_manager.py +1 -1
- django_cfg/modules/django_llm/llm/requests/chat_handler.py +2 -2
- django_cfg/modules/django_llm/llm/requests/embedding_handler.py +1 -1
- django_cfg/modules/django_llm/llm/responses/response_builder.py +2 -2
- django_cfg/modules/django_llm/llm/stats/stats_manager.py +1 -1
- django_cfg/modules/django_llm/llm/tokenizer.py +10 -9
- django_cfg/modules/django_llm/translator/__init__.py +1 -1
- django_cfg/modules/django_llm/translator/cache.py +36 -35
- django_cfg/modules/django_llm/translator/detectors/__init__.py +1 -1
- django_cfg/modules/django_llm/translator/detectors/script_detector.py +0 -1
- django_cfg/modules/django_llm/translator/stats/stats_tracker.py +1 -1
- django_cfg/modules/django_llm/translator/translator.py +5 -4
- django_cfg/modules/django_llm/translator/translators/__init__.py +1 -1
- django_cfg/modules/django_llm/translator/translators/json_translator.py +1 -1
- django_cfg/modules/django_llm/translator/utils/__init__.py +1 -1
- django_cfg/modules/django_llm/translator/utils/prompt_builder.py +0 -1
- django_cfg/modules/django_logging/__init__.py +1 -1
- django_cfg/modules/django_logging/django_logger.py +33 -34
- django_cfg/modules/django_logging/logger.py +3 -7
- django_cfg/modules/django_ngrok/__init__.py +7 -7
- django_cfg/modules/django_ngrok/management/commands/runserver_ngrok.py +33 -30
- django_cfg/modules/django_ngrok/service.py +33 -32
- django_cfg/modules/django_tailwind/templates/django_tailwind/base.html +4 -36
- django_cfg/modules/django_tailwind/templates/django_tailwind/components/navbar.html +1 -1
- django_cfg/modules/django_tasks/__init__.py +5 -5
- django_cfg/modules/django_tasks/dramatiq_setup.py +1 -1
- django_cfg/modules/django_tasks/factory.py +1 -1
- django_cfg/modules/django_tasks/management/commands/rundramatiq.py +39 -40
- django_cfg/modules/django_tasks/management/commands/rundramatiq_simulator.py +79 -80
- django_cfg/modules/django_tasks/management/commands/task_clear.py +34 -34
- django_cfg/modules/django_tasks/management/commands/task_status.py +34 -34
- django_cfg/modules/django_tasks/service.py +4 -3
- django_cfg/modules/django_tasks/settings.py +1 -1
- django_cfg/modules/django_telegram/__init__.py +4 -4
- django_cfg/modules/django_telegram/management/commands/test_telegram.py +4 -5
- django_cfg/modules/django_telegram/service.py +4 -3
- django_cfg/modules/django_telegram/utils.py +1 -1
- django_cfg/modules/django_twilio/__init__.py +15 -16
- django_cfg/modules/django_twilio/_imports.py +1 -1
- django_cfg/modules/django_twilio/base.py +9 -5
- django_cfg/modules/django_twilio/email_otp.py +4 -3
- django_cfg/modules/django_twilio/exceptions.py +36 -36
- django_cfg/modules/django_twilio/management/commands/test_twilio.py +6 -7
- django_cfg/modules/django_twilio/models.py +54 -53
- django_cfg/modules/django_twilio/sendgrid_service.py +70 -72
- django_cfg/modules/django_twilio/simple_service.py +42 -41
- django_cfg/modules/django_twilio/sms.py +1 -0
- django_cfg/modules/django_twilio/twilio_service.py +79 -83
- django_cfg/modules/django_twilio/unified.py +6 -5
- django_cfg/modules/django_twilio/utils.py +2 -3
- django_cfg/modules/django_twilio/whatsapp.py +3 -2
- django_cfg/modules/django_unfold/__init__.py +7 -6
- django_cfg/modules/django_unfold/callbacks/actions.py +6 -5
- django_cfg/modules/django_unfold/callbacks/apizones.py +122 -0
- django_cfg/modules/django_unfold/callbacks/base.py +9 -8
- django_cfg/modules/django_unfold/callbacks/charts.py +36 -37
- django_cfg/modules/django_unfold/callbacks/commands.py +2 -2
- django_cfg/modules/django_unfold/callbacks/main.py +27 -27
- django_cfg/modules/django_unfold/callbacks/statistics.py +12 -12
- django_cfg/modules/django_unfold/callbacks/system.py +5 -5
- django_cfg/modules/django_unfold/callbacks/users.py +4 -4
- django_cfg/modules/django_unfold/dashboard.py +29 -29
- django_cfg/modules/django_unfold/models/__init__.py +23 -8
- django_cfg/modules/django_unfold/models/config.py +84 -81
- django_cfg/modules/django_unfold/models/dashboard.py +20 -19
- django_cfg/modules/django_unfold/models/dropdown.py +6 -4
- django_cfg/modules/django_unfold/models/navigation.py +6 -4
- django_cfg/modules/django_unfold/models/tabs.py +4 -3
- django_cfg/modules/django_unfold/models.py +2 -3
- django_cfg/modules/django_unfold/system_monitor.py +27 -25
- django_cfg/modules/django_unfold/tailwind.py +12 -14
- django_cfg/modules/django_unfold/utils.py +7 -6
- django_cfg/pyproject.toml +1 -1
- django_cfg/registry/__init__.py +3 -3
- django_cfg/registry/core.py +8 -8
- django_cfg/registry/modules.py +2 -2
- django_cfg/registry/services.py +2 -2
- django_cfg/registry/third_party.py +3 -3
- django_cfg/routing/__init__.py +3 -3
- django_cfg/routing/callbacks.py +27 -26
- django_cfg/routing/routers.py +2 -2
- django_cfg/static/js/api/accounts/client.mjs +69 -0
- django_cfg/static/js/api/accounts/index.mjs +13 -0
- django_cfg/static/js/api/base.mjs +166 -0
- django_cfg/static/js/api/index.mjs +100 -0
- django_cfg/static/js/api/ipc/client.mjs +74 -0
- django_cfg/static/js/api/ipc/index.mjs +13 -0
- django_cfg/static/js/api/leads/client.mjs +71 -0
- django_cfg/static/js/api/leads/index.mjs +13 -0
- django_cfg/static/js/api/newsletter/client.mjs +109 -0
- django_cfg/static/js/api/newsletter/index.mjs +13 -0
- django_cfg/static/js/api/payments/client.mjs +1264 -0
- django_cfg/static/js/api/payments/index.mjs +13 -0
- django_cfg/static/js/api/support/client.mjs +84 -0
- django_cfg/static/js/api/support/index.mjs +13 -0
- django_cfg/static/js/api/tasks/client.mjs +74 -0
- django_cfg/static/js/api/tasks/index.mjs +13 -0
- django_cfg/static/js/api/types.mjs +729 -0
- django_cfg/static/js/api-loader.mjs +169 -0
- django_cfg/templates/admin/snippets/zones/zones_table.html +4 -3
- django_cfg/templatetags/django_cfg.py +4 -4
- django_cfg/utils/path_resolution.py +49 -50
- django_cfg/utils/smart_defaults.py +27 -29
- django_cfg/utils/version_check.py +14 -14
- {django_cfg-1.4.20.dist-info → django_cfg-1.4.23.dist-info}/METADATA +1 -1
- django_cfg-1.4.23.dist-info/RECORD +1137 -0
- django_cfg/apps/payments/static/payments/js/api-client.js +0 -408
- django_cfg/modules/django_ipc_client/dashboard/README.md +0 -517
- django_cfg/modules/django_ipc_client/dashboard/UNFOLD_INTEGRATION.md +0 -439
- django_cfg/modules/django_ipc_client/dashboard/__init__.py +0 -11
- django_cfg/modules/django_ipc_client/dashboard/apps.py +0 -22
- django_cfg/modules/django_ipc_client/dashboard/templates/django_ipc_dashboard/dashboard.html +0 -200
- django_cfg/modules/django_ipc_client/dashboard/urls.py +0 -22
- django_cfg/modules/django_ipc_client/dashboard/urls_admin.py +0 -9
- django_cfg/modules/django_ipc_client/dashboard/views.py +0 -251
- django_cfg/modules/django_rpc_old/POETRY.md +0 -344
- django_cfg/modules/django_rpc_old/README.md +0 -397
- django_cfg/modules/django_rpc_old/TESTING.md +0 -358
- django_cfg/modules/django_rpc_old/__init__.py +0 -39
- django_cfg/modules/django_rpc_old/client.py +0 -531
- django_cfg/modules/django_rpc_old/config.py +0 -279
- django_cfg/modules/django_rpc_old/exceptions.py +0 -172
- django_cfg/modules/django_unfold/callbacks/revolution.py +0 -81
- django_cfg-1.4.20.dist-info/RECORD +0 -1110
- /django_cfg/{modules/django_ipc_client → apps/ipc}/README.md +0 -0
- /django_cfg/{modules/django_ipc_client → apps/ipc/services/client}/config.py +0 -0
- {django_cfg-1.4.20.dist-info → django_cfg-1.4.23.dist-info}/WHEEL +0 -0
- {django_cfg-1.4.20.dist-info → django_cfg-1.4.23.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.4.20.dist-info → django_cfg-1.4.23.dist-info}/licenses/LICENSE +0 -0
@@ -3,64 +3,65 @@ Archive managers for document archive models.
|
|
3
3
|
"""
|
4
4
|
|
5
5
|
import logging
|
6
|
-
from
|
7
|
-
|
8
|
-
from typing import Optional, List, Dict, Any
|
6
|
+
from typing import Any, Dict, List, Optional
|
7
|
+
|
9
8
|
from django.contrib.auth import get_user_model
|
9
|
+
from django.db import models, transaction
|
10
|
+
from django.db.models import Avg, Count, Q, Sum
|
10
11
|
|
11
12
|
User = get_user_model()
|
12
13
|
|
13
14
|
|
14
15
|
class DocumentArchiveManager(models.Manager):
|
15
16
|
"""Custom manager for DocumentArchive model."""
|
16
|
-
|
17
|
+
|
17
18
|
def for_user(self, user):
|
18
19
|
"""Explicitly filter by specific user."""
|
19
20
|
return self.get_queryset().filter(user=user)
|
20
|
-
|
21
|
+
|
21
22
|
def all_users(self):
|
22
23
|
"""Get unfiltered queryset (admin use)."""
|
23
24
|
return self.get_queryset()
|
24
|
-
|
25
|
+
|
25
26
|
def processed(self):
|
26
27
|
"""Get only processed archives."""
|
27
28
|
from ..models.base import ProcessingStatus
|
28
29
|
return self.get_queryset().filter(
|
29
30
|
processing_status=ProcessingStatus.COMPLETED
|
30
31
|
)
|
31
|
-
|
32
|
+
|
32
33
|
def pending_processing(self):
|
33
34
|
"""Get archives pending processing."""
|
34
35
|
from ..models.base import ProcessingStatus
|
35
36
|
return self.get_queryset().filter(
|
36
37
|
processing_status=ProcessingStatus.PENDING
|
37
38
|
)
|
38
|
-
|
39
|
+
|
39
40
|
def failed_processing(self):
|
40
41
|
"""Get archives that failed processing."""
|
41
42
|
from ..models.base import ProcessingStatus
|
42
43
|
return self.get_queryset().filter(
|
43
44
|
processing_status=ProcessingStatus.FAILED
|
44
45
|
)
|
45
|
-
|
46
|
+
|
46
47
|
def by_content_hash(self, content_hash: str):
|
47
48
|
"""Find archives by content hash."""
|
48
49
|
return self.get_queryset().filter(content_hash=content_hash)
|
49
|
-
|
50
|
+
|
50
51
|
def by_archive_type(self, archive_type: str):
|
51
52
|
"""Get archives by type (zip, tar, etc.)."""
|
52
53
|
return self.get_queryset().filter(archive_type=archive_type)
|
53
|
-
|
54
|
+
|
54
55
|
def with_stats(self):
|
55
56
|
"""Get archives with item and chunk statistics."""
|
56
57
|
return self.get_queryset().select_related('user').prefetch_related(
|
57
58
|
'items', 'chunks', 'categories'
|
58
59
|
)
|
59
|
-
|
60
|
+
|
60
61
|
def get_processing_statistics(self, user=None) -> Dict[str, Any]:
|
61
62
|
"""Get archive processing statistics."""
|
62
63
|
queryset = self.for_user(user) if user else self.get_queryset()
|
63
|
-
|
64
|
+
|
64
65
|
# Get basic statistics
|
65
66
|
stats = queryset.aggregate(
|
66
67
|
total_archives=Count('id'),
|
@@ -72,7 +73,7 @@ class DocumentArchiveManager(models.Manager):
|
|
72
73
|
total_cost=Sum('total_cost_usd'),
|
73
74
|
avg_processing_time=Avg('processing_duration_ms')
|
74
75
|
)
|
75
|
-
|
76
|
+
|
76
77
|
# Calculate averages manually to avoid aggregate on aggregate error
|
77
78
|
if stats['total_archives'] and stats['total_archives'] > 0:
|
78
79
|
stats['avg_items_per_archive'] = (stats['total_items'] or 0) / stats['total_archives']
|
@@ -80,27 +81,27 @@ class DocumentArchiveManager(models.Manager):
|
|
80
81
|
else:
|
81
82
|
stats['avg_items_per_archive'] = 0
|
82
83
|
stats['avg_chunks_per_archive'] = 0
|
83
|
-
|
84
|
+
|
84
85
|
return stats
|
85
|
-
|
86
|
+
|
86
87
|
def check_duplicate_before_save(self, user, title, file_size, exclude_id=None):
|
87
88
|
"""Check for duplicate archive before saving. Returns (is_duplicate, existing_archive)."""
|
88
89
|
if not title or not file_size:
|
89
90
|
return False, None
|
90
|
-
|
91
|
+
|
91
92
|
# Use all_users() to bypass user filtering
|
92
93
|
query = self.all_users().filter(
|
93
|
-
user=user,
|
94
|
+
user=user,
|
94
95
|
title=title,
|
95
96
|
file_size=file_size
|
96
97
|
)
|
97
|
-
|
98
|
+
|
98
99
|
if exclude_id:
|
99
100
|
query = query.exclude(pk=exclude_id)
|
100
|
-
|
101
|
+
|
101
102
|
existing_archive = query.first()
|
102
103
|
return existing_archive is not None, existing_archive
|
103
|
-
|
104
|
+
|
104
105
|
def reprocess(self, archive_id: str) -> bool:
|
105
106
|
"""
|
106
107
|
Reset and reprocess an archive.
|
@@ -116,9 +117,9 @@ class DocumentArchiveManager(models.Manager):
|
|
116
117
|
"""
|
117
118
|
from ..models.base import ProcessingStatus
|
118
119
|
from ..tasks.archive_tasks import process_archive_task
|
119
|
-
|
120
|
+
|
120
121
|
logger = logging.getLogger(__name__)
|
121
|
-
|
122
|
+
|
122
123
|
try:
|
123
124
|
# Import the model directly to avoid queryset issues
|
124
125
|
from ..models.archive import DocumentArchive
|
@@ -126,74 +127,74 @@ class DocumentArchiveManager(models.Manager):
|
|
126
127
|
archive = DocumentArchive.objects.get(pk=archive_id)
|
127
128
|
except DocumentArchive.DoesNotExist:
|
128
129
|
raise ValueError(f"Archive with ID {archive_id} not found")
|
129
|
-
except Exception
|
130
|
+
except Exception:
|
130
131
|
raise
|
131
|
-
|
132
|
+
|
132
133
|
# Check if archive has a file
|
133
134
|
if not archive.archive_file:
|
134
135
|
raise ValueError("Archive has no file to process")
|
135
|
-
|
136
|
+
|
136
137
|
# Check if archive is already being processed
|
137
138
|
if archive.processing_status == ProcessingStatus.PROCESSING:
|
138
139
|
raise ValueError(f"Archive {archive.id} is already being processed")
|
139
|
-
|
140
|
+
|
140
141
|
# Set processing status immediately to prevent concurrent reprocessing
|
141
142
|
# Use select_for_update to prevent race conditions
|
142
143
|
with transaction.atomic():
|
143
144
|
archive = DocumentArchive.objects.select_for_update().get(pk=archive_id)
|
144
145
|
if archive.processing_status == ProcessingStatus.PROCESSING:
|
145
146
|
raise ValueError(f"Archive {archive.id} is already being processed by another process")
|
146
|
-
|
147
|
+
|
147
148
|
archive.processing_status = ProcessingStatus.PROCESSING
|
148
149
|
archive.save(update_fields=['processing_status'])
|
149
150
|
logger.info(f"🔒 Locked archive {archive.id} for reprocessing")
|
150
|
-
|
151
|
+
|
151
152
|
logger.info(f"🔄 Starting reprocessing for archive {archive.id} ({archive.title})")
|
152
|
-
|
153
|
+
|
153
154
|
# Reset processing status and clear error
|
154
155
|
archive.processing_status = ProcessingStatus.PENDING
|
155
156
|
archive.processing_error = ""
|
156
157
|
archive.processing_duration_ms = 0
|
157
158
|
archive.processed_at = None
|
158
|
-
|
159
|
+
|
159
160
|
# Clear existing items and chunks using Django ORM with proper transaction handling
|
160
161
|
from ..models.archive import ArchiveItem, ArchiveItemChunk
|
161
|
-
|
162
|
+
|
162
163
|
# Count existing records first
|
163
164
|
items_count = ArchiveItem.objects.filter(archive=archive).count()
|
164
165
|
chunks_count = ArchiveItemChunk.objects.filter(item__archive=archive).count()
|
165
|
-
|
166
|
+
|
166
167
|
logger.info(f"🗑️ Found {items_count} items and {chunks_count} chunks to delete")
|
167
|
-
|
168
|
+
|
168
169
|
if items_count > 0 or chunks_count > 0:
|
169
170
|
# Delete in separate transaction to ensure complete removal before new processing
|
170
171
|
try:
|
171
172
|
with transaction.atomic():
|
172
173
|
# Delete chunks first (foreign key dependency)
|
173
174
|
chunks_deleted, _ = ArchiveItemChunk.objects.filter(item__archive=archive).delete()
|
174
|
-
|
175
|
+
|
175
176
|
# Delete items
|
176
177
|
items_deleted, _ = ArchiveItem.objects.filter(archive=archive).delete()
|
177
|
-
|
178
|
+
|
178
179
|
# Verify deletion outside transaction with retry logic
|
179
180
|
import time
|
180
181
|
max_retries = 3
|
181
182
|
for retry in range(max_retries):
|
182
183
|
remaining_items = ArchiveItem.objects.filter(archive=archive).count()
|
183
184
|
remaining_chunks = ArchiveItemChunk.objects.filter(item__archive=archive).count()
|
184
|
-
|
185
|
+
|
185
186
|
if remaining_items == 0 and remaining_chunks == 0:
|
186
187
|
break
|
187
|
-
|
188
|
+
|
188
189
|
if retry < max_retries - 1:
|
189
190
|
logger.warning(f"⚠️ Retry {retry + 1}: Still {remaining_items} items and {remaining_chunks} chunks remaining, waiting...")
|
190
191
|
time.sleep(0.2)
|
191
192
|
else:
|
192
193
|
logger.error(f"❌ Failed to delete all records after {max_retries} retries! {remaining_items} items and {remaining_chunks} chunks still remain")
|
193
194
|
raise ValueError(f"Failed to clear existing archive data after {max_retries} retries. {remaining_items} items and {remaining_chunks} chunks still exist.")
|
194
|
-
|
195
|
+
|
195
196
|
logger.info(f"🗑️ Successfully deleted {items_deleted} items and {chunks_deleted} chunks")
|
196
|
-
|
197
|
+
|
197
198
|
except Exception as e:
|
198
199
|
logger.error(f"❌ Error during deletion: {e}")
|
199
200
|
# Reset processing status on error
|
@@ -203,36 +204,36 @@ class DocumentArchiveManager(models.Manager):
|
|
203
204
|
raise
|
204
205
|
else:
|
205
206
|
logger.info("🗑️ No existing records to delete")
|
206
|
-
|
207
|
+
|
207
208
|
# Reset statistics
|
208
209
|
archive.total_items = 0
|
209
210
|
archive.processed_items = 0
|
210
211
|
archive.total_chunks = 0
|
211
212
|
archive.vectorized_chunks = 0
|
212
213
|
archive.total_cost_usd = 0.0
|
213
|
-
|
214
|
+
|
214
215
|
archive.save()
|
215
216
|
logger.info(f"💾 Archive {archive.id} reset to PENDING status")
|
216
|
-
|
217
|
+
|
217
218
|
# Trigger reprocessing directly via task
|
218
219
|
process_archive_task.send(str(archive.id), str(archive.user.id))
|
219
220
|
logger.info(f"🚀 Queued reprocessing task for archive {archive.id}")
|
220
|
-
|
221
|
+
|
221
222
|
return True
|
222
|
-
|
223
|
+
|
223
224
|
def get_vectorization_progress(self, archive_id):
|
224
225
|
"""Get vectorization progress for an archive."""
|
225
226
|
try:
|
227
|
+
|
226
228
|
from ..models.archive import ArchiveItemChunk
|
227
|
-
|
228
|
-
|
229
|
+
|
229
230
|
# Count chunks using Django ORM
|
230
|
-
|
231
|
+
|
231
232
|
# Get all chunks for this archive
|
232
233
|
chunks_qs = ArchiveItemChunk.objects.filter(archive_id=archive_id)
|
233
|
-
|
234
|
+
|
234
235
|
total = chunks_qs.count()
|
235
|
-
|
236
|
+
|
236
237
|
# Count vectorized chunks by checking if embedding has non-zero values
|
237
238
|
# We'll check if the first element is not 0.0 as a proxy for non-zero vector
|
238
239
|
vectorized = 0
|
@@ -240,7 +241,7 @@ class DocumentArchiveManager(models.Manager):
|
|
240
241
|
for chunk in chunks_qs.only('embedding'):
|
241
242
|
if chunk.embedding is not None and len(chunk.embedding) > 0 and any(x != 0.0 for x in chunk.embedding):
|
242
243
|
vectorized += 1
|
243
|
-
|
244
|
+
|
244
245
|
return {
|
245
246
|
'total': total,
|
246
247
|
'vectorized': vectorized,
|
@@ -259,65 +260,65 @@ class DocumentArchiveManager(models.Manager):
|
|
259
260
|
|
260
261
|
class ArchiveItemManager(models.Manager):
|
261
262
|
"""Custom manager for ArchiveItem model."""
|
262
|
-
|
263
|
+
|
263
264
|
def for_user(self, user):
|
264
265
|
"""Explicitly filter by specific user."""
|
265
266
|
return self.get_queryset().filter(user=user)
|
266
|
-
|
267
|
+
|
267
268
|
def all_users(self):
|
268
269
|
"""Get unfiltered queryset (admin use)."""
|
269
270
|
return self.get_queryset()
|
270
|
-
|
271
|
+
|
271
272
|
def for_archive(self, archive_id: str):
|
272
273
|
"""Get items for specific archive."""
|
273
274
|
return self.get_queryset().filter(archive_id=archive_id)
|
274
|
-
|
275
|
+
|
275
276
|
def by_content_type(self, content_type: str):
|
276
277
|
"""Get items by content type."""
|
277
278
|
return self.get_queryset().filter(content_type=content_type)
|
278
|
-
|
279
|
+
|
279
280
|
def by_language(self, language: str):
|
280
281
|
"""Get items by programming language."""
|
281
282
|
return self.get_queryset().filter(language=language)
|
282
|
-
|
283
|
+
|
283
284
|
def processable(self):
|
284
285
|
"""Get only processable items."""
|
285
286
|
return self.get_queryset().filter(is_processable=True)
|
286
|
-
|
287
|
+
|
287
288
|
def code_files(self):
|
288
289
|
"""Get only code files."""
|
289
290
|
return self.get_queryset().filter(content_type='code')
|
290
|
-
|
291
|
+
|
291
292
|
def document_files(self):
|
292
293
|
"""Get only document files."""
|
293
294
|
return self.get_queryset().filter(content_type='document')
|
294
|
-
|
295
|
+
|
295
296
|
def data_files(self):
|
296
297
|
"""Get only data files."""
|
297
298
|
return self.get_queryset().filter(content_type='data')
|
298
|
-
|
299
|
+
|
299
300
|
def with_chunks(self):
|
300
301
|
"""Get items with their chunks."""
|
301
302
|
return self.get_queryset().prefetch_related('chunks')
|
302
|
-
|
303
|
+
|
303
304
|
def get_content_type_distribution(self, archive_id: Optional[str] = None) -> Dict[str, int]:
|
304
305
|
"""Get distribution of content types."""
|
305
306
|
queryset = self.get_queryset()
|
306
307
|
if archive_id:
|
307
308
|
queryset = queryset.filter(archive_id=archive_id)
|
308
|
-
|
309
|
+
|
309
310
|
return dict(
|
310
311
|
queryset.values('content_type').annotate(
|
311
312
|
count=Count('id')
|
312
313
|
).values_list('content_type', 'count')
|
313
314
|
)
|
314
|
-
|
315
|
+
|
315
316
|
def get_language_distribution(self, archive_id: Optional[str] = None) -> Dict[str, int]:
|
316
317
|
"""Get distribution of programming languages."""
|
317
318
|
queryset = self.get_queryset().filter(language__isnull=False).exclude(language='')
|
318
319
|
if archive_id:
|
319
320
|
queryset = queryset.filter(archive_id=archive_id)
|
320
|
-
|
321
|
+
|
321
322
|
return dict(
|
322
323
|
queryset.values('language').annotate(
|
323
324
|
count=Count('id')
|
@@ -327,43 +328,43 @@ class ArchiveItemManager(models.Manager):
|
|
327
328
|
|
328
329
|
class ArchiveItemChunkManager(models.Manager):
|
329
330
|
"""Custom manager for ArchiveItemChunk model."""
|
330
|
-
|
331
|
+
|
331
332
|
def for_user(self, user):
|
332
333
|
"""Explicitly filter by specific user."""
|
333
334
|
return self.get_queryset().filter(user=user)
|
334
|
-
|
335
|
+
|
335
336
|
def all_users(self):
|
336
337
|
"""Get unfiltered queryset (admin use)."""
|
337
338
|
return self.get_queryset()
|
338
|
-
|
339
|
+
|
339
340
|
def for_archive(self, archive_id: str):
|
340
341
|
"""Get chunks for specific archive."""
|
341
342
|
return self.get_queryset().filter(archive_id=archive_id)
|
342
|
-
|
343
|
+
|
343
344
|
def for_item(self, item_id: str):
|
344
345
|
"""Get chunks for specific item."""
|
345
346
|
return self.get_queryset().filter(item_id=item_id)
|
346
|
-
|
347
|
+
|
347
348
|
def by_chunk_type(self, chunk_type: str):
|
348
349
|
"""Get chunks by type."""
|
349
350
|
return self.get_queryset().filter(chunk_type=chunk_type)
|
350
|
-
|
351
|
+
|
351
352
|
def vectorized(self):
|
352
353
|
"""Get only vectorized chunks."""
|
353
354
|
return self.get_queryset().filter(embedding__isnull=False)
|
354
|
-
|
355
|
+
|
355
356
|
def pending_vectorization(self):
|
356
357
|
"""Get chunks pending vectorization."""
|
357
358
|
return self.get_queryset().filter(embedding__isnull=True)
|
358
|
-
|
359
|
+
|
359
360
|
def by_content_type(self, content_type: str):
|
360
361
|
"""Get chunks by parent item content type."""
|
361
362
|
return self.get_queryset().filter(item__content_type=content_type)
|
362
|
-
|
363
|
+
|
363
364
|
def by_language(self, language: str):
|
364
365
|
"""Get chunks by parent item language."""
|
365
366
|
return self.get_queryset().filter(item__language=language)
|
366
|
-
|
367
|
+
|
367
368
|
def semantic_search(
|
368
369
|
self,
|
369
370
|
query_embedding: List[float],
|
@@ -375,35 +376,35 @@ class ArchiveItemChunkManager(models.Manager):
|
|
375
376
|
):
|
376
377
|
"""Perform semantic search with advanced filtering."""
|
377
378
|
from pgvector.django import CosineDistance
|
378
|
-
|
379
|
+
|
379
380
|
queryset = self.get_queryset().filter(embedding__isnull=False)
|
380
|
-
|
381
|
+
|
381
382
|
# Apply filters
|
382
383
|
if content_types:
|
383
384
|
queryset = queryset.filter(item__content_type__in=content_types)
|
384
|
-
|
385
|
+
|
385
386
|
if languages:
|
386
387
|
queryset = queryset.filter(item__language__in=languages)
|
387
|
-
|
388
|
+
|
388
389
|
if chunk_types:
|
389
390
|
queryset = queryset.filter(chunk_type__in=chunk_types)
|
390
|
-
|
391
|
+
|
391
392
|
return queryset.annotate(
|
392
393
|
similarity=1 - CosineDistance('embedding', query_embedding)
|
393
394
|
).filter(
|
394
395
|
similarity__gte=similarity_threshold
|
395
396
|
).order_by('-similarity')[:limit]
|
396
|
-
|
397
|
+
|
397
398
|
def with_context(self):
|
398
399
|
"""Get chunks with archive and item context."""
|
399
400
|
return self.get_queryset().select_related('archive', 'item')
|
400
|
-
|
401
|
+
|
401
402
|
def get_vectorization_statistics(self, archive_id: Optional[str] = None) -> Dict[str, Any]:
|
402
403
|
"""Get vectorization statistics."""
|
403
404
|
queryset = self.get_queryset()
|
404
405
|
if archive_id:
|
405
406
|
queryset = queryset.filter(archive_id=archive_id)
|
406
|
-
|
407
|
+
|
407
408
|
return queryset.aggregate(
|
408
409
|
total_chunks=Count('id'),
|
409
410
|
vectorized_chunks=Count('id', filter=Q(embedding__isnull=False)),
|
@@ -412,13 +413,13 @@ class ArchiveItemChunkManager(models.Manager):
|
|
412
413
|
avg_tokens_per_chunk=Avg('token_count'),
|
413
414
|
avg_cost_per_chunk=Avg('embedding_cost')
|
414
415
|
)
|
415
|
-
|
416
|
+
|
416
417
|
def get_chunk_type_distribution(self, archive_id: Optional[str] = None) -> Dict[str, int]:
|
417
418
|
"""Get distribution of chunk types."""
|
418
419
|
queryset = self.get_queryset()
|
419
420
|
if archive_id:
|
420
421
|
queryset = queryset.filter(archive_id=archive_id)
|
421
|
-
|
422
|
+
|
422
423
|
return dict(
|
423
424
|
queryset.values('chunk_type').annotate(
|
424
425
|
count=Count('id')
|
@@ -2,29 +2,29 @@
|
|
2
2
|
Base managers for knowbase models.
|
3
3
|
"""
|
4
4
|
|
5
|
-
from django.db import models
|
6
5
|
from django.contrib.auth import get_user_model
|
6
|
+
from django.db import models
|
7
7
|
|
8
8
|
User = get_user_model()
|
9
9
|
|
10
10
|
|
11
11
|
class BaseKnowbaseManager(models.Manager):
|
12
12
|
"""Base manager with common functionality for knowbase models."""
|
13
|
-
|
13
|
+
|
14
14
|
def for_user(self, user):
|
15
15
|
"""Explicitly filter by specific user."""
|
16
16
|
return self.get_queryset().filter(user=user)
|
17
|
-
|
17
|
+
|
18
18
|
def all_users(self):
|
19
19
|
"""Get unfiltered queryset (admin use)."""
|
20
20
|
return self.get_queryset()
|
21
|
-
|
21
|
+
|
22
22
|
def public(self):
|
23
23
|
"""Get public records (if model has is_public field)."""
|
24
24
|
if hasattr(self.model, 'is_public'):
|
25
25
|
return self.get_queryset().filter(is_public=True)
|
26
26
|
return self.get_queryset()
|
27
|
-
|
27
|
+
|
28
28
|
def active(self):
|
29
29
|
"""Get active records (if model has is_active field)."""
|
30
30
|
if hasattr(self.model, 'is_active'):
|
@@ -2,61 +2,62 @@
|
|
2
2
|
Chat managers for session and message management.
|
3
3
|
"""
|
4
4
|
|
5
|
-
from
|
6
|
-
|
7
|
-
from typing import Optional, List
|
5
|
+
from typing import Optional
|
6
|
+
|
8
7
|
from django.contrib.auth import get_user_model
|
8
|
+
from django.db import models
|
9
|
+
from django.db.models import Avg, Count, Q, Sum
|
9
10
|
|
10
11
|
User = get_user_model()
|
11
12
|
|
12
13
|
|
13
14
|
class ChatSessionManager(models.Manager):
|
14
15
|
"""Custom manager for ChatSession model."""
|
15
|
-
|
16
|
+
|
16
17
|
def for_user(self, user):
|
17
18
|
"""Explicitly filter by specific user."""
|
18
19
|
return self.get_queryset().filter(user=user)
|
19
|
-
|
20
|
+
|
20
21
|
def all_users(self):
|
21
22
|
"""Get unfiltered queryset (admin use)."""
|
22
23
|
return self.get_queryset()
|
23
|
-
|
24
|
+
|
24
25
|
def active(self):
|
25
26
|
"""Get only active chat sessions."""
|
26
27
|
return self.get_queryset().filter(is_active=True)
|
27
|
-
|
28
|
+
|
28
29
|
def inactive(self):
|
29
30
|
"""Get only inactive chat sessions."""
|
30
31
|
return self.get_queryset().filter(is_active=False)
|
31
|
-
|
32
|
+
|
32
33
|
def recent(self, limit: int = 10):
|
33
34
|
"""Get recent sessions ordered by update time."""
|
34
35
|
return self.get_queryset().order_by('-updated_at')[:limit]
|
35
|
-
|
36
|
+
|
36
37
|
def by_model(self, model_name: str):
|
37
38
|
"""Get sessions using specific model."""
|
38
39
|
return self.get_queryset().filter(model_name=model_name)
|
39
|
-
|
40
|
+
|
40
41
|
def with_message_count(self):
|
41
42
|
"""Get sessions with message count annotation."""
|
42
43
|
return self.get_queryset().annotate(
|
43
44
|
message_count=Count('messages')
|
44
45
|
)
|
45
|
-
|
46
|
+
|
46
47
|
def with_stats(self):
|
47
48
|
"""Get sessions with full statistics."""
|
48
49
|
return self.get_queryset().select_related('user').prefetch_related('messages')
|
49
|
-
|
50
|
+
|
50
51
|
def search_by_title(self, query: str):
|
51
52
|
"""Search sessions by title."""
|
52
53
|
return self.get_queryset().filter(
|
53
54
|
title__icontains=query
|
54
55
|
).order_by('-updated_at')
|
55
|
-
|
56
|
+
|
56
57
|
def get_user_statistics(self, user=None):
|
57
58
|
"""Get user's chat statistics."""
|
58
59
|
queryset = self.for_user(user) if user else self.get_queryset()
|
59
|
-
|
60
|
+
|
60
61
|
return queryset.aggregate(
|
61
62
|
total_sessions=Count('id'),
|
62
63
|
active_sessions=Count('id', filter=Q(is_active=True)),
|
@@ -70,51 +71,51 @@ class ChatSessionManager(models.Manager):
|
|
70
71
|
|
71
72
|
class ChatMessageManager(models.Manager):
|
72
73
|
"""Custom manager for ChatMessage model."""
|
73
|
-
|
74
|
+
|
74
75
|
def for_user(self, user):
|
75
76
|
"""Explicitly filter by specific user."""
|
76
77
|
return self.get_queryset().filter(user=user)
|
77
|
-
|
78
|
+
|
78
79
|
def all_users(self):
|
79
80
|
"""Get unfiltered queryset (admin use)."""
|
80
81
|
return self.get_queryset()
|
81
|
-
|
82
|
+
|
82
83
|
def for_session(self, session_id: str):
|
83
84
|
"""Get messages for specific session."""
|
84
85
|
return self.get_queryset().filter(session_id=session_id).order_by('created_at')
|
85
|
-
|
86
|
+
|
86
87
|
def user_messages(self):
|
87
88
|
"""Get only user messages."""
|
88
89
|
return self.get_queryset().filter(role='user')
|
89
|
-
|
90
|
+
|
90
91
|
def assistant_messages(self):
|
91
92
|
"""Get only assistant messages."""
|
92
93
|
return self.get_queryset().filter(role='assistant')
|
93
|
-
|
94
|
+
|
94
95
|
def system_messages(self):
|
95
96
|
"""Get only system messages."""
|
96
97
|
return self.get_queryset().filter(role='system')
|
97
|
-
|
98
|
+
|
98
99
|
def by_model(self, model_name: str):
|
99
100
|
"""Get messages generated by specific model."""
|
100
101
|
return self.get_queryset().filter(model_name=model_name)
|
101
|
-
|
102
|
+
|
102
103
|
def recent(self, limit: int = 50):
|
103
104
|
"""Get recent messages."""
|
104
105
|
return self.get_queryset().order_by('-created_at')[:limit]
|
105
|
-
|
106
|
+
|
106
107
|
def with_context(self):
|
107
108
|
"""Get messages that have context chunks."""
|
108
109
|
return self.get_queryset().exclude(context_chunks=[])
|
109
|
-
|
110
|
+
|
110
111
|
def expensive_messages(self, min_cost: float = 0.01):
|
111
112
|
"""Get messages above certain cost threshold."""
|
112
113
|
return self.get_queryset().filter(cost_usd__gte=min_cost)
|
113
|
-
|
114
|
+
|
114
115
|
def slow_messages(self, min_time_ms: int = 5000):
|
115
116
|
"""Get messages that took long to process."""
|
116
117
|
return self.get_queryset().filter(processing_time_ms__gte=min_time_ms)
|
117
|
-
|
118
|
+
|
118
119
|
def get_conversation_history(self, session_id: str, limit: Optional[int] = None):
|
119
120
|
"""Get conversation history for session."""
|
120
121
|
queryset = self.for_session(session_id)
|
@@ -124,11 +125,11 @@ class ChatMessageManager(models.Manager):
|
|
124
125
|
# Reverse to get chronological order
|
125
126
|
queryset = reversed(queryset)
|
126
127
|
return list(queryset)
|
127
|
-
|
128
|
+
|
128
129
|
def get_usage_statistics(self, user=None):
|
129
130
|
"""Get message usage statistics."""
|
130
131
|
queryset = self.for_user(user) if user else self.get_queryset()
|
131
|
-
|
132
|
+
|
132
133
|
return queryset.aggregate(
|
133
134
|
total_messages=Count('id'),
|
134
135
|
user_messages=Count('id', filter=Q(role='user')),
|