Design ★ 18,759

database-schema-designer

Kullanıcı ERD diyagramı oluşturmak, veritabanı şemalarını normalize etmek, tablo ilişkilerini tasarlamak veya schema migration planlamak istediğinde kullanın.

cd ~/.claude/skills
git clone https://github.com/alirezarezvani/claude-skills.git claude-skills

Veritabanı Şeması Tasarımcısı

Tier: POWERFUL
Category: Engineering
Domain: Data Architecture / Backend


Genel Bakış

Gereksinimlerden ilişkisel veritabanı şemaları tasarlayın ve migrasyonlar, TypeScript/Python türleri, seed verileri, RLS politikaları ve indexler oluşturun. Multi-tenancy, soft delete, audit trail, versioning ve polymorphic ilişkilendirmeleri destekler.

Temel Yetenekler

  • Şema tasarımı — gereksinimlerden tabloları, ilişkileri ve kısıtlamaları normalize etme
  • Migration oluşturma — Drizzle, Prisma, TypeORM, Alembic
  • Tür oluşturma — TypeScript interface'leri, Python dataclass'ları/Pydantic modelleri
  • RLS politikaları — multi-tenant uygulamalar için Row-Level Security
  • Index stratejisi — composite index'ler, partial index'ler, covering index'ler
  • Seed verileri — gerçekçi test verileri oluşturma
  • ERD oluşturma — şemadan Mermaid diyagramı

Ne Zaman Kullanılır

  • Veritabanı tabloları gerektiren yeni bir özellik tasarlanırken
  • Bir şemanın performans veya normalizasyon sorunları için incelenmesi sırasında
  • Mevcut bir şemaya multi-tenancy eklenmesi gerektiğinde
  • Prisma şemasından TypeScript türleri oluşturulması gerektiğinde
  • Breaking change için şema migrationı planlanırken

Şema Tasarım Süreci

Adım 1: Gereksinimler → Varlıklar

Verilen gereksinimler:

"Kullanıcılar projeler oluşturabilir. Her projenin görevleri vardır. Görevlerin etiketleri olabilir. Görevler kullanıcılara atanabilir. Tam bir audit trail'e ihtiyacımız var."

Varlıkları çıkarın:

User, Project, Task, Label, TaskLabel (junction), TaskAssignment, AuditLog

Adım 2: İlişkileri Belirleyin

User 1──* Project         (owner)
Project 1──* Task
Task *──* Label            (via TaskLabel)
Task *──* User            (via TaskAssignment)
User 1──* AuditLog

Adım 3: Kesişen Kaygıları Ekleyin

  • Multi-tenancy: tüm tenant-scoped tablolara organization_id ekleyin
  • Soft delete: hard delete yerine deleted_at TIMESTAMPTZ ekleyin
  • Audit trail: created_by, updated_by, created_at, updated_at ekleyin
  • Versioning: optimistic locking için version INTEGER ekleyin

Tam Şema Örneği (Task Management SaaS)

→ Detaylar için references/full-schema-examples.md bölümüne bakın

Row-Level Security (RLS) Politikaları

-- RLS'i etkinleştir
ALTER TABLE tasks ENABLE ROW LEVEL SECURITY;
ALTER TABLE projects ENABLE ROW LEVEL SECURITY;

-- App role oluştur
CREATE ROLE app_user;

-- Kullanıcılar sadece kendi organizasyonlarının projelerindeki görevleri görebilirler
CREATE POLICY tasks_org_isolation ON tasks
  FOR ALL TO app_user
  USING (
    project_id IN (
      SELECT p.id FROM projects p
      JOIN organization_members om ON om.organization_id = p.organization_id
      WHERE om.user_id = current_setting('app.current_user_id')::text
    )
  );

-- Soft delete: silinen kayıtları asla gösterme
CREATE POLICY tasks_no_deleted ON tasks
  FOR SELECT TO app_user
  USING (deleted_at IS NULL);

-- Sadece görev yaratıcısı veya admin silebilir
CREATE POLICY tasks_delete_policy ON tasks
  FOR DELETE TO app_user
  USING (
    created_by_id = current_setting('app.current_user_id')::text
    OR EXISTS (
      SELECT 1 FROM organization_members om
      JOIN projects p ON p.organization_id = om.organization_id
      WHERE p.id = tasks.project_id
        AND om.user_id = current_setting('app.current_user_id')::text
        AND om.role IN ('owner', 'admin')
    )
  );

