fix: apply optimistic locking to deposit API and add weather types
Security (P1): - Add optimistic locking to /api/deposit/deduct endpoint - Prevent race conditions on concurrent balance deductions - Return 409 Conflict on version mismatch with retry hint Type Safety (P1): - Add WttrResponse, WttrCurrentCondition, WttrWeatherDay types - Remove `as any` from weather-tool.ts - Add safety checks for malformed API responses Both P1 issues from security review resolved. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,39 @@
|
||||
// Weather Tool - wttr.in integration
|
||||
import type { Env } from '../types';
|
||||
|
||||
// wttr.in API 응답 타입 정의
|
||||
interface WttrCurrentCondition {
|
||||
temp_C: string;
|
||||
FeelsLikeC: string;
|
||||
weatherDesc: Array<{ value: string }>;
|
||||
humidity: string;
|
||||
windspeedKmph: string;
|
||||
winddir16Point: string;
|
||||
uvIndex: string;
|
||||
visibility: string;
|
||||
}
|
||||
|
||||
interface WttrWeatherDay {
|
||||
date: string;
|
||||
maxtempC: string;
|
||||
mintempC: string;
|
||||
hourly: Array<{
|
||||
time: string;
|
||||
tempC: string;
|
||||
weatherDesc: Array<{ value: string }>;
|
||||
chanceofrain: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
interface WttrResponse {
|
||||
current_condition: WttrCurrentCondition[];
|
||||
weather: WttrWeatherDay[];
|
||||
nearest_area: Array<{
|
||||
areaName: Array<{ value: string }>;
|
||||
country: Array<{ value: string }>;
|
||||
}>;
|
||||
}
|
||||
|
||||
export const weatherTool = {
|
||||
type: 'function',
|
||||
function: {
|
||||
@@ -26,8 +59,25 @@ export async function executeWeather(args: { city: string }, env?: Env): Promise
|
||||
const response = await fetch(
|
||||
`${wttrUrl}/${encodeURIComponent(city)}?format=j1`
|
||||
);
|
||||
const data = await response.json() as any;
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`API 응답 실패: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json() as WttrResponse;
|
||||
|
||||
// 안전한 접근 - 데이터 유효성 확인
|
||||
if (!data.current_condition?.[0]) {
|
||||
return `날씨 정보를 가져올 수 없습니다: ${city}`;
|
||||
}
|
||||
|
||||
const current = data.current_condition[0];
|
||||
|
||||
// weatherDesc 배열 존재 확인
|
||||
if (!current.weatherDesc?.[0]?.value) {
|
||||
return `날씨 정보가 불완전합니다: ${city}`;
|
||||
}
|
||||
|
||||
return `🌤 ${city} 날씨
|
||||
온도: ${current.temp_C}°C (체감 ${current.FeelsLikeC}°C)
|
||||
상태: ${current.weatherDesc[0].value}
|
||||
|
||||
Reference in New Issue
Block a user