codex-django-cli 0.2.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.
Files changed (212) hide show
  1. codex_django_cli/__init__.py +12 -0
  2. codex_django_cli/blueprints/apps/default/__init__.py +0 -0
  3. codex_django_cli/blueprints/apps/default/admin/__init__.py +0 -0
  4. codex_django_cli/blueprints/apps/default/apps.py.j2 +0 -0
  5. codex_django_cli/blueprints/apps/default/forms/__init__.py +0 -0
  6. codex_django_cli/blueprints/apps/default/models/__init__.py +0 -0
  7. codex_django_cli/blueprints/apps/default/modules/__init__.py +0 -0
  8. codex_django_cli/blueprints/apps/default/selector/__init__.py +0 -0
  9. codex_django_cli/blueprints/apps/default/services/__init__.py +0 -0
  10. codex_django_cli/blueprints/apps/default/tests/__init__.py +0 -0
  11. codex_django_cli/blueprints/apps/default/translations.py.j2 +0 -0
  12. codex_django_cli/blueprints/apps/default/urls.py.j2 +0 -0
  13. codex_django_cli/blueprints/apps/default/views/__init__.py +0 -0
  14. codex_django_cli/blueprints/deploy/shared/.dockerignore.j2 +24 -0
  15. codex_django_cli/blueprints/deploy/shared/.env.example.j2 +64 -0
  16. codex_django_cli/blueprints/deploy/shared/backend/Dockerfile.j2 +36 -0
  17. codex_django_cli/blueprints/deploy/shared/backend/entrypoint.sh.j2 +20 -0
  18. codex_django_cli/blueprints/deploy/shared/nginx/Dockerfile.local.j2 +14 -0
  19. codex_django_cli/blueprints/deploy/shared/nginx/nginx-main.conf.j2 +67 -0
  20. codex_django_cli/blueprints/deploy/shared/nginx/site-local.conf.j2 +66 -0
  21. codex_django_cli/blueprints/deploy/shared/worker/Dockerfile.j2 +25 -0
  22. codex_django_cli/blueprints/deploy/stack/docker/base.Dockerfile.j2 +38 -0
  23. codex_django_cli/blueprints/deploy/stack/docker/django.Dockerfile.j2 +27 -0
  24. codex_django_cli/blueprints/deploy/stack/docker/entrypoint.sh.j2 +19 -0
  25. codex_django_cli/blueprints/deploy/stack/docker-compose.apps.yml.j2 +41 -0
  26. codex_django_cli/blueprints/deploy/stack/docker-compose.infra.yml.j2 +80 -0
  27. codex_django_cli/blueprints/deploy/stack/docker-compose.local.apps.yml.j2 +41 -0
  28. codex_django_cli/blueprints/deploy/stack/docker-compose.local.infra.yml.j2 +94 -0
  29. codex_django_cli/blueprints/deploy/stack/docker-compose.test.yml.j2 +63 -0
  30. codex_django_cli/blueprints/deploy/stack/nginx/Dockerfile.j2 +12 -0
  31. codex_django_cli/blueprints/deploy/stack/nginx/conf.d/default.conf.j2 +68 -0
  32. codex_django_cli/blueprints/deploy/stack/nginx/site.conf.template.j2 +81 -0
  33. codex_django_cli/blueprints/deploy/stack_workflows/ci-develop.yml.j2 +42 -0
  34. codex_django_cli/blueprints/deploy/stack_workflows/ci-main.yml.j2 +165 -0
  35. codex_django_cli/blueprints/deploy/stack_workflows/deploy-cluster.yml.j2 +112 -0
  36. codex_django_cli/blueprints/deploy/standalone/docker-compose.prod.yml.j2 +118 -0
  37. codex_django_cli/blueprints/deploy/standalone/docker-compose.test.yml.j2 +86 -0
  38. codex_django_cli/blueprints/deploy/standalone/docker-compose.yml.j2 +151 -0
  39. codex_django_cli/blueprints/deploy/standalone/nginx/Dockerfile.j2 +18 -0
  40. codex_django_cli/blueprints/deploy/standalone/nginx/site.conf.template.j2 +168 -0
  41. codex_django_cli/blueprints/deploy/standalone_workflows/ci-develop.yml.j2 +42 -0
  42. codex_django_cli/blueprints/deploy/standalone_workflows/ci-main.yml.j2 +113 -0
  43. codex_django_cli/blueprints/deploy/standalone_workflows/deploy-production-tag.yml.j2 +211 -0
  44. codex_django_cli/blueprints/features/booking/booking/__init__.py.j2 +0 -0
  45. codex_django_cli/blueprints/features/booking/booking/admin.py.j2 +52 -0
  46. codex_django_cli/blueprints/features/booking/booking/apps.py.j2 +8 -0
  47. codex_django_cli/blueprints/features/booking/booking/models.py.j2 +142 -0
  48. codex_django_cli/blueprints/features/booking/booking/selectors.py.j2 +102 -0
  49. codex_django_cli/blueprints/features/booking/booking/urls.py.j2 +12 -0
  50. codex_django_cli/blueprints/features/booking/booking/views.py.j2 +174 -0
  51. codex_django_cli/blueprints/features/booking/booking/wiki.md.j2 +142 -0
  52. codex_django_cli/blueprints/features/booking/cabinet/templates/cabinet/booking/my_bookings.html +249 -0
  53. codex_django_cli/blueprints/features/booking/cabinet/views/booking.py.j2 +70 -0
  54. codex_django_cli/blueprints/features/booking/system/admin/booking_settings.py.j2 +31 -0
  55. codex_django_cli/blueprints/features/booking/system/models/booking_settings.py.j2 +7 -0
  56. codex_django_cli/blueprints/features/booking/templates/booking/booking_page.html +137 -0
  57. codex_django_cli/blueprints/features/booking/templates/booking/partials/step_confirm.html +143 -0
  58. codex_django_cli/blueprints/features/booking/templates/booking/partials/step_date.html +184 -0
  59. codex_django_cli/blueprints/features/booking/templates/booking/partials/step_service.html +78 -0
  60. codex_django_cli/blueprints/features/booking/templates/booking/partials/step_time.html +89 -0
  61. codex_django_cli/blueprints/features/client_cabinet/cabinet/adapters.py.j2 +21 -0
  62. codex_django_cli/blueprints/features/client_cabinet/cabinet/templates/cabinet/client/my_appointments.html +58 -0
  63. codex_django_cli/blueprints/features/client_cabinet/cabinet/templates/cabinet/client/profile.html +107 -0
  64. codex_django_cli/blueprints/features/client_cabinet/cabinet/templates/cabinet/client/settings.html +106 -0
  65. codex_django_cli/blueprints/features/client_cabinet/cabinet/templates/cabinet/client/settings_notifications.html +106 -0
  66. codex_django_cli/blueprints/features/client_cabinet/cabinet/templates/cabinet/client/settings_privacy.html +135 -0
  67. codex_django_cli/blueprints/features/client_cabinet/cabinet/views/client.py.j2 +49 -0
  68. codex_django_cli/blueprints/features/client_cabinet/system/models/user_profile.py.j2 +22 -0
  69. codex_django_cli/blueprints/features/notifications/arq/client.j2 +22 -0
  70. codex_django_cli/blueprints/features/notifications/feature/models/email_content.j2 +15 -0
  71. codex_django_cli/blueprints/features/notifications/feature/selectors/email_content.j2 +23 -0
  72. codex_django_cli/blueprints/features/notifications/feature/services/notification.j2 +66 -0
  73. codex_django_cli/blueprints/project/cabinet/__init__.py +0 -0
  74. codex_django_cli/blueprints/project/cabinet/admin/__init__.py +0 -0
  75. codex_django_cli/blueprints/project/cabinet/apps.py.j2 +11 -0
  76. codex_django_cli/blueprints/project/cabinet/cabinet.py.j2 +33 -0
  77. codex_django_cli/blueprints/project/cabinet/forms/__init__.py +0 -0
  78. codex_django_cli/blueprints/project/cabinet/mock.py.j2 +110 -0
  79. codex_django_cli/blueprints/project/cabinet/models/__init__.py +0 -0
  80. codex_django_cli/blueprints/project/cabinet/modules/__init__.py +0 -0
  81. codex_django_cli/blueprints/project/cabinet/selector/__init__.py +3 -0
  82. codex_django_cli/blueprints/project/cabinet/selector/users.py.j2 +25 -0
  83. codex_django_cli/blueprints/project/cabinet/services/__init__.py +0 -0
  84. codex_django_cli/blueprints/project/cabinet/static/cabinet/css/base.css +11 -0
  85. codex_django_cli/blueprints/project/cabinet/static/cabinet/css/compiler_config.json +5 -0
  86. codex_django_cli/blueprints/project/cabinet/static/cabinet/css/theme/tokens.css +30 -0
  87. codex_django_cli/blueprints/project/cabinet/static/cabinet/js/app/cabinet.js +37 -0
  88. codex_django_cli/blueprints/project/cabinet/static/cabinet/js/compiler_config.json +7 -0
  89. codex_django_cli/blueprints/project/cabinet/templates/cabinet/users/detail.html +91 -0
  90. codex_django_cli/blueprints/project/cabinet/templates/cabinet/users/index.html +97 -0
  91. codex_django_cli/blueprints/project/cabinet/tests/__init__.py +0 -0
  92. codex_django_cli/blueprints/project/cabinet/translations.py.j2 +2 -0
  93. codex_django_cli/blueprints/project/cabinet/urls.py.j2 +22 -0
  94. codex_django_cli/blueprints/project/cabinet/views/__init__.py +3 -0
  95. codex_django_cli/blueprints/project/cabinet/views/users.py.j2 +17 -0
  96. codex_django_cli/blueprints/project/core/__init__.py.j2 +1 -0
  97. codex_django_cli/blueprints/project/core/apps.py.j2 +15 -0
  98. codex_django_cli/blueprints/project/core/asgi.py.j2 +7 -0
  99. codex_django_cli/blueprints/project/core/logger.py.j2 +57 -0
  100. codex_django_cli/blueprints/project/core/redis.py.j2 +4 -0
  101. codex_django_cli/blueprints/project/core/settings/__init__.py.j2 +4 -0
  102. codex_django_cli/blueprints/project/core/settings/base.py.j2 +67 -0
  103. codex_django_cli/blueprints/project/core/settings/dev.py.j2 +56 -0
  104. codex_django_cli/blueprints/project/core/settings/modules/__init__.py.j2 +1 -0
  105. codex_django_cli/blueprints/project/core/settings/modules/admin.py.j2 +72 -0
  106. codex_django_cli/blueprints/project/core/settings/modules/apps.py.j2 +64 -0
  107. codex_django_cli/blueprints/project/core/settings/modules/cache.py.j2 +49 -0
  108. codex_django_cli/blueprints/project/core/settings/modules/codex.py.j2 +39 -0
  109. codex_django_cli/blueprints/project/core/settings/modules/database.py.j2 +49 -0
  110. codex_django_cli/blueprints/project/core/settings/modules/internationalization.py.j2 +43 -0
  111. codex_django_cli/blueprints/project/core/settings/modules/logging.py.j2 +45 -0
  112. codex_django_cli/blueprints/project/core/settings/modules/middleware.py.j2 +17 -0
  113. codex_django_cli/blueprints/project/core/settings/modules/security.py.j2 +53 -0
  114. codex_django_cli/blueprints/project/core/settings/modules/sitemap.py.j2 +14 -0
  115. codex_django_cli/blueprints/project/core/settings/modules/static.py.j2 +36 -0
  116. codex_django_cli/blueprints/project/core/settings/modules/templates.py.j2 +29 -0
  117. codex_django_cli/blueprints/project/core/settings/prod.py.j2 +77 -0
  118. codex_django_cli/blueprints/project/core/settings/test.py.j2 +40 -0
  119. codex_django_cli/blueprints/project/core/sitemaps.py.j2 +26 -0
  120. codex_django_cli/blueprints/project/core/urls.py.j2 +71 -0
  121. codex_django_cli/blueprints/project/core/wsgi.py.j2 +7 -0
  122. codex_django_cli/blueprints/project/features/__init__.py.j2 +0 -0
  123. codex_django_cli/blueprints/project/features/main/admin/__init__.py +0 -0
  124. codex_django_cli/blueprints/project/features/main/apps.py.j2 +8 -0
  125. codex_django_cli/blueprints/project/features/main/forms/__init__.py +0 -0
  126. codex_django_cli/blueprints/project/features/main/models/__init__.py +0 -0
  127. codex_django_cli/blueprints/project/features/main/sitemaps.py.j2 +23 -0
  128. codex_django_cli/blueprints/project/features/main/tests/__init__.py +0 -0
  129. codex_django_cli/blueprints/project/features/main/translations.py.j2 +2 -0
  130. codex_django_cli/blueprints/project/features/main/urls.py.j2 +8 -0
  131. codex_django_cli/blueprints/project/features/main/views/__init__.py.j2 +9 -0
  132. codex_django_cli/blueprints/project/manage.py.j2 +39 -0
  133. codex_django_cli/blueprints/project/static/css/base/components.css +88 -0
  134. codex_django_cli/blueprints/project/static/css/base/footer.css +43 -0
  135. codex_django_cli/blueprints/project/static/css/base/header.css +76 -0
  136. codex_django_cli/blueprints/project/static/css/base/layout.css +58 -0
  137. codex_django_cli/blueprints/project/static/css/base/reset.css +65 -0
  138. codex_django_cli/blueprints/project/static/css/base/tokens.css +45 -0
  139. codex_django_cli/blueprints/project/static/css/base.css +31 -0
  140. codex_django_cli/blueprints/project/static/css/compiler_config.json +10 -0
  141. codex_django_cli/blueprints/project/static/css/pages/contacts.css +42 -0
  142. codex_django_cli/blueprints/project/static/css/pages/errors.css +11 -0
  143. codex_django_cli/blueprints/project/static/css/pages/home.css +120 -0
  144. codex_django_cli/blueprints/project/static/js/app/main.js +8 -0
  145. codex_django_cli/blueprints/project/static/js/vendor/alpine.min.js +9 -0
  146. codex_django_cli/blueprints/project/static/js/vendor/htmx.min.js +9 -0
  147. codex_django_cli/blueprints/project/static/manifest.json +15 -0
  148. codex_django_cli/blueprints/project/static/robots.txt +4 -0
  149. codex_django_cli/blueprints/project/system/__init__.py.j2 +1 -0
  150. codex_django_cli/blueprints/project/system/admin/__init__.py.j2 +15 -0
  151. codex_django_cli/blueprints/project/system/admin/seo.py.j2 +28 -0
  152. codex_django_cli/blueprints/project/system/admin/settings.py.j2 +65 -0
  153. codex_django_cli/blueprints/project/system/admin/static.py.j2 +18 -0
  154. codex_django_cli/blueprints/project/system/apps.py.j2 +9 -0
  155. codex_django_cli/blueprints/project/system/forms/__init__.py.j2 +1 -0
  156. codex_django_cli/blueprints/project/system/management/__init__.py +0 -0
  157. codex_django_cli/blueprints/project/system/management/commands/__init__.py +0 -0
  158. codex_django_cli/blueprints/project/system/management/commands/dev.py.j2 +5 -0
  159. codex_django_cli/blueprints/project/system/management/commands/menu.py.j2 +81 -0
  160. codex_django_cli/blueprints/project/system/management/commands/runserver_plus.py.j2 +46 -0
  161. codex_django_cli/blueprints/project/system/management/commands/update_all_content.py.j2 +17 -0
  162. codex_django_cli/blueprints/project/system/management/commands/update_site_settings.py.j2 +80 -0
  163. codex_django_cli/blueprints/project/system/models/__init__.py.j2 +15 -0
  164. codex_django_cli/blueprints/project/system/models/seo.py.j2 +37 -0
  165. codex_django_cli/blueprints/project/system/models/settings.py.j2 +31 -0
  166. codex_django_cli/blueprints/project/system/models/static.py.j2 +13 -0
  167. codex_django_cli/blueprints/project/system/services/__init__.py.j2 +1 -0
  168. codex_django_cli/blueprints/project/system/urls.py.j2 +7 -0
  169. codex_django_cli/blueprints/project/system/views/__init__.py.j2 +1 -0
  170. codex_django_cli/blueprints/project/system/views/errors.py.j2 +13 -0
  171. codex_django_cli/blueprints/project/templates/base.html.j2 +53 -0
  172. codex_django_cli/blueprints/project/templates/errors/400.html +9 -0
  173. codex_django_cli/blueprints/project/templates/errors/403.html +9 -0
  174. codex_django_cli/blueprints/project/templates/errors/404.html +16 -0
  175. codex_django_cli/blueprints/project/templates/errors/500.html +16 -0
  176. codex_django_cli/blueprints/project/templates/includes/_analytics_body.html +2 -0
  177. codex_django_cli/blueprints/project/templates/includes/_analytics_head.html +2 -0
  178. codex_django_cli/blueprints/project/templates/includes/_cookie_consent.html +2 -0
  179. codex_django_cli/blueprints/project/templates/includes/_critical_css.html +38 -0
  180. codex_django_cli/blueprints/project/templates/includes/_footer.html +57 -0
  181. codex_django_cli/blueprints/project/templates/includes/_header.html.j2 +75 -0
  182. codex_django_cli/blueprints/project/templates/includes/_hreflang_tags.html.j2 +11 -0
  183. codex_django_cli/blueprints/project/templates/includes/_meta.html +44 -0
  184. codex_django_cli/blueprints/project/templates/main/contacts.html +38 -0
  185. codex_django_cli/blueprints/project/templates/main/home.html +128 -0
  186. codex_django_cli/blueprints/project/templates/main/home.html.j2 +129 -0
  187. codex_django_cli/blueprints/project/templates/sitemap.xml +16 -0
  188. codex_django_cli/blueprints/repo/.env.example.j2 +15 -0
  189. codex_django_cli/blueprints/repo/.github/workflows/.gitkeep +1 -0
  190. codex_django_cli/blueprints/repo/.gitignore +38 -0
  191. codex_django_cli/blueprints/repo/README.md.j2 +32 -0
  192. codex_django_cli/blueprints/repo/docs/README.md +5 -0
  193. codex_django_cli/blueprints/repo/pyproject.toml.j2 +46 -0
  194. codex_django_cli/blueprints/repo/tools/dev/check.py.j2 +23 -0
  195. codex_django_cli/blueprints/repo/tools/dev/generate_project_tree.py +15 -0
  196. codex_django_cli/commands/__init__.py +1 -0
  197. codex_django_cli/commands/add_app.py +56 -0
  198. codex_django_cli/commands/booking.py +92 -0
  199. codex_django_cli/commands/client_cabinet.py +66 -0
  200. codex_django_cli/commands/deploy.py +96 -0
  201. codex_django_cli/commands/init.py +216 -0
  202. codex_django_cli/commands/notifications.py +59 -0
  203. codex_django_cli/commands/quality.py +116 -0
  204. codex_django_cli/engine.py +113 -0
  205. codex_django_cli/main.py +470 -0
  206. codex_django_cli/prompts.py +258 -0
  207. codex_django_cli/py.typed +0 -0
  208. codex_django_cli/utils.py +25 -0
  209. codex_django_cli-0.2.0.dist-info/METADATA +66 -0
  210. codex_django_cli-0.2.0.dist-info/RECORD +212 -0
  211. codex_django_cli-0.2.0.dist-info/WHEEL +4 -0
  212. codex_django_cli-0.2.0.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,57 @@
