Skip to content

Commit

Permalink
Merge pull request #20 from RickV85/ai_analysis
Browse files Browse the repository at this point in the history
Ai analysis
  • Loading branch information
RickV85 authored Apr 15, 2024
2 parents 6507f0c + c0d7b02 commit dcf4003
Show file tree
Hide file tree
Showing 20 changed files with 606 additions and 74 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ jobs:
with:
runTests: false
build: npm run build
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

- name: Save .next folder
uses: actions/upload-artifact@v4
Expand Down Expand Up @@ -65,3 +67,4 @@ jobs:
POSTGRES_URL: ${{ secrets.POSTGRES_URL }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ SendTemps is a full-stack Next.js 14 application designed for Colorado Front Ran
- **Seamless User Account Management:** Integrates Google OAuth and NextAuth for a secure, streamlined sign-in experience with persistent sessions, enabling easy access to location customization features.
- **Interactive Mapping:** Features a point-and-click Google Maps interface for easy creation of backcountry locations, with an auto-updating, user-friendly UI.
- **Robust Location Management:** Employs a Vercel PostgreSQL database for durable storage of custom locations, supporting full CRUD operations through Next.js APIs for dynamic user interaction.
- **AI-Powered Recommendations:** Using prompt engineering, integrated AI to analyze forecasts and recommend optimal days to engage in the sports that the user selected location is associated with.
- **Optimized User Experience:** Implements intelligent error handling and automatic retry mechanisms for NOAA forecast API requests, ensuring smooth and informative user interactions.
- **Standalone Display:** Designed for optimal performance on mobile devices, with capabilities for home screen addition, paving the way for full Progressive Web App functionality in the future.
- **Hourly Forecast Display:** New as of 2.26.24 - Provides detailed hourly weather forecasts for more precise activity planning.
Expand All @@ -26,7 +27,6 @@ SendTemps is a full-stack Next.js 14 application designed for Colorado Front Ran
- **Multiple Sport Association:** Enable users to associate multiple sports with a single location for enhanced flexibility.
- **Customizable Default Views:** Allow users to personalize the locations around the Front Range that are loaded by default. This would allow a user to further personalize the application, increasing engagement by reducing irrelevant information.
- **Enhanced Search Functionality:** Implement text-based search with autocomplete to streamline location finding. This would be especially useful if a user has many locations and the current select inputs become too cumbersome.
- **AI-Powered Recommendations:** Using prompt engineering, integrate AI to analyze forecasts and recommend optimal days to engage in the sports that the location is associated with.

## Technical Challenges
- Google OAuth / NextAuth
Expand All @@ -45,6 +45,7 @@ SendTemps is a full-stack Next.js 14 application designed for Colorado Front Ran
- Google OAuth
- NextAuth
- Google Maps API
- OpenAI API
- Vercel Storage
- Cypress E2E Testing

Expand Down
28 changes: 19 additions & 9 deletions cypress/e2e/dailyForecast.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ describe("daily forecast display", () => {
}
);

// Intercept OpenAI AI call
cy.intercept("/api/open_ai/send_score", { fixture: "sendscore.json" });

cy.visit("/");

// Select Climbing in TypeSelect
Expand All @@ -44,19 +47,26 @@ describe("daily forecast display", () => {
.find("p.day-forecast-text")
.should(
"have.text",
"Sunny. High near 57, with temperatures falling to around 52 in the afternoon. West wind 30 to 36 mph, with gusts as high as 54 mph."
"Sunny. High near 57, with temperatures falling to around 52 in the afternoon. West wind 30 to 36 mph, with gusts as high as 54 mph. Humidity 17% to 19% RH."
);
});

it("should display the humidity details if available", () => {
cy.get("@todayForecast")
.find("div.day-header-details>p")
.eq(0)
.should("have.text", "Max 19% RH");
it("should display a summary from AI data", () => {
cy.get("p.send-score-summary").should(
"have.text",
"Thursday is the best day for rock climbing with sunny skies, a high near 51°F, and light west winds. Friday is also a good option with a high near 61°F and light southwest winds. Saturday could work as well with a high near 59°F and mostly clear skies."
);
});

cy.get("@todayForecast")
.find("div.day-header-details>p")
it("should display the SendScore on forecast tiles", () => {
cy.get("article.detailed-day-forecast")
.eq(1)
.should("have.text", "Min 17% RH");
.as("tonightForecast")
.find("div.day-header-details>p")
.should("have.text", "SendScore: 1");
});

it("should display a tip to click on forecast tiles for hourly forecasts", () => {
cy.get("p.hour-forecast-tip").should("be.visible");
});
});
41 changes: 41 additions & 0 deletions cypress/e2e/forecastFetchErrors.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ describe("daily forecast display errors", () => {
}
);

// Intercept OpenAI AI call
cy.intercept("/api/open_ai/send_score", { fixture: "sendscore.json" });

cy.wait(10000);

cy.get("div.loading-msg-div")
Expand Down Expand Up @@ -95,6 +98,9 @@ describe("daily forecast display errors", () => {
}
);

// Intercept OpenAI AI call
cy.intercept("/api/open_ai/send_score", { fixture: "sendscore.json" });

cy.wait(10000);

cy.get("div.loading-msg-div")
Expand All @@ -104,4 +110,39 @@ describe("daily forecast display errors", () => {
"Oh, no! All hourly forecast fetch attempts failed. Please reload the page and try again."
);
});

