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:
kappa
2026-01-30 05:30:59 +09:00
parent 18e7d3ca6e
commit 2b1bc6a371
17 changed files with 1237 additions and 364 deletions

View File

@@ -243,6 +243,9 @@ wrangler d1 execute telegram-conversations --file=migrations/001_rollback.sql
|------|------|--------|
| `001_optimize_prefix_indexes.sql` | 입금자명 prefix 인덱스 최적화 (99% 성능 향상) | 2026-01-19 |
| `002_add_version_columns.sql` | Optimistic Locking (user_deposits.version) | 2026-01-20 |
| `003_add_server_tables.sql` | server_orders, server_specs 테이블 추가 | 2026-01-28 |
| `004_add_terminated_at.sql` | server_orders.terminated_at 컬럼 추가 | 2026-01-28 |
| `005_add_stopped_status.sql` | server_orders 테이블에 'stopped' 상태 추가 | 2026-01-29 |
**마이그레이션 작업 내용 (001):**
- `deposit_transactions.depositor_name_prefix` 컬럼 추가
@@ -251,7 +254,13 @@ wrangler d1 execute telegram-conversations --file=migrations/001_rollback.sql
- 기존 데이터 backfill (SUBSTR 함수로 자동 채우기)
- 성능: Full Table Scan → Index Scan
**검증 명령:**
**마이그레이션 작업 내용 (005):**
- `server_orders` 테이블 CHECK constraint 수정 (SQLite 제약사항으로 테이블 재생성)
- status 값에 'stopped' 추가 (pending, provisioning, active, stopped, failed, cancelled, terminated)
- 모든 인덱스 재생성 (idx_server_orders_user, idx_server_orders_status, idx_server_orders_idempotency_unique)
- 기존 데이터 보존 (임시 테이블 사용)
**검증 명령 (001):**
```sql
-- 인덱스 사용 확인
EXPLAIN QUERY PLAN
@@ -262,6 +271,20 @@ WHERE status = 'pending' AND type = 'deposit'
-- 결과에 "USING INDEX idx_transactions_prefix_pending" 포함되어야 함
```
**검증 명령 (005):**
```sql
-- CHECK constraint 확인 (stopped 상태 포함 여부)
SELECT sql FROM sqlite_master WHERE name = 'server_orders';
-- 인덱스 존재 확인
SELECT name FROM sqlite_master
WHERE type = 'index' AND tbl_name = 'server_orders';
-- stopped 상태 테스트 (에러 없이 성공해야 함)
-- INSERT INTO server_orders (user_id, spec_id, status, region, price_paid)
-- VALUES (1, 1, 'stopped', 'Tokyo', 1000);
```
---
## Code Style & Conventions
@@ -1353,6 +1376,44 @@ binding = "CLOUD_ORCHESTRATOR"
service = "cloud-orchestrator"
```
### 서버 주문 상태 전이
**상태 정의:**
| 상태 | 설정 주체 | UI 표시 | 설명 |
|------|----------|---------|------|
| `pending` | telegram-bot | ❌ 표시 안 함 | Queue 대기 중 (내부용) |
| `provisioning` | cloud-orchestrator | ✅ 🔄 생성 중... | Cloud Orchestrator 처리 중 |
| `active` | cloud-orchestrator | ✅ 🟢 가동 중 | 서버 준비 완료 |
| `stopped` | cloud-orchestrator | ✅ ⛔ 중지됨 | 서버 중지됨 |
| `failed` | cloud-orchestrator | ❌ 표시 안 함 | 프로비저닝 실패 |
| `terminated` | telegram-bot | ❌ 표시 안 함 | 서버 삭제 완료 |
**상태 전이 흐름:**
```
사용자: "서버 신청"
telegram-bot: POST /api/provision (status = 'pending')
↓ Queue 등록
cloud-orchestrator: Worker 처리
├─ Queue 가져오기 → status = 'provisioning'
├─ Incus 인스턴스 생성 (2-5분)
└─ 완료 → status = 'active'
"내 서버 목록":
- pending: 표시 안 함 (내부용)
- provisioning: "🔄 생성 중..." 표시
- active: "🟢 가동 중" 표시
```
**상태 변경 권한:**
- **telegram-bot**: `pending` 설정 (주문 생성), `terminated` 설정 (삭제 후)
- **cloud-orchestrator**: `provisioning`, `active`, `stopped`, `failed` 설정
**"내 서버 목록" 표시 규칙:**
-**표시**: `provisioning`, `active` (+ provider_instance_id 존재)
-**제외**: `pending`, `failed`, `terminated`, `deleted`
-**제외**: `active`인데 `provider_instance_id`가 없는 경우 (프로비저닝 실패)
---
## Domain System