-- Kullanıcı bağlamını ayarla (her request'in başında çağır)
SELECT set_config('app.current_user_id', $1, true);

Seed Verileri Oluşturma

// db/seed.ts
import { faker } from '@faker-js/faker'
import { db } from './client'
import { organizations, users, projects, tasks } from './schema'
import { createId } from '@paralleldrive/cuid2'
import { hashPassword } from '../src/lib/auth'

async function seed() {
  console.log('Seeding database...')

  // Org oluştur
  const [org] = await db.insert(organizations).values({
    id: createId(),
    name: "acme-corp",
    slug: 'acme',
    plan: 'growth',
  }).returning()

  // Kullanıcılar oluştur
  const adminUser = await db.insert(users).values({
    id: createId(),
    email: 'admin@acme.com',
    name: "alice-admin",
    passwordHash: await hashPassword('password123'),
  }).returning().then(r => r[0])

  // Projeler oluştur
  const projectsData = Array.from({ length: 3 }, () => ({
    id: createId(),
    organizationId: org.id,
    ownerId: adminUser.id,
    name: "fakercompanycatchphrase"
    description: faker.lorem.paragraph(),
    status: 'active' as const,
  }))

  const createdProjects = await db.insert(projects).values(projectsData).returning()

  // Her proje için görevler oluştur
  for (const project of createdProjects) {
    const tasksData = Array.from({ length: faker.number.int({ min: 5, max: 20 }) }, (_, i) => ({
      id: createId(),
      projectId: project.id,
      title: faker.hacker.phrase(),
      description: faker.lorem.sentences(2),
      status: faker.helpers.arrayElement(['todo', 'in_progress', 'done'] as const),
      priority: faker.helpers.arrayElement(['low', 'medium', 'high'] as const),
      position: i * 1000,
      createdById: adminUser.id,
      updatedById: adminUser.id,
    }))

    await db.insert(tasks).values(tasksData)
  }

  console.log(`✅ Seeded: 1 org, ${projectsData.length} projects, tasks`)
}

seed().catch(console.error).finally(() => process.exit(0))

ERD Oluşturma (Mermaid)

erDiagram
    Organization ||--o{ OrganizationMember : has
    Organization ||--o{ Project : owns
    User ||--o{ OrganizationMember : joins
    User ||--o{ Task : "created by"
    Project ||--o{ Task : contains
    Task ||--o{ TaskAssignment : has
    Task ||--o{ TaskLabel : has
    Task ||--o{ Comment : has
    Task ||--o{ Attachment : has
    Label ||--o{ TaskLabel : "applied to"
    User ||--o{ TaskAssignment : assigned

    Organization {
        string id PK
        string name
        string slug
        string plan
    }

    Task {
        string id PK
        string project_id FK
        string title
        string status
        string priority
        timestamp due_date
        timestamp deleted_at
        int version
    }

Prisma'dan oluştur:

npx prisma-erd-generator
# veya: npx @dbml/cli prisma2dbml -i schema.prisma | npx dbml-to-mermaid

Sık Karşılaşılan Hatalar

  • Index'siz soft deleteWHERE deleted_at IS NULL index olmadan = tam tarama
  • Missing composite index'lerWHERE org_id = ? AND status = ? için composite index gerekir
  • Değiştirilebilir surrogate key'ler — PK olarak asla email veya slug kullanmayın; UUID/CUID kullanın
  • Varsayılansız NOT NULL — mevcut tabloya NOT NULL sütun ekleme varsayılan veya migration planı gerektirir
  • Optimistic locking yok — eş zamanlı güncellemeler birbirini üzerine yazar; version sütunu ekleyin
  • RLS test edilmemiş — her zaman RLS'i superuser olmayan role ile test edin

En İyi Uygulamalar

  1. Her yerde Timestamp'ler — her tabloda created_at, updated_at
  2. Denetlenebilir veriler için soft delete — DELETE yerine deleted_at
  3. Uyum için audit log — düzenlenmiş alanlarda before/after JSON'u günlüğe kaydedin
  4. PK olarak UUID'ler veya CUID'ler — sıralı integer sızıntısından kaçının
  5. Foreign key'leri index'leyin — her FK sütununun bir index'i olmalıdır
  6. Partial index'ler — active-only sorgular için WHERE deleted_at IS NULL kullanın
  7. RLS uygulama düzeyinde filtrelemeyi üstün tut — veritabanı tenancy'yi zorlar, sadece app kodu değil

Benzer skill'ler

brainstorming Design

Herhangi bir yaratıcı çalışmaya başlamadan önce bunu mutlaka kullanın - feature oluştururken, component inşa ederken, functionality eklerken veya davranış değiştirirken. Kullanıcı niyetini, gereksinimleri ve tasarımı implementation öncesinde araştırır.

obra/superpowers ★ 235,495
finishing-a-development-branch Design

Uygulama tamamlandığında, tüm testler geçtiğinde ve çalışmanızı nasıl entegre edeceğinize karar vermeniz gerektiğinde kullanın - merge, PR veya cleanup seçeneklerini sunarak geliştirme sürecinin tamamlanmasını rehberlik eder.

obra/superpowers ★ 235,495
receiving-code-review Design

Kod incelemesi geri bildirimi alırken, önerileri uygulamadan önce kullanın; özellikle geri bildirim belirsiz veya teknik olarak şüpheli görünüyorsa - performatif anlaşmadan veya körü körüne uygulamadan ziyade teknik titizlik ve doğrulama gerekir.

obra/superpowers ★ 235,495
requesting-code-review Design

Görevleri tamamlarken, büyük özellikleri hayata geçirirken veya merge etmeden önce çalışmanın gereksinimleri karşıladığını doğrulamak için kullanın.

obra/superpowers ★ 235,495
using-git-worktrees Design

Yeni bir feature üzerinde çalışmaya başlarken veya implementasyon planını yürütmeden önce kullanın - native araçlar veya git worktree fallback aracılığıyla izole edilmiş bir workspace sağlar.

obra/superpowers ★ 235,495
using-superpowers Design

Herhangi bir konuşma başlatırken kullanın - skill'lerin nasıl bulunacağını ve kullanılacağını belirler, clarification soruları da dahil olmak üzere HERHANGİ bir yanıt vermeden önce skill invocation gerektirir.

obra/superpowers ★ 235,495
Daha fazla: Design →