- Added migration 025 for the Ticket System, creating tables for tickets, comments, attachments, worklogs, prepaid cards, and audit logs. - Introduced migration 026 to add ticket-related permissions to the auth system and assign them to user groups. - Developed a test suite for the Ticket Module, validating database schema, ticket number generation, prepaid card constraints, service logic, worklog creation, audit logging, and views.
202 lines
8.7 KiB
Python
202 lines
8.7 KiB
Python
"""
|
|
Configuration Module
|
|
Handles environment variables and application settings
|
|
"""
|
|
|
|
import os
|
|
from typing import List
|
|
from pydantic_settings import BaseSettings
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
"""Application settings loaded from environment variables"""
|
|
|
|
# Database
|
|
DATABASE_URL: str = "postgresql://bmc_hub:bmc_hub@localhost:5432/bmc_hub"
|
|
|
|
# API
|
|
API_HOST: str = "0.0.0.0"
|
|
API_PORT: int = 8000
|
|
|
|
# Security
|
|
SECRET_KEY: str = "dev-secret-key-change-in-production"
|
|
ALLOWED_ORIGINS: List[str] = ["http://localhost:8000", "http://localhost:3000"]
|
|
|
|
# Logging
|
|
LOG_LEVEL: str = "INFO"
|
|
LOG_FILE: str = "logs/app.log"
|
|
|
|
# e-conomic Integration
|
|
ECONOMIC_API_URL: str = "https://restapi.e-conomic.com"
|
|
ECONOMIC_APP_SECRET_TOKEN: str = ""
|
|
ECONOMIC_AGREEMENT_GRANT_TOKEN: str = ""
|
|
ECONOMIC_READ_ONLY: bool = True
|
|
ECONOMIC_DRY_RUN: bool = True
|
|
|
|
# vTiger CRM Integration
|
|
VTIGER_URL: str = ""
|
|
VTIGER_USERNAME: str = ""
|
|
VTIGER_API_KEY: str = ""
|
|
VTIGER_PASSWORD: str = "" # Fallback hvis API key ikke virker
|
|
|
|
# Simply-CRM Integration (Legacy System med CVR data)
|
|
OLD_VTIGER_URL: str = "https://bmcnetworks.simply-crm.dk"
|
|
OLD_VTIGER_USERNAME: str = "ct"
|
|
OLD_VTIGER_ACCESS_KEY: str = "b00ff2b7c08d591"
|
|
|
|
# Time Tracking Module - vTiger Integration (Isoleret)
|
|
TIMETRACKING_VTIGER_READ_ONLY: bool = True # 🚨 SAFETY: Bloker ALLE skrivninger til vTiger
|
|
TIMETRACKING_VTIGER_DRY_RUN: bool = True # 🚨 SAFETY: Log uden at synkronisere
|
|
|
|
# Time Tracking Module - Order Management
|
|
TIMETRACKING_ADMIN_UNLOCK_CODE: str = "" # Kode for at låse eksporterede ordrer op
|
|
|
|
# Time Tracking Module - e-conomic Integration (Isoleret)
|
|
TIMETRACKING_ECONOMIC_READ_ONLY: bool = True # 🚨 SAFETY: Bloker ALLE skrivninger til e-conomic
|
|
TIMETRACKING_ECONOMIC_DRY_RUN: bool = True # 🚨 SAFETY: Log uden at eksportere
|
|
TIMETRACKING_EXPORT_TYPE: str = "draft" # draft|booked (draft er sikrest)
|
|
|
|
# Time Tracking Module - Business Logic
|
|
TIMETRACKING_DEFAULT_HOURLY_RATE: float = 850.00 # DKK pr. time (fallback)
|
|
TIMETRACKING_AUTO_ROUND: bool = True # Auto-afrund til nærmeste 0.5 time
|
|
TIMETRACKING_ROUND_INCREMENT: float = 0.5 # Afrundingsinterval (0.25, 0.5, 1.0)
|
|
TIMETRACKING_ROUND_METHOD: str = "up" # up (op til), nearest (nærmeste), down (ned til)
|
|
TIMETRACKING_REQUIRE_APPROVAL: bool = True # Kræv manuel godkendelse (ikke auto-approve)
|
|
|
|
# Ollama AI Integration
|
|
OLLAMA_ENDPOINT: str = "http://ai_direct.cs.blaahund.dk"
|
|
OLLAMA_MODEL: str = "qwen2.5-coder:7b" # qwen2.5-coder fungerer bedre til JSON udtrækning
|
|
|
|
# Ticket System Module
|
|
TICKET_ENABLED: bool = True
|
|
TICKET_EMAIL_INTEGRATION: bool = False # 🚨 SAFETY: Disable email-to-ticket until configured
|
|
TICKET_AUTO_ASSIGN: bool = False # Auto-assign tickets based on rules
|
|
TICKET_DEFAULT_PRIORITY: str = "normal" # low|normal|high|urgent
|
|
TICKET_REQUIRE_CUSTOMER: bool = False # Allow tickets without customer link
|
|
TICKET_NOTIFICATION_ENABLED: bool = False # Notify on status changes
|
|
|
|
# Ticket System - e-conomic Integration
|
|
TICKET_ECONOMIC_READ_ONLY: bool = True # 🚨 SAFETY: Block all writes to e-conomic
|
|
TICKET_ECONOMIC_DRY_RUN: bool = True # 🚨 SAFETY: Log without executing
|
|
TICKET_ECONOMIC_AUTO_EXPORT: bool = False # Auto-export billable worklog
|
|
|
|
# Email System Configuration
|
|
EMAIL_TO_TICKET_ENABLED: bool = False # 🚨 SAFETY: Disable auto-processing until configured
|
|
|
|
# Email Fetching (IMAP)
|
|
USE_GRAPH_API: bool = False # Use Microsoft Graph API instead of IMAP (preferred)
|
|
IMAP_SERVER: str = "outlook.office365.com"
|
|
IMAP_PORT: int = 993
|
|
IMAP_USE_SSL: bool = True
|
|
IMAP_USERNAME: str = ""
|
|
IMAP_PASSWORD: str = ""
|
|
IMAP_FOLDER: str = "INBOX"
|
|
IMAP_READ_ONLY: bool = True # 🚨 SAFETY: Never mark emails as read or modify mailbox
|
|
|
|
# Microsoft Graph API (OAuth2)
|
|
GRAPH_TENANT_ID: str = ""
|
|
GRAPH_CLIENT_ID: str = ""
|
|
GRAPH_CLIENT_SECRET: str = ""
|
|
GRAPH_USER_EMAIL: str = "" # Email account to monitor
|
|
|
|
# Email Processing
|
|
EMAIL_PROCESS_INTERVAL_MINUTES: int = 5 # Background job frequency
|
|
EMAIL_MAX_FETCH_PER_RUN: int = 50 # Limit emails per processing cycle
|
|
EMAIL_RETENTION_DAYS: int = 90 # Days to keep emails before soft delete
|
|
|
|
# Email Classification (AI)
|
|
EMAIL_AI_ENABLED: bool = True
|
|
EMAIL_AI_CONFIDENCE_THRESHOLD: float = 0.7 # Minimum confidence for auto-processing
|
|
EMAIL_AUTO_CLASSIFY: bool = True # Run AI classification on new emails
|
|
|
|
# Email Rules Engine (DEPRECATED - Use workflows instead)
|
|
EMAIL_RULES_ENABLED: bool = False # 🚨 LEGACY: Disabled by default, use EMAIL_WORKFLOWS_ENABLED instead
|
|
EMAIL_RULES_AUTO_PROCESS: bool = False # 🚨 SAFETY: Require manual approval initially
|
|
|
|
# Email Workflows (RECOMMENDED)
|
|
EMAIL_WORKFLOWS_ENABLED: bool = True # Enable automated workflows based on classification (replaces rules)
|
|
|
|
# Company Info
|
|
OWN_CVR: str = "29522790" # BMC Denmark ApS - ignore when detecting vendors
|
|
|
|
# File Upload
|
|
UPLOAD_DIR: str = "uploads"
|
|
MAX_FILE_SIZE_MB: int = 50
|
|
ALLOWED_EXTENSIONS: List[str] = [".pdf", ".png", ".jpg", ".jpeg", ".txt", ".csv"]
|
|
|
|
# Module System Configuration
|
|
MODULES_ENABLED: bool = True # Enable/disable entire module system
|
|
MODULES_DIR: str = "app/modules" # Directory for dynamic modules
|
|
MODULES_AUTO_RELOAD: bool = True # Hot-reload modules on changes (dev only)
|
|
|
|
# Backup System Configuration
|
|
# Safety switches (default to safe mode)
|
|
BACKUP_ENABLED: bool = False # 🚨 SAFETY: Disable backups until explicitly enabled
|
|
BACKUP_DRY_RUN: bool = True # 🚨 SAFETY: Log operations without executing
|
|
BACKUP_READ_ONLY: bool = True # 🚨 SAFETY: Allow reads but block destructive operations
|
|
|
|
# Backup formats
|
|
DB_DAILY_FORMAT: str = "dump" # dump (compressed) or sql (plain text)
|
|
DB_MONTHLY_FORMAT: str = "sql" # Monthly backups use plain SQL for readability
|
|
|
|
# Backup scope
|
|
BACKUP_INCLUDE_UPLOADS: bool = True # Include uploads/ directory
|
|
BACKUP_INCLUDE_LOGS: bool = True # Include logs/ directory
|
|
BACKUP_INCLUDE_DATA: bool = True # Include data/ directory (templates, configs)
|
|
|
|
# Storage configuration
|
|
BACKUP_STORAGE_PATH: str = "/opt/backups" # Production: /opt/backups, Dev: ./backups
|
|
BACKUP_MAX_SIZE_GB: int = 50 # Maximum total backup storage size
|
|
STORAGE_WARNING_THRESHOLD_PCT: int = 80 # Warn when storage exceeds this percentage
|
|
|
|
# Rotation policy
|
|
RETENTION_DAYS: int = 30 # Keep daily backups for 30 days
|
|
MONTHLY_KEEP_MONTHS: int = 12 # Keep monthly backups for 12 months
|
|
|
|
# Offsite configuration (SFTP/SSH)
|
|
OFFSITE_ENABLED: bool = False # 🚨 SAFETY: Disable offsite uploads until configured
|
|
OFFSITE_WEEKLY_DAY: str = "sunday" # Day for weekly offsite upload (monday-sunday)
|
|
OFFSITE_RETRY_MAX_ATTEMPTS: int = 3 # Maximum retry attempts for failed uploads
|
|
OFFSITE_RETRY_DELAY_HOURS: int = 1 # Hours between retry attempts
|
|
SFTP_HOST: str = "" # SFTP server hostname or IP
|
|
SFTP_PORT: int = 22 # SFTP server port
|
|
SFTP_USER: str = "" # SFTP username
|
|
SFTP_PASSWORD: str = "" # SFTP password (if not using SSH key)
|
|
SSH_KEY_PATH: str = "" # Path to SSH private key (preferred over password)
|
|
SFTP_REMOTE_PATH: str = "/backups/bmc_hub" # Remote directory for backups
|
|
|
|
# Notification configuration (Mattermost)
|
|
MATTERMOST_ENABLED: bool = False # 🚨 SAFETY: Disable until webhook configured
|
|
MATTERMOST_WEBHOOK_URL: str = "" # Mattermost incoming webhook URL
|
|
MATTERMOST_CHANNEL: str = "backups" # Channel name for backup notifications
|
|
NOTIFY_ON_FAILURE: bool = True # Send notification on backup/offsite failures
|
|
NOTIFY_ON_SUCCESS_OFFSITE: bool = True # Send notification on successful offsite upload
|
|
|
|
class Config:
|
|
env_file = ".env"
|
|
case_sensitive = True
|
|
extra = "ignore" # Ignore extra fields from .env
|
|
|
|
|
|
settings = Settings()
|
|
|
|
|
|
def get_module_config(module_name: str, key: str, default=None):
|
|
"""
|
|
Hent modul-specifik konfiguration fra miljøvariabel
|
|
|
|
Pattern: MODULES__{MODULE_NAME}__{KEY}
|
|
Eksempel: MODULES__MY_MODULE__API_KEY
|
|
|
|
Args:
|
|
module_name: Navn på modul (fx "my_module")
|
|
key: Config key (fx "API_KEY")
|
|
default: Default værdi hvis ikke sat
|
|
|
|
Returns:
|
|
Konfigurationsværdi eller default
|
|
"""
|
|
import os
|
|
env_key = f"MODULES__{module_name.upper()}__{key.upper()}"
|
|
return os.getenv(env_key, default)
|