1
+ import logging
2
+ from typing import TYPE_CHECKING, Union
3
+
4
+ from django.conf import settings
5
+
6
+ if TYPE_CHECKING:
7
+ from loguru import Logger
8
+
9
+ # Declare logger with a Union type to satisfy mypy
10
+ logger: Union[logging.Logger, "Logger"]
11
+
12
+ try:
13
+ from codex_core.common.loguru_setup import setup_logging
14
+ from loguru import logger as loguru_logger
15
+
16
+ logger = loguru_logger
17
+ LOGURU_AVAILABLE = True
18
+ except ImportError:
19
+ logger = logging.getLogger(__name__)
20
+ LOGURU_AVAILABLE = False
21
+
22
+
23
+ class DjangoLoggingSettingsAdapter:
24
+ """Adapts Django settings to codex-core LoggingSettingsProtocol."""
25
+
26
+ def __init__(self) -> None:
27
+ self.log_level_console = getattr(settings, "LOG_LEVEL_CONSOLE", "INFO")
28
+ self.log_level_file = getattr(settings, "LOG_LEVEL_FILE", "DEBUG")
29
+ self.log_rotation = getattr(settings, "LOG_ROTATION", "10 MB")
30
+ self.log_dir = getattr(settings, "LOG_DIR", "logs")
31
+ self.debug = getattr(settings, "DEBUG", False)
32
+
33
+
34
+ def init_logging() -> None:
35
+ """Initialize logging based on project settings and available libraries."""
36
+ if not LOGURU_AVAILABLE:
37
+ # Fallback to standard Django LOGGING already configured in settings
38
+ if isinstance(logger, logging.Logger):
39
+ logger.info("Loguru or codex-core not found. Using standard Django logging.")
40
+ return
41
+
42
+ # Use codex-core setup
43
+ service_name = getattr(settings, "PROJECT_NAME", "django-backend")
44
+ adapter = DjangoLoggingSettingsAdapter()
45
+
46
+ setup_logging(
47
+ settings=adapter,
48
+ service_name=service_name,
49
+ intercept_loggers=["django", "django.server", "django.db.backends"],
50
+ log_levels={
51
+ "django.db.backends": logging.WARNING,
52
+ "django.utils.autoreload": logging.WARNING,
53
+ },
54
+ )
55
+
56
+ if not isinstance(logger, logging.Logger):
57
+ logger.info(f"Loguru initialized via codex-core for {service_name}")
@@ -0,0 +1,4 @@
1
+ from codex_django.core.redis.managers.base import BaseDjangoRedisManager
2
+
3
+ # Initialize the base manager which wraps the platform's RedisService
4
+ redis_manager = BaseDjangoRedisManager()
@@ -0,0 +1,4 @@
1
+ """
2
+ Core project settings module.
3
+ """
4
+ from .base import * # noqa
@@ -0,0 +1,67 @@
1
+ """
2
+ Cloud-Native Django Settings.
3
+ Supports layered configuration: Environment Variables > Project .env > Common .env.
4
+ Ready for Docker Compose, Swarm, and Kubernetes.
5
+ """
6
+
7
+ import os
8
+ from pathlib import Path
9
+
10
+ from dotenv import load_dotenv
11
+
12
+ # ═══════════════════════════════════════════
13
+ # Paths & Project Identity
14
+ # ═══════════════════════════════════════════
15
+
16
+ # Root of Django project (where manage.py is)
17
+ BASE_DIR = Path(__file__).resolve().parent.parent.parent
18
+
19
+ # 1. Try to load Common .env (Infrastructure level)
20
+ # Path can be overridden via ENV_COMMON_PATH for Swarm/K8s
21
+ common_env = os.environ.get("ENV_COMMON_PATH")
22
+ if common_env and os.path.exists(common_env):
23
+ load_dotenv(common_env)
24
+ else:
25
+ # Fallback for local dev: look 2 levels up
26
+ load_dotenv(BASE_DIR.parent.parent / ".env")
27
+
28
+ # 2. Try to load Project-specific .env
29
+ # override=True ensures project settings take precedence
30
+ project_env = os.environ.get("ENV_PROJECT_PATH")
31
+ if project_env and os.path.exists(project_env):
32
+ load_dotenv(project_env, override=True)
33
+ else:
34
+ # Fallback for local dev: look in current folder
35
+ load_dotenv(BASE_DIR / ".env", override=True)
36
+
37
+ # 3. Project Identity
38
+ # Must be set in .env or by Orchestrator. Fallback to folder name.
39
+ PROJECT_NAME = os.environ.get("PROJECT_NAME", BASE_DIR.name)
40
+
41
+ # ═══════════════════════════════════════════
42
+ # Core Django Settings (MUST be defined early)
43
+ # ═══════════════════════════════════════════
44
+ ROOT_URLCONF = "{{ project_name }}.core.urls"
45
+ WSGI_APPLICATION = "{{ project_name }}.core.wsgi.application"
46
+ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
47
+
48
+ # ═══════════════════════════════════════════
49
+ # Import Modules
50
+ # ═══════════════════════════════════════════
51
+
52
+ from .modules.security import * # noqa
53
+ from .modules.apps import * # noqa
54
+ from .modules.middleware import * # noqa
55
+ from .modules.database import * # noqa
56
+ from .modules.cache import * # noqa
57
+ from .modules.internationalization import * # noqa
58
+ from .modules.static import * # noqa
59
+ from .modules.templates import * # noqa
60
+ from .modules.logging import * # noqa
61
+ from .modules.admin import * # noqa
62
+ from .modules.sitemap import * # noqa
63
+ from .modules.codex import * # noqa
64
+
65
+ # ═══════════════════════════════════════════
66
+ # General Settings
67
+ # ═══════════════════════════════════════════
@@ -0,0 +1,56 @@
1
+ """
2
+ {{ project_name }} — Development Settings.
3
+
4
+ Inherits from base.py. SQLite, DEBUG=True, verbose logging.
5
+ """
6
+
7
+ from .base import * # noqa: F403
8
+
9
+ # ═══════════════════════════════════════════
10
+ # Debug
11
+ # ═══════════════════════════════════════════
12
+
13
+ DEBUG = True
14
+
15
+ # ═══════════════════════════════════════════
16
+ # Cache — LocMemCache (no Redis needed in dev)
17
+ # ═══════════════════════════════════════════
18
+
19
+ CACHES = {
20
+ "default": {
21
+ "BACKEND": "django.core.cache.backends.locmem.LocMemCache",
22
+ }
23
+ }
24
+ SESSION_ENGINE = "django.contrib.sessions.backends.db"
25
+
26
+ # ═══════════════════════════════════════════
27
+ # CSRF Trusted Origins
28
+ # ═══════════════════════════════════════════
29
+
30
+ CSRF_TRUSTED_ORIGINS = ["http://localhost:8080"]
31
+
32
+ # ═══════════════════════════════════════════
33
+ # Database — SQLite
34
+ # ═══════════════════════════════════════════
35
+
36
+ # SQLite is already configured in base.py as default.
37
+ # No changes needed here unless you want to override.
38
+
39
+ # ═══════════════════════════════════════════
40
+ # Logging
41
+ # ═══════════════════════════════════════════
42
+
43
+ # In dev, we might want more verbose logging to console
44
+ LOGGING = {
45
+ "version": 1,
46
+ "disable_existing_loggers": False,
47
+ "handlers": {
48
+ "console": {
49
+ "class": "logging.StreamHandler",
50
+ },
51
+ },
52
+ "root": {
53
+ "handlers": ["console"],
54
+ "level": "DEBUG",
55
+ },
56
+ }
@@ -0,0 +1 @@
1
+ # Settings modules package
@@ -0,0 +1,72 @@
1
+ import os
2
+ from pathlib import Path
3
+
4
+ # Root of Django project: src/backend_django
5
+ BASE_DIR = Path(__file__).resolve().parent.parent.parent.parent
6
+ PROJECT_NAME = os.environ.get("PROJECT_NAME", BASE_DIR.name)
7
+
8
+ UNFOLD = {
9
+ "SITE_TITLE": os.environ.get("ADMIN_SITE_TITLE", f"{PROJECT_NAME.replace('_', ' ').title()} Admin"),
10
+ "SITE_HEADER": os.environ.get("ADMIN_SITE_HEADER", PROJECT_NAME.replace("_", " ").title()),
11
+ "SITE_SYMBOL": "dashboard",
12
+ "COLORS": {
13
+ "primary": {
14
+ "50": "239, 246, 255",
15
+ "100": "219, 234, 254",
16
+ "200": "191, 219, 254",
17
+ "300": "147, 197, 253",
18
+ "400": "96, 165, 250",
19
+ "500": "59, 130, 246",
20
+ "600": "37, 99, 235",
21
+ "700": "29, 78, 216",
22
+ "800": "30, 64, 175",
23
+ "900": "30, 58, 138",
24
+ "950": "23, 37, 84",
25
+ },
26
+ },
27
+ "SIDEBAR": {
28
+ "show_search": True,
29
+ "show_all_applications": False,
30
+ "navigation": [
31
+ {
32
+ "title": "Leads & Contacts",
33
+ "items": [
34
+ {
35
+ "title": "Contact Requests",
36
+ "icon": "mail",
37
+ "link": "/admin/main/contactrequest/",
38
+ },
39
+ ],
40
+ },
41
+ {
42
+ "title": "System & Settings",
43
+ "items": [
44
+ {
45
+ "title": "Site Settings",
46
+ "icon": "settings",
47
+ "link": "/admin/system/sitesettings/",
48
+ "permission": lambda request: request.user.is_superuser,
49
+ },
50
+ {
51
+ "title": "Static Translations",
52
+ "icon": "translate",
53
+ "link": "/admin/system/statictranslation/",
54
+ "permission": lambda request: request.user.is_superuser,
55
+ },
56
+ {
57
+ "title": "SEO Pages",
58
+ "icon": "search",
59
+ "link": "/admin/system/staticpageseo/",
60
+ "permission": lambda request: request.user.is_superuser,
61
+ },
62
+ {
63
+ "title": "Users",
64
+ "icon": "person",
65
+ "link": "/admin/auth/user/",
66
+ "permission": lambda request: request.user.is_superuser,
67
+ },
68
+ ],
69
+ },
70
+ ],
71
+ },
72
+ }
@@ -0,0 +1,64 @@
1
+ # ═══════════════════════════════════════════
2
+ # Application definition
3
+ # ═══════════════════════════════════════════
4
+
5
+ DJANGO_APPS = [
6
+ "django.contrib.admin",
7
+ "django.contrib.auth",
8
+ "django.contrib.contenttypes",
9
+ "django.contrib.sessions",
10
+ "django.contrib.messages",
11
+ "django.contrib.staticfiles",
12
+ "django.contrib.sitemaps",
13
+ ]
14
+
15
+ THIRD_PARTY_APPS = [
16
+ # Auth
17
+ "allauth",
18
+ "allauth.account",
19
+ "allauth.socialaccount",
20
+ "allauth.socialaccount.providers.google",
21
+ # Admin
22
+ "unfold",
23
+ "unfold.contrib.filters",
24
+ "unfold.contrib.forms",
25
+ "unfold.contrib.inlines",
26
+ "unfold.contrib.import_export",
27
+ "unfold.contrib.guardian",
28
+ "unfold.contrib.simple_history",
29
+ "django_prometheus",
30
+ "ninja",
31
+ ]
32
+
33
+ {%- if enable_i18n %}
34
+ THIRD_PARTY_APPS.insert(0, "modeltranslation")
35
+ {%- endif %}
36
+
37
+ # ═══════════════════════════════════════════
38
+ # Codex Library Apps
39
+ # ═══════════════════════════════════════════
40
+ CODEX_APPS = [
41
+ "codex_django.cabinet",
42
+ "codex_django.showcase",
43
+ ]
44
+
45
+ # ═══════════════════════════════════════════
46
+ # Codex Library Settings
47
+ # ═══════════════════════════════════════════
48
+ CODEX_SITE_SETTINGS_MODEL = "system.SiteSettings"
49
+ {%- if enable_i18n %}
50
+ CODEX_STATIC_TRANSLATION_MODEL = "system.StaticTranslation"
51
+ {%- endif %}
52
+ CODEX_STATIC_PAGE_SEO_MODEL = "system.StaticPageSeo"
53
+
54
+ LOCAL_APPS = [
55
+ "core",
56
+ "system",
57
+ "cabinet",
58
+ "features.main",
59
+ {%- if with_booking %}
60
+ "booking",
61
+ {%- endif %}
62
+ ]
63
+
64
+ INSTALLED_APPS = CODEX_APPS + THIRD_PARTY_APPS + DJANGO_APPS + LOCAL_APPS
@@ -0,0 +1,49 @@
1
+ import os
2
+ from pathlib import Path
3
+ from urllib.parse import quote_plus
4
+
5
+ # In container: /app. Locally: src/backend_django
6
+ BASE_DIR = Path(__file__).resolve().parent.parent.parent.parent
7
+ PROJECT_NAME = BASE_DIR.name
8
+
9
+ # ═══════════════════════════════════════════
10
+ # Redis & ARQ
11
+ # ═══════════════════════════════════════════
12
+
13
+ REDIS_HOST = os.environ.get("REDIS_HOST", "localhost")
14
+ REDIS_PORT = int(os.environ.get("REDIS_PORT", 6379))
15
+ REDIS_PASSWORD = os.environ.get("REDIS_PASSWORD", None)
16
+
17
+ IS_INSIDE_DOCKER = os.path.exists("/.dockerenv")
18
+ if REDIS_HOST == "localhost" and IS_INSIDE_DOCKER:
19
+ REDIS_HOST = "redis"
20
+
21
+ if REDIS_PASSWORD:
22
+ clean_password = REDIS_PASSWORD.strip("'\"").strip()
23
+ encoded_password = quote_plus(clean_password)
24
+ REDIS_URL = f"redis://:{encoded_password}@{REDIS_HOST}:{REDIS_PORT}/0"
25
+ else:
26
+ REDIS_URL = f"redis://{REDIS_HOST}:{REDIS_PORT}/0"
27
+
28
+ # ═══════════════════════════════════════════
29
+ # Cache & Sessions (Isolated by PROJECT_NAME)
30
+ # ═══════════════════════════════════════════
31
+
32
+ CACHES = {
33
+ "default": {
34
+ "BACKEND": "django_redis.cache.RedisCache",
35
+ "LOCATION": REDIS_URL,
36
+ "KEY_PREFIX": PROJECT_NAME,
37
+ "OPTIONS": {
38
+ "CLIENT_CLASS": "django_redis.client.DefaultClient",
39
+ },
40
+ }
41
+ }
42
+
43
+ SESSION_ENGINE = "django.contrib.sessions.backends.cache"
44
+ SESSION_CACHE_ALIAS = "default"
45
+ SESSION_COOKIE_NAME = f"sessionid_{PROJECT_NAME}"
46
+
47
+ # --- Ratelimit ---
48
+ RATELIMIT_USE_CACHE = "default"
49
+ RATELIMIT_VIEW = "features.main.views.legal.ratelimit_view"
@@ -0,0 +1,39 @@
1
+ import os
2
+
3
+ # ═══════════════════════════════════════════
4
+ # Authentication & django-allauth
5
+ # ═══════════════════════════════════════════
6
+
7
+ AUTHENTICATION_BACKENDS = [
8
+ "django.contrib.auth.backends.ModelBackend",
9
+ "allauth.account.auth_backends.AuthenticationBackend",
10
+ ]
11
+
12
+ ACCOUNT_LOGIN_METHODS = {"email"}
13
+ ACCOUNT_SIGNUP_FIELDS = ["email*", "password1*", "password2*"]
14
+ ACCOUNT_EMAIL_VERIFICATION = "optional"
15
+ ACCOUNT_UNIQUE_EMAIL = True
16
+
17
+ LOGIN_URL = "/cabinet/login/"
18
+ LOGIN_REDIRECT_URL = "/cabinet/"
19
+ LOGOUT_REDIRECT_URL = "/cabinet/login/"
20
+
21
+ SOCIALACCOUNT_PROVIDERS = {
22
+ "google": {
23
+ "APP": {
24
+ "client_id": os.environ.get("GOOGLE_CLIENT_ID", ""),
25
+ "secret": os.environ.get("GOOGLE_CLIENT_SECRET", ""),
26
+ },
27
+ "SCOPE": ["profile", "email"],
28
+ "AUTH_PARAMS": {"access_type": "online"},
29
+ }
30
+ }
31
+
32
+ # ═══════════════════════════════════════════
33
+ # Client Cabinet [codex-django add client-cabinet]
34
+ # Uncomment after running the scaffold command
35
+ # ═══════════════════════════════════════════
36
+
37
+ # ACCOUNT_ADAPTER = "cabinet.adapters.CabinetAccountAdapter"
38
+ # CABINET_DEFAULT_URL = "/cabinet/"
39
+ # CABINET_CLIENT_URL = "/cabinet/my/"
@@ -0,0 +1,49 @@
1
+ import os
2
+ from pathlib import Path
3
+
4
+ import dj_database_url
5
+
6
+ # Root of Django project: src/backend_django
7
+ BASE_DIR = Path(__file__).resolve().parent.parent.parent.parent
8
+ PROJECT_NAME = BASE_DIR.name
9
+
10
+ # ═══════════════════════════════════════════
11
+ # Database
12
+ # ═══════════════════════════════════════════
13
+
14
+ DATABASE_URL = os.environ.get("DATABASE_URL")
15
+ DEBUG = os.environ.get("DEBUG", "False").lower() in ("true", "1", "t")
16
+ IS_DOCKER = os.environ.get("IS_DOCKER", "False").lower() in ("true", "1", "t")
17
+
18
+ if DATABASE_URL:
19
+ # Production (Neon or other)
20
+ DATABASES = {
21
+ "default": dj_database_url.config(
22
+ default=DATABASE_URL,
23
+ conn_max_age=600,
24
+ conn_health_checks=True,
25
+ )
26
+ }
27
+ elif IS_DOCKER and DEBUG:
28
+ # Local Postgres in Docker Cluster (infra)
29
+ DATABASES = {
30
+ "default": {
31
+ "ENGINE": "django.db.backends.postgresql",
32
+ "NAME": os.environ.get("POSTGRES_DB", "landing_cluster"),
33
+ "USER": os.environ.get("POSTGRES_USER", "postgres"),
34
+ "PASSWORD": os.environ.get("POSTGRES_PASSWORD", "postgres"),
35
+ "HOST": os.environ.get("POSTGRES_HOST", "db"),
36
+ "PORT": os.environ.get("POSTGRES_PORT", "5432"),
37
+ }
38
+ }
39
+ else:
40
+ # Fallback to SQLite for local development without Docker
41
+ data_dir = BASE_DIR.parent.parent / "data" / "db"
42
+ data_dir.mkdir(parents=True, exist_ok=True)
43
+
44
+ DATABASES = {
45
+ "default": {
46
+ "ENGINE": "django.db.backends.sqlite3",
47
+ "NAME": str(data_dir / f"{PROJECT_NAME}.sqlite3"),
48
+ }
49
+ }
@@ -0,0 +1,43 @@
1
+ import os
2
+ from pathlib import Path
3
+
4
+ from codex_django.core.i18n.discovery import discover_locale_paths
5
+
6
+ # Root of Django project: src/backend_django
7
+ BASE_DIR = Path(__file__).resolve().parent.parent.parent.parent
8
+
9
+ # ═══════════════════════════════════════════
10
+ # Internationalization
11
+ # ═══════════════════════════════════════════
12
+
13
+ LANGUAGE_CODE = os.environ.get("LANGUAGE_CODE", "{{ languages[0] }}")
14
+ TIME_ZONE = os.environ.get("TIME_ZONE", "UTC")
15
+ USE_I18N = {{ enable_i18n }}
16
+ USE_TZ = True
17
+
18
+ {%- if enable_i18n %}
19
+ LANGUAGES = [
20
+ {%- for lang in languages %}
21
+ {%- if lang == 'en' %}
22
+ ("en", "English"),
23
+ {%- elif lang == 'ru' %}
24
+ ("ru", "Russian"),
25
+ {%- elif lang == 'de' %}
26
+ ("de", "Deutsch"),
27
+ {%- elif lang == 'uk' %}
28
+ ("uk", "Ukrainian"),
29
+ {%- else %}
30
+ ("{{ lang }}", "{{ lang }}"),
31
+ {%- endif %}
32
+ {%- endfor %}
33
+ ]
34
+
35
+ try:
36
+ import modeltranslation # noqa
37
+ MODELTRANSLATION_DEFAULT_LANGUAGE = LANGUAGE_CODE.split("-")[0]
38
+ MODELTRANSLATION_LANGUAGES = ({% for lang in languages %}"{{ lang }}"{% if not loop.last %}, {% endif %}{% endfor %})
39
+ except ImportError:
40
+ pass
41
+
42
+ LOCALE_PATHS = discover_locale_paths(BASE_DIR)
43
+ {%- endif %}
@@ -0,0 +1,45 @@
1
+ import os
2
+ from pathlib import Path
3
+
4
+ # Root of Django project: src/backend_django
5
+ BASE_DIR = Path(__file__).resolve().parent.parent.parent.parent
6
+
7
+ # ═══════════════════════════════════════════
8
+ # Logging (codex-core compatible)
9
+ # ═══════════════════════════════════════════
10
+
11
+ # Loguru / codex-core compatible fields (used in core/logger.py)
12
+ LOG_LEVEL_CONSOLE = os.environ.get("LOG_LEVEL_CONSOLE", "INFO")
13
+ LOG_LEVEL_FILE = os.environ.get("LOG_LEVEL_FILE", "DEBUG")
14
+ LOG_ROTATION = os.environ.get("LOG_ROTATION", "10 MB")
15
+ LOG_DIR = os.environ.get("LOG_DIR", str(BASE_DIR.parent.parent / "logs"))
16
+
17
+ # Standard Django LOGGING (fallback if loguru is disabled/missing)
18
+ LOGGING = {
19
+ "version": 1,
20
+ "disable_existing_loggers": False,
21
+ "formatters": {
22
+ "verbose": {
23
+ "format": "{levelname} {asctime} {module} {process:d} {thread:d} {message}",
24
+ "style": "{",
25
+ },
26
+ "simple": {
27
+ "format": "{levelname} {message}",
28
+ "style": "{",
29
+ },
30
+ },
31
+ "handlers": {
32
+ "console": {
33
+ "level": LOG_LEVEL_CONSOLE,
34
+ "class": "logging.StreamHandler",
35
+ "formatter": "simple",
36
+ },
37
+ },
38
+ "loggers": {
39
+ "django": {
40
+ "handlers": ["console"],
41
+ "level": "INFO",
42
+ "propagate": True,
43
+ },
44
+ },
45
+ }
@@ -0,0 +1,17 @@
1
+ # ═══════════════════════════════════════════
2
+ # Middleware definition
3
+ # ═══════════════════════════════════════════
4
+
5
+ MIDDLEWARE = [
6
+ "django_prometheus.middleware.PrometheusBeforeMiddleware",
7
+ "django.middleware.security.SecurityMiddleware",
8
+ "django.contrib.sessions.middleware.SessionMiddleware",
9
+ "django.middleware.locale.LocaleMiddleware",
10
+ "django.middleware.common.CommonMiddleware",
11
+ "django.middleware.csrf.CsrfViewMiddleware",
12
+ "django.contrib.auth.middleware.AuthenticationMiddleware",
13
+ "django.contrib.messages.middleware.MessageMiddleware",
14
+ "django.middleware.clickjacking.XFrameOptionsMiddleware",
15
+ "django_prometheus.middleware.PrometheusAfterMiddleware",
16
+ "allauth.account.middleware.AccountMiddleware",
17
+ ]
@@ -0,0 +1,53 @@
1
+ import os
2
+ from urllib.parse import urlparse
3
+
4
+ # ═══════════════════════════════════════════
5
+ # Security
6
+ # ═══════════════════════════════════════════
7
+
8
+ SECRET_KEY = os.environ.get("SECRET_KEY", "django-insecure-CHANGE-ME")
9
+ FIELD_ENCRYPTION_KEY = os.environ.get("FIELD_ENCRYPTION_KEY", "")
10
+
11
+ # Main switch for the whole system
12
+ DEBUG = os.environ.get("DEBUG", "True").lower() in ("true", "1", "yes")
13
+
14
+ # --- Smart ALLOWED_HOSTS ---
15
+ ALLOWED_HOSTS = ["localhost", "127.0.0.1", "backend"]
16
+
17
+ env_hosts = os.environ.get("ALLOWED_HOSTS", "")
18
+ if env_hosts:
19
+ ALLOWED_HOSTS.extend([h.strip() for h in env_hosts.split(",") if h.strip()])
20
+
21
+ SITE_BASE_URL = os.environ.get("SITE_BASE_URL", "http://127.0.0.1:8000/")
22
+ if not SITE_BASE_URL.endswith("/"):
23
+ SITE_BASE_URL += "/"
24
+
25
+ # CSRF: include the configured site URL + common local dev ports
26
+ CSRF_TRUSTED_ORIGINS = [SITE_BASE_URL.rstrip("/")]
27
+ if DEBUG:
28
+ CSRF_TRUSTED_ORIGINS += [
29
+ "http://127.0.0.1:8000",
30
+ "http://localhost:8000",
31
+ "http://127.0.0.1:8080",
32
+ "http://localhost:8080",
33
+ ]
34
+
35
+ # Canonical domain for SEO (no trailing slash)
36
+ CANONICAL_DOMAIN = os.environ.get("CANONICAL_DOMAIN", "")
37
+ if CANONICAL_DOMAIN.endswith("/"):
38
+ CANONICAL_DOMAIN = CANONICAL_DOMAIN[:-1]
39
+
40
+ domain = urlparse(SITE_BASE_URL).netloc
41
+ if domain:
42
+ clean_domain = domain.split(":")[0]
43
+ if clean_domain not in ALLOWED_HOSTS:
44
+ ALLOWED_HOSTS.append(clean_domain)
45
+
46
+ if not clean_domain.startswith("www."):
47
+ www_domain = f"www.{clean_domain}"
48
+ if www_domain not in ALLOWED_HOSTS:
49
+ ALLOWED_HOSTS.append(www_domain)
50
+
51
+ if DEBUG:
52
+ # Allow local tunnels dynamically to ease development
53
+ ALLOWED_HOSTS.extend([".ngrok-free.app", ".ngrok-free.dev", ".ngrok.io", ".loca.lt"])
@@ -0,0 +1,14 @@
1
+ # ═══════════════════════════════════════════
2
+ # Sitemap Settings
3
+ # ═══════════════════════════════════════════
4
+
5
+ # List of named URLs to include in the static sitemap
6
+ SITEMAP_STATIC_PAGES = [
7
+ "home",
8
+ "contacts",
9
+ "impressum",
10
+ "datenschutz",
11
+ ]
12
+
13
+ # Default language for x-default in sitemap
14
+ SITEMAP_DEFAULT_LANGUAGE = "de"