Initial commit - production deployment
This commit is contained in:
192
services/pos/app/core/config.py
Normal file
192
services/pos/app/core/config.py
Normal file
@@ -0,0 +1,192 @@
|
||||
# services/pos/app/core/config.py
|
||||
"""
|
||||
POS Integration Service Configuration
|
||||
"""
|
||||
|
||||
import os
|
||||
from typing import List, Optional
|
||||
from pydantic import Field
|
||||
from shared.config.base import BaseServiceSettings
|
||||
|
||||
|
||||
class Settings(BaseServiceSettings):
|
||||
"""POS Integration service settings extending base configuration"""
|
||||
|
||||
# Override service-specific settings
|
||||
SERVICE_NAME: str = "pos-service"
|
||||
VERSION: str = "1.0.0"
|
||||
APP_NAME: str = "Bakery POS Integration Service"
|
||||
DESCRIPTION: str = "Integration service for external POS systems (Square, Toast, Lightspeed)"
|
||||
|
||||
# API Configuration
|
||||
API_V1_STR: str = "/api/v1"
|
||||
|
||||
# Database configuration (secure approach - build from components)
|
||||
@property
|
||||
def DATABASE_URL(self) -> str:
|
||||
"""Build database URL from secure components"""
|
||||
# Try complete URL first (for backward compatibility)
|
||||
complete_url = os.getenv("POS_DATABASE_URL")
|
||||
if complete_url:
|
||||
return complete_url
|
||||
|
||||
# Build from components (secure approach)
|
||||
user = os.getenv("POS_DB_USER", "pos_user")
|
||||
password = os.getenv("POS_DB_PASSWORD", "pos_pass123")
|
||||
host = os.getenv("POS_DB_HOST", "localhost")
|
||||
port = os.getenv("POS_DB_PORT", "5432")
|
||||
name = os.getenv("POS_DB_NAME", "pos_db")
|
||||
|
||||
return f"postgresql+asyncpg://{user}:{password}@{host}:{port}/{name}"
|
||||
|
||||
# POS-specific Redis database
|
||||
REDIS_DB: int = Field(default=5, env="POS_REDIS_DB")
|
||||
|
||||
# ================================================================
|
||||
# POS PROVIDER CONFIGURATIONS
|
||||
# ================================================================
|
||||
|
||||
# Square POS Configuration
|
||||
SQUARE_APPLICATION_ID: Optional[str] = Field(default=None, env="SQUARE_APPLICATION_ID")
|
||||
SQUARE_ACCESS_TOKEN: Optional[str] = Field(default=None, env="SQUARE_ACCESS_TOKEN")
|
||||
SQUARE_WEBHOOK_SIGNATURE_KEY: Optional[str] = Field(default=None, env="SQUARE_WEBHOOK_SIGNATURE_KEY")
|
||||
SQUARE_ENVIRONMENT: str = Field(default="sandbox", env="SQUARE_ENVIRONMENT") # sandbox or production
|
||||
SQUARE_BASE_URL: str = "https://connect.squareup.com"
|
||||
SQUARE_SANDBOX_URL: str = "https://connect.squareupsandbox.com"
|
||||
|
||||
@property
|
||||
def SQUARE_API_URL(self) -> str:
|
||||
return self.SQUARE_SANDBOX_URL if self.SQUARE_ENVIRONMENT == "sandbox" else self.SQUARE_BASE_URL
|
||||
|
||||
# Toast POS Configuration
|
||||
TOAST_CLIENT_ID: Optional[str] = Field(default=None, env="TOAST_CLIENT_ID")
|
||||
TOAST_CLIENT_SECRET: Optional[str] = Field(default=None, env="TOAST_CLIENT_SECRET")
|
||||
TOAST_WEBHOOK_SECRET: Optional[str] = Field(default=None, env="TOAST_WEBHOOK_SECRET")
|
||||
TOAST_ENVIRONMENT: str = Field(default="sandbox", env="TOAST_ENVIRONMENT") # sandbox or production
|
||||
TOAST_BASE_URL: str = "https://ws-api.toasttab.com"
|
||||
TOAST_SANDBOX_URL: str = "https://ws-sandbox-api.toasttab.com"
|
||||
|
||||
@property
|
||||
def TOAST_API_URL(self) -> str:
|
||||
return self.TOAST_SANDBOX_URL if self.TOAST_ENVIRONMENT == "sandbox" else self.TOAST_BASE_URL
|
||||
|
||||
# Lightspeed POS Configuration
|
||||
LIGHTSPEED_CLIENT_ID: Optional[str] = Field(default=None, env="LIGHTSPEED_CLIENT_ID")
|
||||
LIGHTSPEED_CLIENT_SECRET: Optional[str] = Field(default=None, env="LIGHTSPEED_CLIENT_SECRET")
|
||||
LIGHTSPEED_WEBHOOK_SECRET: Optional[str] = Field(default=None, env="LIGHTSPEED_WEBHOOK_SECRET")
|
||||
LIGHTSPEED_CLUSTER_ID: Optional[str] = Field(default=None, env="LIGHTSPEED_CLUSTER_ID")
|
||||
LIGHTSPEED_BASE_URL: str = "https://api-{cluster}.lightspeedhq.com"
|
||||
|
||||
def get_lightspeed_api_url(self, cluster_id: Optional[str] = None) -> str:
|
||||
cluster = cluster_id or self.LIGHTSPEED_CLUSTER_ID or "us1"
|
||||
return self.LIGHTSPEED_BASE_URL.format(cluster=cluster)
|
||||
|
||||
# ================================================================
|
||||
# WEBHOOK CONFIGURATION
|
||||
# ================================================================
|
||||
|
||||
# Webhook Base Configuration
|
||||
WEBHOOK_BASE_URL: str = Field(default="https://your-domain.com", env="WEBHOOK_BASE_URL")
|
||||
WEBHOOK_SECRET: str = Field(default="your-webhook-secret", env="WEBHOOK_SECRET")
|
||||
WEBHOOK_TIMEOUT_SECONDS: int = Field(default=30, env="WEBHOOK_TIMEOUT_SECONDS")
|
||||
|
||||
# Webhook Rate Limiting
|
||||
WEBHOOK_RATE_LIMIT_PER_MINUTE: int = Field(default=1000, env="WEBHOOK_RATE_LIMIT_PER_MINUTE")
|
||||
WEBHOOK_BURST_LIMIT: int = Field(default=100, env="WEBHOOK_BURST_LIMIT")
|
||||
|
||||
# Webhook Retry Configuration
|
||||
WEBHOOK_MAX_RETRIES: int = Field(default=3, env="WEBHOOK_MAX_RETRIES")
|
||||
WEBHOOK_RETRY_DELAY_SECONDS: int = Field(default=5, env="WEBHOOK_RETRY_DELAY_SECONDS")
|
||||
|
||||
# ================================================================
|
||||
# SYNC CONFIGURATION
|
||||
# ================================================================
|
||||
|
||||
# Data Synchronization Settings
|
||||
SYNC_ENABLED: bool = Field(default=True, env="POS_SYNC_ENABLED")
|
||||
SYNC_INTERVAL_SECONDS: int = Field(default=300, env="POS_SYNC_INTERVAL_SECONDS") # 5 minutes
|
||||
SYNC_BATCH_SIZE: int = Field(default=100, env="POS_SYNC_BATCH_SIZE")
|
||||
SYNC_MAX_RETRY_ATTEMPTS: int = Field(default=3, env="POS_SYNC_MAX_RETRY_ATTEMPTS")
|
||||
SYNC_RETRY_DELAY_SECONDS: int = Field(default=60, env="POS_SYNC_RETRY_DELAY_SECONDS")
|
||||
|
||||
# Historical Data Sync
|
||||
HISTORICAL_SYNC_DAYS: int = Field(default=30, env="POS_HISTORICAL_SYNC_DAYS")
|
||||
INITIAL_SYNC_BATCH_SIZE: int = Field(default=50, env="POS_INITIAL_SYNC_BATCH_SIZE")
|
||||
|
||||
# ================================================================
|
||||
# SECURITY & ENCRYPTION
|
||||
# ================================================================
|
||||
|
||||
# API Credential Encryption
|
||||
ENCRYPTION_KEY: Optional[str] = Field(default=None, env="POS_ENCRYPTION_KEY")
|
||||
CREDENTIALS_ENCRYPTION_ENABLED: bool = Field(default=True, env="POS_CREDENTIALS_ENCRYPTION_ENABLED")
|
||||
|
||||
# API Rate Limiting
|
||||
API_RATE_LIMIT_PER_MINUTE: int = Field(default=60, env="POS_API_RATE_LIMIT_PER_MINUTE")
|
||||
API_BURST_LIMIT: int = Field(default=10, env="POS_API_BURST_LIMIT")
|
||||
|
||||
# ================================================================
|
||||
# CACHING CONFIGURATION
|
||||
# ================================================================
|
||||
|
||||
# POS Data Cache TTL
|
||||
POS_CONFIG_CACHE_TTL: int = Field(default=3600, env="POS_CONFIG_CACHE_TTL") # 1 hour
|
||||
POS_TRANSACTION_CACHE_TTL: int = Field(default=300, env="POS_TRANSACTION_CACHE_TTL") # 5 minutes
|
||||
POS_PRODUCT_CACHE_TTL: int = Field(default=1800, env="POS_PRODUCT_CACHE_TTL") # 30 minutes
|
||||
|
||||
# ================================================================
|
||||
# SUPPORTED POS SYSTEMS
|
||||
# ================================================================
|
||||
|
||||
SUPPORTED_POS_SYSTEMS: List[str] = ["square", "toast", "lightspeed"]
|
||||
|
||||
# Default POS system for new tenants
|
||||
DEFAULT_POS_SYSTEM: str = Field(default="square", env="DEFAULT_POS_SYSTEM")
|
||||
|
||||
# ================================================================
|
||||
# INTER-SERVICE COMMUNICATION
|
||||
# ================================================================
|
||||
|
||||
# Override service URLs
|
||||
SALES_SERVICE_URL: str = Field(
|
||||
default="http://sales-service:8000",
|
||||
env="SALES_SERVICE_URL"
|
||||
)
|
||||
|
||||
INVENTORY_SERVICE_URL: str = Field(
|
||||
default="http://inventory-service:8000",
|
||||
env="INVENTORY_SERVICE_URL"
|
||||
)
|
||||
|
||||
# ================================================================
|
||||
# BUSINESS RULES
|
||||
# ================================================================
|
||||
|
||||
# Transaction Processing
|
||||
MIN_TRANSACTION_AMOUNT: float = Field(default=0.01, env="POS_MIN_TRANSACTION_AMOUNT")
|
||||
MAX_TRANSACTION_AMOUNT: float = Field(default=10000.0, env="POS_MAX_TRANSACTION_AMOUNT")
|
||||
|
||||
# Duplicate Detection Window (in minutes)
|
||||
DUPLICATE_DETECTION_WINDOW: int = Field(default=5, env="POS_DUPLICATE_DETECTION_WINDOW")
|
||||
|
||||
# Data Retention
|
||||
TRANSACTION_RETENTION_DAYS: int = Field(default=1095, env="POS_TRANSACTION_RETENTION_DAYS") # 3 years
|
||||
WEBHOOK_LOG_RETENTION_DAYS: int = Field(default=30, env="POS_WEBHOOK_LOG_RETENTION_DAYS")
|
||||
SYNC_LOG_RETENTION_DAYS: int = Field(default=90, env="POS_SYNC_LOG_RETENTION_DAYS")
|
||||
|
||||
# ================================================================
|
||||
# MONITORING & ALERTING
|
||||
# ================================================================
|
||||
|
||||
# Health Check Configuration
|
||||
POS_HEALTH_CHECK_ENABLED: bool = Field(default=True, env="POS_HEALTH_CHECK_ENABLED")
|
||||
POS_HEALTH_CHECK_INTERVAL: int = Field(default=60, env="POS_HEALTH_CHECK_INTERVAL") # seconds
|
||||
|
||||
# Alert Thresholds
|
||||
WEBHOOK_FAILURE_THRESHOLD: int = Field(default=5, env="POS_WEBHOOK_FAILURE_THRESHOLD")
|
||||
SYNC_FAILURE_THRESHOLD: int = Field(default=3, env="POS_SYNC_FAILURE_THRESHOLD")
|
||||
API_ERROR_THRESHOLD: int = Field(default=10, env="POS_API_ERROR_THRESHOLD")
|
||||
|
||||
|
||||
# Global settings instance
|
||||
settings = Settings()
|
||||
Reference in New Issue
Block a user