From c5ee417b82fb49aa83043513be41a64b1613ff18 Mon Sep 17 00:00:00 2001
From: tuckersiegel <siegel.tucker@gmail.com>
Date: Mon, 22 Feb 2021 21:07:31 -0500
Subject: [PATCH] major refactor

---
 controllers/gddAccumulatedController.js       | 125 ++++++++
 controllers/gddController.js                  | 125 ++++++++
 controllers/gddNormalController.js            | 102 ++++++
 gddController.js                              | 290 ------------------
 lib/utils.js                                  |  44 +++
 routes.js                                     | 203 ------------
 .../product/accumulated/accumulated_year.js   |   6 +
 routes/api/product/daily/daily_year.js        |   6 +
 routes/api/product/normal/normal.js           |   6 +
 routes/api/product/product_index.js           |   7 +
 routes/index.js                               |   5 +
 server.js                                     |   4 +-
 swagger_definition.yaml                       | 276 +++++++++++++++++
 13 files changed, 704 insertions(+), 495 deletions(-)
 create mode 100644 controllers/gddAccumulatedController.js
 create mode 100644 controllers/gddController.js
 create mode 100644 controllers/gddNormalController.js
 delete mode 100644 gddController.js
 create mode 100644 lib/utils.js
 delete mode 100644 routes.js
 create mode 100644 routes/api/product/accumulated/accumulated_year.js
 create mode 100644 routes/api/product/daily/daily_year.js
 create mode 100644 routes/api/product/normal/normal.js
 create mode 100644 routes/api/product/product_index.js
 create mode 100644 routes/index.js
 create mode 100644 swagger_definition.yaml

