sto-k-odnomu/backend/prisma/seed.ts
2026-01-10 02:43:06 +03:00

422 lines
13 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { PrismaClient } from '@prisma/client';
import * as fs from 'fs';
import * as path from 'path';
import { randomUUID } from 'crypto';
const prisma = new PrismaClient();
// Helper function: Add UUIDs to questions and answers if they don't have them
// This is a copy from src/utils/question-utils.ts to avoid dependency on src in production
interface Answer {
id?: string;
text: string;
points: number;
}
interface Question {
id?: string;
text?: string;
question?: string;
answers: Answer[];
}
function ensureQuestionIds(questions: Question[]): Question[] {
return questions.map((question) => {
const questionId = question.id || randomUUID();
const questionText = question.text || question.question || '';
const answersWithIds = question.answers.map((answer) => ({
...answer,
id: answer.id || randomUUID(),
}));
return {
...question,
id: questionId,
text: questionText,
question: questionText, // Keep both fields for compatibility
answers: answersWithIds,
};
});
}
async function main() {
console.log('Starting seed...');
// Create demo user
const demoUser = await prisma.user.upsert({
where: { email: 'demo@100k1.ru' },
update: {},
create: {
email: 'demo@100k1.ru',
name: 'Демо пользователь',
},
});
console.log('Demo user created:', demoUser);
// Demo questions data
const demoQuestions = [
{
text: 'Что дед мороз делает летом?',
answers: [
{ text: 'Отдыхает', points: 100 },
{ text: 'Готовит подарки', points: 80 },
{ text: 'Спит', points: 60 },
{ text: 'Путешествует', points: 40 },
{ text: 'Загорает', points: 20 },
{ text: 'Работает', points: 10 },
],
},
{
text: 'Что намазывают на хлеб?',
answers: [
{ text: 'Масло', points: 100 },
{ text: 'Икру', points: 80 },
{ text: 'Варенье', points: 60 },
{ text: 'Паштет', points: 40 },
{ text: 'Майонез', points: 20 },
{ text: 'Горчицу', points: 10 },
],
},
{
text: 'Кто работает в новый год?',
answers: [
{ text: 'Дед Мороз', points: 100 },
{ text: 'Снегурочка', points: 80 },
{ text: 'Врач', points: 60 },
{ text: 'Полицейский', points: 40 },
{ text: 'Таксист', points: 20 },
{ text: 'Продавец', points: 10 },
],
},
{
text: 'Почему лошадь не курит?',
answers: [
{ text: 'Боится умереть', points: 100 },
{ text: 'Неудобно (копыта мешают)', points: 80 },
{ text: 'Не хочет', points: 60 },
{ text: 'Не продают', points: 40 },
],
},
{
text: 'Какая самая "лошадиная" фамилия?',
answers: [
{ text: 'Конев', points: 100 },
{ text: 'Жеребцов', points: 80 },
{ text: 'Кобылин', points: 60 },
{ text: 'Табунов', points: 40 },
{ text: 'Лошадкин', points: 20 },
],
},
{
text: 'Что носят на голове?',
answers: [
{ text: 'Шапка', points: 100 },
{ text: 'Шляпа', points: 80 },
{ text: 'Кепка', points: 60 },
{ text: 'Корона', points: 40 },
{ text: 'Платок', points: 20 },
{ text: 'Панама', points: 10 },
],
},
{
text: 'Что можно найти в холодильнике?',
answers: [
{ text: 'Еда', points: 100 },
{ text: 'Молоко', points: 80 },
{ text: 'Колбаса', points: 60 },
{ text: 'Масло', points: 40 },
{ text: 'Лёд', points: 20 },
{ text: 'Свет', points: 10 },
],
},
{
text: 'Где можно встретить новый год?',
answers: [
{ text: 'Дома', points: 100 },
{ text: 'На улице', points: 80 },
{ text: 'В кафе', points: 60 },
{ text: 'У друзей', points: 40 },
{ text: 'На работе', points: 20 },
{ text: 'В самолёте', points: 10 },
],
},
];
// Create question pack
const demoQuestionsWithIds = ensureQuestionIds(demoQuestions);
const questionPack = await prisma.questionPack.upsert({
where: { id: 'demo-pack-1' },
update: {},
create: {
id: 'demo-pack-1',
name: 'Демо пак вопросов',
description: 'Базовый набор вопросов для игры "100 к 1"',
category: 'Общие',
isPublic: true,
createdBy: demoUser.id,
questions: demoQuestionsWithIds as any,
questionCount: demoQuestionsWithIds.length,
rating: 5.0,
},
});
console.log('Question pack created:', questionPack);
// Create family questions pack
const familyQuestions = [
{
text: 'Что мама говорит чаще всего?',
answers: [
{ text: 'Убери', points: 100 },
{ text: 'Поешь', points: 80 },
{ text: 'Спать', points: 60 },
{ text: 'Я люблю тебя', points: 40 },
{ text: 'Делай уроки', points: 20 },
],
},
{
text: 'Что папа делает на выходных?',
answers: [
{ text: 'Отдыхает', points: 100 },
{ text: 'Чинит что-то', points: 80 },
{ text: 'Смотрит телевизор', points: 60 },
{ text: 'Спит', points: 40 },
{ text: 'Работает', points: 20 },
],
},
{
text: 'Что бабушка любит дарить внукам?',
answers: [
{ text: 'Деньги', points: 100 },
{ text: 'Еду', points: 80 },
{ text: 'Одежду', points: 60 },
{ text: 'Игрушки', points: 40 },
{ text: 'Конфеты', points: 20 },
],
},
];
const familyQuestionsWithIds = ensureQuestionIds(familyQuestions);
const familyPack = await prisma.questionPack.upsert({
where: { id: 'family-pack-1' },
update: {},
create: {
id: 'family-pack-1',
name: 'Семейные вопросы',
description: 'Вопросы для семейной игры',
category: 'Семья',
isPublic: true,
createdBy: demoUser.id,
questions: familyQuestionsWithIds as any,
questionCount: familyQuestionsWithIds.length,
rating: 4.8,
},
});
console.log('Family pack created:', familyPack);
// Read default questions from JSON file
// questions.json is in the project root, one level up from backend/
const questionsJsonPath = path.resolve(
process.cwd(),
'../questions.json',
);
const questionsJson = JSON.parse(
fs.readFileSync(questionsJsonPath, 'utf-8'),
);
// Transform questions: remove id field
const defaultQuestions = questionsJson.map((q: any) => ({
text: q.text,
answers: q.answers,
}));
// Add UUID to questions
const defaultQuestionsWithIds = ensureQuestionIds(defaultQuestions);
// Create default question pack
const defaultPack = await prisma.questionPack.upsert({
where: { id: 'default-pack-1' },
update: {},
create: {
id: 'default-pack-1',
name: 'Новогодние вопросы',
description: 'Новогодние вопросы',
category: 'Новый год',
isPublic: true,
createdBy: demoUser.id,
questions: defaultQuestionsWithIds as any,
questionCount: defaultQuestionsWithIds.length,
rating: 5.0,
},
});
console.log('Default pack created:', defaultPack);
// Create default themes
const defaultThemes = [
{
id: 'new-year',
name: 'Новый год',
icon: '🎄',
description: 'Праздничная новогодняя тема с золотым свечением',
isPublic: true,
colors: {
bgPrimary: 'linear-gradient(135deg, #1a4d7a 0%, #2b0d4f 50%, #4a1942 100%)',
bgOverlay: 'rgba(10, 10, 30, 0.4)',
bgCard: 'rgba(255, 255, 255, 0.12)',
bgCardHover: 'rgba(255, 255, 255, 0.18)',
textPrimary: '#ffffff',
textSecondary: 'rgba(255, 255, 255, 0.95)',
textGlow: 'rgba(255, 215, 0, 1)',
accentPrimary: '#ffd700',
accentSecondary: '#ff6b6b',
accentSuccess: '#4ecdc4',
borderColor: 'rgba(255, 215, 0, 0.4)',
borderGlow: 'rgba(255, 215, 0, 0.6)',
},
settings: {
shadowSm: '0 2px 15px rgba(255, 215, 0, 0.2)',
shadowMd: '0 4px 20px rgba(255, 215, 0, 0.3)',
shadowLg: '0 8px 35px rgba(255, 215, 0, 0.4)',
blurAmount: '10px',
borderRadiusSm: '12px',
borderRadiusMd: '15px',
borderRadiusLg: '20px',
animationSpeed: '0.3s',
},
},
{
id: 'family',
name: 'Семейная',
icon: '🏠',
description: 'Светлая и уютная тема для семейной игры',
isPublic: true,
colors: {
bgPrimary: 'linear-gradient(135deg, #56ccf2 0%, #2f80ed 50%, #b2fefa 100%)',
bgOverlay: 'rgba(255, 255, 255, 0.1)',
bgCard: 'rgba(255, 255, 255, 0.25)',
bgCardHover: 'rgba(255, 255, 255, 0.35)',
textPrimary: '#2d3748',
textSecondary: '#4a5568',
textGlow: 'rgba(47, 128, 237, 0.8)',
accentPrimary: '#2f80ed',
accentSecondary: '#eb5757',
accentSuccess: '#27ae60',
borderColor: 'rgba(47, 128, 237, 0.3)',
borderGlow: 'rgba(47, 128, 237, 0.5)',
},
settings: {
shadowSm: '0 2px 10px rgba(47, 128, 237, 0.15)',
shadowMd: '0 4px 15px rgba(47, 128, 237, 0.2)',
shadowLg: '0 8px 30px rgba(47, 128, 237, 0.25)',
blurAmount: '10px',
borderRadiusSm: '12px',
borderRadiusMd: '15px',
borderRadiusLg: '20px',
animationSpeed: '0.3s',
},
},
{
id: 'party',
name: 'Вечеринка',
icon: '🎉',
description: 'Яркая энергичная тема для шумных компаний',
isPublic: true,
colors: {
bgPrimary: 'linear-gradient(135deg, #f093fb 0%, #f5576c 50%, #4facfe 100%)',
bgOverlay: 'rgba(0, 0, 0, 0.2)',
bgCard: 'rgba(255, 255, 255, 0.15)',
bgCardHover: 'rgba(255, 255, 255, 0.25)',
textPrimary: '#ffffff',
textSecondary: 'rgba(255, 255, 255, 0.95)',
textGlow: 'rgba(255, 87, 108, 1)',
accentPrimary: '#f5576c',
accentSecondary: '#f093fb',
accentSuccess: '#4facfe',
borderColor: 'rgba(255, 87, 108, 0.5)',
borderGlow: 'rgba(255, 87, 108, 0.7)',
},
settings: {
shadowSm: '0 2px 15px rgba(245, 87, 108, 0.3)',
shadowMd: '0 4px 20px rgba(245, 87, 108, 0.4)',
shadowLg: '0 8px 35px rgba(245, 87, 108, 0.5)',
blurAmount: '10px',
borderRadiusSm: '12px',
borderRadiusMd: '15px',
borderRadiusLg: '20px',
animationSpeed: '0.2s',
},
},
{
id: 'dark',
name: 'Темная',
icon: '🌙',
description: 'Контрастная тема для ТВ и проектора',
isPublic: true,
colors: {
bgPrimary: 'linear-gradient(135deg, #0f0f0f 0%, #1a1a1a 100%)',
bgOverlay: 'rgba(0, 0, 0, 0.7)',
bgCard: 'rgba(40, 40, 40, 0.8)',
bgCardHover: 'rgba(60, 60, 60, 0.9)',
textPrimary: '#e0e0e0',
textSecondary: '#b0b0b0',
textGlow: 'rgba(100, 255, 218, 0.8)',
accentPrimary: '#64ffda',
accentSecondary: '#ff5370',
accentSuccess: '#c3e88d',
borderColor: 'rgba(100, 255, 218, 0.3)',
borderGlow: 'rgba(100, 255, 218, 0.5)',
},
settings: {
shadowSm: '0 2px 10px rgba(0, 0, 0, 0.5)',
shadowMd: '0 4px 15px rgba(0, 0, 0, 0.6)',
shadowLg: '0 8px 30px rgba(0, 0, 0, 0.7)',
blurAmount: '5px',
borderRadiusSm: '12px',
borderRadiusMd: '15px',
borderRadiusLg: '20px',
animationSpeed: '0.3s',
},
},
];
for (const theme of defaultThemes) {
await prisma.theme.upsert({
where: { id: theme.id },
update: {
name: theme.name,
icon: theme.icon,
description: theme.description,
isPublic: theme.isPublic,
colors: theme.colors as any,
settings: theme.settings as any,
},
create: {
id: theme.id,
name: theme.name,
icon: theme.icon,
description: theme.description,
isPublic: theme.isPublic,
createdBy: demoUser.id,
colors: theme.colors as any,
settings: theme.settings as any,
},
});
console.log(`Theme "${theme.name}" created/updated`);
}
console.log('Seed completed successfully!');
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error('Seed error:', e);
await prisma.$disconnect();
process.exit(1);
});