CREATE TABLE IF NOT EXISTS telegram_users ( id INT AUTO_INCREMENT PRIMARY KEY, telegram_id BIGINT NOT NULL UNIQUE, username VARCHAR(64) NULL, first_name VARCHAR(255) NULL, last_name VARCHAR(255) NULL, language_code VARCHAR(16) NULL, is_admin BOOLEAN NOT NULL DEFAULT FALSE, is_blocked BOOLEAN NOT NULL DEFAULT FALSE, discount_ever_used BOOLEAN NOT NULL DEFAULT FALSE, last_seen_at DATETIME NOT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, INDEX ix_telegram_users_telegram_id (telegram_id) ); CREATE TABLE IF NOT EXISTS remnawave_users ( id INT AUTO_INCREMENT PRIMARY KEY, owner_telegram_user_id INT NULL, rw_uuid CHAR(36) NOT NULL UNIQUE, rw_id BIGINT NOT NULL UNIQUE, short_uuid VARCHAR(48) NOT NULL UNIQUE, username VARCHAR(36) NOT NULL UNIQUE, status VARCHAR(16) NOT NULL, traffic_limit_bytes BIGINT NOT NULL DEFAULT 0, used_traffic_bytes DOUBLE NOT NULL DEFAULT 0, lifetime_used_traffic_bytes DOUBLE NOT NULL DEFAULT 0, expire_at DATETIME NOT NULL, telegram_id BIGINT NULL, email VARCHAR(320) NULL, description TEXT NULL, tag VARCHAR(16) NULL, hwid_device_limit INT NULL, external_squad_uuid CHAR(36) NULL, trojan_password VARCHAR(64) NOT NULL, vless_uuid CHAR(36) NOT NULL, ss_password VARCHAR(64) NOT NULL, last_triggered_threshold INT NOT NULL DEFAULT 0, sub_revoked_at DATETIME NULL, sub_last_user_agent VARCHAR(512) NULL, sub_last_opened_at DATETIME NULL, last_traffic_reset_at DATETIME NULL, subscription_url TEXT NOT NULL, online_at DATETIME NULL, first_connected_at DATETIME NULL, last_connected_node_uuid CHAR(36) NULL, remote_created_at DATETIME NOT NULL, remote_updated_at DATETIME NOT NULL, synced_at DATETIME NOT NULL, CONSTRAINT fk_remnawave_users_owner FOREIGN KEY (owner_telegram_user_id) REFERENCES telegram_users (id) ON DELETE SET NULL, INDEX ix_remnawave_users_rw_uuid (rw_uuid), INDEX ix_remnawave_users_short_uuid (short_uuid), INDEX ix_remnawave_users_username (username), INDEX ix_remnawave_users_telegram_id (telegram_id), INDEX ix_remnawave_users_email (email), INDEX ix_remnawave_users_tag (tag) ); CREATE TABLE IF NOT EXISTS internal_squads ( uuid CHAR(36) PRIMARY KEY, name VARCHAR(255) NOT NULL, synced_at DATETIME NOT NULL ); CREATE TABLE IF NOT EXISTS remnawave_user_internal_squads ( user_id INT NOT NULL, squad_uuid CHAR(36) NOT NULL, PRIMARY KEY (user_id, squad_uuid), CONSTRAINT fk_rw_user_squad_user FOREIGN KEY (user_id) REFERENCES remnawave_users (id) ON DELETE CASCADE, CONSTRAINT fk_rw_user_squad_squad FOREIGN KEY (squad_uuid) REFERENCES internal_squads (uuid) ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS subscription_request_logs ( id INT AUTO_INCREMENT PRIMARY KEY, remote_id BIGINT NOT NULL UNIQUE, user_uuid CHAR(36) NOT NULL, request_at DATETIME NOT NULL, request_ip VARCHAR(45) NULL, user_agent TEXT NULL, synced_at DATETIME NOT NULL, CONSTRAINT fk_subscription_request_logs_user FOREIGN KEY (user_uuid) REFERENCES remnawave_users (rw_uuid) ON DELETE CASCADE, INDEX ix_subscription_request_logs_user_uuid (user_uuid), INDEX ix_subscription_request_logs_request_at (request_at) ); CREATE TABLE IF NOT EXISTS guides ( id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(255) NOT NULL, short_description VARCHAR(512) NOT NULL DEFAULT '', body_text TEXT NOT NULL, is_active BOOLEAN NOT NULL DEFAULT TRUE, created_by_telegram_id BIGINT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, INDEX ix_guides_is_active (is_active), INDEX ix_guides_created_by_telegram_id (created_by_telegram_id) ); CREATE TABLE IF NOT EXISTS guide_photos ( id INT AUTO_INCREMENT PRIMARY KEY, guide_id INT NOT NULL, file_id VARCHAR(512) NOT NULL, position INT NOT NULL DEFAULT 0, created_at DATETIME NOT NULL, CONSTRAINT fk_guide_photos_guide FOREIGN KEY (guide_id) REFERENCES guides (id) ON DELETE CASCADE, INDEX ix_guide_photos_guide_id (guide_id) ); CREATE TABLE IF NOT EXISTS support_tickets ( id INT AUTO_INCREMENT PRIMARY KEY, public_id VARCHAR(32) NOT NULL UNIQUE, telegram_id BIGINT NOT NULL, username VARCHAR(64) NULL, display_name VARCHAR(255) NOT NULL, user_message TEXT NOT NULL, support_chat_id BIGINT NOT NULL, support_thread_id INT NULL, support_message_id BIGINT NULL, status VARCHAR(16) NOT NULL DEFAULT 'OPEN', created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, UNIQUE KEY ix_support_tickets_chat_message (support_chat_id, support_message_id), INDEX ix_support_tickets_public_id (public_id), INDEX ix_support_tickets_telegram_id (telegram_id), INDEX ix_support_tickets_support_chat_id (support_chat_id) ); CREATE TABLE IF NOT EXISTS referral_invites ( id INT AUTO_INCREMENT PRIMARY KEY, inviter_telegram_id BIGINT NOT NULL, invited_telegram_id BIGINT NOT NULL UNIQUE, invited_username VARCHAR(64) NULL, invited_display_name VARCHAR(255) NOT NULL, discount_used BOOLEAN NOT NULL DEFAULT FALSE, created_at DATETIME NOT NULL, INDEX ix_referral_invites_inviter_telegram_id (inviter_telegram_id), INDEX ix_referral_invites_invited_telegram_id (invited_telegram_id) ); CREATE TABLE IF NOT EXISTS referral_codes ( id INT AUTO_INCREMENT PRIMARY KEY, telegram_id BIGINT NOT NULL UNIQUE, code VARCHAR(32) NOT NULL UNIQUE, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, INDEX ix_referral_codes_telegram_id (telegram_id), INDEX ix_referral_codes_code (code) ); CREATE TABLE IF NOT EXISTS promo_codes ( id INT AUTO_INCREMENT PRIMARY KEY, code VARCHAR(32) NOT NULL UNIQUE, plan_code VARCHAR(64) NULL, discount_percent INT NOT NULL DEFAULT 0, expires_at DATETIME NULL, is_active BOOLEAN NOT NULL DEFAULT TRUE, created_by_telegram_id BIGINT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, INDEX ix_promo_codes_code (code), INDEX ix_promo_codes_plan_code (plan_code), INDEX ix_promo_codes_expires_at (expires_at), INDEX ix_promo_codes_is_active (is_active), INDEX ix_promo_codes_created_by_telegram_id (created_by_telegram_id) ); CREATE TABLE IF NOT EXISTS promo_code_applications ( id INT AUTO_INCREMENT PRIMARY KEY, telegram_id BIGINT NOT NULL UNIQUE, promo_code_id INT NOT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, CONSTRAINT fk_promo_code_applications_promo_code FOREIGN KEY (promo_code_id) REFERENCES promo_codes (id) ON DELETE CASCADE, INDEX ix_promo_code_applications_telegram_id (telegram_id), INDEX ix_promo_code_applications_promo_code_id (promo_code_id) ); CREATE TABLE IF NOT EXISTS payment_orders ( id INT AUTO_INCREMENT PRIMARY KEY, order_uuid CHAR(36) NOT NULL UNIQUE, telegram_user_id INT NOT NULL, telegram_id BIGINT NOT NULL, plan_code VARCHAR(64) NOT NULL, plan_title VARCHAR(255) NOT NULL, plan_duration_days INT NOT NULL, traffic_limit_bytes BIGINT NOT NULL DEFAULT 0, traffic_limit_strategy VARCHAR(32) NOT NULL DEFAULT 'NO_RESET', amount_stars INT NOT NULL, currency VARCHAR(8) NOT NULL DEFAULT 'XTR', status VARCHAR(32) NOT NULL DEFAULT 'PENDING', invoice_payload VARCHAR(128) NOT NULL UNIQUE, provision_username VARCHAR(36) NOT NULL, remnawave_user_uuid CHAR(36) NULL, subscription_url TEXT NULL, telegram_payment_charge_id VARCHAR(255) NULL UNIQUE, provider_payment_charge_id VARCHAR(255) NULL, error_message TEXT NULL, paid_at DATETIME NULL, fulfilled_at DATETIME NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, CONSTRAINT fk_payment_orders_telegram_user FOREIGN KEY (telegram_user_id) REFERENCES telegram_users (id) ON DELETE CASCADE, INDEX ix_payment_orders_order_uuid (order_uuid), INDEX ix_payment_orders_telegram_user_id (telegram_user_id), INDEX ix_payment_orders_telegram_id (telegram_id), INDEX ix_payment_orders_plan_code (plan_code), INDEX ix_payment_orders_status (status), INDEX ix_payment_orders_invoice_payload (invoice_payload), INDEX ix_payment_orders_provision_username (provision_username), INDEX ix_payment_orders_remnawave_user_uuid (remnawave_user_uuid) );