Skip to main content

Database Workflow

Comprehensive guide по работе с PostgreSQL и Prisma в goLoot.

TL;DR для быстрого старта
# Изменил schema.prisma → создать миграцию
npx prisma migrate dev --name add_new_field

# Применить миграции на staging/prod
bash scripts/db/prisma-sync.sh deploy

# Сбросить dev БД
pnpm db:reset

1. Quick Reference

Команды по задачам

ЗадачаКомандаОкружение
Изменил schema.prismanpx prisma migrate dev --name XDev
Применить миграцииbash scripts/db/prisma-sync.sh deployStaging/Prod
Сбросить БДpnpm db:resetDev only
Посмотреть данныеpnpm db:studioAny
Запросить БДbash scripts/db/db-query.sh dev "SELECT..."Any
Найти модель в schemaОткрыть backend/prisma/SCHEMA_GUIDE.mdAny

Скрипты проекта

СкриптНазначение
scripts/db/prisma-sync.shУниверсальный скрипт для миграций
scripts/db/reset-db.shПолный сброс БД с автодетекцией workflow
scripts/db/db-query.shRead-only запросы с маскировкой данных
scripts/db/prisma-info.shПоказать текущее окружение БД

2. Prisma Workflows

Migration-based (текущий) ✅

Когда используется: goLoot сейчас (после baseline миграции)

Принцип: Все изменения схемы = файлы миграций в git

# Development
npx prisma migrate dev --name add_field

# Production
npx prisma migrate deploy

Преимущества:

  • ✅ История изменений в git
  • ✅ Безопасный rollback (git revert)
  • ✅ Team sync автоматически
  • ✅ Production-ready

Недостатки:

  • ⏱️ Медленнее на ~5 секунд
  • 📁 Больше файлов в git

Push-based (legacy)

Когда использовался: goLoot раньше (до миграции)

Принцип: Прямая синхронизация schema.prisma → БД

npx prisma db push

Преимущества:

  • ⚡ Быстро
  • 📁 Меньше файлов

Недостатки:

  • ❌ Нет истории изменений
  • ❌ Невозможен rollback
  • ❌ Schema drift между окружениями
  • ⚠️ Может потерять данные (drop columns)
goLoot перешёл на Migration-based

Baseline миграция создана: 20260216083239_my_change

С этого момента используй только migrate dev, не db push!


3. Команды Prisma

Development

Создать миграцию

# После изменения schema.prisma
npx prisma migrate dev --name descriptive_name

# Что происходит:
# 1. Prisma генерирует SQL из diff
# 2. Применяет к dev БД
# 3. Генерирует Prisma Client
# 4. Запускает seed (если настроен)

Нейминг миграций:

  • add_user_tier_field
  • fix_quest_validation
  • refactor_referral_schema
  • my_change (неинформативно)
  • test123 (бессмысленно)

Сбросить БД

# Полный сброс (удаляет данные!)
npx prisma migrate reset

# Или через наш скрипт (с автодетекцией)
pnpm db:reset
ВНИМАНИЕ

migrate reset удаляет ВСЕ данные! Используй только в dev.

Студия БД

# Открыть Prisma Studio (GUI для БД)
pnpm db:studio

# Откроется http://localhost:5555

Production/Staging

Применить миграции

# Через наш скрипт (рекомендуется)
bash scripts/db/prisma-sync.sh deploy

# Или напрямую
npx prisma migrate deploy

Что делает migrate deploy:

  • Применяет только новые миграции
  • Не трогает данные
  • Идемпотентно (можно запускать много раз)
  • Безопасно для production

Проверить статус

npx prisma migrate status

# Показывает:
# - Какие миграции применены
# - Есть ли pending миграции
# - Schema drift (расхождения)

4. Скрипты проекта

prisma-sync.sh

Универсальный скрипт для работы с миграциями.

# Использование
bash scripts/db/prisma-sync.sh <command> [options]

Команды:

push (deprecated для prod)

bash scripts/db/prisma-sync.sh push
  • Применяет db push
  • Заблокирован для production
  • Используй только если точно знаешь зачем

migrate <name>

bash scripts/db/prisma-sync.sh migrate "add_tier_field"
  • Создаёт миграцию через migrate dev
  • Автоматически очищает имя (убирает спецсимволы)
  • Для development окружения

deploy ✅

bash scripts/db/prisma-sync.sh deploy
  • Применяет миграции через migrate deploy
  • Для staging/production
  • Для prod требует подтверждение
  • Маскирует credentials в выводе

Пример вывода:

Deploying migrations to prod...
Environment: prod
Database: postgresql://***@94.125.100.192:5432/***

⚠️ WARNING: Deploying to PRODUCTION database!
Migrations will be applied from prisma/migrations/

Continue? (yes/no): yes

✔ 1 migration applied successfully

✅ Migrations deployed successfully to prod

reset-db.sh

Полный сброс БД с автоматической детекцией workflow.

# Использование
bash scripts/db/reset-db.sh [dev|staging|prod]

# Или через pnpm
pnpm db:reset

Автодетекция:

  • Если есть prisma/migrations/ → Migration-based workflow
  • Если нет → Push-based workflow

Пример:

pnpm db:reset

# Вывод:
📋 Обнаружены миграции → используем migration-based workflow

1. Сброс через Prisma Migrate...
2. Seed выполнен автоматически

✅ БД сброшена и заполнена базовыми данными (workflow: migrations)

db-query.sh

Read-only запросы к БД с автоматической маскировкой чувствительных данных.

# Использование
bash scripts/db/db-query.sh [dev|staging|prod] "SQL"

Примеры:

# Топ-10 пользователей по XP
bash scripts/db/db-query.sh dev "
SELECT id, \"firstName\", xp, level
FROM users
ORDER BY xp DESC
LIMIT 10
"

# Статистика квизов
bash scripts/db/db-query.sh dev "
SELECT COUNT(*) as total,
AVG(score) as avg_score
FROM quiz_results
WHERE \"completedAt\" > NOW() - INTERVAL '7 days'
"

Безопасность:

  • ✅ Только SELECT запросы
  • ❌ Блокирует INSERT/UPDATE/DELETE
  • 🔒 Автоматически маскирует: apiKey, steamId, telegramId, IP
  • ⚠️ Предупреждение при запросах к prod

Маскировка полей:

ПолеДоПосле
apiKeysk-live-abc123***API_KEY***
steamId7656119812345678976561***6789
telegramId1234567891234***789
ipAddress192.168.1.100192.168.*.*

prisma-info.sh

Показать текущее окружение БД.

bash scripts/db/prisma-info.sh

# Вывод:
ENV=dev
URL=postgresql://***@94.125.100.192:5432/goloot
DB_NAME=goloot
HOST=94.125.100.192
IS_PROD=false

5. SCHEMA_GUIDE.md

backend/prisma/schema.prisma содержит 3022 строки — читать полностью неэффективно.

Решение: карта схемы

Файл: backend/prisma/SCHEMA_GUIDE.md

Содержит:

  • Список всех моделей с номерами строк
  • Группировка по доменам
  • Quick lookup по букве
  • Top 10 largest моделей

Использование

Шаг 1: Открой SCHEMA_GUIDE.md

# Найди нужную модель
grep -i "User" backend/prisma/SCHEMA_GUIDE.md

Шаг 2: Узнай строки

| Model | Lines | Description |
|-------|-------|-------------|
| **User** | 14-199 | User entity (118 fields) |

Шаг 3: Читай только нужные строки

# Read модель User (lines 14-199)
# offset=14, limit=186 (199-14+1)

Примеры:

# User модель (lines 14-199)
Read backend/prisma/schema.prisma offset=14 limit=186

# Quest модель (lines 1416-1548)
Read backend/prisma/schema.prisma offset=1416 limit=133

# Item модель (lines 640-730)
Read backend/prisma/schema.prisma offset=640 limit=91

Quick Stats

МетрикаЗначение
Models75
Enums36
Lines~3,022
Domains22

Top 10 Largest Models

#ModelLinesFields
1User14-199118
2Quest1416-154870
3UserSeasonStats2086-216247
4Item640-73042
5Season1885-193932

6. Troubleshooting

"Migration already applied"

Проблема: Пытаешься применить миграцию, которая уже в БД.

# Пометить как применённую вручную
npx prisma migrate resolve --applied "MIGRATION_NAME"

# Пример:
npx prisma migrate resolve --applied "20260216083239_my_change"

"Database schema is not in sync"

Проблема: Schema drift — БД не соответствует миграциям.

# 1. Посмотреть drift
npx prisma migrate diff \
--from-schema-datamodel prisma/schema.prisma \
--to-schema-datasource prisma/schema.prisma

# 2. Создать миграцию для исправления
npx prisma migrate dev --name fix_drift

"Migration failed" на production

НЕ ПАНИКОВАТЬ!

# 1. Восстановить backup (см. deployment/09-backup-migration.md)
psql -h HOST -U USER DB < backup_before_migrate.sql

# 2. Исследовать проблему
npx prisma migrate status

# 3. Исправить миграцию локально
# 4. Протестировать на staging
# 5. Попробовать снова

ERR_PNPM_OUTDATED_LOCKFILE

Проблема: pnpm-lock.yaml не в sync с package.json.

# В корне проекта
pnpm install

# Закоммитить pnpm-lock.yaml вместе с package.json
git add pnpm-lock.yaml package.json
git commit -m "chore: update dependencies"

"The table does not exist"

Проблема: Пытаешься использовать модель, но таблицы нет в БД.

# Применить миграции
npx prisma migrate deploy

# Или сгенерировать схему (если миграций нет)
npx prisma db push

Prisma Client не видит изменения

Проблема: Изменил schema.prisma, но TypeScript не видит новые поля.

# Регенерировать Prisma Client
npx prisma generate

# Перезапустить TypeScript server в VSCode
# Cmd+Shift+P → "TypeScript: Restart TS Server"

7. Production Checklist

Перед применением миграций на production:

  • Миграция протестирована на dev
  • Миграция протестирована на staging
  • Создан backup БД
  • Backup проверен (можно восстановить)
  • Миграция не содержит DROP без default
  • Миграция не содержит breaking changes для API
  • Команда проинформирована (если даунтайм)
  • Rollback план готов