# services/pos/app/core/config.py """ POS Integration Service Configuration """ 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" # Override database URL to use POS_DATABASE_URL DATABASE_URL: str = Field( default="postgresql+asyncpg://pos_user:pos_pass123@pos-db:5432/pos_db", env="POS_DATABASE_URL" ) # 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()