121 lines
4.5 KiB
Python
121 lines
4.5 KiB
Python
from peewee import *
|
||
from flask_login import UserMixin
|
||
import os
|
||
import datetime
|
||
import uuid
|
||
|
||
USE_SQLITE = os.environ.get("USE_SQLITE") == "1"
|
||
|
||
if USE_SQLITE:
|
||
db = SqliteDatabase(os.environ.get("SQLITE_PATH", "survey.db"))
|
||
else:
|
||
db = PostgresqlDatabase(
|
||
os.environ.get("POSTGRES_DB", "survey"),
|
||
user=os.environ.get("POSTGRES_USER", "servey"),
|
||
password=os.environ.get("POSTGRES_PASSWORD", "utOgbZ09servey"),
|
||
host=os.environ.get("POSTGRES_HOST", "db"),
|
||
port=int(os.environ.get("POSTGRES_PORT", 5432))
|
||
)
|
||
|
||
class BaseModel(Model):
|
||
class Meta:
|
||
database = db
|
||
|
||
class User(BaseModel, UserMixin):
|
||
username = CharField(unique=True)
|
||
email = CharField(unique=True)
|
||
password_hash = CharField()
|
||
full_name = CharField(null=True)
|
||
is_admin = BooleanField(default=False)
|
||
|
||
def get_id(self):
|
||
return str(self.id)
|
||
|
||
@property
|
||
def is_active(self):
|
||
return True # ✅ теперь Flask-Login доволен
|
||
|
||
class SurveyType(BaseModel):
|
||
name = CharField(unique=True)
|
||
|
||
class Product(BaseModel):
|
||
name = CharField()
|
||
survey_type = ForeignKeyField(SurveyType, backref='products', on_delete='CASCADE')
|
||
|
||
class Feature(BaseModel):
|
||
question_text = TextField()
|
||
product = ForeignKeyField(Product, backref='features', on_delete='CASCADE')
|
||
|
||
class Platform(BaseModel):
|
||
name = CharField(unique=True)
|
||
survey_type = ForeignKeyField(SurveyType, backref='platforms', on_delete='CASCADE')
|
||
|
||
class PlatformFeature(BaseModel):
|
||
platform = ForeignKeyField(Platform, backref='features', on_delete='CASCADE')
|
||
feature = ForeignKeyField(Feature, backref='platforms', on_delete='CASCADE')
|
||
supported = BooleanField(default=True)
|
||
|
||
# 🔹 Опросы, созданные пользователями
|
||
class UserSurvey(BaseModel):
|
||
user = ForeignKeyField(User, backref='surveys', on_delete='CASCADE')
|
||
survey_type = ForeignKeyField(SurveyType, on_delete='CASCADE')
|
||
name = CharField()
|
||
created_at = DateTimeField(default=datetime.datetime.now)
|
||
|
||
# 🔹 Отправленные приглашения
|
||
class SurveyInvite(BaseModel):
|
||
survey = ForeignKeyField(UserSurvey, backref='invites', on_delete='CASCADE')
|
||
recipient_email = CharField()
|
||
uuid = UUIDField(default=uuid.uuid4, unique=True)
|
||
show_result = BooleanField(default=False)
|
||
ask_full_name = BooleanField(default=False)
|
||
ask_phone = BooleanField(default=False)
|
||
ask_organization = BooleanField(default=False)
|
||
sent_at = DateTimeField(default=datetime.datetime.now)
|
||
responded = BooleanField(default=False)
|
||
|
||
# 🔹 Результаты прохождения опроса
|
||
class SurveyResult(BaseModel):
|
||
invite = ForeignKeyField(SurveyInvite, backref='result')
|
||
full_name = CharField(null=True)
|
||
phone = CharField(null=True)
|
||
organization = CharField(null=True)
|
||
answers = TextField(null=True) # JSON строка ответов
|
||
platform_scores = TextField(null=True) # JSON: { "Platform1": 80, ... }
|
||
unsupported = TextField(null=True) # JSON: { "Platform1": [q1, q2], ... }
|
||
submitted_at = DateTimeField(default=datetime.datetime.now, null=False)
|
||
comment = TextField(null=True) # ← вот это добавляем
|
||
|
||
# Можно добавить поле для процента или JSON с ответами, если нужно
|
||
|
||
def initialize_db():
|
||
"""Инициализация БД с автоматическим фолбэком на SQLite.
|
||
|
||
Логика:
|
||
- Если установлен USE_SQLITE=1, используем SQLite.
|
||
- Иначе пытаемся подключиться к Postgres; при ошибке — переключаемся на SQLite.
|
||
"""
|
||
global db
|
||
|
||
try:
|
||
db.connect()
|
||
except Exception as exc:
|
||
# Если Postgres недоступен и режим SQLite не принудительный — делаем фолбэк
|
||
if not USE_SQLITE:
|
||
sqlite_db = SqliteDatabase(os.environ.get("SQLITE_PATH", "survey.db"))
|
||
# Перепривязываем модели к SQLite
|
||
sqlite_db.bind([
|
||
User, SurveyType, Product, Feature, Platform, PlatformFeature,
|
||
UserSurvey, SurveyInvite, SurveyResult
|
||
], bind_refs=False, bind_backrefs=False)
|
||
db = sqlite_db
|
||
db.connect()
|
||
else:
|
||
raise
|
||
|
||
db.create_tables([
|
||
User, SurveyType, Product, Feature, Platform, PlatformFeature,
|
||
UserSurvey, SurveyInvite, SurveyResult
|
||
], safe=True)
|
||
db.close()
|