Application Settings & Documentation

Application Documentation
Overview of the application's purpose, architecture, and workflow.

Hamilton Rain Event Tracker - Documentation


1. Project Overview


The Hamilton Rain Event Tracker is a web application designed to automate the process of fetching, analyzing, and reporting on rainfall events within the City of Hamilton. It aggregates data from multiple sources, correlates it with specific storm water pond assets, generates rules-based summaries and advice, and produces professional PDF and CSV reports for operational use.


The primary goal is to save time and provide actionable insights for storm water management and maintenance crews.


2. Architecture & Technology Stack


The application is built on a modern, server-centric web stack:


  • **Frontend Framework:** [Next.js](https://nextjs.org/) (with React) using the App Router.
  • **UI Components:** [Shadcn/UI](https://ui.shadcn.com/) - A collection of reusable UI components.
  • **Styling:** [Tailwind CSS](https://tailwindcss.com/) for utility-first styling.
  • **Analysis Engine:** A custom rules-based engine built in TypeScript to generate summaries and advice.
  • **Language:** [TypeScript](https://www.typescriptlang.org/) for type safety and improved developer experience.
  • **Deployment:** Intended for deployment on Firebase App Hosting.

  • 3. Program Flow (End-to-End)


    The core workflow of the application is orchestrated from the client-side Dashboard component.


    1. **User Selects Date:** The user picks a date from the calendar on the main dashboard (src/components/dashboard.tsx).

    2. **Initiate Analysis:** The user clicks the "Start Analysis" button. This triggers the handleAnalysis function in dashboard.tsx.

    3. **Client-Side Orchestration:** The handleAnalysis function acts as the central orchestrator. It makes a series of await-ed calls to the server to fetch data in stages, updating the UI's progress bar after each step.

    4. **Data Fetching (Staged):**

    - The handleAnalysis function sequentially calls the getHistoricalAnalysis server function (src/ai/flows/historical-analysis-flow.ts) for each weather agency ("Open-Meteo", "Environment Canada", and "Weather Underground").

    - **Open-Meteo & Environment Canada:** The function uses the getHourlyRainfallForGauges helper in src/lib/weather-api.ts to make a single, efficient batch API call for all gauges from that source.

    - **Weather Underground:** For "Weather Underground", the getHistoricalAnalysis function iterates through the list of WU gauges sequentially. For each gauge, it awaits the result of the getHourlyRainfallFromWunderground function (src/lib/weather-underground-scraper.ts), which performs the web scraping. This sequential approach ensures robust data collection and returns precise start/stop times.

    5. **Data Correlation:** After all data is fetched and returned to the client, handleAnalysis calls getPondReportForDate (src/lib/data.ts). This function correlates the raw rainfall numbers with the list of storm water ponds, calculating the highest rainfall recorded for each asset.

    6. **Event Magnitude & QA Analysis:** The client then calls getEventMagnitude from src/lib/data.ts. This crucial function:

    - Calculates storm magnitude for each primary (OM) gauge against both **historical** and **projected (2050)** IDF curves.

    - Determines the event's **overall peak magnitude** (highest value from any gauge) and **predominant magnitude** (median value).

    - Performs a **variance analysis** by comparing rainfall totals between paired primary (OM) and secondary (WU) gauges, flagging significant outliers.

    7. **Rules-Based Analysis:** With the correlated data and magnitude analysis, handleAnalysis calls the generateRuleBasedSummary function from src/lib/data.ts. This function uses a deterministic set of rules to generate a professional synopsis and actionable advice, with specific logic to be skeptical of data from flagged outliers.

    8. **UI Update:** The dashboard state is updated with all the fetched data, pond reports, and the generated summary. The results are displayed to the user in the various tables, charts, and cards.

    9. **Report Generation (User-Triggered):**

    - If the rainfall threshold is met, the user is prompted for a Memo ID.

    - The user can click to export a PDF or CSV. This calls the handleExport function.

    - For PDFs, generatePdfReport uses the jspdf and jspdf-autotable libraries to construct a multi-page report. This includes the city logo, an event summary page with high-level statistics, the generated analysis, a detailed list of triggered ponds, and QA/QC tables.

    - For CSVs, helper functions generate a CSV string of the triggered ponds, raw hourly data, or logs, which is then downloaded by the browser.


    4. Managing Hard-Coded Data


    A key aspect of maintaining this application is keeping its core datasets up-to-date. This data is intentionally hard-coded in src/lib/data.ts for simplicity and performance but requires manual updates.


  • **csvData:** A multi-line string variable containing the master list of all storm water ponds. To update, add, or remove a pond, you must edit this string directly, following the existing CSV format.
  • - **Columns:** Facility Number, SWMF ID, Facility Type, Ownership, Operational Maintenance, Municipal Address, Community, Latitude, Longitude, Associated Rain Gauge.lookupValue.

    - The Associated Rain Gauge.lookupValue is crucial, as it links the pond to its primary Open-Meteo rain gauge.


  • **rainGauges:** An array of RainGauge objects. This contains the definitive list of all rain gauges the system can query, including their location, agency, and web address (for WU stations). To add a new gauge, simply add a new object to this array.

  • **gaugeMap:** A key-value object that maps an Open-Meteo gauge (primary) to a corresponding Weather Underground gauge (secondary) for QA/QC comparison.
  • - **To update:** If you add a new OM/WU pair, create a new entry in this map. The key is the title of the Open-Meteo gauge, and the value is the title of the Weather Underground gauge.


  • **IDF Curves:** The projectedIdfCurve and historicalIdfCurve objects contain the Intensity-Duration-Frequency data used for storm magnitude calculations. These should be updated if new climate data becomes available.

  • 5. Potential Future Improvements


  • **CMS for Data Management:** Instead of hard-coding pond and gauge data, integrate a headless CMS (like Firebase Firestore) to manage this data. This would allow non-developers to update assets easily through a web interface.
  • **User Authentication:** Implement user login to track who generates reports and to potentially control access to the application.
  • **Historical Report Database:** Save generated reports (both the data and the AI summary) to a database. This would allow users to view past reports without having to re-run the analysis.
  • **Advanced Charting:** Add more interactive charting features, such as the ability to click on a gauge in the legend to toggle its visibility on the chart.
  • **Automated Report Generation:** Set up a cron job (e.g., using Cloud Scheduler) to automatically run the analysis every day and email the PDF report if the threshold is met.