django-cfg 1.3.11__py3-none-any.whl → 1.4.0__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 +1 -1
- django_cfg/apps/accounts/admin/inlines.py +11 -5
- django_cfg/apps/accounts/admin/user_admin.py +39 -16
- django_cfg/apps/accounts/serializers/profile.py +1 -1
- django_cfg/apps/accounts/services/otp_service.py +18 -11
- django_cfg/apps/accounts/signals.py +15 -24
- django_cfg/apps/accounts/utils/notifications.py +217 -358
- django_cfg/apps/accounts/views/otp.py +2 -2
- django_cfg/apps/accounts/views/webhook.py +1 -1
- django_cfg/apps/agents/core/django_agent.py +1 -1
- django_cfg/apps/api/commands/views.py +66 -83
- django_cfg/apps/api/health/drf_views.py +269 -0
- django_cfg/apps/api/health/serializers.py +45 -0
- django_cfg/apps/api/health/urls.py +6 -1
- django_cfg/apps/knowbase/admin/actions/__init__.py +13 -0
- django_cfg/apps/knowbase/admin/actions/visibility_actions.py +56 -0
- django_cfg/apps/knowbase/admin/document_admin.py +136 -270
- django_cfg/apps/knowbase/admin/helpers/__init__.py +17 -0
- django_cfg/apps/knowbase/admin/helpers/configs.py +72 -0
- django_cfg/apps/knowbase/admin/helpers/display_helpers.py +156 -0
- django_cfg/apps/knowbase/admin/helpers/statistics.py +108 -0
- django_cfg/apps/knowbase/config/constance_fields.py +1 -1
- django_cfg/apps/knowbase/config/settings.py +2 -2
- django_cfg/apps/knowbase/mixins/__init__.py +19 -2
- django_cfg/apps/knowbase/mixins/config/__init__.py +14 -0
- django_cfg/apps/knowbase/mixins/config/defaults.py +75 -0
- django_cfg/apps/knowbase/mixins/config/meta_config.py +120 -0
- django_cfg/apps/knowbase/mixins/creator.py +10 -10
- django_cfg/apps/knowbase/mixins/external_data_mixin.py +105 -403
- django_cfg/apps/knowbase/mixins/generators/__init__.py +16 -0
- django_cfg/apps/knowbase/mixins/generators/content_generator.py +218 -0
- django_cfg/apps/knowbase/mixins/generators/field_analyzer.py +76 -0
- django_cfg/apps/knowbase/mixins/generators/metadata_generator.py +124 -0
- django_cfg/apps/knowbase/mixins/service.py +2 -2
- django_cfg/apps/knowbase/services/archive/__init__.py +1 -0
- django_cfg/apps/knowbase/services/archive/analyzers/__init__.py +17 -0
- django_cfg/apps/knowbase/services/archive/analyzers/complexity_analyzer.py +33 -0
- django_cfg/apps/knowbase/services/archive/analyzers/purpose_detector.py +36 -0
- django_cfg/apps/knowbase/services/archive/analyzers/quality_analyzer.py +39 -0
- django_cfg/apps/knowbase/services/archive/analyzers/tag_generator.py +103 -0
- django_cfg/apps/knowbase/services/archive/chunking/__init__.py +19 -0
- django_cfg/apps/knowbase/services/archive/chunking/base.py +81 -0
- django_cfg/apps/knowbase/services/archive/chunking/json_chunker.py +62 -0
- django_cfg/apps/knowbase/services/archive/chunking/markdown_chunker.py +107 -0
- django_cfg/apps/knowbase/services/archive/chunking/python_chunker.py +248 -0
- django_cfg/apps/knowbase/services/archive/chunking/text_chunker.py +70 -0
- django_cfg/apps/knowbase/services/archive/chunking_service.py +110 -729
- django_cfg/apps/knowbase/services/archive/context/__init__.py +14 -0
- django_cfg/apps/knowbase/services/archive/context/builders.py +220 -0
- django_cfg/apps/knowbase/services/archive/context/models.py +38 -0
- django_cfg/apps/knowbase/services/embedding/models.py +18 -14
- django_cfg/apps/knowbase/services/embedding/processors.py +6 -3
- django_cfg/apps/knowbase/tasks/document_processing.py +11 -3
- django_cfg/apps/leads/tests.py +1 -1
- django_cfg/apps/payments/admin/api_keys_admin.py +1 -1
- django_cfg/apps/payments/admin/balance_admin.py +1 -1
- django_cfg/apps/payments/admin/currencies_admin.py +1 -1
- django_cfg/apps/payments/admin/payments_admin.py +1 -1
- django_cfg/apps/payments/admin/subscriptions_admin.py +1 -1
- django_cfg/apps/payments/admin_interface/templates/payments/base.html +59 -126
- django_cfg/apps/payments/admin_interface/views/api/payments.py +1 -1
- django_cfg/apps/payments/admin_interface/views/api/stats.py +1 -1
- django_cfg/apps/payments/admin_interface/views/api/users.py +1 -1
- django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +1 -1
- django_cfg/apps/payments/admin_interface/views/api/webhook_public.py +1 -1
- django_cfg/apps/payments/admin_interface/views/base.py +29 -2
- django_cfg/apps/payments/apps.py +1 -1
- django_cfg/apps/payments/config/django_cfg_integration.py +2 -2
- django_cfg/apps/payments/config/helpers.py +3 -2
- django_cfg/apps/payments/management/commands/cleanup_expired_data.py +1 -1
- django_cfg/apps/payments/management/commands/currency_stats.py +1 -1
- django_cfg/apps/payments/management/commands/manage_currencies.py +1 -1
- django_cfg/apps/payments/management/commands/manage_providers.py +1 -1
- django_cfg/apps/payments/management/commands/process_pending_payments.py +1 -1
- django_cfg/apps/payments/management/commands/test_providers.py +1 -1
- django_cfg/apps/payments/middleware/api_access.py +1 -1
- django_cfg/apps/payments/middleware/rate_limiting.py +1 -1
- django_cfg/apps/payments/middleware/usage_tracking.py +1 -1
- django_cfg/apps/payments/models/balance.py +2 -2
- django_cfg/apps/payments/models/managers/api_key_managers.py +1 -1
- django_cfg/apps/payments/models/managers/balance_managers.py +1 -1
- django_cfg/apps/payments/models/managers/currency_managers.py +1 -1
- django_cfg/apps/payments/models/managers/payment_managers.py +1 -1
- django_cfg/apps/payments/models/managers/subscription_managers.py +1 -1
- django_cfg/apps/payments/models/payments.py +2 -2
- django_cfg/apps/payments/services/cache_service/__init__.py +1 -1
- django_cfg/apps/payments/services/cache_service/simple_cache.py +10 -5
- django_cfg/apps/payments/services/core/base.py +1 -1
- django_cfg/apps/payments/services/core/currency/__init__.py +13 -0
- django_cfg/apps/payments/services/core/currency/currency_converter.py +57 -0
- django_cfg/apps/payments/services/core/currency/currency_validator.py +61 -0
- django_cfg/apps/payments/services/core/operations/__init__.py +15 -0
- django_cfg/apps/payments/services/core/operations/payment_canceller.py +100 -0
- django_cfg/apps/payments/services/core/operations/payment_creator.py +196 -0
- django_cfg/apps/payments/services/core/operations/status_checker.py +100 -0
- django_cfg/apps/payments/services/core/payment_service.py +124 -612
- django_cfg/apps/payments/services/core/providers/__init__.py +13 -0
- django_cfg/apps/payments/services/core/providers/provider_client.py +132 -0
- django_cfg/apps/payments/services/core/providers/status_mapper.py +89 -0
- django_cfg/apps/payments/services/core/utils/__init__.py +13 -0
- django_cfg/apps/payments/services/core/utils/data_converter.py +48 -0
- django_cfg/apps/payments/services/core/utils/statistics_calculator.py +69 -0
- django_cfg/apps/payments/services/providers/base.py +1 -1
- django_cfg/apps/payments/services/providers/nowpayments/__init__.py +3 -3
- django_cfg/apps/payments/services/providers/nowpayments/parsers/__init__.py +9 -0
- django_cfg/apps/payments/services/providers/nowpayments/parsers/data/__init__.py +23 -0
- django_cfg/apps/payments/services/providers/nowpayments/parsers/data/constants.py +23 -0
- django_cfg/apps/payments/services/providers/nowpayments/parsers/data/currency_names.py +244 -0
- django_cfg/apps/payments/services/providers/nowpayments/parsers/data/patterns.py +511 -0
- django_cfg/apps/payments/services/providers/nowpayments/parsers/parser.py +168 -0
- django_cfg/apps/payments/services/providers/nowpayments/provider.py +1 -1
- django_cfg/apps/payments/services/providers/nowpayments/sync.py +1 -1
- django_cfg/apps/payments/services/providers/registry.py +1 -1
- django_cfg/apps/payments/services/providers/sync_service.py +1 -1
- django_cfg/apps/payments/signals/__init__.py +1 -1
- django_cfg/apps/payments/signals/api_key_signals.py +1 -1
- django_cfg/apps/payments/signals/balance_signals.py +1 -1
- django_cfg/apps/payments/signals/payment_signals.py +1 -1
- django_cfg/apps/payments/signals/subscription_signals.py +1 -1
- django_cfg/apps/payments/views/api/api_keys.py +1 -1
- django_cfg/apps/payments/views/api/balances.py +1 -1
- django_cfg/apps/payments/views/api/base.py +1 -1
- django_cfg/apps/payments/views/api/currencies.py +1 -1
- django_cfg/apps/payments/views/api/payments.py +1 -1
- django_cfg/apps/payments/views/api/subscriptions.py +1 -1
- django_cfg/apps/payments/views/api/webhooks.py +1 -1
- django_cfg/apps/payments/views/serializers/api_keys.py +1 -1
- django_cfg/apps/payments/views/serializers/balances.py +1 -1
- django_cfg/apps/payments/views/serializers/currencies.py +1 -1
- django_cfg/apps/payments/views/serializers/payments.py +1 -1
- django_cfg/apps/payments/views/serializers/subscriptions.py +1 -1
- django_cfg/apps/payments/views/serializers/webhooks.py +1 -1
- django_cfg/apps/support/admin/support_admin.py +21 -13
- django_cfg/apps/support/templates/support/chat/access_denied.html +21 -27
- django_cfg/apps/support/templates/support/chat/ticket_chat.html +183 -254
- django_cfg/apps/support/utils/support_email_service.py +1 -1
- django_cfg/apps/tasks/templates/tasks/layout/base.html +20 -115
- django_cfg/apps/tasks/utils/simulator.py +1 -1
- django_cfg/apps/tasks/views/dashboard.py +33 -3
- django_cfg/apps/urls.py +5 -1
- django_cfg/cli/README.md +57 -471
- django_cfg/cli/commands/create_project.py +140 -529
- django_cfg/cli/main.py +13 -10
- django_cfg/core/__init__.py +63 -6
- django_cfg/core/base/__init__.py +5 -0
- django_cfg/core/base/config_model.py +652 -0
- django_cfg/core/builders/__init__.py +11 -0
- django_cfg/core/builders/apps_builder.py +258 -0
- django_cfg/core/builders/middleware_builder.py +115 -0
- django_cfg/core/builders/security_builder.py +96 -0
- django_cfg/core/config.py +20 -892
- django_cfg/core/constants.py +69 -0
- django_cfg/core/environment/__init__.py +9 -0
- django_cfg/core/exceptions.py +45 -298
- django_cfg/core/generation/__init__.py +51 -0
- django_cfg/core/generation/core_generators/__init__.py +0 -0
- django_cfg/core/generation/core_generators/settings.py +90 -0
- django_cfg/core/generation/core_generators/static.py +82 -0
- django_cfg/core/generation/core_generators/templates.py +141 -0
- django_cfg/core/generation/data_generators/__init__.py +15 -0
- django_cfg/core/generation/data_generators/cache.py +132 -0
- django_cfg/core/generation/data_generators/database.py +117 -0
- django_cfg/core/generation/generation.py +92 -0
- django_cfg/core/generation/integration_generators/__init__.py +21 -0
- django_cfg/core/generation/integration_generators/api.py +237 -0
- django_cfg/core/generation/integration_generators/sessions.py +65 -0
- django_cfg/core/generation/integration_generators/tailwind.py +54 -0
- django_cfg/core/generation/integration_generators/tasks.py +92 -0
- django_cfg/core/generation/integration_generators/third_party.py +144 -0
- django_cfg/core/generation/orchestrator.py +285 -0
- django_cfg/core/generation/protocols.py +30 -0
- django_cfg/core/generation/security_generators/__init__.py +0 -0
- django_cfg/core/generation/utility_generators/__init__.py +24 -0
- django_cfg/core/generation/utility_generators/email.py +58 -0
- django_cfg/core/generation/utility_generators/i18n.py +66 -0
- django_cfg/core/generation/utility_generators/limits.py +58 -0
- django_cfg/core/generation/utility_generators/logging.py +66 -0
- django_cfg/core/generation/utility_generators/security.py +101 -0
- django_cfg/core/generation/utils/__init__.py +0 -0
- django_cfg/core/generation/utils/helpers.py +32 -0
- django_cfg/core/integration/__init__.py +18 -25
- django_cfg/core/integration/display/startup.py +146 -133
- django_cfg/core/integration/url_integration.py +13 -2
- django_cfg/core/services/__init__.py +5 -0
- django_cfg/core/services/config_service.py +121 -0
- django_cfg/core/state/__init__.py +9 -0
- django_cfg/core/state/registry.py +84 -0
- django_cfg/core/types/__init__.py +15 -0
- django_cfg/core/types/aliases.py +15 -0
- django_cfg/core/types/enums.py +49 -0
- django_cfg/dashboard/DEBUG_README.md +105 -0
- django_cfg/dashboard/REFACTORING_SUMMARY.md +237 -0
- django_cfg/dashboard/__init__.py +24 -0
- django_cfg/dashboard/components.py +308 -0
- django_cfg/dashboard/debug.py +176 -0
- django_cfg/dashboard/management/__init__.py +0 -0
- django_cfg/dashboard/management/commands/__init__.py +0 -0
- django_cfg/dashboard/management/commands/debug_dashboard.py +109 -0
- django_cfg/dashboard/sections/__init__.py +1 -0
- django_cfg/dashboard/sections/base.py +128 -0
- django_cfg/dashboard/sections/commands.py +32 -0
- django_cfg/dashboard/sections/overview.py +394 -0
- django_cfg/dashboard/sections/stats.py +48 -0
- django_cfg/dashboard/sections/system.py +73 -0
- django_cfg/management/commands/check_settings.py +6 -2
- django_cfg/management/commands/clear_constance.py +6 -1
- django_cfg/management/commands/create_token.py +5 -4
- django_cfg/management/commands/generate.py +5 -0
- django_cfg/management/commands/list_urls.py +7 -2
- django_cfg/management/commands/migrate_all.py +6 -2
- django_cfg/management/commands/migrator.py +6 -1
- django_cfg/management/commands/rundramatiq.py +6 -1
- django_cfg/management/commands/rundramatiq_simulator.py +11 -4
- django_cfg/management/commands/runserver_ngrok.py +9 -7
- django_cfg/management/commands/script.py +25 -21
- django_cfg/management/commands/show_config.py +6 -1
- django_cfg/management/commands/show_urls.py +8 -3
- django_cfg/management/commands/superuser.py +5 -4
- django_cfg/management/commands/task_clear.py +8 -3
- django_cfg/management/commands/task_status.py +8 -3
- django_cfg/management/commands/test_email.py +6 -1
- django_cfg/management/commands/test_telegram.py +6 -1
- django_cfg/management/commands/test_twilio.py +6 -1
- django_cfg/management/commands/tree.py +7 -4
- django_cfg/models/__init__.py +88 -3
- django_cfg/models/api/__init__.py +27 -0
- django_cfg/models/{api.py → api/config.py} +1 -1
- django_cfg/models/api/drf/__init__.py +21 -0
- django_cfg/models/api/drf/config.py +101 -0
- django_cfg/models/api/drf/redoc.py +31 -0
- django_cfg/models/api/drf/spectacular.py +129 -0
- django_cfg/models/api/drf/swagger.py +59 -0
- django_cfg/models/{api_keys.py → api/keys.py} +16 -6
- django_cfg/models/{limits.py → api/limits.py} +0 -1
- django_cfg/models/base/__init__.py +14 -0
- django_cfg/models/django/__init__.py +16 -0
- django_cfg/models/{constance.py → django/constance.py} +1 -1
- django_cfg/models/{environment.py → django/environment.py} +1 -1
- django_cfg/models/infrastructure/__init__.py +17 -0
- django_cfg/models/{cache.py → infrastructure/cache.py} +3 -2
- django_cfg/models/infrastructure/database/__init__.py +22 -0
- django_cfg/models/infrastructure/database/config.py +265 -0
- django_cfg/models/infrastructure/database/converters.py +91 -0
- django_cfg/models/infrastructure/database/parsers.py +96 -0
- django_cfg/models/infrastructure/database/routing.py +85 -0
- django_cfg/models/infrastructure/database/validators.py +170 -0
- django_cfg/models/{logging.py → infrastructure/logging.py} +1 -1
- django_cfg/models/{security.py → infrastructure/security.py} +2 -2
- django_cfg/models/ngrok/__init__.py +11 -0
- django_cfg/models/ngrok/auth.py +37 -0
- django_cfg/models/ngrok/config.py +77 -0
- django_cfg/models/ngrok/tunnel.py +35 -0
- django_cfg/models/payments/__init__.py +20 -0
- django_cfg/models/payments/api_keys.py +57 -0
- django_cfg/models/{payments.py → payments/config.py} +56 -154
- django_cfg/models/payments/providers/__init__.py +15 -0
- django_cfg/models/payments/providers/base.py +25 -0
- django_cfg/models/payments/providers/nowpayments.py +48 -0
- django_cfg/models/services/__init__.py +18 -0
- django_cfg/models/services/base.py +65 -0
- django_cfg/models/{email.py → services/email.py} +1 -1
- django_cfg/models/services/telegram.py +172 -0
- django_cfg/models/tasks/__init__.py +51 -0
- django_cfg/models/tasks/backends.py +250 -0
- django_cfg/models/tasks/config.py +314 -0
- django_cfg/models/tasks/utils.py +174 -0
- django_cfg/modules/base.py +18 -3
- django_cfg/modules/django_admin/decorators/actions.py +1 -1
- django_cfg/modules/django_admin/decorators/display.py +1 -1
- django_cfg/modules/django_admin/mixins/standalone_actions_mixin.py +1 -1
- django_cfg/modules/django_cfg_rpc_client/README.md +346 -0
- django_cfg/modules/django_cfg_rpc_client/__init__.py +51 -0
- django_cfg/modules/django_cfg_rpc_client/client.py +540 -0
- django_cfg/modules/django_cfg_rpc_client/config.py +207 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/README.md +517 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/UNFOLD_INTEGRATION.md +439 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/__init__.py +11 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/apps.py +22 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/monitor.py +435 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/static/django_cfg_rpc_dashboard/js/dashboard.js +373 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/templates/django_cfg_rpc_dashboard/base.html +76 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/templates/django_cfg_rpc_dashboard/dashboard.html +200 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/urls.py +22 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/urls_admin.py +9 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/views.py +251 -0
- django_cfg/modules/django_cfg_rpc_client/exceptions.py +201 -0
- django_cfg/modules/django_drf_theme/CHANGELOG.md +210 -0
- django_cfg/modules/django_drf_theme/EXAMPLE.md +465 -0
- django_cfg/modules/django_drf_theme/IMPLEMENTATION.md +232 -0
- django_cfg/modules/django_drf_theme/README.md +207 -0
- django_cfg/modules/django_drf_theme/TAILWIND_CDN_GUIDE.md +274 -0
- django_cfg/modules/django_drf_theme/__init__.py +23 -0
- django_cfg/modules/django_drf_theme/apps.py +15 -0
- django_cfg/modules/django_drf_theme/renderers.py +58 -0
- django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/api.html +375 -0
- django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/base.html +938 -0
- django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/forms/filter_form.html +132 -0
- django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/forms/raw_data_form.html +123 -0
- django_cfg/modules/django_drf_theme/templatetags/__init__.py +1 -0
- django_cfg/modules/django_drf_theme/templatetags/tailwind_tags.py +57 -0
- django_cfg/modules/django_email/__init__.py +14 -0
- django_cfg/modules/{django_email.py → django_email/service.py} +78 -113
- django_cfg/modules/django_email/utils.py +40 -0
- django_cfg/modules/django_health/__init__.py +9 -0
- django_cfg/modules/{django_health.py → django_health/service.py} +23 -21
- django_cfg/modules/django_llm/llm/client.py +155 -550
- django_cfg/modules/django_llm/llm/embeddings/__init__.py +13 -0
- django_cfg/modules/django_llm/llm/embeddings/mock_embedder.py +106 -0
- django_cfg/modules/django_llm/llm/embeddings/openai_embedder.py +79 -0
- django_cfg/modules/django_llm/llm/models_api/__init__.py +9 -0
- django_cfg/modules/django_llm/llm/models_api/models_query.py +163 -0
- django_cfg/modules/django_llm/llm/providers/__init__.py +15 -0
- django_cfg/modules/django_llm/llm/providers/config_builder.py +103 -0
- django_cfg/modules/django_llm/llm/providers/provider_manager.py +148 -0
- django_cfg/modules/django_llm/llm/providers/provider_selector.py +60 -0
- django_cfg/modules/django_llm/llm/requests/__init__.py +15 -0
- django_cfg/modules/django_llm/llm/requests/cache_manager.py +170 -0
- django_cfg/modules/django_llm/llm/requests/chat_handler.py +199 -0
- django_cfg/modules/django_llm/llm/requests/embedding_handler.py +113 -0
- django_cfg/modules/django_llm/llm/responses/__init__.py +9 -0
- django_cfg/modules/django_llm/llm/responses/response_builder.py +131 -0
- django_cfg/modules/django_llm/llm/stats/__init__.py +9 -0
- django_cfg/modules/django_llm/llm/stats/stats_manager.py +107 -0
- django_cfg/modules/django_llm/translator/detectors/__init__.py +13 -0
- django_cfg/modules/django_llm/translator/detectors/language_detector.py +90 -0
- django_cfg/modules/django_llm/translator/detectors/script_detector.py +153 -0
- django_cfg/modules/django_llm/translator/stats/__init__.py +11 -0
- django_cfg/modules/django_llm/translator/stats/stats_tracker.py +85 -0
- django_cfg/modules/django_llm/translator/translator.py +150 -603
- django_cfg/modules/django_llm/translator/translators/__init__.py +15 -0
- django_cfg/modules/django_llm/translator/translators/json_translator.py +316 -0
- django_cfg/modules/django_llm/translator/translators/text_translator.py +139 -0
- django_cfg/modules/django_llm/translator/utils/__init__.py +13 -0
- django_cfg/modules/django_llm/translator/utils/prompt_builder.py +110 -0
- django_cfg/modules/django_llm/translator/utils/text_utils.py +114 -0
- django_cfg/modules/django_logging/FIXES_SUMMARY.md +276 -0
- django_cfg/modules/django_logging/LOGGING_GUIDE.md +504 -0
- django_cfg/modules/django_logging/__init__.py +14 -0
- django_cfg/modules/{django_logger.py → django_logging/django_logger.py} +13 -13
- django_cfg/modules/{logger.py → django_logging/logger.py} +14 -4
- django_cfg/modules/django_ngrok/__init__.py +39 -0
- django_cfg/modules/{django_ngrok.py → django_ngrok/service.py} +14 -42
- django_cfg/modules/django_rpc_old/POETRY.md +344 -0
- django_cfg/modules/django_rpc_old/README.md +397 -0
- django_cfg/modules/django_rpc_old/TESTING.md +358 -0
- django_cfg/modules/django_rpc_old/__init__.py +39 -0
- django_cfg/modules/django_rpc_old/client.py +531 -0
- django_cfg/modules/django_rpc_old/config.py +279 -0
- django_cfg/modules/django_rpc_old/exceptions.py +172 -0
- django_cfg/modules/django_tailwind/README.md +478 -0
- django_cfg/modules/django_tailwind/__init__.py +7 -0
- django_cfg/modules/django_tailwind/apps.py +10 -0
- django_cfg/modules/django_tailwind/templates/django_tailwind/app.html +5 -0
- django_cfg/modules/django_tailwind/templates/django_tailwind/base.html +117 -0
- django_cfg/modules/django_tailwind/templates/django_tailwind/components/navbar.html +124 -0
- django_cfg/modules/django_tailwind/templates/django_tailwind/components/theme_toggle.html +54 -0
- django_cfg/modules/django_tailwind/templates/django_tailwind/components/user_menu.html +116 -0
- django_cfg/modules/django_tailwind/templates/django_tailwind/simple.html +46 -0
- django_cfg/modules/django_tailwind/templatetags/__init__.py +1 -0
- django_cfg/modules/django_tailwind/templatetags/tailwind_info.py +185 -0
- django_cfg/modules/django_tasks/__init__.py +29 -0
- django_cfg/modules/django_tasks/factory.py +127 -0
- django_cfg/modules/{django_tasks.py → django_tasks/service.py} +45 -274
- django_cfg/modules/django_tasks/settings.py +107 -0
- django_cfg/modules/django_telegram/__init__.py +29 -0
- django_cfg/modules/{django_telegram.py → django_telegram/service.py} +45 -113
- django_cfg/modules/django_telegram/utils.py +62 -0
- django_cfg/modules/django_twilio/__init__.py +54 -107
- django_cfg/modules/django_twilio/_imports.py +30 -0
- django_cfg/modules/django_twilio/base.py +192 -0
- django_cfg/modules/django_twilio/email_otp.py +227 -0
- django_cfg/modules/django_twilio/sendgrid_service.py +1 -1
- django_cfg/modules/django_twilio/simple_service.py +1 -2
- django_cfg/modules/django_twilio/sms.py +94 -0
- django_cfg/modules/django_twilio/twilio_service.py +2 -3
- django_cfg/modules/django_twilio/unified.py +310 -0
- django_cfg/modules/django_twilio/utils.py +190 -0
- django_cfg/modules/django_twilio/whatsapp.py +137 -0
- django_cfg/modules/django_unfold/callbacks/base.py +198 -7
- django_cfg/modules/django_unfold/callbacks/main.py +102 -10
- django_cfg/modules/django_unfold/dashboard.py +65 -43
- django_cfg/modules/django_unfold/models/config.py +13 -12
- django_cfg/modules/django_unfold/models/navigation.py +8 -3
- django_cfg/modules/django_unfold/models/tabs.py +2 -2
- django_cfg/modules/django_unfold/templates/unfold/helpers/app_list.html +102 -0
- django_cfg/registry/core.py +24 -26
- django_cfg/registry/modules.py +5 -2
- django_cfg/registry/services.py +20 -3
- django_cfg/registry/third_party.py +8 -8
- django_cfg/static/admin/css/dashboard.css +260 -0
- django_cfg/static/admin/js/commands.js +171 -0
- django_cfg/static/admin/js/dashboard.js +126 -0
- django_cfg/templates/admin/components/management_commands.js +375 -0
- django_cfg/templates/admin/components/progress_bar.html +18 -23
- django_cfg/templates/admin/index.html +48 -20
- django_cfg/templates/admin/index_new.html +106 -0
- django_cfg/templates/admin/layouts/base_dashboard.html +60 -0
- django_cfg/templates/admin/layouts/dashboard_with_tabs.html +1 -20
- django_cfg/templates/admin/sections/commands_section.html +626 -0
- django_cfg/templates/admin/sections/overview_section.html +112 -0
- django_cfg/templates/admin/sections/stats_section.html +35 -0
- django_cfg/templates/admin/sections/system_section.html +99 -0
- django_cfg/templates/admin/snippets/components/CHARTS_GUIDE.md +322 -0
- django_cfg/templates/admin/snippets/components/activity_tracker.html +85 -47
- django_cfg/templates/admin/snippets/components/charts_section.html +154 -64
- django_cfg/templates/admin/snippets/components/django_commands.html +3 -3
- django_cfg/templates/admin/snippets/components/recent_activity_improved.html +25 -0
- django_cfg/templates/admin/snippets/components/recent_users_table.html +1 -1
- django_cfg/templates/admin/snippets/components/system_metrics.html +179 -93
- django_cfg/templates/admin/snippets/zones/zones_table.html +2 -2
- django_cfg/templatetags/django_cfg.py +7 -1
- django_cfg/utils/smart_defaults.py +4 -4
- django_cfg-1.4.0.dist-info/METADATA +920 -0
- {django_cfg-1.3.11.dist-info → django_cfg-1.4.0.dist-info}/RECORD +425 -196
- django_cfg/apps/accounts/utils/auth_email_service.py +0 -84
- django_cfg/apps/payments/services/providers/nowpayments/parsers.py +0 -879
- django_cfg/core/generation.py +0 -621
- django_cfg/management/commands/validate_config.py +0 -189
- django_cfg/models/database.py +0 -480
- django_cfg/models/drf.py +0 -272
- django_cfg/models/ngrok.py +0 -122
- django_cfg/models/services.py +0 -440
- django_cfg/models/tasks.py +0 -550
- django_cfg/modules/django_twilio/service.py +0 -942
- django_cfg/template_archive/django_sample.zip +0 -0
- django_cfg/templates/rest_framework/api.html +0 -12
- django_cfg/utils/toolkit.py +0 -703
- django_cfg-1.3.11.dist-info/METADATA +0 -1029
- /django_cfg/apps/accounts/management/commands/{test_otp.py → otp_test.py} +0 -0
- /django_cfg/core/{environment.py → environment/detector.py} +0 -0
- /django_cfg/models/{cors.py → api/cors.py} +0 -0
- /django_cfg/models/{jwt.py → api/jwt.py} +0 -0
- /django_cfg/models/{base.py → base/config.py} +0 -0
- /django_cfg/models/{cfg.py → base/module.py} +0 -0
- /django_cfg/models/{revolution.py → django/revolution.py} +0 -0
- /django_cfg/modules/{dramatiq_setup.py → django_tasks/dramatiq_setup.py} +0 -0
- {django_cfg-1.3.11.dist-info → django_cfg-1.4.0.dist-info}/WHEEL +0 -0
- {django_cfg-1.3.11.dist-info → django_cfg-1.4.0.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.3.11.dist-info → django_cfg-1.4.0.dist-info}/licenses/LICENSE +0 -0
django_cfg/modules/django_cfg_rpc_client/dashboard/static/django_cfg_rpc_dashboard/js/dashboard.js
ADDED
@@ -0,0 +1,373 @@
|
|
1
|
+
/**
|
2
|
+
* RPC Dashboard JavaScript
|
3
|
+
*
|
4
|
+
* Handles:
|
5
|
+
* - Tab switching
|
6
|
+
* - Auto-refresh
|
7
|
+
* - Live data updates
|
8
|
+
* - API communication
|
9
|
+
*/
|
10
|
+
|
11
|
+
class RPCDashboard {
|
12
|
+
constructor() {
|
13
|
+
this.autoRefresh = true;
|
14
|
+
this.refreshInterval = 5000; // 5 seconds
|
15
|
+
this.intervalId = null;
|
16
|
+
this.currentTab = 'overview';
|
17
|
+
|
18
|
+
// Get API base URL from data attribute (supports custom mounting)
|
19
|
+
this.apiBase = document.body.dataset.apiBase || '/admin/rpc/api';
|
20
|
+
// Clean up trailing slash if present
|
21
|
+
this.apiBase = this.apiBase.replace(/\/$/, '');
|
22
|
+
|
23
|
+
this.init();
|
24
|
+
}
|
25
|
+
|
26
|
+
init() {
|
27
|
+
console.log('🚀 RPC Dashboard initializing...');
|
28
|
+
|
29
|
+
// Setup tab switching
|
30
|
+
this.setupTabs();
|
31
|
+
|
32
|
+
// Setup auto-refresh toggle
|
33
|
+
this.setupAutoRefresh();
|
34
|
+
|
35
|
+
// Initial data load
|
36
|
+
this.loadAllData();
|
37
|
+
|
38
|
+
// Start auto-refresh
|
39
|
+
this.startAutoRefresh();
|
40
|
+
|
41
|
+
console.log('✅ RPC Dashboard initialized');
|
42
|
+
}
|
43
|
+
|
44
|
+
setupTabs() {
|
45
|
+
const tabButtons = document.querySelectorAll('.tab-button');
|
46
|
+
|
47
|
+
tabButtons.forEach(button => {
|
48
|
+
button.addEventListener('click', (e) => {
|
49
|
+
const tabName = e.target.dataset.tab;
|
50
|
+
this.switchTab(tabName);
|
51
|
+
});
|
52
|
+
});
|
53
|
+
}
|
54
|
+
|
55
|
+
switchTab(tabName) {
|
56
|
+
// Update buttons
|
57
|
+
document.querySelectorAll('.tab-button').forEach(btn => {
|
58
|
+
if (btn.dataset.tab === tabName) {
|
59
|
+
btn.classList.add('active', 'text-blue-400', 'border-blue-400');
|
60
|
+
btn.classList.remove('text-gray-400', 'border-transparent');
|
61
|
+
} else {
|
62
|
+
btn.classList.remove('active', 'text-blue-400', 'border-blue-400');
|
63
|
+
btn.classList.add('text-gray-400', 'border-transparent');
|
64
|
+
}
|
65
|
+
});
|
66
|
+
|
67
|
+
// Update panels
|
68
|
+
document.querySelectorAll('.tab-panel').forEach(panel => {
|
69
|
+
panel.classList.add('hidden');
|
70
|
+
});
|
71
|
+
|
72
|
+
const activePanel = document.getElementById(`${tabName}-tab`);
|
73
|
+
if (activePanel) {
|
74
|
+
activePanel.classList.remove('hidden');
|
75
|
+
}
|
76
|
+
|
77
|
+
this.currentTab = tabName;
|
78
|
+
|
79
|
+
// Load tab-specific data
|
80
|
+
this.loadTabData(tabName);
|
81
|
+
}
|
82
|
+
|
83
|
+
setupAutoRefresh() {
|
84
|
+
const toggle = document.getElementById('auto-refresh-toggle');
|
85
|
+
|
86
|
+
if (toggle) {
|
87
|
+
toggle.checked = this.autoRefresh;
|
88
|
+
|
89
|
+
toggle.addEventListener('change', (e) => {
|
90
|
+
this.autoRefresh = e.target.checked;
|
91
|
+
|
92
|
+
if (this.autoRefresh) {
|
93
|
+
this.startAutoRefresh();
|
94
|
+
} else {
|
95
|
+
this.stopAutoRefresh();
|
96
|
+
}
|
97
|
+
});
|
98
|
+
}
|
99
|
+
}
|
100
|
+
|
101
|
+
startAutoRefresh() {
|
102
|
+
if (this.intervalId) {
|
103
|
+
clearInterval(this.intervalId);
|
104
|
+
}
|
105
|
+
|
106
|
+
this.intervalId = setInterval(() => {
|
107
|
+
if (this.autoRefresh) {
|
108
|
+
this.loadAllData();
|
109
|
+
}
|
110
|
+
}, this.refreshInterval);
|
111
|
+
}
|
112
|
+
|
113
|
+
stopAutoRefresh() {
|
114
|
+
if (this.intervalId) {
|
115
|
+
clearInterval(this.intervalId);
|
116
|
+
this.intervalId = null;
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
async loadAllData() {
|
121
|
+
try {
|
122
|
+
await this.loadOverviewStats();
|
123
|
+
await this.loadHealthStatus();
|
124
|
+
await this.loadTabData(this.currentTab);
|
125
|
+
this.updateLastUpdate();
|
126
|
+
} catch (error) {
|
127
|
+
console.error('Error loading data:', error);
|
128
|
+
this.showError('Failed to load data');
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
132
|
+
async loadTabData(tabName) {
|
133
|
+
switch (tabName) {
|
134
|
+
case 'overview':
|
135
|
+
// Already loaded in loadOverviewStats
|
136
|
+
break;
|
137
|
+
case 'requests':
|
138
|
+
await this.loadRecentRequests();
|
139
|
+
break;
|
140
|
+
case 'notifications':
|
141
|
+
await this.loadNotificationStats();
|
142
|
+
break;
|
143
|
+
case 'methods':
|
144
|
+
await this.loadMethodStats();
|
145
|
+
break;
|
146
|
+
}
|
147
|
+
}
|
148
|
+
|
149
|
+
async loadOverviewStats() {
|
150
|
+
try {
|
151
|
+
const response = await fetch(`${this.apiBase}/overview/`);
|
152
|
+
const data = await response.json();
|
153
|
+
|
154
|
+
if (data.success) {
|
155
|
+
const stats = data.data;
|
156
|
+
|
157
|
+
// Update stats cards
|
158
|
+
this.updateElement('total-requests', stats.total_requests_today || 0);
|
159
|
+
this.updateElement('active-methods-count', stats.active_methods?.length || 0);
|
160
|
+
this.updateElement('avg-response-time', (stats.avg_response_time_ms || 0).toFixed(0));
|
161
|
+
this.updateElement('success-rate', (stats.success_rate || 0).toFixed(1));
|
162
|
+
|
163
|
+
// Update top method (XSS-safe)
|
164
|
+
if (stats.top_method) {
|
165
|
+
const topMethodElement = document.getElementById('top-method');
|
166
|
+
if (topMethodElement) {
|
167
|
+
const code = document.createElement('code');
|
168
|
+
code.className = 'bg-gray-700 px-2 py-1 rounded text-blue-300';
|
169
|
+
code.textContent = stats.top_method; // Safe from XSS
|
170
|
+
topMethodElement.innerHTML = '';
|
171
|
+
topMethodElement.appendChild(code);
|
172
|
+
}
|
173
|
+
}
|
174
|
+
}
|
175
|
+
} catch (error) {
|
176
|
+
console.error('Error loading overview stats:', error);
|
177
|
+
}
|
178
|
+
}
|
179
|
+
|
180
|
+
async loadHealthStatus() {
|
181
|
+
try {
|
182
|
+
const response = await fetch(`${this.apiBase}/health/`);
|
183
|
+
const data = await response.json();
|
184
|
+
|
185
|
+
if (data.success) {
|
186
|
+
const health = data.data;
|
187
|
+
|
188
|
+
// Update health indicator
|
189
|
+
const indicator = document.getElementById('health-indicator');
|
190
|
+
if (indicator) {
|
191
|
+
const isHealthy = health.redis_connected && health.stream_exists;
|
192
|
+
indicator.innerHTML = `
|
193
|
+
<span class="pulse-dot w-2 h-2 ${isHealthy ? 'bg-green-500' : 'bg-red-500'} rounded-full"></span>
|
194
|
+
<span class="text-sm text-gray-300">${isHealthy ? 'Connected' : 'Disconnected'}</span>
|
195
|
+
`;
|
196
|
+
}
|
197
|
+
}
|
198
|
+
} catch (error) {
|
199
|
+
console.error('Error loading health status:', error);
|
200
|
+
}
|
201
|
+
}
|
202
|
+
|
203
|
+
async loadRecentRequests() {
|
204
|
+
try {
|
205
|
+
const response = await fetch(`${this.apiBase}/requests/?count=50`);
|
206
|
+
const data = await response.json();
|
207
|
+
|
208
|
+
if (data.success) {
|
209
|
+
const requests = data.data.requests || [];
|
210
|
+
this.renderRequestsTable(requests);
|
211
|
+
}
|
212
|
+
} catch (error) {
|
213
|
+
console.error('Error loading recent requests:', error);
|
214
|
+
}
|
215
|
+
}
|
216
|
+
|
217
|
+
renderRequestsTable(requests) {
|
218
|
+
const tbody = document.getElementById('requests-table-body');
|
219
|
+
if (!tbody) return;
|
220
|
+
|
221
|
+
if (requests.length === 0) {
|
222
|
+
tbody.innerHTML = `
|
223
|
+
<tr>
|
224
|
+
<td colspan="4" class="px-4 py-8 text-center text-gray-400">
|
225
|
+
No recent requests found
|
226
|
+
</td>
|
227
|
+
</tr>
|
228
|
+
`;
|
229
|
+
return;
|
230
|
+
}
|
231
|
+
|
232
|
+
tbody.innerHTML = requests.map(req => `
|
233
|
+
<tr class="hover:bg-gray-700">
|
234
|
+
<td class="px-4 py-3 text-sm text-gray-300">
|
235
|
+
${this.formatTimestamp(req.timestamp)}
|
236
|
+
</td>
|
237
|
+
<td class="px-4 py-3">
|
238
|
+
<code class="text-sm bg-gray-700 px-2 py-1 rounded text-blue-300">${req.method || 'unknown'}</code>
|
239
|
+
</td>
|
240
|
+
<td class="px-4 py-3 text-sm text-gray-400 font-mono">
|
241
|
+
${(req.correlation_id || '').substring(0, 8)}...
|
242
|
+
</td>
|
243
|
+
<td class="px-4 py-3 text-sm text-gray-400">
|
244
|
+
<details class="cursor-pointer">
|
245
|
+
<summary class="text-blue-400 hover:text-blue-300">View</summary>
|
246
|
+
<pre class="mt-2 text-xs bg-gray-900 p-2 rounded overflow-auto max-h-40">${JSON.stringify(req.params || {}, null, 2)}</pre>
|
247
|
+
</details>
|
248
|
+
</td>
|
249
|
+
</tr>
|
250
|
+
`).join('');
|
251
|
+
}
|
252
|
+
|
253
|
+
async loadNotificationStats() {
|
254
|
+
try {
|
255
|
+
const response = await fetch(`${this.apiBase}/notifications/`);
|
256
|
+
const data = await response.json();
|
257
|
+
|
258
|
+
if (data.success) {
|
259
|
+
const stats = data.data;
|
260
|
+
this.renderNotificationStats(stats);
|
261
|
+
}
|
262
|
+
} catch (error) {
|
263
|
+
console.error('Error loading notification stats:', error);
|
264
|
+
}
|
265
|
+
}
|
266
|
+
|
267
|
+
renderNotificationStats(stats) {
|
268
|
+
const container = document.getElementById('notification-stats-content');
|
269
|
+
if (!container) return;
|
270
|
+
|
271
|
+
const byType = stats.by_type || {};
|
272
|
+
const total = stats.total_sent || 0;
|
273
|
+
|
274
|
+
container.innerHTML = `
|
275
|
+
<div class="space-y-4">
|
276
|
+
<div class="flex items-center justify-between p-4 bg-gray-700 rounded">
|
277
|
+
<span class="text-gray-300">Total Sent</span>
|
278
|
+
<span class="text-2xl font-bold text-white">${total}</span>
|
279
|
+
</div>
|
280
|
+
<div class="flex items-center justify-between p-4 bg-gray-700 rounded">
|
281
|
+
<span class="text-gray-300">Delivery Rate</span>
|
282
|
+
<span class="text-2xl font-bold text-green-400">${stats.delivery_rate || 0}%</span>
|
283
|
+
</div>
|
284
|
+
<div>
|
285
|
+
<h4 class="text-md font-semibold text-white mb-3">By Type</h4>
|
286
|
+
<div class="space-y-2">
|
287
|
+
${Object.entries(byType).map(([type, count]) => `
|
288
|
+
<div class="flex items-center justify-between p-3 bg-gray-700 rounded">
|
289
|
+
<span class="text-gray-300">${type}</span>
|
290
|
+
<span class="text-white font-medium">${count}</span>
|
291
|
+
</div>
|
292
|
+
`).join('') || '<p class="text-gray-400">No data available</p>'}
|
293
|
+
</div>
|
294
|
+
</div>
|
295
|
+
</div>
|
296
|
+
`;
|
297
|
+
}
|
298
|
+
|
299
|
+
async loadMethodStats() {
|
300
|
+
try {
|
301
|
+
const response = await fetch(`${this.apiBase}/methods/`);
|
302
|
+
const data = await response.json();
|
303
|
+
|
304
|
+
if (data.success) {
|
305
|
+
const methods = data.data.methods || [];
|
306
|
+
this.renderMethodsTable(methods);
|
307
|
+
}
|
308
|
+
} catch (error) {
|
309
|
+
console.error('Error loading method stats:', error);
|
310
|
+
}
|
311
|
+
}
|
312
|
+
|
313
|
+
renderMethodsTable(methods) {
|
314
|
+
const tbody = document.getElementById('methods-table-body');
|
315
|
+
if (!tbody) return;
|
316
|
+
|
317
|
+
if (methods.length === 0) {
|
318
|
+
tbody.innerHTML = `
|
319
|
+
<tr>
|
320
|
+
<td colspan="4" class="px-4 py-8 text-center text-gray-400">
|
321
|
+
No method data available
|
322
|
+
</td>
|
323
|
+
</tr>
|
324
|
+
`;
|
325
|
+
return;
|
326
|
+
}
|
327
|
+
|
328
|
+
tbody.innerHTML = methods.map(method => `
|
329
|
+
<tr class="hover:bg-gray-700">
|
330
|
+
<td class="px-4 py-3">
|
331
|
+
<code class="text-sm bg-gray-700 px-2 py-1 rounded text-blue-300">${method.method}</code>
|
332
|
+
</td>
|
333
|
+
<td class="px-4 py-3 text-sm text-white font-medium">${method.count}</td>
|
334
|
+
<td class="px-4 py-3 text-sm text-gray-300">${method.percentage}%</td>
|
335
|
+
<td class="px-4 py-3 text-sm text-gray-300">${method.avg_time_ms}ms</td>
|
336
|
+
</tr>
|
337
|
+
`).join('');
|
338
|
+
}
|
339
|
+
|
340
|
+
updateElement(id, value) {
|
341
|
+
const element = document.getElementById(id);
|
342
|
+
if (element) {
|
343
|
+
element.textContent = value;
|
344
|
+
}
|
345
|
+
}
|
346
|
+
|
347
|
+
formatTimestamp(isoString) {
|
348
|
+
try {
|
349
|
+
const date = new Date(isoString);
|
350
|
+
return date.toLocaleTimeString();
|
351
|
+
} catch {
|
352
|
+
return 'N/A';
|
353
|
+
}
|
354
|
+
}
|
355
|
+
|
356
|
+
updateLastUpdate() {
|
357
|
+
const element = document.getElementById('last-update');
|
358
|
+
if (element) {
|
359
|
+
const now = new Date();
|
360
|
+
element.textContent = `Last updated: ${now.toLocaleTimeString()}`;
|
361
|
+
}
|
362
|
+
}
|
363
|
+
|
364
|
+
showError(message) {
|
365
|
+
console.error('Dashboard error:', message);
|
366
|
+
// TODO: Show error notification to user
|
367
|
+
}
|
368
|
+
}
|
369
|
+
|
370
|
+
// Initialize dashboard when DOM is ready
|
371
|
+
document.addEventListener('DOMContentLoaded', () => {
|
372
|
+
window.rpcDashboard = new RPCDashboard();
|
373
|
+
});
|
django_cfg/modules/django_cfg_rpc_client/dashboard/templates/django_cfg_rpc_dashboard/base.html
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
{% extends 'django_tailwind/app.html' %}
|
2
|
+
{% load static %}
|
3
|
+
|
4
|
+
{% block title %}{% block page_title_text %}RPC Monitor{% endblock %} - Django-CFG{% endblock %}
|
5
|
+
|
6
|
+
{# Navbar configuration #}
|
7
|
+
{% block header %}
|
8
|
+
{% with navbar_items=rpc_nav_items %}
|
9
|
+
{% include 'django_tailwind/components/navbar.html' with title="RPC Monitor" icon='<span class="material-icons text-3xl text-blue-400">insights</span>' nav_items=navbar_items full_width=True %}
|
10
|
+
{% endwith %}
|
11
|
+
|
12
|
+
{# RPC-specific header info #}
|
13
|
+
<div class="bg-gray-800 dark:bg-gray-900 border-b border-gray-700 dark:border-gray-800">
|
14
|
+
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-3">
|
15
|
+
<div class="flex items-center justify-between text-sm">
|
16
|
+
<p class="text-gray-400 dark:text-gray-500">Real-time WebSocket & RPC Activity</p>
|
17
|
+
|
18
|
+
<div class="flex items-center space-x-4">
|
19
|
+
<!-- Health indicator -->
|
20
|
+
<div id="health-indicator" class="flex items-center space-x-2">
|
21
|
+
<span class="pulse-dot w-2 h-2 bg-green-500 rounded-full"></span>
|
22
|
+
<span class="text-gray-300 dark:text-gray-400">Connected</span>
|
23
|
+
</div>
|
24
|
+
|
25
|
+
<!-- Auto-refresh toggle -->
|
26
|
+
<label class="flex items-center space-x-2 cursor-pointer">
|
27
|
+
<span class="text-gray-300 dark:text-gray-400">Auto-refresh</span>
|
28
|
+
<input type="checkbox" id="auto-refresh-toggle" checked
|
29
|
+
class="toggle-checkbox rounded border-gray-600 text-blue-600 focus:ring-blue-500">
|
30
|
+
</label>
|
31
|
+
</div>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
</div>
|
35
|
+
{% endblock %}
|
36
|
+
|
37
|
+
{% block extra_head %}
|
38
|
+
{{ block.super }}
|
39
|
+
<!-- Material Icons -->
|
40
|
+
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
41
|
+
|
42
|
+
<style>
|
43
|
+
.stat-card {
|
44
|
+
transition: transform 0.2s, box-shadow 0.2s;
|
45
|
+
}
|
46
|
+
|
47
|
+
.stat-card:hover {
|
48
|
+
transform: translateY(-2px);
|
49
|
+
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
|
50
|
+
}
|
51
|
+
|
52
|
+
.pulse-dot {
|
53
|
+
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
54
|
+
}
|
55
|
+
|
56
|
+
@keyframes pulse {
|
57
|
+
0%, 100% {
|
58
|
+
opacity: 1;
|
59
|
+
}
|
60
|
+
50% {
|
61
|
+
opacity: 0.5;
|
62
|
+
}
|
63
|
+
}
|
64
|
+
</style>
|
65
|
+
|
66
|
+
{% block extra_css %}{% endblock %}
|
67
|
+
{% endblock %}
|
68
|
+
|
69
|
+
{% block body %}
|
70
|
+
{{ block.super }}
|
71
|
+
<script>
|
72
|
+
// Set API base URL for dashboard.js
|
73
|
+
// Must run before dashboard.js initializes
|
74
|
+
document.body.setAttribute('data-api-base', "{% url 'django_cfg_rpc_dashboard:api_overview' %}/..");
|
75
|
+
</script>
|
76
|
+
{% endblock %}
|
django_cfg/modules/django_cfg_rpc_client/dashboard/templates/django_cfg_rpc_dashboard/dashboard.html
ADDED
@@ -0,0 +1,200 @@
|
|
1
|
+
{% extends 'django_cfg_rpc_dashboard/base.html' %}
|
2
|
+
{% load static %}
|
3
|
+
|
4
|
+
{% block title %}Dashboard{% endblock %}
|
5
|
+
|
6
|
+
{% block content %}
|
7
|
+
<!-- Overview Stats Cards -->
|
8
|
+
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
|
9
|
+
<!-- Total Requests -->
|
10
|
+
<div class="stat-card bg-gray-800 rounded-lg p-6 border border-gray-700">
|
11
|
+
<div class="flex items-center justify-between mb-4">
|
12
|
+
<span class="material-icons text-4xl text-blue-400">bar_chart</span>
|
13
|
+
<span class="text-xs text-gray-400">Today</span>
|
14
|
+
</div>
|
15
|
+
<h3 class="text-2xl font-bold text-white mb-1" id="total-requests">
|
16
|
+
{{ overview_stats.total_requests_today|default:"0" }}
|
17
|
+
</h3>
|
18
|
+
<p class="text-sm text-gray-400">Total Requests</p>
|
19
|
+
</div>
|
20
|
+
|
21
|
+
<!-- Active Methods -->
|
22
|
+
<div class="stat-card bg-gray-800 rounded-lg p-6 border border-gray-700">
|
23
|
+
<div class="flex items-center justify-between mb-4">
|
24
|
+
<span class="material-icons text-4xl text-green-400">functions</span>
|
25
|
+
<span class="text-xs text-gray-400">Active</span>
|
26
|
+
</div>
|
27
|
+
<h3 class="text-2xl font-bold text-white mb-1" id="active-methods-count">
|
28
|
+
{{ overview_stats.active_methods|length|default:"0" }}
|
29
|
+
</h3>
|
30
|
+
<p class="text-sm text-gray-400">Active Methods</p>
|
31
|
+
</div>
|
32
|
+
|
33
|
+
<!-- Avg Response Time -->
|
34
|
+
<div class="stat-card bg-gray-800 rounded-lg p-6 border border-gray-700">
|
35
|
+
<div class="flex items-center justify-between mb-4">
|
36
|
+
<span class="material-icons text-4xl text-yellow-400">timer</span>
|
37
|
+
<span class="text-xs text-gray-400">Average</span>
|
38
|
+
</div>
|
39
|
+
<h3 class="text-2xl font-bold text-white mb-1" id="avg-response-time">
|
40
|
+
{{ overview_stats.avg_response_time_ms|default:"0" }}<span class="text-lg text-gray-400">ms</span>
|
41
|
+
</h3>
|
42
|
+
<p class="text-sm text-gray-400">Response Time</p>
|
43
|
+
</div>
|
44
|
+
|
45
|
+
<!-- Success Rate -->
|
46
|
+
<div class="stat-card bg-gray-800 rounded-lg p-6 border border-gray-700">
|
47
|
+
<div class="flex items-center justify-between mb-4">
|
48
|
+
<span class="material-icons text-4xl text-purple-400">check_circle</span>
|
49
|
+
<span class="text-xs text-gray-400">Rate</span>
|
50
|
+
</div>
|
51
|
+
<h3 class="text-2xl font-bold text-white mb-1" id="success-rate">
|
52
|
+
{{ overview_stats.success_rate|default:"0" }}<span class="text-lg text-gray-400">%</span>
|
53
|
+
</h3>
|
54
|
+
<p class="text-sm text-gray-400">Success Rate</p>
|
55
|
+
</div>
|
56
|
+
</div>
|
57
|
+
|
58
|
+
<!-- System Status -->
|
59
|
+
<div class="bg-gray-800 rounded-lg p-6 border border-gray-700 mb-8">
|
60
|
+
<h2 class="text-xl font-bold text-white mb-4 flex items-center">
|
61
|
+
<span class="material-icons mr-2">health_and_safety</span>
|
62
|
+
System Status
|
63
|
+
</h2>
|
64
|
+
<div id="system-status" class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
65
|
+
<!-- Redis Status -->
|
66
|
+
<div class="flex items-center space-x-3">
|
67
|
+
<span class="material-icons {% if health.redis_connected %}text-green-500{% else %}text-red-500{% endif %}">
|
68
|
+
{% if health.redis_connected %}check_circle{% else %}cancel{% endif %}
|
69
|
+
</span>
|
70
|
+
<div>
|
71
|
+
<p class="text-sm font-medium text-white">Redis</p>
|
72
|
+
<p class="text-xs text-gray-400">
|
73
|
+
{% if health.redis_connected %}Connected (DB 2){% else %}Disconnected{% endif %}
|
74
|
+
</p>
|
75
|
+
</div>
|
76
|
+
</div>
|
77
|
+
|
78
|
+
<!-- Stream Status -->
|
79
|
+
<div class="flex items-center space-x-3">
|
80
|
+
<span class="material-icons {% if health.stream_exists %}text-green-500{% else %}text-gray-500{% endif %}">
|
81
|
+
{% if health.stream_exists %}stream{% else %}stream_off{% endif %}
|
82
|
+
</span>
|
83
|
+
<div>
|
84
|
+
<p class="text-sm font-medium text-white">Request Stream</p>
|
85
|
+
<p class="text-xs text-gray-400">
|
86
|
+
{% if health.stream_exists %}{{ health.stream_length }} entries{% else %}Not initialized{% endif %}
|
87
|
+
</p>
|
88
|
+
</div>
|
89
|
+
</div>
|
90
|
+
|
91
|
+
<!-- Activity Status -->
|
92
|
+
<div class="flex items-center space-x-3">
|
93
|
+
<span class="material-icons {% if health.recent_activity %}text-green-500{% else %}text-yellow-500{% endif %}">
|
94
|
+
{% if health.recent_activity %}notifications_active{% else %}notifications_paused{% endif %}
|
95
|
+
</span>
|
96
|
+
<div>
|
97
|
+
<p class="text-sm font-medium text-white">Recent Activity</p>
|
98
|
+
<p class="text-xs text-gray-400">
|
99
|
+
{% if health.recent_activity %}Active (last 5 min){% else %}No recent activity{% endif %}
|
100
|
+
</p>
|
101
|
+
</div>
|
102
|
+
</div>
|
103
|
+
</div>
|
104
|
+
</div>
|
105
|
+
|
106
|
+
<!-- Tabs Navigation -->
|
107
|
+
<div class="border-b border-gray-700 mb-6">
|
108
|
+
<nav class="flex space-x-4">
|
109
|
+
<button class="tab-button active px-4 py-2 text-blue-400 border-b-2 border-blue-400 font-medium" data-tab="overview">
|
110
|
+
Overview
|
111
|
+
</button>
|
112
|
+
<button class="tab-button px-4 py-2 text-gray-400 hover:text-gray-300 border-b-2 border-transparent font-medium" data-tab="requests">
|
113
|
+
Recent Requests
|
114
|
+
</button>
|
115
|
+
<button class="tab-button px-4 py-2 text-gray-400 hover:text-gray-300 border-b-2 border-transparent font-medium" data-tab="notifications">
|
116
|
+
Notifications
|
117
|
+
</button>
|
118
|
+
<button class="tab-button px-4 py-2 text-gray-400 hover:text-gray-300 border-b-2 border-transparent font-medium" data-tab="methods">
|
119
|
+
Methods
|
120
|
+
</button>
|
121
|
+
</nav>
|
122
|
+
</div>
|
123
|
+
|
124
|
+
<!-- Tab Content -->
|
125
|
+
<div class="tab-content">
|
126
|
+
<!-- Overview Tab (Active by default) -->
|
127
|
+
<div id="overview-tab" class="tab-panel">
|
128
|
+
<div class="bg-gray-800 rounded-lg p-6 border border-gray-700">
|
129
|
+
<h3 class="text-lg font-bold text-white mb-4">Top Method</h3>
|
130
|
+
<p class="text-gray-300" id="top-method">
|
131
|
+
{% if overview_stats.top_method %}
|
132
|
+
<code class="bg-gray-700 px-2 py-1 rounded text-blue-300">{{ overview_stats.top_method }}</code>
|
133
|
+
{% else %}
|
134
|
+
No data available
|
135
|
+
{% endif %}
|
136
|
+
</p>
|
137
|
+
</div>
|
138
|
+
</div>
|
139
|
+
|
140
|
+
<!-- Recent Requests Tab -->
|
141
|
+
<div id="requests-tab" class="tab-panel hidden">
|
142
|
+
<div class="bg-gray-800 rounded-lg border border-gray-700 overflow-hidden">
|
143
|
+
<table class="w-full">
|
144
|
+
<thead class="bg-gray-900">
|
145
|
+
<tr>
|
146
|
+
<th class="px-4 py-3 text-left text-xs font-medium text-gray-400 uppercase">Time</th>
|
147
|
+
<th class="px-4 py-3 text-left text-xs font-medium text-gray-400 uppercase">Method</th>
|
148
|
+
<th class="px-4 py-3 text-left text-xs font-medium text-gray-400 uppercase">Correlation ID</th>
|
149
|
+
<th class="px-4 py-3 text-left text-xs font-medium text-gray-400 uppercase">Params</th>
|
150
|
+
</tr>
|
151
|
+
</thead>
|
152
|
+
<tbody id="requests-table-body" class="divide-y divide-gray-700">
|
153
|
+
<tr>
|
154
|
+
<td colspan="4" class="px-4 py-8 text-center text-gray-400">
|
155
|
+
Loading...
|
156
|
+
</td>
|
157
|
+
</tr>
|
158
|
+
</tbody>
|
159
|
+
</table>
|
160
|
+
</div>
|
161
|
+
</div>
|
162
|
+
|
163
|
+
<!-- Notifications Tab -->
|
164
|
+
<div id="notifications-tab" class="tab-panel hidden">
|
165
|
+
<div class="bg-gray-800 rounded-lg p-6 border border-gray-700">
|
166
|
+
<h3 class="text-lg font-bold text-white mb-4">Notification Statistics</h3>
|
167
|
+
<div id="notification-stats-content">
|
168
|
+
<p class="text-gray-400">Loading...</p>
|
169
|
+
</div>
|
170
|
+
</div>
|
171
|
+
</div>
|
172
|
+
|
173
|
+
<!-- Methods Tab -->
|
174
|
+
<div id="methods-tab" class="tab-panel hidden">
|
175
|
+
<div class="bg-gray-800 rounded-lg border border-gray-700 overflow-hidden">
|
176
|
+
<table class="w-full">
|
177
|
+
<thead class="bg-gray-900">
|
178
|
+
<tr>
|
179
|
+
<th class="px-4 py-3 text-left text-xs font-medium text-gray-400 uppercase">Method</th>
|
180
|
+
<th class="px-4 py-3 text-left text-xs font-medium text-gray-400 uppercase">Count</th>
|
181
|
+
<th class="px-4 py-3 text-left text-xs font-medium text-gray-400 uppercase">Percentage</th>
|
182
|
+
<th class="px-4 py-3 text-left text-xs font-medium text-gray-400 uppercase">Avg Time</th>
|
183
|
+
</tr>
|
184
|
+
</thead>
|
185
|
+
<tbody id="methods-table-body" class="divide-y divide-gray-700">
|
186
|
+
<tr>
|
187
|
+
<td colspan="4" class="px-4 py-8 text-center text-gray-400">
|
188
|
+
Loading...
|
189
|
+
</td>
|
190
|
+
</tr>
|
191
|
+
</tbody>
|
192
|
+
</table>
|
193
|
+
</div>
|
194
|
+
</div>
|
195
|
+
</div>
|
196
|
+
{% endblock %}
|
197
|
+
|
198
|
+
{% block extra_js %}
|
199
|
+
<script src="{% static 'django_cfg_rpc_dashboard/js/dashboard.js' %}"></script>
|
200
|
+
{% endblock %}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
"""
|
2
|
+
URL patterns for RPC Dashboard.
|
3
|
+
|
4
|
+
Mount at: /admin/rpc/ or custom path
|
5
|
+
"""
|
6
|
+
|
7
|
+
from django.urls import path
|
8
|
+
from . import views
|
9
|
+
|
10
|
+
app_name = 'django_cfg_rpc_dashboard'
|
11
|
+
|
12
|
+
urlpatterns = [
|
13
|
+
# Main dashboard page
|
14
|
+
path('', views.dashboard_view, name='dashboard'),
|
15
|
+
|
16
|
+
# API endpoints
|
17
|
+
path('api/overview/', views.api_overview_stats, name='api_overview'),
|
18
|
+
path('api/requests/', views.api_recent_requests, name='api_requests'),
|
19
|
+
path('api/notifications/', views.api_notification_stats, name='api_notifications'),
|
20
|
+
path('api/methods/', views.api_method_stats, name='api_methods'),
|
21
|
+
path('api/health/', views.api_health_check, name='api_health'),
|
22
|
+
]
|