[30388f42] Infrastructure Hardening: Repaired CE/Connector DB schema, fixed frontend styling build, implemented robust echo shield in worker v2.1.1, and integrated Lead Engine into gateway.

This commit is contained in:
2026-03-07 14:08:42 +00:00
parent 35c30bc39a
commit d1b77fd2f6
415 changed files with 24100 additions and 13301 deletions

View File

@@ -1,45 +1,66 @@
import os
from dotenv import load_dotenv
# Load environment variables
if os.path.exists(".env"):
load_dotenv(".env", override=True)
elif os.path.exists("../.env"):
load_dotenv("../.env", override=True)
# Explicitly load .env from the project root.
# CRITICAL: override=True ensures we read from the .env file even if
# stale env vars are present in the shell process.
dotenv_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '.env'))
if os.path.exists(dotenv_path):
load_dotenv(dotenv_path=dotenv_path, override=True)
class Config:
# SuperOffice API Configuration
SO_CLIENT_ID = os.getenv("SO_SOD")
SO_CLIENT_SECRET = os.getenv("SO_CLIENT_SECRET")
SO_CONTEXT_IDENTIFIER = os.getenv("SO_CONTEXT_IDENTIFIER")
SO_REFRESH_TOKEN = os.getenv("SO_REFRESH_TOKEN")
# Company Explorer Configuration
CE_API_URL = os.getenv("CE_API_URL", "http://company-explorer:8000")
CE_API_USER = os.getenv("CE_API_USER", "admin")
CE_API_PASSWORD = os.getenv("CE_API_PASSWORD", "gemini")
class Settings:
def __init__(self):
# --- Infrastructure ---
# Internal Docker URL for Company Explorer
self.COMPANY_EXPLORER_URL = os.getenv("COMPANY_EXPLORER_URL", "http://company-explorer:8000")
# --- SuperOffice API Credentials ---
# Fallback for empty string in env var
env_val = os.getenv("SO_ENVIRONMENT")
self.SO_ENVIRONMENT = env_val if env_val else "online3"
self.SO_CLIENT_ID = os.getenv("SO_CLIENT_ID", "")
self.SO_CLIENT_SECRET = os.getenv("SO_CLIENT_SECRET", "")
self.SO_REFRESH_TOKEN = os.getenv("SO_REFRESH_TOKEN", "")
self.SO_REDIRECT_URI = os.getenv("SO_REDIRECT_URI", "http://localhost")
self.SO_CONTEXT_IDENTIFIER = os.getenv("SO_CONTEXT_IDENTIFIER", "Cust55774") # e.g. Cust12345
# --- Feature Flags ---
self.ENABLE_WEBSITE_SYNC = os.getenv("ENABLE_WEBSITE_SYNC", "False").lower() in ("true", "1", "t")
# Mappings (IDs from SuperOffice)
# Vertical IDs (List Items)
self.VERTICAL_MAP_JSON = os.getenv("VERTICAL_MAP_JSON", '{"Automotive - Dealer": 1613, "Corporate - Campus": 1614, "Energy - Grid & Utilities": 1615, "Energy - Solar/Wind": 1616, "Healthcare - Care Home": 1617, "Healthcare - Hospital": 1618, "Hospitality - Gastronomy": 1619, "Hospitality - Hotel": 1620, "Industry - Manufacturing": 1621, "Infrastructure - Communities": 1622, "Infrastructure - Public": 1623, "Infrastructure - Transport": 1624, "Infrastructure - Parking": 1625, "Leisure - Entertainment": 1626, "Leisure - Fitness": 1627, "Leisure - Indoor Active": 1628, "Leisure - Outdoor Park": 1629, "Leisure - Wet & Spa": 1630, "Logistics - Warehouse": 1631, "Others": 1632, "Reinigungsdienstleister": 1633, "Retail - Food": 1634, "Retail - Non-Food": 1635, "Retail - Shopping Center": 1636, "Tech - Data Center": 1637}')
# UDF Mapping (ProgIds) - Defaulting to SOD values, should be overridden in Prod
UDF_CONTACT_MAPPING = {
"ai_challenge_sentence": os.getenv("UDF_CONTACT_CHALLENGE", "SuperOffice:1"),
"ai_sentence_timestamp": os.getenv("UDF_CONTACT_TIMESTAMP", "SuperOffice:2"),
"ai_sentence_source_hash": os.getenv("UDF_CONTACT_HASH", "SuperOffice:3"),
"ai_last_outreach_date": os.getenv("UDF_CONTACT_OUTREACH", "SuperOffice:4")
}
# Persona / Job Role IDs (List Items for "Position" field)
self.PERSONA_MAP_JSON = os.getenv("PERSONA_MAP_JSON", '{}')
UDF_PERSON_MAPPING = {
"ai_email_draft": os.getenv("UDF_PERSON_DRAFT", "SuperOffice:1"),
"ma_status": os.getenv("UDF_PERSON_STATUS", "SuperOffice:2")
}
# User Defined Fields (ProgIDs)
self.UDF_SUBJECT = os.getenv("UDF_SUBJECT", "SuperOffice:5")
self.UDF_INTRO = os.getenv("UDF_INTRO", "SuperOffice:6")
self.UDF_SOCIAL_PROOF = os.getenv("UDF_SOCIAL_PROOF", "SuperOffice:7")
self.UDF_VERTICAL = os.getenv("UDF_VERTICAL", "SuperOffice:5")
self.UDF_OPENER = os.getenv("UDF_OPENER", "SuperOffice:6")
self.UDF_OPENER_SECONDARY = os.getenv("UDF_OPENER_SECONDARY", "SuperOffice:7")
self.UDF_CAMPAIGN = os.getenv("UDF_CAMPAIGN", "SuperOffice:23") # Default from discovery
self.UDF_UNSUBSCRIBE_LINK = os.getenv("UDF_UNSUBSCRIBE_LINK", "SuperOffice:22")
self.UDF_SUMMARY = os.getenv("UDF_SUMMARY", "SuperOffice:84")
self.UDF_LAST_UPDATE = os.getenv("UDF_LAST_UPDATE", "SuperOffice:85")
self.UDF_LAST_OUTREACH = os.getenv("UDF_LAST_OUTREACH", "SuperOffice:88")
# MA Status ID Mapping (Text -> ID) - Defaulting to discovered SOD values
MA_STATUS_ID_MAP = {
"Ready_to_Send": int(os.getenv("MA_STATUS_ID_READY", 11)),
"Sent_Week1": int(os.getenv("MA_STATUS_ID_WEEK1", 12)),
"Sent_Week2": int(os.getenv("MA_STATUS_ID_WEEK2", 13)),
"Bounced": int(os.getenv("MA_STATUS_ID_BOUNCED", 14)),
"Soft_Denied": int(os.getenv("MA_STATUS_ID_DENIED", 15)),
"Interested": int(os.getenv("MA_STATUS_ID_INTERESTED", 16)),
"Out_of_Office": int(os.getenv("MA_STATUS_ID_OOO", 17)),
"Unsubscribed": int(os.getenv("MA_STATUS_ID_UNSUB", 18))
}
# --- User Whitelist (Roboplanet Associates) ---
# Includes both Numerical IDs and Shortnames for robustness
self.ROBOPLANET_WHITELIST = {
# IDs
485, 454, 487, 515, 469, 528, 512, 465, 486, 493, 468, 476, 455, 483,
492, 523, 470, 457, 498, 491, 464, 525, 527, 496, 490, 497, 456, 479,
# Shortnames
"RAAH", "RIAK", "RABA", "RJBU", "RPDU", "RCGO", "RBHA", "RAHE", "RPHO",
"RSHO", "RMJO", "DKE", "RAKI", "RSKO", "RMKR", "RSLU", "REME", "RNSL",
"RAPF", "ROBO", "RBRU", "RSSC", "RBSC", "RASC", "RKAB", "RDSE", "RSSH",
"RJST", "JUTH", "RSWA", "RCWE", "RJZH", "EVZ"
}
# Global instance
settings = Settings()