diff --git a/controllers/gddAccumulatedController.js b/controllers/gddAccumulatedController.js
new file mode 100644
index 0000000..d9fb707
--- /dev/null
+++ b/controllers/gddAccumulatedController.js
@@ -0,0 +1,125 @@
+gdd = require('../models/gdd.js');
+gdd_current = require('../models/gdd_current.js');
+utils = require('../lib/utils');
+
+function send_response(message, gdds, data, res) {
+    res.json({
+        message: message,
+        date: data["last_date"],
+        data: gdds,
+        closest_lon: data["location"]["coordinates"][0],
+        closest_lat: data["location"]["coordinates"][1]
+    })
+}
+
+function find(collection, query, projection, temps, res) {
+    collection.findOne(query, projection).then(function(data) {
+        var min_temps = data["min_temps"]
+        var max_temps = data["max_temps"]
+        var gdds = [];
+
+        var { t_base, t_max, t_min } = temps;
+        
+        var min_temp = 0
+        var max_temp = 0
+
+        var gdd_sum = 0;
+        
+        for (var i = 0; i < min_temps.length; i++) {
+            min_temp = min_temps[i] >= t_min ? min_temps[i] : t_min;
+            max_temp = max_temps[i] <= t_max ? max_temps[i] : t_max;
+            gdd_sum += ((max_temp + min_temp) / 2) - t_base
+            gdds.push(gdd_sum)
+        }
+        send_response("Accumulated GDDs", gdds, data, res);
+    }, function(err) {
+        res.status(500).send({"internal error": err})
+    })
+}
+
+
+exports.accumulated_gdd = function (req, res) {
+
+    var year = parseInt(req.params.year);
+    var product = req.params.product;
+
+    var latitude = parseFloat(req.body.latitude)
+    var longitude = parseFloat(req.body.longitude)
+
+    var query = {
+        location: { 
+            "$near": {
+                "$geometry": {
+                    "type": "Point", 
+                    "coordinates": [longitude, latitude]
+                },
+            },
+        },
+        year: year,
+    }
+
+    var t_base = 50
+    var t_max = 86
+    var t_min = 50 
+
+    errors = []
+
+    if (year < 1981 || year > new Date().getFullYear()) {
+        errors.push({
+            parameter_error: "year",
+            message: year.toString() + " is out of bounds for GDD calculations. Must be between 1981 - Current Year"
+        });
+    }
+
+    if (latitude < 24.083334 || latitude > 49.916668) {
+        errors.push({
+            parameter_error: "latitude",
+            message: latitude.toString() + " is out of bounds for GDD calculations. Must be between 24.083334 - 49.916668"
+        });
+    }
+
+    if (req.body.hasOwnProperty("t_base")) {
+        t_base = parseFloat(req.body.t_base);
+        if (t_base < t_min) {
+            t_min = t_base;
+        }
+    } else {
+        out = utils.product_base_switch(product, errors);
+        t_base = out.t_base;
+        t_min = out.t_min;
+        errors = out.errors;
+    }
+    
+
+    if (longitude < -125 || longitude > -66.5) {
+        errors.push({
+            parameter_error: "longitude",
+            message: longitude.toString() + " is out of bounds for GDD calculations. Must be between -125.0 - -66.5"
+        });
+    }
+
+    if (errors.length > 0) {
+        res.status(400).send({
+            errors: errors
+        })
+    }
+
+    var projection = {
+        min_temps: 1,
+        max_temps: 1,
+        location: 1,
+    }
+
+    temps = {
+        t_base: t_base,
+        t_max: t_max,
+        t_min: t_min,
+    }
+
+    if (year != new Date().getFullYear()) {
+        find(gdd, query, projection, temps, res);
+    } else {
+        find(gdd_current, query, projection, temps, res);
+    }
+   
+};
\ No newline at end of file
diff --git a/controllers/gddController.js b/controllers/gddController.js
new file mode 100644
index 0000000..95302f3
--- /dev/null
+++ b/controllers/gddController.js
@@ -0,0 +1,125 @@
+gdd = require('../models/gdd.js');
+gdd_current = require('../models/gdd_current.js');
+utils = require('../lib/utils');
+
+
+
+function send_response(message, gdds, data, res) {
+    res.json({
+        message: message,
+        date: data["last_date"],
+        data: gdds,
+        closest_lon: data["location"]["coordinates"][0],
+        closest_lat: data["location"]["coordinates"][1]
+    })
+}
+
+function find(collection, query, projection, temps, res) {
+    collection.findOne(query, projection).then(function(data) {
+        var min_temps = data["min_temps"]
+        var max_temps = data["max_temps"]
+        var gdds = [];
+
+        var { t_base, t_max, t_min } = temps;
+        
+        var min_temp = 0
+        var max_temp = 0
+        
+        for (var i = 0; i < min_temps.length; i++) {
+            min_temp = min_temps[i] >= t_min ? min_temps[i] : t_min;
+            max_temp = max_temps[i] <= t_max ? max_temps[i] : t_max;
+
+            gdds.push(((max_temp + min_temp) / 2) - t_base)
+        }
+        send_response("GDDs", gdds, data, res);
+    }, function(err) {
+        res.status(500).send({"internal error": err})
+    })
+}
+
+
+exports.year_gdd = function (req, res) {
+
+    var year = parseInt(req.params.year);
+    var product = req.params.product;
+
+    var latitude = parseFloat(req.body.latitude)
+    var longitude = parseFloat(req.body.longitude)
+
+    var query = {
+        location: { 
+            "$near": {
+                "$geometry": {
+                    "type": "Point", 
+                    "coordinates": [longitude, latitude]
+                },
+            },
+        },
+        year: year,
+    }
+
+    var t_base = 50
+    var t_max = 86
+    var t_min = 50 
+
+    errors = []
+
+    if (year < 1981 || year > new Date().getFullYear()) {
+        errors.push({
+            parameter_error: "year",
+            message: year.toString() + " is out of bounds for GDD calculations. Must be between 1981 - Current Year"
+        });
+    }
+
+    if (latitude < 24.083334 || latitude > 49.916668) {
+        errors.push({
+            parameter_error: "latitude",
+            message: latitude.toString() + " is out of bounds for GDD calculations. Must be between 24.083334 - 49.916668"
+        });
+    }
+
+    if (req.body.hasOwnProperty("t_base")) {
+        t_base = parseFloat(req.body.t_base);
+        if (t_base < t_min) {
+            t_min = t_base;
+        }
+    } else {
+        out = utils.product_base_switch(product, errors);
+        t_base = out.t_base;
+        t_min = out.t_min;
+        errors = out.errors;
+    }
+    
+
+    if (longitude < -125 || longitude > -66.5) {
+        errors.push({
+            parameter_error: "longitude",
+            message: longitude.toString() + " is out of bounds for GDD calculations. Must be between -125.0 - -66.5"
+        });
+    }
+
+    if (errors.length > 0) {
+        res.status(400).send({
+            errors: errors
+        })
+    }
+
+    var projection = {
+        min_temps: 1,
+        max_temps: 1,
+        location: 1,
+    }
+
+    temps = {
+        t_base: t_base,
+        t_max: t_max,
+        t_min: t_min,
+    }
+
+    if (year != new Date().getFullYear()) {
+        find(gdd, query, projection, temps, res);
+    } else {
+        find(gdd_current, query, projection, temps, res);
+    }
+   
+};
\ No newline at end of file
diff --git a/controllers/gddNormalController.js b/controllers/gddNormalController.js
new file mode 100644
index 0000000..54f8a01
--- /dev/null
+++ b/controllers/gddNormalController.js
@@ -0,0 +1,102 @@
+normals = require('../models/normals.js');
+utils = require('../lib/utils');
+
+function find(collection, query, projection, temps, res) {
+    collection.findOne(query, projection).then(function(data) {
+        var min_temps = data["min_temps"]
+        var max_temps = data["max_temps"]
+        var gdds = [];
+
+        var { t_base, t_max, t_min } = temps;
+        
+        var min_temp = 0
+        var max_temp = 0
+
+        for (var i = 0; i < min_temps.length; i++) {
+            min_temp = min_temps[i] >= t_min ? min_temps[i] : t_min;
+            max_temp = max_temps[i] <= t_max ? max_temps[i] : t_max;
+            gdds.push(((max_temp + min_temp) / 2) - t_base)
+        }
+
+        res.json({
+            message: "30-year Normal GDDs",
+            data: gdds,
+            closest_lon: data["location"]["coordinates"][0],
+            closest_lat: data["location"]["coordinates"][1]
+        })
+    }, function(err) {
+        res.status(500).send({"internal error": err})
+    })
+}
+
+
+exports.normal = function (req, res) {
+
+    var product = req.params.product;
+
+    var latitude = parseFloat(req.body.latitude)
+    var longitude = parseFloat(req.body.longitude)
+    
+    var query = {
+        location: { 
+            "$near": {
+                "$geometry": {
+                    "type": "Point", 
+                    "coordinates": [longitude, latitude]
+                },
+            },
+        },
+    }
+
+    var projection = {
+        min_temps: 1,
+        max_temps: 1,
+        location: 1,
+    }
+    
+    var t_base = 50
+    var t_max = 86
+    var t_min = 50 
+
+    errors = []
+
+    if (latitude < 24.083334 || latitude > 49.916668) {
+        errors.push({
+            parameter_error: "latitude",
+            message: latitude.toString() + " is out of bounds for GDD calculations. Must be between 24.083334 - 49.916668"
+        });
+    }
+
+    if (req.body.hasOwnProperty("t_base")) {
+        t_base = parseFloat(req.body.t_base);
+        if (t_base < t_min) {
+            t_min = t_base;
+        }
+    } else {
+        out = utils.product_base_switch(product, errors);
+        t_base = out.t_base;
+        t_min = out.t_min;
+        errors = out.errors;
+    }
+
+    if (longitude < -125 || longitude > -66.5) {
+        errors.push({
+            parameter_error: "longitude",
+            message: longitude.toString() + " is out of bounds for GDD calculations. Must be between -125.0 - -66.5"
+        });
+    }
+
+    if (errors.length > 0) {
+        res.status(400).send({
+            errors: errors
+        })
+    }
+
+    temps = {
+        t_base: t_base,
+        t_max: t_max,
+        t_min: t_min,
+    }
+
+    find(normals, query, projection, temps, res);
+};
\ No newline at end of file
diff --git a/gddController.js b/gddController.js
deleted file mode 100644
index dc82891..0000000
--- a/gddController.js
+++ /dev/null
@@ -1,290 +0,0 @@
-gdd = require('./models/gdd.js');
-gdd_current = require('./models/gdd_current.js');
-normals = require('./models/normals.js');
-
-function isNumeric(value) {
-    return /^-?\d+$/.test(value);
-}
-
-exports.year_gdd = function (req, res) {
-    if (!isNumeric(req.params.year)) {
-        res.status(400).send({"parameter error": "\"year\" parameter is not an integer"})
-    }
-    var year = parseInt(req.params.year);
-    var product = req.params.product;
-
-    if (typeof req.body.latitude === "undefined" || typeof req.body.longitude === "undefined") {
-        res.status(400).send({"parameter error": "missing latitude or longitude"})
-    }
-
-    var latitude = parseFloat(req.body.latitude)
-    var longitude = parseFloat(req.body.longitude)
-
-    var query = {
-        location: { 
-            "$near": {
-                "$geometry": {
-                    "type": "Point", 
-                    "coordinates": [longitude, latitude]
-                },
-            },
-        },
-        year: year,
-    }
-
-    var projection = {
-        min_temps: 1,
-        max_temps: 1,
-        location: 1,
-    }
-    
-    var t_base = 50
-    var t_max = 86
-    var t_min = 50 
-
-    errors = []
-
-    if (year < 1981 || year > new Date().getFullYear()) {
-        errors.push({
-            parameter_error: "year",
-            message: year.toString() + " is out of bounds for GDD calculations. Must be between 1981 - Current Year"
-        });
-    }
-
-    if (latitude < 24.083334 || latitude > 49.916668) {
-        errors.push({
-            parameter_error: "latitude",
-            message: latitude.toString() + " is out of bounds for GDD calculations. Must be between 24.083334 - 49.916668"
-        });
-    }
-
-    if (req.body.hasOwnProperty("t_base")) {
-        t_base = parseFloat(req.body.t_base);
-        if (t_base < t_min) {
-            t_min = t_base;
-        }
-    } else {
-        switch (product) {
-            case "soybean":
-            case "corn":
-            case "sunflower":
-            case "tomato":
-            case "sugar_beat":
-                t_base = 50;
-                break;
-            case "potato":
-                t_base = 44.6;
-                t_min = 44.6; // NEED TO ASK ABOUT MIN AND MAX TEMPS IN DAY. SHOULD T_MIN BE SET EQUAL TO T_BASE IF IT IS LESS THAN T_BASE?
-                break;
-            case "wheat":
-                t_base = 41.9;
-                t_min = 41.9;
-                break;
-            case "peas":
-                t_base = 41;
-                t_min = 41;
-                break;
-            case "brussels_sprout":
-            case "parsley":
-            case "cabbage":
-                t_base = 32;
-                t_min = 32;
-                break;
-            default:
-                errors.push({
-                    parameter_error: "product",
-                    message: product + " is not available for GDD calculations"
-                });
-                break;
-        }
-    }
-
-    if (longitude < -125 || longitude > -66.5) {
-        errors.push({
-            parameter_error: "longitude",
-            message: longitude.toString() + " is out of bounds for GDD calculations. Must be between -125.0 - -66.5"
-        });
-    }
-
-    if (errors.length > 0) {
-        res.status(400).send({
-            errors: errors
-        })
-    }
-    if (year != new Date().getFullYear()) {
-        gdd.findOne(query, projection).then(function(data) {
-            var min_temps = data["min_temps"]
-            var max_temps = data["max_temps"]
-            var gdds = [];
-            
-            var min_temp = 0
-            var max_temp = 0
-    
-            for (var i = 0; i < min_temps.length; i++) {
-                min_temp = min_temps[i] >= t_min ? min_temps[i] : t_min;
-                max_temp = max_temps[i] <= t_max ? max_temps[i] : t_max;
-                gdds.push(((max_temp + min_temp) / 2) - t_base)
-            }
-    
-            res.json({
-                message: "GDDs",
-                date: data["last_date"],
-                data: gdds,
-                closest_lon: data["location"]["coordinates"][0],
-                closest_lat: data["location"]["coordinates"][1]
-            })
-    
-        }, function(err) {
-            console.log(err);
-        })
-    } else {
-        gdd_current.findOne(query, projection).then(function(data) {
-            var min_temps = data["min_temps"]
-            var max_temps = data["max_temps"]
-            var gdds = [];
-            
-            var min_temp = 0
-            var max_temp = 0
-    
-            for (var i = 0; i < min_temps.length; i++) {
-                min_temp = min_temps[i] >= t_min ? min_temps[i] : t_min;
-                max_temp = max_temps[i] <= t_max ? max_temps[i] : t_max;
-                gdds.push(((max_temp + min_temp) / 2) - t_base)
-            }
-    
-            res.json({
-                message: "GDDs",
-                date: data["last_date"],
-                data: gdds,
-                closest_lon: data["location"]["coordinates"][0],
-                closest_lat: data["location"]["coordinates"][1]
-            })
-    
-        }, function(err) {
-            console.log(err);
-        })
-    }
-   
-};
-
-exports.normal = function (req, res) {
-
-    var product = req.params.product;
-
-    if (typeof req.body.latitude === "undefined" || typeof req.body.longitude === "undefined") {
-        res.status(400).send({"parameter error": "missing latitude or longitude"})
-    }
-
-    var latitude = parseFloat(req.body.latitude)
-    var longitude = parseFloat(req.body.longitude)
-    
-    var query = {
-        location: { 
-            "$near": {
-                "$geometry": {
-                    "type": "Point", 
-                    "coordinates": [longitude, latitude]
-                },
-            },
-        },
-    }
-
-    var projection = {
-        min_temps: 1,
-        max_temps: 1,
-        location: 1,
-    }
-    
-    var t_base = 50
-    var t_max = 86
-    var t_min = 50 
-
-    errors = []
-
-    if (latitude < 24.083334 || latitude > 49.916668) {
-        errors.push({
-            parameter_error: "latitude",
-            message: latitude.toString() + " is out of bounds for GDD calculations. Must be between 24.083334 - 49.916668"
-        });
-    }
-
-    if (req.body.hasOwnProperty("t_base")) {
-        t_base = parseFloat(req.body.t_base);
-        if (t_base < t_min) {
-            t_min = t_base;
-        }
-    } else {
-        switch (product) {
-            case "soybean":
-            case "corn":
-            case "sunflower":
-            case "tomato":
-            case "sugar_beat":
-                t_base = 50;
-                break;
-            case "potato":
-                t_base = 44.6;
-                t_min = 44.6; // NEED TO ASK ABOUT MIN AND MAX TEMPS IN DAY. SHOULD T_MIN BE SET EQUAL TO T_BASE IF IT IS LESS THAN T_BASE?
-                break;
-            case "wheat":
-                t_base = 41.9;
-                t_min = 41.9;
-                break;
-            case "peas":
-                t_base = 41;
-                t_min = 41;
-                break;
-            case "brussels_sprout":
-            case "parsley":
-            case "cabbage":
-                t_base = 32;
-                t_min = 32;
-                break;
-            default:
-                errors.push({
-                    parameter_error: "product",
-                    message: product + " is not available for GDD calculations"
-                });
-                break;
-        }
-    }
-
-    if (longitude < -125 || longitude > -66.5) {
-        errors.push({
-            parameter_error: "longitude",
-            message: longitude.toString() + " is out of bounds for GDD calculations. Must be between -125.0 - -66.5"
-        });
-    }
-
-    if (errors.length > 0) {
-        res.status(400).send({
-            errors: errors
-        })
-    }
-
-    normals.findOne(query, projection).then(function(data) {
-        var min_temps = data["min_temps"]
-        var max_temps = data["max_temps"]
-        var gdds = [];
-        
-        var min_temp = 0
-        var max_temp = 0
-
-        for (var i = 0; i < min_temps.length; i++) {
-            min_temp = min_temps[i] >= t_min ? min_temps[i] : t_min;
-            max_temp = max_temps[i] <= t_max ? max_temps[i] : t_max;
-            gdds.push(((max_temp + min_temp) / 2) - t_base)
-        }
-
-        res.json({
-            message: "30-year Normal GDDs",
-            data: gdds,
-            closest_lon: data["location"]["coordinates"][0],
-            closest_lat: data["location"]["coordinates"][1]
-        })
-
-    }, function(err) {
-        console.log(err);
-    })
-   
-};
diff --git a/lib/utils.js b/lib/utils.js
new file mode 100644
index 0000000..72d51f4
--- /dev/null
+++ b/lib/utils.js
@@ -0,0 +1,44 @@
+
+function product_base_switch(product, errors) {
+    switch (product) {
+        case "soybean":
+        case "corn":
+        case "sunflower":
+        case "tomato":
+        case "sugar_beat":
+            t_base = 50;
+            t_min = 50;
+            break;
+        case "potato":
+            t_base = 44.6;
+            t_min = 44.6; // NEED TO ASK ABOUT MIN AND MAX TEMPS IN DAY. SHOULD T_MIN BE SET EQUAL TO T_BASE IF IT IS LESS THAN T_BASE?
+            break;
+        case "wheat":
+            t_base = 41.9;
+            t_min = 41.9;
+            break;
+        case "peas":
+            t_base = 41;
+            t_min = 41;
+            break;
+        case "brussels_sprout":
+        case "parsley":
+        case "cabbage":
+            t_base = 32;
+            t_min = 32;
+            break;
+        default:
+            errors.push({
+                parameter_error: "product",
+                message: product + " is not available for GDD calculations"
+            });
+            break;
+    }
+    return {
+        t_base: t_base,
+        t_min: t_min,
+        errors: errors
+    }
+}
+
+module.exports.product_base_switch = product_base_switch;
\ No newline at end of file
diff --git a/routes.js b/routes.js
deleted file mode 100644
index 6a75791..0000000
--- a/routes.js
+++ /dev/null
@@ -1,203 +0,0 @@
-
-let router = require('express').Router();
-
-var gddController = require('./gddController');
-/**
- * @swagger        
- * /api/{product}/daily/{year}:
- *      post:
- *          summary: Returns GDD data
- *          description: Returns GDD data for a specific product, year, lat, and lon
- *          produces:
- *              - application/json
- *          consumes:
- *              - application/json
- *          parameters:
- *            - in: path
- *              name: product
- *              required: true
- *              description: Agricultural product to calculate gdd for
- *              schema:
- *                  type: string
- *                  enum: [corn, soybean, sugar_beet, sunflower, tomato, potato, wheat, peas, parsley, brussels_sprouts, cabbage]
- *            - in: path
- *              name: year
- *              required: true
- *              description: Year to calculate gdd on
- *              schema:
- *                  type: integer
- *                  minimum: 1981
- *          requestBody:
- *              content:
- *                  application/json:
- *                      schema:
- *                          type: object
- *                          required:
- *                              - longitude
- *                              - latitude
- *                          properties:
- *                              latitude:
- *                                  description: latitude to calculate gdd on
- *                                  type: number
- *                                  minimum: 24.083334
- *                                  maximum: 49.916668
- *                                  example: 38.99
- *                              longitude:
- *                                  description: longitude to calculate gdd on
- *                                  type: number
- *                                  minimum: -125.0
- *                                  maximum: -66.5
- *                                  example: -76.94
- *                              t_base:
- *                                  description: Base temperature to calculate gdd on, in fahrenheit. NOT REQUIRED
- *                                  type: number
- *                                  example: 50
- *                  
- *          responses:
- *              200:
- *                  description: Success
- *                  content:
- *                      application/json:
- *                          schema:
- *                              type: object
- *                              properties:
- *                                  message:
- *                                      type: string
- *                                      example: GDDs
- *                                  date:
- *                                      type: string
- *                                      format: date
- *                                  data:
- *                                      type: array
- *                                      items:
- *                                          type: number
- *                                      minItems: 1
- *                                      maxItems: 365
- *                                  closest_lat:
- *                                      type: number
- *                                      minimum: 24.083334
- *                                      maximum: 49.916668
- *                                      example: 38.99
- *                                  closest_lon:
- *                                      type: number
- *                                      minimum: -125.0
- *                                      maximum: -66.5
- *                                      example: -76.94
- *              400:
- *                  description: Bad Request
- *                  content:
- *                      application/json:
- *                          schema:
- *                              type: object
- *                              properties:
- *                                  errors:
- *                                      type: array
- *                                      items:
- *                                          type: object
- *                                          properties:
- *                                              parameter_error:
- *                                                  type: string
- *                                                  example: latitude
- *                                              message:
- *                                                  type: string
- *                                                  example: 22.5 is out of bounds for GDD calculations. Must be between 24.083334 - 49.916668
- * 
-/api/{product}/normal:
- *      post:
- *          summary: Returns GDD data on a 30 year normal
- *          description: Returns GDD normals for a specific lat, and lon
- *          parameters:
- *            - in: path
- *              name: product
- *              required: true
- *              description: Agricultural product to calculate gdd for
- *              schema:
- *                  type: string
- *                  enum: [corn, soybean, sugar_beet, sunflower, tomato, potato, wheat, peas, parsley, brussels_sprouts, cabbage]
- *          requestBody:
- *              content:
- *                  application/json:
- *                      schema:
- *                          type: object
- *                          required:
- *                              - longitude
- *                              - latitude
- *                          properties:
- *                              latitude:
- *                                  description: latitude to calculate gdd on
- *                                  type: number
- *                                  minimum: 24.083334
- *                                  maximum: 49.916668
- *                                  example: 38.99
- *                              longitude:
- *                                  description: longitude to calculate gdd on
- *                                  type: number
- *                                  minimum: -125.0
- *                                  maximum: -66.5
- *                                  example: -76.94
- *                              t_base:
- *                                  description: Base temperature to calculate gdd on, in fahrenheit. NOT REQUIRED
- *                                  type: number
- *                                  example: 50
- *                  
- *          responses:
- *              200:
- *                  description: Success
- *                  content:
- *                      application/json:
- *                          schema:
- *                              type: object
- *                              properties:
- *                                  message:
- *                                      type: string
- *                                      example: 30-year normal GDDs
- *                                  data:
- *                                      type: array
- *                                      items:
- *                                          type: number
- *                                  closest_lat:
- *                                      type: number
- *                                      minimum: 24.083334
- *                                      maximum: 49.916668
- *                                      example: 38.99
- *                                  closest_lon:
- *                                      type: number
- *                                      minimum: -125.0
- *                                      maximum: -66.5
- *                                      example: -78.5
- *              400:
- *                  description: Bad Request
- *                  content:
- *                      application/json:
- *                          schema:
- *                              type: object
- *                              properties:
- *                                  errors:
- *                                      type: array
- *                                      items:
- *                                          type: object
- *                                          properties:
- *                                              parameter_error:
- *                                                  type: string
- *                                                  example: latitude
- *                                              message:
- *                                                  type: string
- *                                                  example: 22.5 is out of bounds for GDD calculations. Must be between 24.083334 - 49.916668
- * 
- * 
- *                  
- *                          
- *                       
- *                          
- *          
-*/
-router.route('/:product/daily/:year')
-    .post(gddController.year_gdd)
-
-router.route('/:product/normal')
-    .post(gddController.normal)
-
-module.exports = router;
-
-
-
diff --git a/routes/api/product/accumulated/accumulated_year.js b/routes/api/product/accumulated/accumulated_year.js
new file mode 100644
index 0000000..42830e8
--- /dev/null
+++ b/routes/api/product/accumulated/accumulated_year.js
@@ -0,0 +1,6 @@
+const router = require('express').Router();
+const controller = require("../../../../controllers/gddAccumulatedController")
+
+router.route("/:year").post(controller.accumulated_gdd)
+
+module.exports = router;
diff --git a/routes/api/product/daily/daily_year.js b/routes/api/product/daily/daily_year.js
new file mode 100644
index 0000000..4b74c66
--- /dev/null
+++ b/routes/api/product/daily/daily_year.js
@@ -0,0 +1,6 @@
+const router = require('express').Router();
+const controller = require("../../../../controllers/gddController")
+
+router.route("/:year").post(controller.year_gdd)
+
+module.exports = router;
diff --git a/routes/api/product/normal/normal.js b/routes/api/product/normal/normal.js
new file mode 100644
index 0000000..302bccc
--- /dev/null
+++ b/routes/api/product/normal/normal.js
@@ -0,0 +1,6 @@
+const router = require('express').Router();
+const controller = require("../../../../controllers/gddNormalController")
+
+router.route("/").post(controller.normal)
+
+module.exports = router;
diff --git a/routes/api/product/product_index.js b/routes/api/product/product_index.js
new file mode 100644
index 0000000..d669452
--- /dev/null
+++ b/routes/api/product/product_index.js
@@ -0,0 +1,7 @@
+const router = require('express').Router();
+
+router.use('/normal', require('./normal/normal'));
+router.use('/daily', require('./daily/daily_year'));
+router.use('/accumulated', require('./accumulated/accumulated_year'));
+
+module.exports = router;
diff --git a/routes/index.js b/routes/index.js
new file mode 100644
index 0000000..30955b1
--- /dev/null
+++ b/routes/index.js
@@ -0,0 +1,5 @@
+const router = require('express').Router();
+
+router.use('/:product', require('./api/product/product_index'));
+
+module.exports = router;
diff --git a/server.js b/server.js
index efccad9..fcfa29e 100644
--- a/server.js
+++ b/server.js
@@ -13,7 +13,7 @@ const port = 4000;
 
 const app = express();
 
