diff --git a/backend/routes/weather.js b/backend/routes/weather.js index 7178b4a..1e08c19 100644 --- a/backend/routes/weather.js +++ b/backend/routes/weather.js @@ -25,9 +25,56 @@ router.get("/", async (req, res) => { params.q = q || city; } - const response = await axios.get(`${baseUrl}/weather`, { params }); - res.json(response.data); + // 1. Fetch Current Weather (to get lat/lon and timezone) + const currentResponse = await axios.get(`${baseUrl}/weather`, { params }); + const currentData = currentResponse.data; + const { coord } = currentData; + + // 2. Fetch Forecast (for daily min/max) & Air Quality + const [forecastResponse, airResponse] = await Promise.all([ + axios.get(`${baseUrl}/forecast`, { + params: { ...params, lat: coord.lat, lon: coord.lon }, + }), + axios.get(`${baseUrl}/air_pollution`, { + params: { lat: coord.lat, lon: coord.lon, appid: apiKey }, + }), + ]); + + // 3. Process Forecast for Today's Min/Max (Seoul Time: UTC+9) + // OpenWeatherMap returns timestamps in UTC. + // Seoul is UTC+9. + const SeoulOffset = 9 * 60 * 60 * 1000; + const nowKST = new Date(Date.now() + SeoulOffset); + const todayStr = nowKST.toISOString().split("T")[0]; // YYYY-MM-DD in KST + + const todayItems = forecastResponse.data.list.filter((item) => { + const itemDateKST = new Date(item.dt * 1000 + SeoulOffset); + const itemDateStr = itemDateKST.toISOString().split("T")[0]; + return itemDateStr === todayStr; + }); + + if (todayItems.length > 0) { + // Find min and max from the 3-hour segments + const minTemp = Math.min(...todayItems.map((item) => item.main.temp_min)); + const maxTemp = Math.max(...todayItems.map((item) => item.main.temp_max)); + + // Update the response structure + currentData.main.temp_min = minTemp; + currentData.main.temp_max = maxTemp; + } + + // 4. Attach Air Quality (AQI) + // OpenWeatherMap AQI: 1 (Good) ... 5 (Very Poor) + if (airResponse.data.list && airResponse.data.list.length > 0) { + currentData.aqi = airResponse.data.list[0].main.aqi; + } + + res.json(currentData); } catch (error) { + console.error("Weather API Error:", error.message); + if (error.response) { + console.error("Data:", error.response.data); + } res.status(500).json({ message: "Failed to fetch weather" }); } }); diff --git a/flutter_app/android/app/src/main/AndroidManifest.xml b/flutter_app/android/app/src/main/AndroidManifest.xml index a4f82cd..5db760f 100644 --- a/flutter_app/android/app/src/main/AndroidManifest.xml +++ b/flutter_app/android/app/src/main/AndroidManifest.xml @@ -3,6 +3,9 @@ +