feat: add optimistic locking and improve type safety

- Implement optimistic locking for deposit balance updates
  - Prevent race conditions in concurrent deposit requests
  - Add automatic retry with exponential backoff (max 3 attempts)
  - Add version column to user_deposits table

- Improve type safety across codebase
  - Add explicit types for Namecheap API responses
  - Add typed function arguments (ManageDepositArgs, etc.)
  - Remove `any` types from deposit-agent and tool files

- Add reconciliation job for balance integrity verification
  - Compare user_deposits.balance vs SUM(confirmed transactions)
  - Alert admin on discrepancy detection

- Set up test environment with Vitest + Miniflare
  - Add 50+ test cases for deposit system
  - Add helper functions for test data creation

- Update documentation
  - Add migration guide for version columns
  - Document optimistic locking patterns

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
kappa
2026-01-19 23:23:09 +09:00
parent 8d0fe30722
commit f5df0c0ffe
21 changed files with 13448 additions and 169 deletions

View File

@@ -111,3 +111,212 @@ export interface BankNotification {
transactionTime?: Date;
rawMessage: string;
}
// Namecheap API 응답 타입
export interface NamecheapPriceResponse {
tld: string;
krw: number;
usd?: number;
register_krw?: number;
renew_krw?: number;
transfer_krw?: number;
}
export interface NamecheapDomainInfo {
name: string;
created: string;
expires: string;
is_expired: boolean;
auto_renew: boolean;
is_locked: boolean;
whois_guard: boolean;
nameservers?: string[];
}
export interface NamecheapCheckResult {
[domain: string]: boolean;
}
export interface NamecheapDomainListItem {
name: string;
created: string;
expires: string;
is_expired: boolean;
auto_renew: boolean;
is_locked: boolean;
whois_guard: boolean;
}
// Function Calling 인자 타입
export interface ManageDomainArgs {
action: 'register' | 'check' | 'whois' | 'list' | 'info' | 'get_ns' | 'set_ns' | 'price' | 'cheapest';
domain?: string;
nameservers?: string[];
tld?: string;
}
export interface ManageDepositArgs {
action: 'balance' | 'account' | 'request' | 'history' | 'cancel' | 'pending' | 'confirm' | 'reject';
depositor_name?: string;
amount?: number;
transaction_id?: number;
limit?: number;
}
export interface SuggestDomainsArgs {
keywords: string;
}
export interface SearchWebArgs {
query: string;
}
export interface LookupDocsArgs {
library: string;
query: string;
}
// Deposit Agent 결과 타입
export interface DepositBalanceResult {
balance: number;
formatted: string;
}
export interface DepositAccountInfoResult {
bank: string;
account: string;
holder: string;
instruction: string;
}
export interface DepositRequestResult {
success: boolean;
auto_matched: boolean;
transaction_id: number;
amount: number;
depositor_name: string;
status?: string;
new_balance?: number;
message: string;
account_info?: {
bank: string;
account: string;
holder: string;
};
}
export interface DepositTransaction {
id: number;
type: string;
amount: number;
status: string;
depositor_name: string;
description: string | null;
created_at: string;
confirmed_at: string | null;
}
export interface DepositTransactionsResult {
transactions: DepositTransaction[];
message?: string;
}
export interface DepositCancelResult {
success: boolean;
transaction_id: number;
message: string;
}
export interface DepositPendingItem {
id: number;
amount: number;
depositor_name: string;
created_at: string;
user: string;
}
export interface DepositPendingResult {
pending: DepositPendingItem[];
message?: string;
}
export interface DepositConfirmResult {
success: boolean;
transaction_id: number;
amount: number;
message: string;
}
export interface DepositRejectResult {
success: boolean;
transaction_id: number;
message: string;
}
export interface DepositErrorResult {
error: string;
}
export type DepositFunctionResult =
| DepositBalanceResult
| DepositAccountInfoResult
| DepositRequestResult
| DepositTransactionsResult
| DepositCancelResult
| DepositPendingResult
| DepositConfirmResult
| DepositRejectResult
| DepositErrorResult;
// Brave Search API 응답 타입
export interface BraveSearchResult {
title: string;
description: string;
url: string;
}
export interface BraveSearchResponse {
web?: {
results: BraveSearchResult[];
};
}
// OpenAI API 응답 타입
export interface OpenAIMessage {
role: string;
content: string;
}
export interface OpenAIChoice {
message: OpenAIMessage;
}
export interface OpenAIResponse {
choices?: OpenAIChoice[];
}
// Context7 API 응답 타입
export interface Context7Library {
id: string;
name: string;
}
export interface Context7SearchResponse {
libraries?: Context7Library[];
}
export interface Context7DocsResponse {
context?: string;
content?: string;
message?: string;
error?: string;
}
// Telegram Inline Keyboard 데이터
export interface DomainRegisterKeyboardData {
type: 'domain_register';
domain: string;
price: number;
}
export type KeyboardData = DomainRegisterKeyboardData;