Adding registration and pilot mode

This commit is contained in:
danilgryaznev 2025-09-27 22:38:59 +03:00
parent 1535453cb7
commit 4215c800ee
3 changed files with 54 additions and 17 deletions

View File

@ -51,10 +51,8 @@ cp .env.example .env
# при необходимости включите в .env подтверждение почты
# ALABUGA_REQUIRE_EMAIL_CONFIRMATION=true
# применяем миграции
alembic upgrade head
# создаём демо-данные (команда выполняется из корня репозитория)
# база поднимется сама: при старте приложения автоматически выполняется Alembic upgrade head.
# Для ручной подготовки можно вызвать команду ниже — она прогоняет миграции и добавляет демо-данные.
cd ..
python -m scripts.seed_data
cd backend

View File

@ -2,13 +2,20 @@
from __future__ import annotations
from pathlib import Path
from alembic import command
from alembic.config import Config
from alembic.script import ScriptDirectory
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from sqlalchemy import inspect, text
from app.api.routes import admin, auth, journal, missions, onboarding, store, users
from app.core.config import settings
from app.db.session import engine
from app.models.base import Base
ALEMBIC_CONFIG = Path(__file__).resolve().parents[1] / "alembic.ini"
app = FastAPI(title=settings.project_name)
@ -22,11 +29,49 @@ app.add_middleware(
)
def run_migrations() -> None:
"""Гарантируем, что база обновлена до последней схемы Alembic."""
config = Config(str(ALEMBIC_CONFIG))
config.set_main_option("sqlalchemy.url", str(settings.database_url))
inspector = inspect(engine)
script = ScriptDirectory.from_config(config)
head_revision = script.get_current_head()
tables = inspector.get_table_names()
current_revision: str | None = None
if "alembic_version" in tables:
with engine.begin() as conn:
row = conn.execute(text("SELECT version_num FROM alembic_version LIMIT 1")).fetchone()
current_revision = row[0] if row else None
if "alembic_version" not in tables or current_revision is None:
if tables:
# База создана через Base.metadata.create_all. Добавляем отсутствующие поля вручную
# и фиксируем версию как актуальную, чтобы последующие миграции применялись штатно.
user_columns = {col["name"] for col in inspector.get_columns("users")}
with engine.begin() as conn:
if "preferred_branch" not in user_columns:
conn.execute(text("ALTER TABLE users ADD COLUMN preferred_branch VARCHAR(160)"))
if "motivation" not in user_columns:
conn.execute(text("ALTER TABLE users ADD COLUMN motivation TEXT"))
conn.execute(text("CREATE TABLE IF NOT EXISTS alembic_version (version_num VARCHAR(32) NOT NULL)"))
conn.execute(text("DELETE FROM alembic_version"))
conn.execute(text("INSERT INTO alembic_version (version_num) VALUES (:rev)"), {"rev": head_revision})
return
# Таблиц ещё нет — создадим их миграциями.
command.upgrade(config, "head")
return
command.upgrade(config, "head")
@app.on_event("startup")
def on_startup() -> None:
"""Создаём таблицы, если миграции ещё не применены."""
"""Прогоняем миграции перед обработкой запросов."""
Base.metadata.create_all(bind=engine)
run_migrations()
app.include_router(auth.router)

View File

@ -13,7 +13,7 @@ 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, engine
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
@ -21,24 +21,18 @@ from app.models.rank import Rank, RankCompetencyRequirement, RankMissionRequirem
from app.models.onboarding import OnboardingSlide
from app.models.store import StoreItem
from app.models.user import Competency, CompetencyCategory, User, UserCompetency, UserRole
from app.main import run_migrations
DATA_SENTINEL = settings.sqlite_path.parent / ".seeded"
def ensure_database() -> None:
"""Создаём таблицы, если их ещё нет."""
from app.models.base import Base
Base.metadata.create_all(bind=engine)
def seed() -> None:
if DATA_SENTINEL.exists():
print("Database already seeded, skipping")
return
ensure_database()
# Перед наполнением БД убеждаемся, что применены все миграции.
run_migrations()
session: Session = SessionLocal()
try: