Turtor Docs
Databáze

Migrace

Workflow pro práci s databázovými migracemi

Turtor používá TypeORM migrace pro verzování databázového schématu. Migrace se generují automaticky z entity definic.

Příkazy

# Spuštění migrací
pnpm db:migrate

# Generování migrace z entity změn (z apps/api/)
cd apps/api
pnpm db:generate src/database/migrations/MigrationName

# Drop a re-create (pouze vývoj!)
pnpm db:drop
pnpm db:migrate
pnpm db:seed

Umístění

apps/api/
├── data-source.ts                  # CLI data source (pro migrace)
├── src/config/database.config.ts   # Runtime data source (pro NestJS)
└── src/database/migrations/        # Migrační soubory
    ├── 1769438279865-InitialSchema.ts
    ├── 1769873413603-CreateMagicLinksTable.ts
    └── ...

Existují dva data source soubory -- data-source.ts (CLI pro migrace) a database.config.ts (NestJS runtime). Oba musí být synchronizované ohledně připojení a entity paths.

Workflow

1. Upravte entitu

// apps/api/src/modules/users/entities/user.entity.ts
@Column({ name: 'new_field', type: 'varchar', nullable: true })
newField: string | null;

2. Vygenerujte migraci

cd apps/api
pnpm db:generate src/database/migrations/AddNewFieldToUser

Příkaz vytvoří soubor s časovým razítkem: 1736726700000-AddNewFieldToUser.ts

3. Zkontrolujte SQL

export class AddNewFieldToUser1736726700000 implements MigrationInterface {
  public async up(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(
      `ALTER TABLE "users" ADD "new_field" varchar`
    );
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(
      `ALTER TABLE "users" DROP COLUMN "new_field"`
    );
  }
}

4. Spusťte migraci

pnpm db:migrate

Po každé změně entity MUSÍTE spustit migraci. Bez ní API běží, ale požadavky selžou s chybami typu column "new_field" does not exist. Entity změny aktualizují pouze TypeScript typy -- databázové schéma vyžaduje migraci.

Pravidla

  1. Vždy generujte přes CLI -- nikdy nevytvářejte migrační soubory ručně
  2. Zkontrolujte SQL -- projděte vygenerovaný SQL před spuštěním
  3. Bez destruktivních změn bez zálohy -- před DROP operacemi nejdřív pnpm db:backup
  4. Testujte lokálně -- spusťte migraci na dev databázi před produkcí
  5. Malé migrace -- jedna změna na migraci, pokud je to možné

Pojmenovávací konvence

Název migrace by měl popisovat změnu:

# Přidání sloupce
pnpm db:generate src/database/migrations/AddPhoneToUsers

# Vytvoření tabulky
pnpm db:generate src/database/migrations/CreateNotificationsTable

# Přidání indexu
pnpm db:generate src/database/migrations/AddStatusIndexToCourses

# Změna relace
pnpm db:generate src/database/migrations/AddRegionToInstructors

Transakce

Pro operace zahrnující více tabulek používejte transakce:

await this.dataSource.transaction(async (manager) => {
  const booking = await manager.save(Booking, bookingData);
  await manager.save(Payment, paymentData);
  await manager.update(Course, courseId, {
    currentParticipants: () => 'current_participants + 1',
  });
});

Data Source konfigurace

CLI (data-source.ts)

{
  type: 'postgres',
  host: process.env.DATABASE_HOST || 'localhost',
  port: parseInt(process.env.DATABASE_PORT || '5432', 10),
  username: process.env.DATABASE_USER || 'turtor',
  password: process.env.DATABASE_PASSWORD || 'turtor_secret',
  database: process.env.DATABASE_NAME || 'turtor',
  entities: ['src/**/*.entity{.ts,.js}'],
  migrations: ['src/database/migrations/*{.ts,.js}'],
  synchronize: false,
}

Runtime (database.config.ts)

{
  type: 'postgres',
  autoLoadEntities: true,   // NestJS auto-discovers entities
  synchronize: false,       // NIKDY true v produkci
  logging: NODE_ENV === 'development',
  migrations: [__dirname + '/../database/migrations/*{.ts,.js}'],
}

synchronize: false je povinné v produkci. Nastavení na true by automaticky měnilo schéma bez migrací -- s rizikem ztráty dat.

Docker prostředí

ProstředíPortDatabázeDocker soubor
Development5433turtordocker/docker-compose.yml
Test6433turtor_testdocker/docker-compose.test.yml
E2E5435turtor_e2edocker/docker-compose.e2e.yml
# Spuštění dev databáze
pnpm docker:up

# PostgreSQL bude na localhost:5433

Časté problémy

"column does not exist"

Entity byla změněna, ale migrace nebyla vygenerována a spuštěna:

cd apps/api
pnpm db:generate src/database/migrations/FixMissingColumn
pnpm db:migrate

Migrace se nespustí

Zkontrolujte, že data-source.ts má správné připojení a cesty k migracím. .env soubor musí být v apps/api/.

Konflikt portů

Dev databáze běží na portu 5433 (ne výchozí 5432), aby se zabránilo konfliktu s jinými projekty.