Files
Salon/backend/salon_api/settings.py
T
mohd dc68ecfe4c Summary of what I changed and added:
Added initial migrations for accounts, salons, bookings, payments.
0001_initial.py
0001_initial.py
0001_initial.py
0001_initial.py
Added demo seeding command.
seed_demo.py
OTP provider abstraction now includes Twilio + Unifonic adapter scaffolds (not implemented yet, they raise).
otp.py
Moyasar gateway scaffold added (not implemented yet, raises).
gateway.py
Added .env loading in settings and expanded .env.example for OTP and Moyasar.
settings.py
.env.example
Captured current gaps/risks in a tracked doc as requested.
risks.md
Updated README with seeding guidance and risk doc pointer.
README.md
2026-02-27 15:10:30 +03:00

133 lines
3.7 KiB
Python

import os
from pathlib import Path
from datetime import timedelta
from urllib.parse import urlparse
from dotenv import load_dotenv
BASE_DIR = Path(__file__).resolve().parent.parent
load_dotenv(BASE_DIR / ".env")
SECRET_KEY = os.getenv("DJANGO_SECRET_KEY", "unsafe-dev-key")
DEBUG = os.getenv("DJANGO_DEBUG", "0") == "1"
ALLOWED_HOSTS = [h.strip() for h in os.getenv("DJANGO_ALLOWED_HOSTS", "").split(",") if h.strip()]
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"rest_framework",
"corsheaders",
"apps.accounts",
"apps.salons",
"apps.bookings",
"apps.payments",
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"corsheaders.middleware.CorsMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = "salon_api.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
WSGI_APPLICATION = "salon_api.wsgi.application"
ASGI_APPLICATION = "salon_api.asgi.application"
def parse_database_url(database_url: str):
parsed = urlparse(database_url)
if parsed.scheme not in {"postgres", "postgresql"}:
return None
return {
"ENGINE": "django.db.backends.postgresql",
"NAME": parsed.path.lstrip("/"),
"USER": parsed.username,
"PASSWORD": parsed.password,
"HOST": parsed.hostname,
"PORT": parsed.port or "5432",
}
DATABASE_URL = os.getenv("DATABASE_URL")
if DATABASE_URL:
parsed_db = parse_database_url(DATABASE_URL)
else:
parsed_db = None
DATABASES = {
"default": parsed_db
or {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}
AUTH_PASSWORD_VALIDATORS = [
{"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"},
{"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"},
{"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"},
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
]
LANGUAGE_CODE = "en-us"
TIME_ZONE = "Asia/Riyadh"
USE_I18N = True
USE_TZ = True
STATIC_URL = "static/"
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
AUTH_USER_MODEL = "accounts.User"
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": (
"rest_framework_simplejwt.authentication.JWTAuthentication",
),
"DEFAULT_PERMISSION_CLASSES": (
"rest_framework.permissions.IsAuthenticatedOrReadOnly",
),
}
SIMPLE_JWT = {
"ACCESS_TOKEN_LIFETIME": timedelta(minutes=30),
"REFRESH_TOKEN_LIFETIME": timedelta(days=7),
"AUTH_HEADER_TYPES": ("Bearer",),
}
CORS_ALLOWED_ORIGINS = [
origin.strip()
for origin in os.getenv("CORS_ALLOWED_ORIGINS", "").split(",")
if origin.strip()
]
OTP_PROVIDER = os.getenv("OTP_PROVIDER", "console")
OTP_EXPIRY_MINUTES = int(os.getenv("OTP_EXPIRY_MINUTES", "5"))
DEFAULT_CURRENCY = os.getenv("DEFAULT_CURRENCY", "SAR")