it("should display an error when the OpenAI fetch fails", () => {
// Intercept Climbing - Lower Boulder Canyon fetchNoaaGridLocation call
cy.intercept("https://api.weather.gov/points/40.004482,-105.355800", {
fixture: "location_details.json",
});

// Intercept Climbing - Lower Boulder Canyon redirected fetchNoaaGridLocation call
cy.intercept("https://api.weather.gov/points/40.0045,-105.3558", {
fixture: "location_details.json",
});

// Intercept Lower Boulder Canyon Detailed daily forecast
cy.intercept("https://api.weather.gov/gridpoints/BOU/51,74/forecast", {
fixture: "detailed_forecast.json",
});

// Intercept Lower Boulder Canyon hourly forecast
cy.intercept(
"https://api.weather.gov/gridpoints/BOU/51,74/forecast/hourly",
{
fixture: "hourly_forecast.json",
}
);

// Intercept OpenAI AI call
cy.intercept("/api/open_ai/send_score", { statusCode: 500 });

cy.get("div.loading-msg-div")
.find("p.error-msg")
.should(
"have.text",
"Oh, no! An error occurred while creating SendScores."
);
});
});
3 changes: 3 additions & 0 deletions cypress/e2e/hourlyForecast.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ describe("hourly forecast display", () => {
}
);

// Intercept OpenAI AI call
cy.intercept("/api/open_ai/send_score", { fixture: "sendscore.json" });

cy.visit("/");

// Select Climbing in TypeSelect
Expand Down
61 changes: 61 additions & 0 deletions cypress/fixtures/sendscore.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"summary": "Thursday is the best day for rock climbing with sunny skies, a high near 51°F, and light west winds. Friday is also a good option with a high near 61°F and light southwest winds. Saturday could work as well with a high near 59°F and mostly clear skies.",
"forecastPeriods": [
{
"name": "This Afternoon",
"sendScore": 3
},
{
"name": "Tonight",
"sendScore": 1
},
{
"name": "Thursday",
"sendScore": 8
},
{
"name": "Thursday Night",
"sendScore": 2
},
{
"name": "Friday",
"sendScore": 7
},
{
"name": "Friday Night",
"sendScore": 3
},
{
"name": "Saturday",
"sendScore": 6
},
{
"name": "Saturday Night",
"sendScore": 2
},
{
"name": "Sunday",
"sendScore": 4
},
{
"name": "Sunday Night",
"sendScore": 1
},
{
"name": "Monday",
"sendScore": 3
},
{
"name": "Monday Night",
"sendScore": 1
},
{
"name": "Tuesday",
"sendScore": 3
},
{
"name": "Tuesday Night",
"sendScore": 1
}
]
}
Loading

0 comments on commit dcf4003

Please sign in to comment.