Ana içeriğe geç

Events DB

Akademi Eğitim Platformu Events DB Dökümanı

Core Tables (MariaDB)

-- 1. Etkinliklerin ana tablosu (Events)
CREATE TABLE events (
event_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
tenant_id BIGINT UNSIGNED NOT NULL, -- Kurumsal için akademi/firma ID'si, freelancer için user_id veya NULL (global)
creator_user_id BIGINT UNSIGNED NOT NULL, -- Oluşturan kullanıcı (FK users)
title VARCHAR(255) NOT NULL,
description TEXT,
event_type ENUM('webinar', 'workshop', 'meetup', 'training', 'other') NOT NULL DEFAULT 'other',
start_datetime DATETIME NOT NULL,
end_datetime DATETIME NOT NULL,
timezone VARCHAR(50) NOT NULL DEFAULT 'Europe/Istanbul', -- TZ desteği önemli (TR default)
is_recurring TINYINT(1) DEFAULT 0,
recurrence_rule TEXT, -- iCal RRULE formatı (JSON veya string: "FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,WE")
location_type ENUM('online', 'offline', 'hybrid') DEFAULT 'online',
location_details VARCHAR(500), -- Adres veya Zoom/Meet linki
capacity INT UNSIGNED DEFAULT NULL, -- Katılım sınırı
is_paid TINYINT(1) DEFAULT 0,
price DECIMAL(10,2) DEFAULT 0.00,
currency CHAR(3) DEFAULT 'TRY',
status ENUM('draft', 'published', 'cancelled', 'completed') DEFAULT 'draft',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

INDEX idx_tenant_start (tenant_id, start_datetime),
INDEX idx_creator (creator_user_id),
INDEX idx_search (title(100), event_type, status) -- Basit arama için
);

-- 2. Tekrar eden etkinliklerde istisnalar (exception) yönetimi
-- Örn: Serideki bir tarihi iptal et veya farklı saate taşı
CREATE TABLE event_exceptions (
exception_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
event_id BIGINT UNSIGNED NOT NULL,
original_start DATETIME NOT NULL,
new_start DATETIME DEFAULT NULL, -- NULL = iptal, dolu = taşındı
new_end DATETIME DEFAULT NULL,
reason TEXT,
FOREIGN KEY (event_id) REFERENCES events(event_id) ON DELETE CASCADE
);

-- 3. Katılımcılar / RSVP (many-to-many)
CREATE TABLE event_attendees (
attendee_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
event_id BIGINT UNSIGNED NOT NULL,
user_id BIGINT UNSIGNED NOT NULL, -- Katılan kullanıcı
status ENUM('invited', 'rsvp_yes', 'rsvp_no', 'rsvp_maybe', 'attended', 'no_show') DEFAULT 'invited',
rsvp_at DATETIME DEFAULT NULL,
attended_at DATETIME DEFAULT NULL, -- Check-in zamanı
notes TEXT, -- Feedback veya özel not
ticket_code VARCHAR(50) UNIQUE, -- Ücretli için unique bilet kodu
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,

UNIQUE KEY uk_event_user (event_id, user_id),
FOREIGN KEY (event_id) REFERENCES events(event_id) ON DELETE CASCADE
-- FOREIGN KEY (user_id) REFERENCES users(id) -- Varsa users tablosu
);

-- 4. Konuşmacılar / Eğitmenler (opsiyonel, events ile many-to-many)
-- 1. Konuşmacıların merkezi profili (reusable)
CREATE TABLE speakers (
speaker_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
tenant_id BIGINT UNSIGNED DEFAULT NULL, -- Opsiyonel: kurumsal tenant'a bağlıysa
user_id BIGINT UNSIGNED DEFAULT NULL, -- Platform kullanıcısıysa (freelancer/eğitmen)
name VARCHAR(255) NOT NULL,
slug VARCHAR(100) UNIQUE DEFAULT NULL, -- seo dostu: mehmet-yilmaz
title VARCHAR(255), -- "Satış Koçu", "CTO", "Bağımsız Eğitmen"
bio TEXT,
photo_url VARCHAR(500), -- profil resmi
linkedin_url VARCHAR(255),
website_url VARCHAR(255),
email VARCHAR(255),
phone VARCHAR(50),
is_verified TINYINT(1) DEFAULT 0, -- platform onaylı mı
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

INDEX idx_user (user_id),
INDEX idx_slug (slug),
INDEX idx_name (name(100))
);

-- 2. Etkinlik ↔ Konuşmacı bağlantı tablosu (N-N)
CREATE TABLE event_speaker_links (
link_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
event_id BIGINT UNSIGNED NOT NULL,
speaker_id BIGINT UNSIGNED NOT NULL,

-- Etkinlik bazında override edebilecek alanlar (isteğe bağlı)
display_order INT UNSIGNED DEFAULT 0, -- konuşmacı sıralaması (1. konuşmacı, 2. ...)
role_in_event ENUM('main_speaker', 'panelist', 'moderator', 'guest', 'other') DEFAULT 'main_speaker',
custom_title VARCHAR(255) DEFAULT NULL, -- bu etkinlik için özel unvan
custom_bio TEXT DEFAULT NULL, -- etkinlik özel kısa bio
speaking_duration_minutes SMALLINT UNSIGNED DEFAULT NULL,

created_at DATETIME DEFAULT CURRENT_TIMESTAMP,

UNIQUE KEY uk_event_speaker (event_id, speaker_id),
FOREIGN KEY (event_id) REFERENCES events(event_id) ON DELETE CASCADE,
FOREIGN KEY (speaker_id) REFERENCES speakers(speaker_id) ON DELETE RESTRICT
-- ON DELETE RESTRICT → konuşmacı silinmesin diye, CASCADE de olabilir ama dikkatli olun
);

-- 5. Bildirim kuyruğu / Log (hatırlatmalar, onaylar vs.)
-- Bu tabloyu cron job ile tarayıp gönderebilirsin (veya Node.js queue)
CREATE TABLE event_notifications (
notification_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
event_id BIGINT UNSIGNED NOT NULL,
attendee_id BIGINT UNSIGNED DEFAULT NULL, -- Belirli kişiye mi, yoksa tümüne mi
type ENUM('reminder_24h', 'reminder_1h', 'started', 'rsvp_confirm', 'cancelled', 'feedback_request'),
channel ENUM('email', 'push', 'sms', 'in_app'),
sent_at DATETIME DEFAULT NULL,
status ENUM('pending', 'sent', 'failed') DEFAULT 'pending',
error_message TEXT,
FOREIGN KEY (event_id) REFERENCES events(event_id) ON DELETE CASCADE,
FOREIGN KEY (attendee_id) REFERENCES event_attendees(attendee_id) ON DELETE SET NULL
);

-- 6. Ödeme / Bilet (freelancer ücretli etkinlik için)
CREATE TABLE event_payments (
payment_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
attendee_id BIGINT UNSIGNED NOT NULL,
amount DECIMAL(10,2) NOT NULL,
currency CHAR(3) DEFAULT 'TRY',
stripe_payment_id VARCHAR(100),
status ENUM('pending', 'paid', 'refunded', 'failed') DEFAULT 'pending',
paid_at DATETIME DEFAULT NULL,
FOREIGN KEY (attendee_id) REFERENCES event_attendees(attendee_id) ON DELETE CASCADE
);