Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MVP Complete #342

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added api/recipe/middleware.js
Empty file.
91 changes: 91 additions & 0 deletions api/recipe/model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
const db = require('../../data/db-config')


async function getById(id) {
// {
// "recipe_id" : 1,
// "recipe_name": "Spaghetti Bolognese",
// "created_at": "2021-01-01 08:23:19.120",
// "steps": [
// {
// "step_id": 11,
// "step_number": 1,
// "step_instructions": "Put a large saucepan on a medium heat",
// "ingredients": []
// },
// {
// "step_id": 12,
// "step_number": 2,
// "step_instructions": "Add 1 tbsp olive oil",
// "ingredients": [
// { "ingredient_id": 27, "ingredient_name": "olive oil", "quantity": 0.014 }
// ]
// },
// ]
// }

// {
// "ingredient_step_info_id": 1,
// "recipe_id": 1,
// "step_id": 1,
// "ingredient_id": 1,
// "ingredient_quantity": 2
// },
const data = await db('ingredient_step_info')
.where('recipe_id', id)

let newData = [];

for(let i = 0; i < data.length; i++) {
let obj = data[i];
let { recipe_id, step_id, ingredient_step_info, ingredient_id, ingredient_quantity } = obj

// find step_id with step number
const step = await db('steps')
.select('step_number', 'instruction')
.where('step_id', step_id)

// 2 In a pan, sauté minced garlic in olive oil until golden.
let { instruction, step_number} = step[0]

const ingredient = await db('ingredients')
.select('ingredient_name')
.where('ingredient_id', ingredient_id)

let ingredientArray = []

for (let i = 0; i < ingredient.length; i++) {
let obj = {
ingredient_id: ingredient_id,
ingredient_name: ingredient[i].ingredient_name,
quantity: ingredient_quantity
}
ingredientArray.push(obj)
}

const newObj = {
step_id: step_id,
step_number: step_number,
step_instructions: instruction,
ingredients: ingredientArray
}

newData.push(newObj)

//{
// "step_id": 12,
// "step_number": 2,
// "step_instructions": "Add 1 tbsp olive oil",
// "ingredients": [
// { "ingredient_id": 27, "ingredient_name": "olive oil", "quantity": 0.014 }
// ]
// },


}
return newData
}

module.exports = {
getById
}
22 changes: 22 additions & 0 deletions api/recipe/router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const express = require('express')
const Recipe = require('./model')

const router = express.Router()



router.get('/:id', async (req, res) => {
const id = req.params.id
const recipeInfo = await Recipe.getById(id)
res.status(200).json(recipeInfo)
})

router.use( (err, req, res, next) => {
res.status( err.status || 500).json({
customMessage: 'something terrible inside the recipe router',
message: err.message,
stack: err.stack
})
})

module.exports = router
14 changes: 14 additions & 0 deletions api/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const express = require('express');

const RecipeRouter = require('./recipe/router');

const server = express();

server.use(express.json());
server.use('/api/recipe', RecipeRouter);
server.use((err, req, res, next) => {
// eslint-disable-line
res.status(err.status || 500).json({ message: err.message });
});

module.exports = server;
8 changes: 8 additions & 0 deletions data/db-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const knex = require('knex')

const configs = require('../knexfile')

const env = process.env.NODE_ENV || 'development'

module.exports = knex(configs[env])

68 changes: 68 additions & 0 deletions data/migrations/20240517001314_first-migration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.up = async function(knex) {
await knex.schema
.createTable('recipes', (table) => {
table.increments('recipe_id');
table.string('recipe_name').notNullable().unique();
})
.createTable('steps', (table) => {
table.increments('step_id');
table.integer('step_number').unsigned();
table.string('instruction').notNullable();
table
.integer('recipe_id')
.unsigned()
.notNullable()
.references('recipe_id')
.inTable('recipes')
.onDelete('RESTRICT')
.onUpdate('RESTRICT');
})
.createTable('ingredients', (table) => {
table.increments('ingredient_id');
table.integer('ingredient_name');
})
.createTable('ingredient_step_info', (table) => {
table.increments('ingredient_step_info_id');
table
.integer('recipe_id')
.unsigned()
.notNullable()
.references('recipe_id')
.inTable('recipes')
.onDelete('RESTRICT')
.onUpdate('RESTRICT');
table
.integer('step_id')
.unsigned()
.notNullable()
.references('step_id')
.inTable('steps')
.onDelete('RESTRICT')
.onUpdate('RESTRICT');
table
.integer('ingredient_id')
.unsigned()
.notNullable()
.references('ingredient_id')
.inTable('ingredients')
.onDelete('RESTRICT')
.onUpdate('RESTRICT');
table.decimal('ingredient_quantity');
});
};

