diff --git a/.env.example b/.env.example deleted file mode 100644 index 8b171090..00000000 --- a/.env.example +++ /dev/null @@ -1,18 +0,0 @@ -# Environment variables declared in this file are automatically made available to Prisma. -# See the documentation for more detail: https://pris.ly/d/prisma-schema#using-environment-variables - -# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server and MongoDB (Preview). -# See the documentation for all the connection string options: https://pris.ly/d/connection-strings - -# We need the following URL environment variables for development purposes: -# - DATABASE_URL is the database you will be querying and must have a schema called 'prisma'. -# - SHADOW_DATABASE_URL can be the same database instance or a different one from DATABASE_URL, and must have -# a schema called 'shadow' whatever the case. -DATABASE_URL="YOUR_DB_URL?schema=prisma" -SHADOW_DATABASE_URL="YOUR_SHADOW_DATABASE_URL?schema=shadow" - -# We need the following URL environment variable for test purposes: -# - TEST_DATABASE_URL must be a **completely separate** database from any other used in this file and needs a schema -# called 'prisma'. - -TEST_DATABASE_URL="YOUR_TEST_DB_URL?schema=prisma" diff --git a/package-lock.json b/package-lock.json index 5f688f1e..1b29cc71 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@prisma/client": "^5.7.1", "cors": "^2.8.5", - "dotenv": "^16.3.1", + "dotenv": "^16.4.5", "express": "^4.18.2", "morgan": "^1.10.0" }, @@ -1957,14 +1957,14 @@ } }, "node_modules/dotenv": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", - "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" + "url": "https://dotenvx.com" } }, "node_modules/ee-first": { diff --git a/package.json b/package.json index 1816d402..5752caa1 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "dependencies": { "@prisma/client": "^5.7.1", "cors": "^2.8.5", - "dotenv": "^16.3.1", + "dotenv": "^16.4.5", "express": "^4.18.2", "morgan": "^1.10.0" } diff --git a/src/controllers/customer.js b/src/controllers/customer.js index 775cfb42..9640da9d 100644 --- a/src/controllers/customer.js +++ b/src/controllers/customer.js @@ -1,17 +1,17 @@ -const { PrismaClientKnownRequestError } = require("@prisma/client") -const { createCustomerDb } = require('../domains/customer.js') + +const { PrismaClientKnownRequestError } = require("@prisma/client"); +const { + createCustomerDb, + updateCustomerByIdDb, +} = require("../domains/customer.js"); const createCustomer = async (req, res) => { - const { - name, - phone, - email - } = req.body + const { name, phone, email } = req.body; if (!name || !phone || !email) { return res.status(400).json({ - error: "Missing fields in request body" - }) + error: "Missing fields in request body", + }); } // Try-catch is a very common way to handle errors in JavaScript. @@ -22,9 +22,9 @@ const createCustomer = async (req, res) => { // instead of the Prisma error being thrown (and the app potentially crashing) we exit the // `try` block (bypassing the `res.status` code) and enter the `catch` block. try { - const createdCustomer = await createCustomerDb(name, phone, email) + const createdCustomer = await createCustomerDb(name, phone, email); - res.status(201).json({ customer: createdCustomer }) + res.status(201).json({ customer: createdCustomer }); } catch (e) { // In this catch block, we are able to specify how different Prisma errors are handled. // Prisma throws errors with its own codes. P2002 is the error code for @@ -35,14 +35,23 @@ const createCustomer = async (req, res) => { // HTTP error codes: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses if (e instanceof PrismaClientKnownRequestError) { if (e.code === "P2002") { - return res.status(409).json({ error: "A customer with the provided email already exists" }) + return res + .status(409) + .json({ error: "A customer with the provided email already exists" }); } } - res.status(500).json({ error: e.message }) + res.status(500).json({ error: e.message }); } -} +}; +const updateCustomerById = async (req, res) => { + const customerId = parseInt(req.params.id); + const { name } = req.body; + const customer = await updateCustomerByIdDb(customerId, name); + res.status(201).json({ customer }); +}; module.exports = { - createCustomer -} + createCustomer, + updateCustomerById, +}; diff --git a/src/controllers/movies.js b/src/controllers/movies.js new file mode 100644 index 00000000..e33a8aa9 --- /dev/null +++ b/src/controllers/movies.js @@ -0,0 +1,49 @@ +const { PrismaClientKnownRequestError } = require("@prisma/client"); +const { + getAllMoviesDb, + createMovieDb, + getAMovieByIdDb, + updateMoviebyIdDb, +} = require("../domains/movies.js"); + +const getAllMovies = async (req, res) => { + const movies = await getAllMoviesDb(); + res.status(200).json({ movies }); +}; +const createAMovie = async (req, res) => { + const { title, runtimeMins } = req.body; + + if (!title || !runtimeMins) { + return res.status(400).json({ + error: "Missing fields in request body", + }); + } + try { + const createdMovie = await createMovieDb(title, runtimeMins); + + res.status(201).json({ movie: createdMovie }); + } catch (e) { + if (e instanceof PrismaClientKnownRequestError) { + if (e.code === "P2002") { + return res + .status(409) + .json({ error: "A movie with the provided title already exists" }); + } + } + + res.status(500).json({ error: e.message }); + } +}; +const getAMovieById = async (req, res) => { + const movieId = parseInt(req.params.id); + const movie = await getAMovieByIdDb(movieId); + res.status(200).json({ movie }); +}; +const updateMoviebyId = async (req, res) => { + const movieId = parseInt(req.params.id); + const { title, runtimeMins } = req.body; + const movie = await updateMoviebyIdDb(movieId, title, runtimeMins); + res.status(201).json({ movie }); +}; + +module.exports = { getAllMovies, createAMovie, getAMovieById, updateMoviebyId }; \ No newline at end of file diff --git a/src/controllers/screen.js b/src/controllers/screen.js new file mode 100644 index 00000000..561f045c --- /dev/null +++ b/src/controllers/screen.js @@ -0,0 +1,33 @@ +const { PrismaClientKnownRequestError } = require("@prisma/client"); +const { createScreenDb } = require("../domains/screen.js"); + + +const createAScreen = async (req, res) => { + const { number } = req.body; + + if (!number) { + return res.status(400).json({ + error: "Missing field in request body", + }); + } + try { + const createdScreen = await createScreenDb(number); + + res.status(201).json({ screen: createdScreen }); + } catch (e) { + if (e instanceof PrismaClientKnownRequestError) { + if (e.code === "P2002") { + return res + .status(409) + .json({ error: "A screen with the provided number already exists" }); + } + } + + + + + res.status(500).json({ error: e.message }); + } +}; + +module.exports = { createAScreen}; \ No newline at end of file diff --git a/src/domains/customer.js b/src/domains/customer.js index c7f315fd..81da2881 100644 --- a/src/domains/customer.js +++ b/src/domains/customer.js @@ -1,26 +1,41 @@ -const prisma = require('../utils/prisma') +const prisma = require("../utils/prisma"); /** * This will create a Customer AND create a new Contact, then automatically relate them with each other * @tutorial https://www.prisma.io/docs/concepts/components/prisma-client/relation-queries#create-a-related-record */ -const createCustomerDb = async (name, phone, email) => await prisma.customer.create({ - data: { - name, - contact: { - create: { - phone, - email - } - } - }, - // We add an `include` outside of the `data` object to make sure the new contact is returned in the result - // This is like doing RETURNING in SQL - include: { - contact: true - } -}) +const createCustomerDb = async (name, phone, email) => + await prisma.customer.create({ + data: { + name, + contact: { + create: { + phone, + email, + }, + }, + }, + // We add an `include` outside of the `data` object to make sure the new contact is returned in the result + // This is like doing RETURNING in SQL + include: { + contact: true, + }, + }); +const updateCustomerByIdDb = async (id, name) => { + return await prisma.customer.update({ + where: { + id, + }, + data: { + name, + }, + include: { + contact: true, + }, + }); +}; module.exports = { - createCustomerDb -} + createCustomerDb, + updateCustomerByIdDb, +}; \ No newline at end of file diff --git a/src/domains/movies.js b/src/domains/movies.js new file mode 100644 index 00000000..d79582ba --- /dev/null +++ b/src/domains/movies.js @@ -0,0 +1,51 @@ +const prisma = require("../utils/prisma"); + +const getAllMoviesDb = async () => { + return await prisma.movie.findMany({ + include: { + screenings: true, + }, + }); +}; +const createMovieDb = async (title, runtimeMins) => { + return await prisma.movie.create({ + data: { + title, + runtimeMins, + }, + include: { + screenings: true, + }, + }); +}; +const getAMovieByIdDb = async (id) => { + return await prisma.movie.findUnique({ + where: { + id, + }, + include: { + screenings: true, + }, + }); +}; +const updateMoviebyIdDb = async (id, title, runtimeMins) => { + return await prisma.movie.update({ + where: { + id, + }, + data: { + title, + runtimeMins, + }, + include: { + screenings: true, + }, + }); +}; + +module.exports = { + getAllMoviesDb, + createMovieDb, + getAMovieByIdDb, + updateMoviebyIdDb, +}; \ No newline at end of file diff --git a/src/domains/screen.js b/src/domains/screen.js new file mode 100644 index 00000000..fd953cf6 --- /dev/null +++ b/src/domains/screen.js @@ -0,0 +1,15 @@ +const prisma = require("../utils/prisma"); + + +const createScreenDb = async (number) => { + return await prisma.screen.create({ + data: { + number, + + }, + + }); + + +} +module.exports = { createScreenDb }; \ No newline at end of file diff --git a/src/routers/customer.js b/src/routers/customer.js index f14a87fc..73955087 100644 --- a/src/routers/customer.js +++ b/src/routers/customer.js @@ -1,6 +1,6 @@ const express = require("express"); const { - createCustomer + createCustomer, updateCustomerById } = require('../controllers/customer'); const router = express.Router(); @@ -9,5 +9,6 @@ const router = express.Router(); // The below /register route extends that, so the end result will be a URL // that looks like http://localhost:4040/customer/register router.post("/register", createCustomer); +router.put("/:id",updateCustomerById) -module.exports = router; +module.exports = router; \ No newline at end of file diff --git a/src/routers/movies.js b/src/routers/movies.js new file mode 100644 index 00000000..c6d3fd5c --- /dev/null +++ b/src/routers/movies.js @@ -0,0 +1,10 @@ +const express = require("express"); +const router = express.Router(); +const { + getAllMovies, createAMovie, getAMovieById, updateMoviebyId + } = require('../controllers/movies'); +router.get('/', getAllMovies) +router.post('/', createAMovie) +router.get('/:id',getAMovieById) +router.put('/:id',updateMoviebyId) +module.exports = router; \ No newline at end of file diff --git a/src/routers/screen.js b/src/routers/screen.js new file mode 100644 index 00000000..86c19c17 --- /dev/null +++ b/src/routers/screen.js @@ -0,0 +1,8 @@ +const express = require("express"); +const router = express.Router(); +const { + createAScreen + } = require('../controllers/screen'); + +router.post('/', createAScreen) +module.exports = router; \ No newline at end of file diff --git a/src/server.js b/src/server.js index 93d47a16..5d3d04e1 100644 --- a/src/server.js +++ b/src/server.js @@ -16,6 +16,9 @@ app.use(express.urlencoded({ extended: true })); // Tell express to use your routers here const customerRouter = require('./routers/customer'); app.use('/customers', customerRouter); +const movieRouter = require ('./routers/movies') +app.use('/movies', movieRouter) +const screenRouter = require ('./routers/screen') +app.use('/screens', screenRouter) - -module.exports = app +module.exports = app \ No newline at end of file