feat: improve server management and refund display
Server Management: - Fix /server command API auth (query param instead of header) - Show server specs (vCPU/RAM/Bandwidth) in /server list - Prevent AI from refusing server deletion based on expiration date - Add explicit instructions in tool description and system prompt Refund Display: - Show before/after balance in server deletion refund message - Format: 환불 전 잔액 → 환불 금액 → 환불 후 잔액 Other Changes: - Add stopped status migration for server orders - Clean up callback handler (remove deprecated code) - Update constants and pattern utilities Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
62
migrations/005_add_stopped_status.sql
Normal file
62
migrations/005_add_stopped_status.sql
Normal file
@@ -0,0 +1,62 @@
|
||||
-- Migration: Add 'stopped' status to server_orders table
|
||||
-- Date: 2026-01-29
|
||||
-- Description: SQLite does not support ALTER TABLE to modify CHECK constraints,
|
||||
-- so we need to recreate the table with the new constraint.
|
||||
|
||||
-- Step 1: Create temporary table with new CHECK constraint
|
||||
CREATE TABLE server_orders_new (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL,
|
||||
spec_id INTEGER NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'pending' CHECK(status IN ('pending', 'provisioning', 'active', 'stopped', 'failed', 'cancelled', 'terminated')),
|
||||
region TEXT NOT NULL,
|
||||
provider_instance_id TEXT,
|
||||
ip_address TEXT,
|
||||
root_password TEXT,
|
||||
price_paid INTEGER NOT NULL,
|
||||
error_message TEXT,
|
||||
provisioned_at DATETIME,
|
||||
terminated_at DATETIME,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
label TEXT,
|
||||
image TEXT,
|
||||
billing_type TEXT DEFAULT 'monthly',
|
||||
expires_at DATETIME,
|
||||
telegram_user_id TEXT,
|
||||
provider TEXT DEFAULT 'anvil',
|
||||
idempotency_key TEXT,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
-- Step 2: Copy existing data
|
||||
INSERT INTO server_orders_new (
|
||||
id, user_id, spec_id, status, region, provider_instance_id, ip_address,
|
||||
root_password, price_paid, error_message, provisioned_at, terminated_at,
|
||||
created_at, updated_at, label, image, billing_type, expires_at,
|
||||
telegram_user_id, provider, idempotency_key
|
||||
)
|
||||
SELECT
|
||||
id, user_id, spec_id, status, region, provider_instance_id, ip_address,
|
||||
root_password, price_paid, error_message, provisioned_at, terminated_at,
|
||||
created_at, updated_at, label, image, billing_type, expires_at,
|
||||
telegram_user_id, provider, idempotency_key
|
||||
FROM server_orders;
|
||||
|
||||
-- Step 3: Drop old table
|
||||
DROP TABLE server_orders;
|
||||
|
||||
-- Step 4: Rename new table
|
||||
ALTER TABLE server_orders_new RENAME TO server_orders;
|
||||
|
||||
-- Step 5: Recreate indexes
|
||||
CREATE INDEX idx_server_orders_user ON server_orders(user_id);
|
||||
|
||||
CREATE INDEX idx_server_orders_status ON server_orders(status, created_at DESC);
|
||||
|
||||
CREATE UNIQUE INDEX idx_server_orders_idempotency_unique
|
||||
ON server_orders(idempotency_key)
|
||||
WHERE idempotency_key IS NOT NULL;
|
||||
|
||||
-- Verification query (comment out for actual migration)
|
||||
-- SELECT COUNT(*) as total_orders, COUNT(DISTINCT status) as status_count FROM server_orders;
|
||||
67
migrations/005_rollback_stopped_status.sql
Normal file
67
migrations/005_rollback_stopped_status.sql
Normal file
@@ -0,0 +1,67 @@
|
||||
-- Rollback Migration: Remove 'stopped' status from server_orders table
|
||||
-- Date: 2026-01-29
|
||||
-- Description: Revert to original CHECK constraint without 'stopped' status
|
||||
-- WARNING: This will fail if there are any rows with status='stopped'
|
||||
|
||||
-- Step 1: Verify no 'stopped' status exists (will fail if found)
|
||||
-- If this SELECT returns rows, manual intervention required
|
||||
SELECT CASE
|
||||
WHEN COUNT(*) > 0 THEN RAISE(ABORT, 'Cannot rollback: server_orders contains stopped status records')
|
||||
ELSE 0
|
||||
END
|
||||
FROM server_orders WHERE status = 'stopped';
|
||||
|
||||
-- Step 2: Create temporary table with original CHECK constraint
|
||||
CREATE TABLE server_orders_rollback (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL,
|
||||
spec_id INTEGER NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'pending' CHECK(status IN ('pending', 'provisioning', 'active', 'failed', 'cancelled', 'terminated')),
|
||||
region TEXT NOT NULL,
|
||||
provider_instance_id TEXT,
|
||||
ip_address TEXT,
|
||||
root_password TEXT,
|
||||
price_paid INTEGER NOT NULL,
|
||||
error_message TEXT,
|
||||
provisioned_at DATETIME,
|
||||
terminated_at DATETIME,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
label TEXT,
|
||||
image TEXT,
|
||||
billing_type TEXT DEFAULT 'monthly',
|
||||
expires_at DATETIME,
|
||||
telegram_user_id TEXT,
|
||||
provider TEXT DEFAULT 'anvil',
|
||||
idempotency_key TEXT,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
-- Step 3: Copy existing data
|
||||
INSERT INTO server_orders_rollback (
|
||||
id, user_id, spec_id, status, region, provider_instance_id, ip_address,
|
||||
root_password, price_paid, error_message, provisioned_at, terminated_at,
|
||||
created_at, updated_at, label, image, billing_type, expires_at,
|
||||
telegram_user_id, provider, idempotency_key
|
||||
)
|
||||
SELECT
|
||||
id, user_id, spec_id, status, region, provider_instance_id, ip_address,
|
||||
root_password, price_paid, error_message, provisioned_at, terminated_at,
|
||||
created_at, updated_at, label, image, billing_type, expires_at,
|
||||
telegram_user_id, provider, idempotency_key
|
||||
FROM server_orders;
|
||||
|
||||
-- Step 4: Drop current table
|
||||
DROP TABLE server_orders;
|
||||
|
||||
-- Step 5: Rename rollback table
|
||||
ALTER TABLE server_orders_rollback RENAME TO server_orders;
|
||||
|
||||
-- Step 6: Recreate indexes
|
||||
CREATE INDEX idx_server_orders_user ON server_orders(user_id);
|
||||
|
||||
CREATE INDEX idx_server_orders_status ON server_orders(status, created_at DESC);
|
||||
|
||||
CREATE UNIQUE INDEX idx_server_orders_idempotency_unique
|
||||
ON server_orders(idempotency_key)
|
||||
WHERE idempotency_key IS NOT NULL;
|
||||
Reference in New Issue
Block a user