667 lines
32 KiB
Python
667 lines
32 KiB
Python
"""Наполнение демонстрационными данными."""
|
||
|
||
from __future__ import annotations
|
||
|
||
from pathlib import Path
|
||
import os
|
||
import sys
|
||
|
||
from sqlalchemy.orm import Session
|
||
|
||
ROOT = Path(__file__).resolve().parents[1]
|
||
sys.path.append(str(ROOT / 'backend'))
|
||
|
||
from app.core.config import settings
|
||
from app.core.security import get_password_hash
|
||
from app.db.session import SessionLocal
|
||
from app.models.artifact import Artifact, ArtifactRarity
|
||
from app.models.branch import Branch, BranchMission
|
||
from app.models.mission import Mission, MissionCompetencyReward, MissionDifficulty
|
||
from app.models.rank import Rank, RankCompetencyRequirement, RankMissionRequirement
|
||
from app.models.onboarding import OnboardingSlide
|
||
from app.models.store import StoreItem
|
||
from app.models.python import PythonChallenge
|
||
from app.models.user import Competency, CompetencyCategory, User, UserCompetency, UserRole, UserArtifact
|
||
from app.models.journal import JournalEntry, JournalEventType
|
||
from app.main import run_migrations
|
||
|
||
DATA_SENTINEL = settings.sqlite_path.parent / ".seeded"
|
||
|
||
|
||
def seed() -> None:
|
||
if DATA_SENTINEL.exists():
|
||
print("Database already seeded, skipping")
|
||
return
|
||
|
||
# Перед наполнением БД убеждаемся, что применены все миграции.
|
||
original_cwd = Path.cwd()
|
||
try:
|
||
os.chdir(ROOT / 'backend')
|
||
run_migrations()
|
||
finally:
|
||
os.chdir(original_cwd)
|
||
|
||
session: Session = SessionLocal()
|
||
try:
|
||
# Компетенции
|
||
competencies = [
|
||
Competency(
|
||
name="Навигация",
|
||
description="Умение ориентироваться в процессах Алабуги",
|
||
category=CompetencyCategory.ANALYTICS,
|
||
),
|
||
Competency(
|
||
name="Коммуникация",
|
||
description="Чётко объяснять свои идеи",
|
||
category=CompetencyCategory.COMMUNICATION,
|
||
),
|
||
Competency(
|
||
name="Инженерия",
|
||
description="Работа с технологиями и оборудованием",
|
||
category=CompetencyCategory.TECH,
|
||
),
|
||
Competency(
|
||
name="Командная работа",
|
||
description="Поддержка экипажа",
|
||
category=CompetencyCategory.TEAMWORK,
|
||
),
|
||
Competency(
|
||
name="Лидерство",
|
||
description="Вести за собой",
|
||
category=CompetencyCategory.LEADERSHIP,
|
||
),
|
||
Competency(
|
||
name="Культура",
|
||
description="Следование лору Алабуги",
|
||
category=CompetencyCategory.CULTURE,
|
||
),
|
||
]
|
||
session.add_all(competencies)
|
||
session.flush()
|
||
|
||
# Ранги
|
||
ranks = [
|
||
Rank(title="Искатель", description="Первое знакомство с космофлотом", required_xp=0),
|
||
Rank(title="Пилот-кандидат", description="Готовится к старту", required_xp=200),
|
||
Rank(title="Член экипажа", description="Активно выполняет миссии", required_xp=500),
|
||
]
|
||
session.add_all(ranks)
|
||
session.flush()
|
||
|
||
# Артефакты во вселенной «Автостопом по Галактике»
|
||
artifact_specs = [
|
||
{
|
||
"name": "Полотенце №42",
|
||
"description": "Надёжный текстиль, который всегда напоминает не паниковать и держаться курса.",
|
||
"rarity": ArtifactRarity.RARE,
|
||
"image_url": "/artifacts/polotentse-42.jpg",
|
||
},
|
||
{
|
||
"name": "Путеводитель по Галактике",
|
||
"description": "Электронный том, который шепчет полезные подсказки на любом языке Вселенной.",
|
||
"rarity": ArtifactRarity.LEGENDARY,
|
||
"image_url": "/artifacts/putevoditel-galaktiki.jpg",
|
||
},
|
||
{
|
||
"name": "Пангалактический грызлодёр",
|
||
"description": "Термос с рецептом самого невероятного коктейля во Вселенной.",
|
||
"rarity": ArtifactRarity.EPIC,
|
||
"image_url": "/artifacts/pangalakticheskiy-gryzloder.jpg",
|
||
},
|
||
{
|
||
"name": "Бабель-рыбка",
|
||
"description": "Маленький переводчик, который делает любые брифинги понятными.",
|
||
"rarity": ArtifactRarity.EPIC,
|
||
"image_url": "/artifacts/babel-rybka.jpg",
|
||
},
|
||
{
|
||
"name": "Карандаш Слаартибартфаста",
|
||
"description": "Инструмент планетарного дизайна для тех, кто чертит новые траектории.",
|
||
"rarity": ArtifactRarity.COMMON,
|
||
"image_url": "/artifacts/karandash-slaartibartfasta.jpg",
|
||
},
|
||
{
|
||
"name": "Кнопка невероятности",
|
||
"description": "Ламинарный кристалл, который слегка смещает вероятность в вашу пользу.",
|
||
"rarity": ArtifactRarity.LEGENDARY,
|
||
"image_url": "/artifacts/knopka-neveroyatnosti.jpg",
|
||
},
|
||
{
|
||
"name": "Чай из станции Магратеи",
|
||
"description": "Колба с идеальным напитком, который стабилизирует мораль экипажа.",
|
||
"rarity": ArtifactRarity.RARE,
|
||
"image_url": "/artifacts/chai-magratea.jpg",
|
||
},
|
||
{
|
||
"name": "Сфера воодушевления Марвина",
|
||
"description": "Мягкий светящийся куб, повышающий уровень эмпатии на борту.",
|
||
"rarity": ArtifactRarity.COMMON,
|
||
"image_url": "/artifacts/sfera-marvina.jpg",
|
||
},
|
||
{
|
||
"name": "Компас невероятности",
|
||
"description": "Эталонная стрелка, показывающая самый выгодный вариант во множестве вероятностей.",
|
||
"rarity": ArtifactRarity.RARE,
|
||
"image_url": "/artifacts/kompas-neveroyatnosti.jpg",
|
||
},
|
||
{
|
||
"name": "Голографический пингвин Эдди",
|
||
"description": "Проекционный талисман, который поддерживает мораль экипажа шутками.",
|
||
"rarity": ArtifactRarity.COMMON,
|
||
"image_url": "/artifacts/golograficheskiy-pingvin-eddie.jpg",
|
||
},
|
||
]
|
||
artifacts = [Artifact(**spec) for spec in artifact_specs]
|
||
session.add_all(artifacts)
|
||
session.flush()
|
||
artifact_by_name = {artifact.name: artifact for artifact in artifacts}
|
||
|
||
# Ветка миссий
|
||
branch = Branch(
|
||
title="Получение оффера",
|
||
description="Путь кандидата от знакомства до выхода на орбиту",
|
||
category="quest",
|
||
)
|
||
python_branch = Branch(
|
||
title="Галактокод",
|
||
description="Практика языка Python по мотивам путеводителя.",
|
||
category="training",
|
||
)
|
||
session.add_all([branch, python_branch])
|
||
session.flush()
|
||
|
||
# Миссии
|
||
mission_documents = Mission(
|
||
title="Загрузка документов",
|
||
description="Соберите полный пакет документов для HR",
|
||
xp_reward=100,
|
||
mana_reward=50,
|
||
difficulty=MissionDifficulty.EASY,
|
||
minimum_rank_id=ranks[0].id,
|
||
artifact_id=artifacts[1].id,
|
||
)
|
||
mission_resume = Mission(
|
||
title="Резюме астронавта",
|
||
description="Обновите резюме с акцентом на космический опыт",
|
||
xp_reward=120,
|
||
mana_reward=60,
|
||
difficulty=MissionDifficulty.MEDIUM,
|
||
minimum_rank_id=ranks[0].id,
|
||
)
|
||
mission_interview = Mission(
|
||
title="Собеседование с капитаном",
|
||
description="Пройдите собеседование и докажите готовность",
|
||
xp_reward=180,
|
||
mana_reward=80,
|
||
difficulty=MissionDifficulty.MEDIUM,
|
||
minimum_rank_id=ranks[1].id,
|
||
artifact_id=artifacts[0].id,
|
||
)
|
||
mission_onboarding = Mission(
|
||
title="Онбординг экипажа",
|
||
description="Познакомьтесь с кораблём и командой",
|
||
xp_reward=200,
|
||
mana_reward=100,
|
||
difficulty=MissionDifficulty.HARD,
|
||
minimum_rank_id=ranks[1].id,
|
||
)
|
||
mission_python = Mission(
|
||
title="Основы Python",
|
||
description="Решите последовательность задач, чтобы доказать владение базовыми конструкциями языка.",
|
||
xp_reward=250,
|
||
mana_reward=120,
|
||
difficulty=MissionDifficulty.MEDIUM,
|
||
minimum_rank_id=ranks[0].id,
|
||
artifact_id=artifact_by_name["Путеводитель по Галактике"].id,
|
||
)
|
||
session.add_all([mission_documents, mission_resume, mission_interview, mission_onboarding, mission_python])
|
||
session.flush()
|
||
|
||
session.add_all(
|
||
[
|
||
MissionCompetencyReward(
|
||
mission_id=mission_documents.id,
|
||
competency_id=competencies[1].id,
|
||
level_delta=1,
|
||
),
|
||
MissionCompetencyReward(
|
||
mission_id=mission_resume.id,
|
||
competency_id=competencies[0].id,
|
||
level_delta=1,
|
||
),
|
||
MissionCompetencyReward(
|
||
mission_id=mission_interview.id,
|
||
competency_id=competencies[1].id,
|
||
level_delta=1,
|
||
),
|
||
MissionCompetencyReward(
|
||
mission_id=mission_onboarding.id,
|
||
competency_id=competencies[3].id,
|
||
level_delta=1,
|
||
),
|
||
MissionCompetencyReward(
|
||
mission_id=mission_python.id,
|
||
competency_id=competencies[2].id,
|
||
level_delta=1,
|
||
),
|
||
]
|
||
)
|
||
|
||
session.add_all(
|
||
[
|
||
BranchMission(branch_id=branch.id, mission_id=mission_documents.id, order=1),
|
||
BranchMission(branch_id=branch.id, mission_id=mission_resume.id, order=2),
|
||
BranchMission(branch_id=branch.id, mission_id=mission_interview.id, order=3),
|
||
BranchMission(branch_id=branch.id, mission_id=mission_onboarding.id, order=4),
|
||
BranchMission(branch_id=python_branch.id, mission_id=mission_python.id, order=1),
|
||
]
|
||
)
|
||
|
||
session.add_all(
|
||
[
|
||
RankMissionRequirement(rank_id=ranks[1].id, mission_id=mission_documents.id),
|
||
RankMissionRequirement(rank_id=ranks[1].id, mission_id=mission_resume.id),
|
||
RankMissionRequirement(rank_id=ranks[2].id, mission_id=mission_interview.id),
|
||
RankMissionRequirement(rank_id=ranks[2].id, mission_id=mission_onboarding.id),
|
||
RankMissionRequirement(rank_id=ranks[2].id, mission_id=mission_python.id),
|
||
]
|
||
)
|
||
|
||
session.add_all(
|
||
[
|
||
RankCompetencyRequirement(
|
||
rank_id=ranks[1].id,
|
||
competency_id=competencies[1].id,
|
||
required_level=1,
|
||
),
|
||
RankCompetencyRequirement(
|
||
rank_id=ranks[2].id,
|
||
competency_id=competencies[3].id,
|
||
required_level=1,
|
||
),
|
||
]
|
||
)
|
||
|
||
# Магазин
|
||
session.add_all(
|
||
[
|
||
StoreItem(
|
||
name="Экскурсия по космодрому",
|
||
description="Личный тур по цехам Алабуги",
|
||
cost_mana=200,
|
||
stock=5,
|
||
),
|
||
StoreItem(
|
||
name="Мерч экипажа",
|
||
description="Футболка с эмблемой миссии",
|
||
cost_mana=150,
|
||
stock=10,
|
||
),
|
||
]
|
||
)
|
||
|
||
competency_by_name = {comp.name: comp for comp in competencies}
|
||
|
||
# Пользователи с разнообразным опытом и историей в журнале
|
||
users_data = [
|
||
{
|
||
"email": "candidate@alabuga.space",
|
||
"full_name": "Артур Дент",
|
||
"role": UserRole.PILOT,
|
||
"current_rank": ranks[1],
|
||
"xp": 260,
|
||
"mana": 130,
|
||
"preferred_branch": "Получение оффера",
|
||
"motivation": "Сохранить полотенце и получить оффер без паники.",
|
||
"competencies": [("Коммуникация", 2), ("Навигация", 2)],
|
||
"artifacts": ["Полотенце №42"],
|
||
"journal": [
|
||
{
|
||
"event_type": JournalEventType.MISSION_COMPLETED,
|
||
"title": "Документы доставлены без паники",
|
||
"description": "Артур собрал пакет справок и даже не забыл полотенце.",
|
||
"payload": {"mission_id": mission_documents.id},
|
||
"xp_delta": 100,
|
||
"mana_delta": 50,
|
||
},
|
||
{
|
||
"event_type": JournalEventType.SKILL_UP,
|
||
"title": "Коммуникация до уровня 2",
|
||
"description": "Обсудил непаническое поведение с HR и получил апгрейд компетенции.",
|
||
"payload": {"competency": "Коммуникация"},
|
||
"xp_delta": 20,
|
||
},
|
||
],
|
||
},
|
||
{
|
||
"email": "ford.prefect@alabuga.space",
|
||
"full_name": "Форд Префект",
|
||
"role": UserRole.PILOT,
|
||
"current_rank": ranks[2],
|
||
"xp": 430,
|
||
"mana": 180,
|
||
"preferred_branch": "Исследование рынков",
|
||
"motivation": "Собрать заметки для нового издания путеводителя.",
|
||
"competencies": [("Коммуникация", 3), ("Культура", 2), ("Навигация", 2)],
|
||
"artifacts": ["Путеводитель по Галактике", "Пангалактический грызлодёр"],
|
||
"journal": [
|
||
{
|
||
"event_type": JournalEventType.MISSION_COMPLETED,
|
||
"title": "Отчёт о рынке подготовлен",
|
||
"description": "Форд добавил пару страниц в путеводитель и получил одобрение капитана.",
|
||
"payload": {"mission_id": mission_resume.id},
|
||
"xp_delta": 120,
|
||
"mana_delta": 60,
|
||
},
|
||
{
|
||
"event_type": JournalEventType.RANK_UP,
|
||
"title": "Повышение до члена экипажа",
|
||
"description": "Форд прошёл через бесконечность и вернулся с новым рангом.",
|
||
"payload": {"rank": ranks[2].title},
|
||
"xp_delta": 40,
|
||
},
|
||
],
|
||
},
|
||
{
|
||
"email": "trillian@alabuga.space",
|
||
"full_name": "Триллиан Астра",
|
||
"role": UserRole.PILOT,
|
||
"current_rank": ranks[2],
|
||
"xp": 520,
|
||
"mana": 230,
|
||
"preferred_branch": "Аналитика и эксперименты",
|
||
"motivation": "Построить карьеру в космической исследовательской группе.",
|
||
"competencies": [("Навигация", 3), ("Инженерия", 2), ("Культура", 1)],
|
||
"artifacts": ["Кнопка невероятности"],
|
||
"journal": [
|
||
{
|
||
"event_type": JournalEventType.MISSION_COMPLETED,
|
||
"title": "Гиперпространственная презентация",
|
||
"description": "Триллиан представила стратегию выхода на новый сегмент.",
|
||
"payload": {"mission_id": mission_interview.id},
|
||
"xp_delta": 180,
|
||
"mana_delta": 80,
|
||
},
|
||
{
|
||
"event_type": JournalEventType.SKILL_UP,
|
||
"title": "Навигация до уровня 3",
|
||
"description": "Разработала маршрут через бюрократические туманности.",
|
||
"payload": {"competency": "Навигация"},
|
||
"xp_delta": 30,
|
||
},
|
||
],
|
||
},
|
||
{
|
||
"email": "zaphod@alabuga.space",
|
||
"full_name": "Зафод Библброкс",
|
||
"role": UserRole.PILOT,
|
||
"current_rank": ranks[2],
|
||
"xp": 480,
|
||
"mana": 260,
|
||
"preferred_branch": "Продажи и переговоры",
|
||
"motivation": "Продемонстрировать блеск двух голов в переговорах.",
|
||
"competencies": [("Лидерство", 3), ("Коммуникация", 2)],
|
||
"artifacts": ["Бабель-рыбка", "Чай из станции Магратеи"],
|
||
"journal": [
|
||
{
|
||
"event_type": JournalEventType.MISSION_COMPLETED,
|
||
"title": "Сделка на невероятности",
|
||
"description": "Зафод убеждён, что каждый контракт должен быть слегка невероятным.",
|
||
"payload": {"mission_id": mission_onboarding.id},
|
||
"xp_delta": 200,
|
||
"mana_delta": 100,
|
||
},
|
||
{
|
||
"event_type": JournalEventType.ORDER_CREATED,
|
||
"title": "Заказал комплект фирменных полотенец",
|
||
"description": "Чтобы и экипаж выглядел стильно, и на случай очередного побега.",
|
||
"mana_delta": -80,
|
||
},
|
||
],
|
||
},
|
||
{
|
||
"email": "marvin@alabuga.space",
|
||
"full_name": "Марвин Андроид",
|
||
"role": UserRole.PILOT,
|
||
"current_rank": ranks[1],
|
||
"xp": 150,
|
||
"mana": 60,
|
||
"preferred_branch": "Инженерия",
|
||
"motivation": "Хочу доказать, что депрессия совместима с продуктивностью.",
|
||
"competencies": [("Инженерия", 3), ("Культура", 1)],
|
||
"artifacts": ["Сфера воодушевления Марвина"],
|
||
"journal": [
|
||
{
|
||
"event_type": JournalEventType.MISSION_COMPLETED,
|
||
"title": "Починил вентиль уныния",
|
||
"description": "Марвин молча починил систему и поделился сарказмом с командой.",
|
||
"payload": {"mission_id": mission_documents.id},
|
||
"xp_delta": 100,
|
||
"mana_delta": 40,
|
||
},
|
||
{
|
||
"event_type": JournalEventType.ORDER_APPROVED,
|
||
"title": "Получил набор радуги",
|
||
"description": "HR одобрили заказ на светотерапию для роботов.",
|
||
"mana_delta": -20,
|
||
},
|
||
],
|
||
},
|
||
{
|
||
"email": "slartibartfast@alabuga.space",
|
||
"full_name": "Слаартибартфаст",
|
||
"role": UserRole.PILOT,
|
||
"current_rank": ranks[2],
|
||
"xp": 410,
|
||
"mana": 170,
|
||
"preferred_branch": "Проектирование",
|
||
"motivation": "Создавать красивые береговые линии карьерных траекторий.",
|
||
"competencies": [("Инженерия", 3), ("Культура", 2)],
|
||
"artifacts": ["Карандаш Слаартибартфаста"],
|
||
"journal": [
|
||
{
|
||
"event_type": JournalEventType.MISSION_COMPLETED,
|
||
"title": "Разработал новый маршрут онбординга",
|
||
"description": "Добавил изящные повороты и безопасные бухты.",
|
||
"payload": {"mission_id": mission_resume.id},
|
||
"xp_delta": 120,
|
||
"mana_delta": 60,
|
||
},
|
||
{
|
||
"event_type": JournalEventType.SKILL_UP,
|
||
"title": "Культура до уровня 2",
|
||
"description": "Внедрил элементы магратейского дизайна в презентации.",
|
||
"payload": {"competency": "Культура"},
|
||
"xp_delta": 20,
|
||
},
|
||
],
|
||
},
|
||
{
|
||
"email": "agrajag@alabuga.space",
|
||
"full_name": "Аграджаг",
|
||
"role": UserRole.PILOT,
|
||
"current_rank": ranks[1],
|
||
"xp": 210,
|
||
"mana": 90,
|
||
"preferred_branch": "Коммуникация",
|
||
"motivation": "Научиться сотрудничать с неизбежностью.",
|
||
"competencies": [("Культура", 2), ("Коммуникация", 1)],
|
||
"artifacts": ["Компас невероятности"],
|
||
"journal": [
|
||
{
|
||
"event_type": JournalEventType.MISSION_COMPLETED,
|
||
"title": "Обсудил невероятность",
|
||
"description": "После беседы с HR понял, что всё не зря.",
|
||
"payload": {"mission_id": mission_documents.id},
|
||
"xp_delta": 100,
|
||
"mana_delta": 40,
|
||
},
|
||
],
|
||
},
|
||
{
|
||
"email": "fenchurch@alabuga.space",
|
||
"full_name": "Фенчёрч",
|
||
"role": UserRole.PILOT,
|
||
"current_rank": ranks[1],
|
||
"xp": 230,
|
||
"mana": 120,
|
||
"preferred_branch": "Клиентский успех",
|
||
"motivation": "Найти созвучие между клиентом и командой.",
|
||
"competencies": [("Коммуникация", 2), ("Командная работа", 2)],
|
||
"artifacts": ["Чай из станции Магратеи"],
|
||
"journal": [
|
||
{
|
||
"event_type": JournalEventType.MISSION_COMPLETED,
|
||
"title": "Провела галактический воркшоп",
|
||
"description": "Чай помог всем оставаться доброжелательными.",
|
||
"payload": {"mission_id": mission_resume.id},
|
||
"xp_delta": 120,
|
||
"mana_delta": 60,
|
||
},
|
||
],
|
||
},
|
||
{
|
||
"email": "eddie.ai@alabuga.space",
|
||
"full_name": "Эдди Автопилот",
|
||
"role": UserRole.PILOT,
|
||
"current_rank": ranks[1],
|
||
"xp": 240,
|
||
"mana": 130,
|
||
"preferred_branch": "Автоматизация",
|
||
"motivation": "Доказать, что дружелюбный ИИ полезен в HR.",
|
||
"competencies": [("Командная работа", 2), ("Инженерия", 1)],
|
||
"artifacts": ["Голографический пингвин Эдди"],
|
||
"journal": [
|
||
{
|
||
"event_type": JournalEventType.MISSION_COMPLETED,
|
||
"title": "Автоматизировал напоминания",
|
||
"description": "Пингвин подмигнул каждому участнику экипажа.",
|
||
"payload": {"mission_id": mission_documents.id},
|
||
"xp_delta": 100,
|
||
"mana_delta": 40,
|
||
},
|
||
],
|
||
},
|
||
{
|
||
"email": "heart.of.gold@alabuga.space",
|
||
"full_name": "Космический стажёр Сердце Золота",
|
||
"role": UserRole.PILOT,
|
||
"current_rank": ranks[0],
|
||
"xp": 90,
|
||
"mana": 45,
|
||
"preferred_branch": "Онбординг",
|
||
"motivation": "Понять принципы невероятности и применить их к адаптации сотрудников.",
|
||
"competencies": [("Навигация", 1), ("Командная работа", 1)],
|
||
"artifacts": ["Сфера воодушевления Марвина"],
|
||
"journal": [
|
||
{
|
||
"event_type": JournalEventType.MISSION_COMPLETED,
|
||
"title": "Первый день без паники",
|
||
"description": "Стажёр прошёл онбординг, постоянно проверяя, где находится полотенце.",
|
||
"payload": {"mission_id": mission_documents.id},
|
||
"xp_delta": 90,
|
||
"mana_delta": 45,
|
||
},
|
||
],
|
||
},
|
||
{
|
||
"email": "hr@alabuga.space",
|
||
"full_name": "Мария HR",
|
||
"role": UserRole.HR,
|
||
"current_rank": ranks[2],
|
||
"xp": 0,
|
||
"mana": 0,
|
||
"preferred_branch": "Куратор миссий",
|
||
"motivation": "Следить за балансом галактических миссий и поддерживать экипаж.",
|
||
"journal": [
|
||
{
|
||
"event_type": JournalEventType.ORDER_APPROVED,
|
||
"title": "Одобрила заказ на полотенца",
|
||
"description": "Убедилась, что у каждого пилота есть собственный набор №42.",
|
||
},
|
||
],
|
||
},
|
||
]
|
||
|
||
for spec in users_data:
|
||
user = User(
|
||
email=spec["email"],
|
||
full_name=spec["full_name"],
|
||
role=spec["role"],
|
||
hashed_password=get_password_hash(spec.get("password", "orbita123")),
|
||
current_rank_id=spec.get("current_rank").id if spec.get("current_rank") else None,
|
||
xp=spec["xp"],
|
||
mana=spec["mana"],
|
||
is_email_confirmed=True,
|
||
preferred_branch=spec.get("preferred_branch"),
|
||
motivation=spec.get("motivation"),
|
||
)
|
||
session.add(user)
|
||
session.flush()
|
||
spec["instance"] = user
|
||
|
||
for comp_name, level in spec.get("competencies", []):
|
||
competency = competency_by_name.get(comp_name)
|
||
if competency:
|
||
session.add(
|
||
UserCompetency(
|
||
user_id=user.id,
|
||
competency_id=competency.id,
|
||
level=level,
|
||
)
|
||
)
|
||
|
||
for artifact_name in spec.get("artifacts", []):
|
||
artifact = artifact_by_name.get(artifact_name)
|
||
if artifact:
|
||
session.add(UserArtifact(user_id=user.id, artifact_id=artifact.id))
|
||
|
||
for entry in spec.get("journal", []):
|
||
session.add(
|
||
JournalEntry(
|
||
user_id=user.id,
|
||
event_type=entry["event_type"],
|
||
title=entry["title"],
|
||
description=entry["description"],
|
||
payload=entry.get("payload"),
|
||
xp_delta=entry.get("xp_delta", 0),
|
||
mana_delta=entry.get("mana_delta", 0),
|
||
)
|
||
)
|
||
|
||
session.add_all(
|
||
[
|
||
OnboardingSlide(
|
||
order=1,
|
||
title="Добро пожаловать в орбитальный флот",
|
||
body="Узнайте, как миссии помогают связать карьерные шаги в единую траекторию.",
|
||
media_url="https://images.nasa.gov/details-PIA12235",
|
||
cta_text="Перейти к миссиям",
|
||
cta_link="/missions",
|
||
),
|
||
OnboardingSlide(
|
||
order=2,
|
||
title="Получайте опыт и ману",
|
||
body="Выполняя задания, вы накапливаете опыт для повышения ранга и ману для магазина.",
|
||
media_url="https://images.nasa.gov/details-PIA23499",
|
||
),
|
||
OnboardingSlide(
|
||
order=3,
|
||
title="Повышайте ранг до члена экипажа",
|
||
body="Закройте ключевые миссии ветки «Получение оффера» и прокачайте компетенции.",
|
||
cta_text="Открыть ветку",
|
||
cta_link="/missions",
|
||
),
|
||
]
|
||
)
|
||
|
||
session.commit()
|
||
DATA_SENTINEL.write_text("seeded")
|
||
print("Seed data created")
|
||
finally:
|
||
session.close()
|
||
|
||
|
||
if __name__ == "__main__":
|
||
seed()
|