feat: add server provisioning system with Queue
- Add server-provision.ts for async server creation - Add SERVER_PROVISION_QUEUE with DLQ for reliability - Add cron job for auto-cleanup of pending orders (5min) - Add server delete confirmation with inline keyboard - Update types for server orders, images, and provisioning - Add server tables to schema (server_orders, server_instances) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
59
schema.sql
59
schema.sql
@@ -86,6 +86,59 @@ CREATE TABLE IF NOT EXISTS deposit_transactions (
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
-- 서버 상담 세션 테이블
|
||||
CREATE TABLE IF NOT EXISTS server_sessions (
|
||||
user_id TEXT PRIMARY KEY,
|
||||
status TEXT NOT NULL CHECK(status IN ('gathering', 'recommending', 'selecting', 'ordering', 'completed')),
|
||||
collected_info TEXT,
|
||||
last_recommendation TEXT,
|
||||
messages TEXT,
|
||||
created_at INTEGER NOT NULL,
|
||||
updated_at INTEGER NOT NULL,
|
||||
expires_at INTEGER NOT NULL
|
||||
);
|
||||
|
||||
-- 서버 주문 테이블
|
||||
CREATE TABLE IF NOT EXISTS server_orders (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL,
|
||||
telegram_user_id TEXT NOT NULL,
|
||||
spec_id INTEGER NOT NULL,
|
||||
region TEXT NOT NULL,
|
||||
label TEXT,
|
||||
price_paid INTEGER NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'pending' CHECK(status IN ('pending', 'provisioning', 'active', 'failed', 'cancelled', 'terminated')),
|
||||
provider TEXT NOT NULL CHECK(provider IN ('linode', 'vultr', 'anvil')),
|
||||
provider_instance_id TEXT,
|
||||
ip_address TEXT,
|
||||
root_password TEXT,
|
||||
error_message TEXT,
|
||||
provisioned_at DATETIME,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
idempotency_key TEXT UNIQUE,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
-- 사용자 서버 테이블 (활성 서버 관리)
|
||||
CREATE TABLE IF NOT EXISTS user_servers (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL,
|
||||
order_id INTEGER NOT NULL UNIQUE,
|
||||
provider TEXT NOT NULL,
|
||||
instance_id TEXT NOT NULL,
|
||||
label TEXT,
|
||||
ip_address TEXT,
|
||||
region TEXT,
|
||||
spec_label TEXT,
|
||||
monthly_price INTEGER,
|
||||
status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active', 'stopped', 'terminated')),
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id),
|
||||
FOREIGN KEY (order_id) REFERENCES server_orders(id)
|
||||
);
|
||||
|
||||
-- 인덱스
|
||||
CREATE INDEX IF NOT EXISTS idx_user_domains_user ON user_domains(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_user_domains_domain ON user_domains(domain);
|
||||
@@ -100,3 +153,9 @@ CREATE INDEX IF NOT EXISTS idx_buffer_chat ON message_buffer(user_id, chat_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_summary_user ON summaries(user_id, chat_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_summary_latest ON summaries(user_id, chat_id, generation DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_users_telegram ON users(telegram_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_server_sessions_expires ON server_sessions(expires_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_server_orders_user ON server_orders(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_server_orders_status ON server_orders(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_server_orders_idempotency ON server_orders(idempotency_key) WHERE idempotency_key IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_user_servers_user ON user_servers(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_user_servers_status ON user_servers(status);
|
||||
|
||||
Reference in New Issue
Block a user