-let apiRoutes = require("./routes")
+let apiRoutes = require("./routes/index")
 
 app.use(express.json());
 app.use(express.urlencoded({extended: true}));
@@ -33,7 +33,7 @@ const swaggerDefinition = {
   
   const swagger_options = {
     swaggerDefinition,
-    apis: ['./routes.js'],
+    apis: ['./swagger_definition.yaml'],
   };
 
 const swaggerSpec = swaggerJSDoc(swagger_options);
diff --git a/swagger_definition.yaml b/swagger_definition.yaml
new file mode 100644
index 0000000..b9113e5
--- /dev/null
+++ b/swagger_definition.yaml
@@ -0,0 +1,276 @@
+paths:
+    /api/{product}/daily/{year}:
+      post:
+        summary: Returns GDD data
+        description: Returns GDD data for a specific product, year, lat, and lon
+        produces:
+            - application/json
+        consumes:
+            - application/json
+        parameters:
+          - in: path
+            name: product
+            required: true
+            description: Agricultural product to calculate gdd for
+            schema:
+                type: string
+                enum: [corn, soybean, sugar_beet, sunflower, tomato, potato, wheat, peas, parsley, brussels_sprouts, cabbage]
+          - in: path
+            name: year
+            required: true
+            description: Year to calculate gdd on
+            schema:
+                type: integer
+                minimum: 1981
+        requestBody:
+            content:
+                application/json:
+                    schema:
+                        type: object
+                        required:
+                            - longitude
+                            - latitude
+                        properties:
+                            latitude:
+                                description: latitude to calculate gdd on
+                                type: number
+                                minimum: 24.083334
+                                maximum: 49.916668
+                                example: 38.99
+                            longitude:
+                                description: longitude to calculate gdd on
+                                type: number
+                                minimum: -125.0
+                                maximum: -66.5
+                                example: -76.94
+                            t_base:
+                                description: Base temperature to calculate gdd on, in fahrenheit. NOT REQUIRED
+                                type: number
+                                example: 50
+                
+        responses:
+            200:
+                description: Success
+                content:
+                    application/json:
+                        schema:
+                            type: object
+                            properties:
+                                message:
+                                    type: string
+                                    example: GDDs
+                                date:
+                                    type: string
+                                    format: date
+                                data:
+                                    type: array
+                                    items:
+                                        type: number
+                                    minItems: 1
+                                    maxItems: 365
+                                closest_lat:
+                                    type: number
+                                    minimum: 24.083334
+                                    maximum: 49.916668
+                                    example: 38.99
+                                closest_lon:
+                                    type: number
+                                    minimum: -125.0
+                                    maximum: -66.5
+                                    example: -76.94
+            400:
+                description: Bad Request
+                content:
+                    application/json:
+                        schema:
+                            type: object
+                            properties:
+                                errors:
+                                    type: array
+                                    items:
+                                        type: object
+                                        properties:
+                                            parameter_error:
+                                                type: string
+                                                example: latitude
+                                            message:
+                                                type: string
+                                                example: 22.5 is out of bounds for GDD calculations. Must be between 24.083334 - 49.916668
+    /api/{product}/normal:
+      post:
+          summary: Returns GDD data on a 30 year normal
+          description: Returns GDD normals for a specific lat, and lon
+          parameters:
+            - in: path
+              name: product
+              required: true
+              description: Agricultural product to calculate gdd for
+              schema:
+                  type: string
+                  enum: [corn, soybean, sugar_beet, sunflower, tomato, potato, wheat, peas, parsley, brussels_sprouts, cabbage]
+          requestBody:
+              content:
+                  application/json:
+                      schema:
+                          type: object
+                          required:
+                              - longitude
+                              - latitude
+                          properties:
+                              latitude:
+                                  description: latitude to calculate gdd on
+                                  type: number
+                                  minimum: 24.083334
+                                  maximum: 49.916668
+                                  example: 38.99
+                              longitude:
+                                  description: longitude to calculate gdd on
+                                  type: number
+                                  minimum: -125.0
+                                  maximum: -66.5
+                                  example: -76.94
+                              t_base:
+                                  description: Base temperature to calculate gdd on, in fahrenheit. NOT REQUIRED
+                                  type: number
+                                  example: 50
+                  
+          responses:
+              200:
+                  description: Success
+                  content:
+                      application/json:
+                          schema:
+                              type: object
+                              properties:
+                                  message:
+                                      type: string
+                                      example: 30-year normal GDDs
+                                  data:
+                                      type: array
+                                      items:
+                                          type: number
+                                  closest_lat:
+                                      type: number
+                                      minimum: 24.083334
+                                      maximum: 49.916668
+                                      example: 38.99
+                                  closest_lon:
+                                      type: number
+                                      minimum: -125.0
+                                      maximum: -66.5
+                                      example: -78.5
+              400:
+                  description: Bad Request
+                  content:
+                      application/json:
+                          schema:
+                              type: object
+                              properties:
+                                  errors:
+                                      type: array
+                                      items:
+                                          type: object
+                                          properties:
+                                              parameter_error:
+                                                  type: string
+                                                  example: latitude
+                                              message:
+                                                  type: string
+                                                  example: 22.5 is out of bounds for GDD calculations. Must be between 24.083334 - 49.916668
+    /api/{product}/accumulated/{year}:
+      post:
+          summary: Returns accumulated GDD data
+          description: Returns accumulated GDD data for a specific product, year, lat, and lon
+          produces:
+              - application/json
+          consumes:
+              - application/json
+          parameters:
+            - in: path
+              name: product
+              required: true
+              description: Agricultural product to calculate gdd for
+              schema:
+                  type: string
+                  enum: [corn, soybean, sugar_beet, sunflower, tomato, potato, wheat, peas, parsley, brussels_sprouts, cabbage]
+            - in: path
+              name: year
+              required: true
+              description: Year to calculate gdd on
+              schema:
+                  type: integer
+                  minimum: 1981
+          requestBody:
+              content:
+                  application/json:
+                      schema:
+                          type: object
+                          required:
+                              - longitude
+                              - latitude
+                          properties:
+                              latitude:
+                                  description: latitude to calculate gdd on
+                                  type: number
+                                  minimum: 24.083334
+                                  maximum: 49.916668
+                                  example: 38.99
+                              longitude:
+                                  description: longitude to calculate gdd on
+                                  type: number
+                                  minimum: -125.0
+                                  maximum: -66.5
+                                  example: -76.94
+                              t_base:
+                                  description: Base temperature to calculate gdd on, in fahrenheit. NOT REQUIRED
+                                  type: number
+                                  example: 50
+                  
+          responses:
+              200:
+                  description: Success
+                  content:
+                      application/json:
+                          schema:
+                              type: object
+                              properties:
+                                  message:
+                                      type: string
+                                      example: GDDs
+                                  date:
+                                      type: string
+                                      format: date
+                                  data:
+                                      type: array
+                                      items:
+                                          type: number
+                                      minItems: 1
+                                      maxItems: 365
+                                  closest_lat:
+                                      type: number
+                                      minimum: 24.083334
+                                      maximum: 49.916668
+                                      example: 38.99
+                                  closest_lon:
+                                      type: number
+                                      minimum: -125.0
+                                      maximum: -66.5
+                                      example: -76.94
+              400:
+                  description: Bad Request
+                  content:
+                      application/json:
+                          schema:
+                              type: object
+                              properties:
+                                  errors:
+                                      type: array
+                                      items:
+                                          type: object
+                                          properties:
+                                              parameter_error:
+                                                  type: string
+                                                  example: latitude
+                                              message:
+                                                  type: string
+                                                  example: 22.5 is out of bounds for GDD calculations. Must be between 24.083334 - 49.916668     
\ No newline at end of file
-- 
GitLab