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

321
docs/CONSTANTS_MIGRATION.md Normal file
View File

@@ -0,0 +1,321 @@
# Constants Migration Guide
**Status**: Constants file created ✅ | Usage migration pending 🚧
This document tracks the migration of magic strings to the centralized `/src/constants/index.ts` file.
## Overview
Magic strings have been extracted into constants for:
- Better maintainability
- Type safety
- Consistency
- Easier refactoring
**Note**: This is a gradual migration. The constants file is ready, but actual usage changes should be done carefully to avoid breaking changes.
## Usage Locations
### SESSION_KEYS.DELETE_CONFIRM (`delete_confirm:`)
**Files using this string:**
- `/src/routes/api/chat.ts:213` - Delete confirmation session creation
- `/src/routes/api/chat.ts:248` - Delete confirmation session retrieval
- `/src/routes/handlers/message-handler.ts:60` - Delete confirmation check
- `/src/tools/server-tool.ts:1005` - Server deletion confirmation
**Migration example:**
```typescript
// Before
const deleteSessionKey = `delete_confirm:${telegramUserId}`;
// After
import { SESSION_KEYS, sessionKey } from './constants';
const deleteSessionKey = sessionKey(SESSION_KEYS.DELETE_CONFIRM, telegramUserId);
```
---
### MESSAGE_MARKERS.DIRECT (`__DIRECT__`)
**Files using this marker:**
- `/src/services/conversation-service.ts:48-51` - Direct marker removal logic
- `/src/openai-service.ts:327-352` - Early return check and processing
- `/src/routes/api/chat.ts:127-130` - Web chat direct marker handling
- `/src/routes/api/chat.ts:426-429` - Another web chat instance
- `/src/tools/server-tool.ts:343-840` - Server tool responses (multiple locations)
- `/src/tools/domain-tool.ts` - Domain tool responses
- `/src/tools/troubleshoot-tool.ts:68` - Troubleshoot tool response
- `/src/summary-service.ts:408` - System prompt instruction
**Migration example:**
```typescript
// Before
if (responseText.includes('__DIRECT__')) {
const directIndex = responseText.indexOf('__DIRECT__');
responseText = responseText.slice(directIndex + '__DIRECT__'.length).trim();
}
// After
import { MESSAGE_MARKERS } from './constants';
if (responseText.includes(MESSAGE_MARKERS.DIRECT)) {
const directIndex = responseText.indexOf(MESSAGE_MARKERS.DIRECT);
responseText = responseText.slice(directIndex + MESSAGE_MARKERS.DIRECT.length).trim();
}
```
---
### MESSAGE_MARKERS.KEYBOARD (`__KEYBOARD__` and `__END__`)
**Files using these markers:**
- `/src/services/conversation-service.ts:69-80` - Keyboard parsing logic
- `/src/openai-service.ts:327-328` - Early return check
- `/src/tools/domain-tool.ts:799` - Keyboard data generation
- `/src/routes/api/chat.ts:127-130` - Web chat (mentioned in grep)
**Migration example:**
```typescript
// Before
const keyboardMatch = responseText.match(/__KEYBOARD__(.+?)__END__\n?/s);
responseText = responseText.replace(/__KEYBOARD__.+?__END__\n?/s, '');
// After
import { MESSAGE_MARKERS } from './constants';
const pattern = new RegExp(`${MESSAGE_MARKERS.KEYBOARD}(.+?)${MESSAGE_MARKERS.KEYBOARD_END}\\n?`, 's');
const keyboardMatch = responseText.match(pattern);
responseText = responseText.replace(pattern, '');
```
---
### MESSAGE_MARKERS.PASSTHROUGH (`__PASSTHROUGH__`)
**Files using this marker:**
- `/src/server-agent.ts:660` - Session end, return to normal conversation
- `/src/server-agent.ts:716` - Another session transition
- `/src/openai-service.ts:233` - Function call result check
- `/src/openai-service.ts:257` - Another function call result check
- `/src/troubleshoot-agent.ts:421` - Agent transition
**Migration example:**
```typescript
// Before
if (result !== '__PASSTHROUGH__') {
return result;
}
// After
import { MESSAGE_MARKERS } from './constants';
if (result !== MESSAGE_MARKERS.PASSTHROUGH) {
return result;
}
```
---
### SESSION_KEYS.SERVER_SESSION (`server_session:`)
**Files using this string:**
- `/src/server-agent.ts` - Server consultation session management
**Migration example:**
```typescript
// Before
const sessionKey = `server_session:${userId}`;
// After
import { SESSION_KEYS, sessionKey } from './constants';
const key = sessionKey(SESSION_KEYS.SERVER_SESSION, userId);
```
---
### TRANSACTION_STATUS values
**Files using these strings:**
- `/src/routes/api/deposit.ts` - Deposit API endpoints
- `/src/tools/deposit-tool.ts` - Deposit tool actions
- `/src/deposit-agent.ts` - Deposit agent logic
- `/src/services/deposit-matcher.ts` - Auto-matching service
- `/src/utils/reconciliation.ts` - Reconciliation job
- `/tests/deposit-agent.test.ts` - Test cases
**Common patterns:**
- `status = 'pending'`
- `status = 'confirmed'`
- `status = 'cancelled'`
- `status = 'rejected'`
**Migration example:**
```typescript
// Before
const result = await env.DB.prepare(
'SELECT * FROM deposit_transactions WHERE status = ?'
).bind('pending').all();
// After
import { TRANSACTION_STATUS } from './constants';
const result = await env.DB.prepare(
'SELECT * FROM deposit_transactions WHERE status = ?'
).bind(TRANSACTION_STATUS.PENDING).all();
```
---
### SERVER_ORDER_STATUS values
**Files using these strings:**
- `/src/tools/server-tool.ts` - Server management tool
- `/src/server-provision.ts` - Server provisioning logic
**Common patterns:**
- `status = 'pending'`
- `status = 'provisioning'`
- `status = 'active'`
- `status = 'failed'`
- `status = 'terminated'`
**Migration example:**
```typescript
// Before
if (order.status === 'active') {
// ...
}
// After
import { SERVER_ORDER_STATUS } from './constants';
if (order.status === SERVER_ORDER_STATUS.ACTIVE) {
// ...
}
```
---
### CALLBACK_PREFIXES values
**Files using these strings:**
- `/src/routes/handlers/callback-query-handler.ts` - Callback query routing
- `/src/tools/domain-tool.ts` - Domain registration buttons
- `/src/tools/server-tool.ts` - Server order buttons
**Common patterns:**
- `confirm_domain_register:example.com:15000`
- `cancel_domain_register:example.com`
- `confirm_server_order:order_123`
**Migration example:**
```typescript
// Before
if (data.startsWith('confirm_domain_register:')) {
// ...
}
// After
import { CALLBACK_PREFIXES } from './constants';
if (data.startsWith(`${CALLBACK_PREFIXES.DOMAIN_REGISTER_CONFIRM}:`)) {
// ...
}
```
---
## Migration Strategy
### Phase 1: Foundation (✅ Complete)
- [x] Create `/src/constants/index.ts`
- [x] Define all constants with proper types
- [x] Add helper functions (`sessionKey`, `parseSessionKey`)
- [x] TypeScript compilation check passes
### Phase 2: High-Priority Migration (🚧 Pending)
**Target**: Critical paths with high maintenance burden
1. **Session keys** (low risk, high benefit)
- `SESSION_KEYS.DELETE_CONFIRM`
- `SESSION_KEYS.SERVER_ORDER_CONFIRM`
- `SESSION_KEYS.SERVER_SESSION`
2. **Transaction status checks** (medium risk, high benefit)
- Database queries with status filters
- Status transitions in business logic
### Phase 3: Message Markers (🚧 Pending)
**Target**: AI response processing
1. **Direct marker processing**
- Standardize removal logic
- Create shared utility function
2. **Keyboard marker processing**
- Centralize regex patterns
- Improve error handling
3. **Passthrough checks**
- Simple find-and-replace
### Phase 4: Complete Migration (📅 Future)
**Target**: All remaining magic strings
- Action constants (SERVER_ACTION, DOMAIN_ACTION, DEPOSIT_ACTION)
- Callback prefixes
- Any remaining hardcoded strings
---
## Testing Checklist
Before merging any migration:
- [ ] TypeScript compilation passes (`npx tsc --noEmit`)
- [ ] All tests pass (`npm test`)
- [ ] Manual testing of affected features
- [ ] No breaking changes to API contracts
- [ ] Documentation updated if needed
---
## Benefits of Migration
1. **Type Safety**: TypeScript can catch typos at compile time
2. **Consistency**: All code uses the same string values
3. **Refactoring**: Change once, update everywhere
4. **Documentation**: Constants serve as inline documentation
5. **IDE Support**: Autocomplete and go-to-definition
---
## Example: Complete Before/After
### Before
```typescript
// Multiple files, inconsistent usage
const key1 = `delete_confirm:${userId}`;
const key2 = 'delete_confirm:' + userId;
if (status === 'pending') { }
if (result === '__PASSTHROUGH__') { }
```
### After
```typescript
import { SESSION_KEYS, TRANSACTION_STATUS, MESSAGE_MARKERS, sessionKey } from './constants';
const key1 = sessionKey(SESSION_KEYS.DELETE_CONFIRM, userId);
const key2 = sessionKey(SESSION_KEYS.DELETE_CONFIRM, userId); // Consistent!
if (status === TRANSACTION_STATUS.PENDING) { }
if (result === MESSAGE_MARKERS.PASSTHROUGH) { }
```
---
## Notes
- **Gradual migration**: Don't rush. Each change should be tested thoroughly.
- **Backward compatibility**: Ensure old code still works during transition.
- **Documentation**: Update CLAUDE.md and README.md when major migrations complete.
- **Communication**: Notify team when changing widely-used constants.
---
**Last Updated**: 2026-01-29
**Status**: Foundation complete, awaiting gradual migration