Files
Krow-workspace/app_core/config/settings.py
2026-04-07 12:31:22 +05:30

78 lines
3.3 KiB
Python

import os
from dotenv import load_dotenv
from pydantic import BaseModel
# Load .env first (if present)
load_dotenv(dotenv_path=".env", override=False)
# Also load .env-example.txt as a fallback for local dev (does not override)
load_dotenv(dotenv_path=".env-example.txt", override=False)
class AppSettings(BaseModel):
# Raw pieces
db_host: str | None = os.getenv("DB_HOST")
db_port: str | None = os.getenv("DB_PORT")
db_name: str | None = os.getenv("DB_NAME")
db_user: str | None = os.getenv("DB_USER")
db_password: str | None = os.getenv("DB_PASSWORD")
db_echo: bool = os.getenv("DB_ECHO", "false").lower() == "true"
# Optional complete URL (takes precedence if set)
database_url_env: str | None = os.getenv("DATABASE_URL")
app_secret: str = os.getenv("APP_SECRET", "change_me")
background_image_url: str | None = os.getenv("BACKGROUND_IMAGE_URL")
# SMTP / Email settings
smtp_host: str | None = os.getenv("SMTP_HOST")
smtp_port: int | None = int(os.getenv("SMTP_PORT", "587"))
smtp_user: str | None = os.getenv("SMTP_USER")
smtp_password: str | None = os.getenv("SMTP_PASSWORD")
smtp_use_tls: bool = os.getenv("SMTP_USE_TLS", "true").lower() == "true"
smtp_from_email: str | None = os.getenv("SMTP_FROM_EMAIL")
smtp_from_name: str = os.getenv("SMTP_FROM_NAME", "Workolik Team")
# Default recipients for automated reports (comma-separated)
report_recipients: str | None = os.getenv("REPORT_RECIPIENTS")
@property
def database_url(self) -> str:
if self.database_url_env:
# Normalize asyncpg to psycopg2 if needed
if self.database_url_env.startswith("postgresql+asyncpg://"):
return self.database_url_env.replace(
"postgresql+asyncpg://", "postgresql+psycopg2://", 1
)
return self.database_url_env
# Build from parts
if all([self.db_host, self.db_port, self.db_name, self.db_user, self.db_password]):
return (
f"postgresql+psycopg2://{self.db_user}:{self.db_password}"
f"@{self.db_host}:{self.db_port}/{self.db_name}"
)
# Fallback empty (will error at runtime if used)
return ""
# Fixed mapping of stores to tenant IDs and division codes
# Used by analytics and data pages to scope queries per store
STORES = [
{"label": "Porters Liquor Claremont - PC", "code": "PC", "tenant_id": 1},
{"label": "Porters Iluka - IP", "code": "IP", "tenant_id": 2},
{"label": "Cellarbrations at Morris Place - ML", "code": "ML", "tenant_id": 3},
{"label": "Cellarbrations at Lynwood - CL", "code": "CL4", "tenant_id": 4},
{"label": "Cellarbrations at Nicholson Road - NL", "code": "NL", "tenant_id": 5},
{"label": "Cellarbrations at Treeby - CL ", "code": "CL6", "tenant_id": 6},
{"label": "The Bottle-O Rossmoyne - RC", "code": "RC", "tenant_id": 7},
{"label": "Porters Liquor Piara Waters - PL", "code": "PL", "tenant_id": 8},
]
# Helper map for quick lookups by code (supports variants like CL-4 → CL4)
STORE_CODE_TO_TENANT_ID: dict[str, int] = {
"PC": 1,
"IP": 2,
"ML": 3,
"CL4": 4, "CL-4": 4, "CL_4": 4, "CL": 4, # default CL → 4
"NL": 5, "NL5": 5, "NL-5": 5,
"CL6": 6, "CL-6": 6, "CL_6": 6,
"RC": 7,
"PL": 8,
}