/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.down = async function(knex) {
await knex.schema
.dropTableIfExists('ingredient_step_info')
.dropTableIfExists('ingredients')
.dropTableIfExists('steps')
.dropTableIfExists('recipes');
};
Binary file added data/recipe.db3
Binary file not shown.
13 changes: 13 additions & 0 deletions data/seeds/01recipes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.seed = async function(knex) {
// Deletes ALL existing entries
await knex('recipes').truncate()
await knex('recipes').insert([
{ recipe_name: 'Pasta Aglio e Olio' },
{ recipe_name: 'Grilled Cheese Sandwich' },
{ recipe_name: 'Greek Yogurt Parfait' },
]);
};
69 changes: 69 additions & 0 deletions data/seeds/02steps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.seed = async function(knex) {
// Deletes ALL existing entries
await knex('steps').truncate()
await knex('steps').insert([
{
step_number: 1,
recipe_id: 1,
instruction: 'Boil spaghetti until al dente, then drain.',
},
{
step_number: 2,
recipe_id: 1,
instruction: 'In a pan, sauté minced garlic in olive oil until golden.',
},
{
step_number: 3,
recipe_id: 1,
instruction:
'Toss cooked pasta in the garlic oil, add red pepper flakes, salt, and chopped parsley.',
},
{
step_number: 4,
recipe_id: 1,
instruction: 'Mix well and serve with grated Parmesan cheese',
},
{
step_number: 1,
recipe_id: 2,
instruction: 'Butter two slices of bread on one side each.',
},
{
step_number: 2,
recipe_id: 2,
instruction:
'Place cheese (cheddar or any melty cheese you like) between the unbuttered sides.',
},
{
step_number: 3,
recipe_id: 2,
instruction: 'Heat a pan over medium heat and place the sandwich.',
},
{
step_number: 4,
recipe_id: 2,
instruction:
'Cook until golden brown on both sides and the cheese melts.',
},
{
step_number: 1,
recipe_id: 3,
instruction:
'In a glass, layer Greek yogurt, granola, and mixed berries (strawberries, blueberries, raspberries).',
},
{
step_number: 2,
recipe_id: 3,
instruction: 'Repeat layers until the glass is full.',
},
{
step_number: 3,
recipe_id: 3,
instruction: 'Top with a drizzle of honey or maple syrup.',
},
]);
};
27 changes: 27 additions & 0 deletions data/seeds/03ingredients.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.seed = async function(knex) {
// Deletes ALL existing entries
await knex('ingredients').truncate()
await knex('ingredients').insert([
{ ingredient_name: 'spaghetti' },
{ ingredient_name: 'minced garlic' },
{ ingredient_name: 'olive oil' },
{ ingredient_name: 'red pepper flakes' },
{ ingredient_name: 'salt' },
{ ingredient_name: 'chopped parsley' },
{ ingredient_name: 'Parmesan cheese' },
{ ingredient_name: 'Butter' },
{ ingredient_name: 'bread' },
{ ingredient_name: 'cheddar cheese' },
{ ingredient_name: 'Greek yogurt' },
{ ingredient_name: 'granola' },
{ ingredient_name: 'strawberries' },
{ ingredient_name: 'blueberries' },
{ ingredient_name: 'raspberries' },
{ ingredient_name: 'honey' },
{ ingredient_name: 'maple syrup' }
]);
};
27 changes: 27 additions & 0 deletions data/seeds/04ingredient_step_info.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.seed = async function(knex) {
// Deletes ALL existing entries
await knex('ingredient_step_info').truncate()
await knex('ingredient_step_info').insert([
{ recipe_id: 1, step_id: 1, ingredient_id: 1, ingredient_quantity: 2 },
{ recipe_id: 1, step_id: 2, ingredient_id: 2, ingredient_quantity: 0.5 },
{ recipe_id: 1, step_id: 2, ingredient_id: 3, ingredient_quantity: 1 },
{ recipe_id: 1, step_id: 3, ingredient_id: 4, ingredient_quantity: 0.1 },
{ recipe_id: 1, step_id: 3, ingredient_id: 5, ingredient_quantity: 0.1 },
{ recipe_id: 1, step_id: 3, ingredient_id: 6, ingredient_quantity: 0.5 },
{ recipe_id: 1, step_id: 4, ingredient_id: 7, ingredient_quantity: 1 },
{ recipe_id: 2, step_id: 1, ingredient_id: 8, ingredient_quantity: 0.5 },
{ recipe_id: 2, step_id: 1, ingredient_id: 9, ingredient_quantity: 2 },
{ recipe_id: 2, step_id: 2, ingredient_id: 10, ingredient_quantity: 2 },
{ recipe_id: 3, step_id: 1, ingredient_id: 11, ingredient_quantity: 6 },
{ recipe_id: 3, step_id: 1, ingredient_id: 12, ingredient_quantity: 1 },
{ recipe_id: 3, step_id: 1, ingredient_id: 13, ingredient_quantity: 2 },
{ recipe_id: 3, step_id: 1, ingredient_id: 14, ingredient_quantity: 2 },
{ recipe_id: 3, step_id: 1, ingredient_id: 15, ingredient_quantity: 2 },
{ recipe_id: 3, step_id: 3, ingredient_id: 16, ingredient_quantity: .5 },
{ recipe_id: 3, step_id: 3, ingredient_id: 17, ingredient_quantity: .5 },
]);
};
9 changes: 9 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import globals from "globals";
import pluginJs from "@eslint/js";


export default [
{files: ["**/*.js"], languageOptions: {sourceType: "commonjs"}},
{languageOptions: { globals: globals.node }},
pluginJs.configs.recommended,
];
7 changes: 7 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const server = require('./api/server.js');

const PORT = process.env.PORT || 9000;

server.listen(PORT, () => {
console.log(`Listening on port ${PORT}...`);
});
30 changes: 30 additions & 0 deletions knexfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Update with your config settings.

/**
* @type { Object.<string, import("knex").Knex.Config> }
*/
module.exports = {

development: {
client: 'sqlite3',
connection: {
filename: './data/recipe.db3'
},
migrations: {
directory: './data/migrations'
},
seeds: {
directory: './data/seeds'
},
pool: {
afterCreate:( conn, done) => {
// runs after a connection is made to the sqlite engine
conn.run('PRAGMA foreign_keys = ON', done) // turn on FK enforcement
},
},
useNullAsDefault: true,
},



};
Loading