mirror of
https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools.git
synced 2026-06-17 23:09:35 +00:00
Founder Strategy & GTM (from prompts #1, #10): - niche-brief.md: Saudi real estate primary, healthcare secondary - icp-brief.md: Full ICP with Arabic objection handling - content-map.md: 20 content ideas, SEO keywords, weekly schedule - outreach-map.md: WhatsApp/Email cold outreach with Arabic templates - launch-plan.md: 14-day sprint + 30-day plan with revenue targets - interview-template.md: 15 Arabic customer discovery questions Claude Code Control Plane (from prompt #2): - .claude/settings.json: Permissions and preferences - .claude/commands/: 5 custom commands (review-pr, release-prep, security-check, generate-tests, architecture-review) - .claude/hooks/: pre-commit.sh (secrets check), pre-push.sh (tests) SaaS Launch Readiness (from prompt #4): - saas-readiness-audit.md: Full audit with gap analysis - deployment-checklist.md: Deploy + rollback procedures - launch-checklist.md: 100+ launch day checklist items - feature_flags.py: Redis-backed feature flags with per-tenant control https://claude.ai/code/session_01LsnvBa7HwF5hs99VZbgLGj
160 lines
5.6 KiB
Python
160 lines
5.6 KiB
Python
"""
|
|
Feature Flags — Dealix AI Revenue OS
|
|
Simple Redis-backed feature flag system with per-tenant control.
|
|
"""
|
|
import logging
|
|
from typing import Optional
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# Default flags and their initial state
|
|
DEFAULT_FLAGS = {
|
|
"ai_sales_agent": False, # Autonomous WhatsApp sales agent
|
|
"sequences": True, # Multi-channel sequences
|
|
"cpq": True, # Configure, Price, Quote
|
|
"signal_intelligence": False, # Real-time signal engine
|
|
"autopilot": False, # Autopilot automation
|
|
"behavior_intelligence": False,# Pattern detection
|
|
"arabic_nlp": True, # Arabic NLP processing
|
|
"lead_scoring_ai": True, # AI-powered lead scoring
|
|
"conversation_intel": False, # Conversation analysis
|
|
"territory_management": True, # Saudi territory routing
|
|
"whatsapp_chatbot": False, # Auto-reply chatbot
|
|
"pdpl_strict_mode": True, # Strict PDPL enforcement
|
|
"forecasting": False, # Sales forecasting
|
|
"alert_delivery": True, # Multi-channel alerts
|
|
"skill_registry": False, # Domain skill system
|
|
}
|
|
|
|
|
|
class FeatureFlagService:
|
|
"""
|
|
Feature flag service using Redis for fast lookups.
|
|
Supports global flags and per-tenant overrides.
|
|
"""
|
|
|
|
def __init__(self, redis_client=None):
|
|
self._redis = redis_client
|
|
self._local_cache: dict[str, bool] = dict(DEFAULT_FLAGS)
|
|
self._tenant_cache: dict[str, dict[str, bool]] = {}
|
|
|
|
def _global_key(self, flag: str) -> str:
|
|
return f"ff:global:{flag}"
|
|
|
|
def _tenant_key(self, flag: str, tenant_id: str) -> str:
|
|
return f"ff:tenant:{tenant_id}:{flag}"
|
|
|
|
async def is_enabled(
|
|
self, flag: str, tenant_id: Optional[str] = None
|
|
) -> bool:
|
|
"""Check if a feature flag is enabled."""
|
|
# Check tenant-specific override first
|
|
if tenant_id and self._redis:
|
|
try:
|
|
val = await self._redis.get(self._tenant_key(flag, tenant_id))
|
|
if val is not None:
|
|
return val == "1"
|
|
except Exception as e:
|
|
logger.warning(f"Redis error checking flag {flag}: {e}")
|
|
|
|
# Check global flag in Redis
|
|
if self._redis:
|
|
try:
|
|
val = await self._redis.get(self._global_key(flag))
|
|
if val is not None:
|
|
return val == "1"
|
|
except Exception as e:
|
|
logger.warning(f"Redis error checking flag {flag}: {e}")
|
|
|
|
# Fallback to local cache / defaults
|
|
return self._local_cache.get(flag, False)
|
|
|
|
async def enable(
|
|
self, flag: str, tenant_id: Optional[str] = None
|
|
) -> bool:
|
|
"""Enable a feature flag globally or for a specific tenant."""
|
|
key = (
|
|
self._tenant_key(flag, tenant_id)
|
|
if tenant_id
|
|
else self._global_key(flag)
|
|
)
|
|
if self._redis:
|
|
try:
|
|
await self._redis.set(key, "1")
|
|
except Exception as e:
|
|
logger.error(f"Redis error enabling flag {flag}: {e}")
|
|
return False
|
|
|
|
if not tenant_id:
|
|
self._local_cache[flag] = True
|
|
logger.info(
|
|
f"Feature flag '{flag}' enabled"
|
|
+ (f" for tenant {tenant_id}" if tenant_id else " globally")
|
|
)
|
|
return True
|
|
|
|
async def disable(
|
|
self, flag: str, tenant_id: Optional[str] = None
|
|
) -> bool:
|
|
"""Disable a feature flag globally or for a specific tenant."""
|
|
key = (
|
|
self._tenant_key(flag, tenant_id)
|
|
if tenant_id
|
|
else self._global_key(flag)
|
|
)
|
|
if self._redis:
|
|
try:
|
|
await self._redis.set(key, "0")
|
|
except Exception as e:
|
|
logger.error(f"Redis error disabling flag {flag}: {e}")
|
|
return False
|
|
|
|
if not tenant_id:
|
|
self._local_cache[flag] = False
|
|
logger.info(
|
|
f"Feature flag '{flag}' disabled"
|
|
+ (f" for tenant {tenant_id}" if tenant_id else " globally")
|
|
)
|
|
return True
|
|
|
|
async def list_flags(
|
|
self, tenant_id: Optional[str] = None
|
|
) -> dict[str, bool]:
|
|
"""List all flags with their current state."""
|
|
result = {}
|
|
for flag in DEFAULT_FLAGS:
|
|
result[flag] = await self.is_enabled(flag, tenant_id)
|
|
return result
|
|
|
|
async def enable_beta(self, tenant_id: str) -> dict[str, bool]:
|
|
"""Enable all beta features for a tenant (beta tester program)."""
|
|
beta_flags = [
|
|
"ai_sales_agent", "signal_intelligence", "autopilot",
|
|
"behavior_intelligence", "conversation_intel",
|
|
"forecasting", "skill_registry", "whatsapp_chatbot",
|
|
]
|
|
enabled = {}
|
|
for flag in beta_flags:
|
|
await self.enable(flag, tenant_id)
|
|
enabled[flag] = True
|
|
logger.info(f"Beta features enabled for tenant {tenant_id}")
|
|
return enabled
|
|
|
|
async def init_defaults(self) -> None:
|
|
"""Initialize default flag values in Redis."""
|
|
if not self._redis:
|
|
return
|
|
for flag, default_val in DEFAULT_FLAGS.items():
|
|
key = self._global_key(flag)
|
|
try:
|
|
exists = await self._redis.exists(key)
|
|
if not exists:
|
|
await self._redis.set(key, "1" if default_val else "0")
|
|
except Exception as e:
|
|
logger.warning(f"Could not init flag {flag}: {e}")
|
|
logger.info(f"Initialized {len(DEFAULT_FLAGS)} feature flags")
|
|
|
|
|
|
# Global singleton (initialize with Redis client at app startup)
|
|
feature_flags = FeatureFlagService()
|