Ребрендинг БАЗА (фундамент): конфиг + профиль воронки в БД

Фаза 1 — config: BRAND «Кибершкола БАЗА», цены/тексты по ТЗ (приветствие,
прайс, интенсив), 8 ссылок-плейсхолдеров с UTM, триггеры (основные/лето).
Фаза 2 — database: JSON-профиль воронки (роль/возраст/игра/уровень/формат/
метки/…) + методы get/set/clear + add_metka. Живой флоу пока не затронут.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Kenik
2026-07-18 17:58:00 +03:00
parent ce2860aec9
commit f6a635cc2e
2 changed files with 105 additions and 1 deletions
+48 -1
View File
@@ -30,7 +30,7 @@ class DatabaseManager:
""")
# Migration checks for existing databases
for col in ["consent_1", "consent_2", "consent_3", "call_time", "vac_data"]:
for col in ["consent_1", "consent_2", "consent_3", "call_time", "vac_data", "profile"]:
try:
cursor.execute(f"ALTER TABLE user_states ADD COLUMN {col} TEXT")
except sqlite3.OperationalError:
@@ -475,6 +475,53 @@ class DatabaseManager:
)
conn.commit()
# --- Профиль воронки БАЗА (JSON в user_states.profile) ---
def get_profile(self, user_id: int) -> Dict[str, Any]:
"""Профиль пользователя из воронки (роль/возраст/игра/уровень/формат/метки/…)."""
with self._get_connection() as conn:
cursor = conn.cursor()
cursor.execute("SELECT profile FROM user_states WHERE user_id = ?", (user_id,))
row = cursor.fetchone()
if row and row[0]:
try:
return json.loads(row[0])
except (ValueError, TypeError):
return {}
return {}
def set_profile_field(self, user_id: int, key: str, value: Any):
"""Обновить одно поле профиля (не спрашиваем повторно то, что уже есть)."""
data = self.get_profile(user_id)
data[key] = value
with self._get_connection() as conn:
cursor = conn.cursor()
cursor.execute(
"INSERT INTO user_states (user_id, profile) VALUES (?, ?) "
"ON CONFLICT(user_id) DO UPDATE SET profile = excluded.profile, last_updated = CURRENT_TIMESTAMP",
(user_id, json.dumps(data, ensure_ascii=False))
)
conn.commit()
def add_metka(self, user_id: int, metka: str):
"""Добавить метку пользователю (хранится списком в профиле, без повторов)."""
data = self.get_profile(user_id)
metki = data.get("metki", [])
if metka not in metki:
metki.append(metka)
data["metki"] = metki
self.set_profile_field(user_id, "metki", metki)
def clear_profile(self, user_id: int):
"""Полностью очистить профиль воронки."""
with self._get_connection() as conn:
cursor = conn.cursor()
cursor.execute(
"INSERT INTO user_states (user_id, profile) VALUES (?, NULL) "
"ON CONFLICT(user_id) DO UPDATE SET profile = NULL, last_updated = CURRENT_TIMESTAMP",
(user_id,)
)
conn.commit()
# --- Вакансии (направления игроков / должности сотрудников) ---
def get_vacancy_options(self, track: str) -> list:
"""Активные опции для трека ('player'|'worker') как список (id, label)."""