diff --git a/.env.example b/.env.example deleted file mode 100644 index 60f3a816..00000000 --- a/.env.example +++ /dev/null @@ -1,6 +0,0 @@ -DATABASE_URL="YOUR_DB_URL" - -# 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 - -TEST_DATABASE_URL="YOUR_TEST_DB_URL" diff --git a/assets/conceptual-modelling.png b/assets/conceptual-modelling.png new file mode 100644 index 00000000..2523e00a Binary files /dev/null and b/assets/conceptual-modelling.png differ diff --git a/assets/logical-modelling.png b/assets/logical-modelling.png new file mode 100644 index 00000000..a1bb60b3 Binary files /dev/null and b/assets/logical-modelling.png differ diff --git a/assets/physical-maodelling.png b/assets/physical-maodelling.png new file mode 100644 index 00000000..448109e1 Binary files /dev/null and b/assets/physical-maodelling.png differ diff --git a/src/controllers/customer.js b/src/controllers/customer.js index 775cfb42..68f83b5e 100644 --- a/src/controllers/customer.js +++ b/src/controllers/customer.js @@ -1,5 +1,5 @@ const { PrismaClientKnownRequestError } = require("@prisma/client") -const { createCustomerDb } = require('../domains/customer.js') +const { createCustomerDb, updateCustomerById } = require('../domains/customer.js') const createCustomer = async (req, res) => { const { @@ -43,6 +43,28 @@ const createCustomer = async (req, res) => { } } +const updateCustomer = async (req, res) => { + + const { id } = req.params + const { name } = req.body + + if (!name) { + return res.status(400).json({ error: 'Invalid data format' }); + } + + try { + + const updateCustomerDetails = await updateCustomerById (id, name) + res.status(201).json({customer: updateCustomerDetails }) + + } catch (error) { + + console.error('Error updating customer:', error) + res.status(500).json({ error: 'Internal server error' }) + + } +} + module.exports = { - createCustomer + createCustomer, updateCustomer } diff --git a/src/controllers/movie.js b/src/controllers/movie.js new file mode 100644 index 00000000..dac92d18 --- /dev/null +++ b/src/controllers/movie.js @@ -0,0 +1,83 @@ +const { PrismaClientKnownRequestError } = require("@prisma/client") +const { getListMovies, postMovie, getMovieById, updateMovieById } = require('../domains/movie.js') + + +const getMovies = async (req, res) => { + + try { + const movies = await getListMovies() + res.status(200).json({movies}) + } catch (error) { + console.error('Error fetching movies:', error) + res.status(500).json({ error: 'Internal server error' }) + } +} + +const createMovie = 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 postMovie(title, runtimeMins) + + res.status(201).json({ + movie: createdMovie + }) + } catch (error) { + + if (error instanceof PrismaClientKnownRequestError) { + if (error.code === "P2002") { + return res.status(409).json({ error: "A movie with the provided title already exists" }) + } + } + + res.status(500).json({ error: error.message }) + } +} + +const fetchMovieByID = async (req, res) => { + + try { + const movieId = req.params.id + const movie = await getMovieById(movieId) + + if (!movie) { + return res.status(404).json({error: 'movie not found'}) + } + + res.status(200).json({movie}) + + } catch (error) { + console.error('Error fetching movie:', error) + res.status(500).json({ error: 'Internal server error' }) + } +} + +const updateMovie = async (req, res) => { + const { id } = req.params + const { title, runtimeMins, screenings } = req.body + + try { + + const updatedMovie = await updateMovieById(id, title, runtimeMins, screenings) + res.status(201).json({ movie: updatedMovie }) + + } catch (error) { + + console.error('Error updating movie and screenings:', error) + res.status(500).json({ error: 'Internal server error' }) + + } + } + + +module.exports = { getMovies, createMovie, fetchMovieByID, updateMovie } \ No newline at end of file diff --git a/src/controllers/screen.js b/src/controllers/screen.js new file mode 100644 index 00000000..851e1259 --- /dev/null +++ b/src/controllers/screen.js @@ -0,0 +1,35 @@ +const { PrismaClientKnownRequestError } = require("@prisma/client") +const { createScreen } = require('../domains/screen.js') + + +const createNewScreen = async (req, res) => { + + const { + number + } = req.body + + if (!number) { + return res.status(400).json({ + error: "Missing fields in request body" + }) + } + + try { + const screen = await createScreen(number) + + res.status(201).json({ + screen: screen + }) + } catch (error) { + + if (error instanceof PrismaClientKnownRequestError) { + if (error.code === "P2002") { + return res.status(409).json({ error: "A screen with the provided number already exists" }) + } + } + + res.status(500).json({ error: error.message }) + } +} + +module.exports = { createNewScreen } \ No newline at end of file diff --git a/src/domains/customer.js b/src/domains/customer.js index c7f315fd..9203a890 100644 --- a/src/domains/customer.js +++ b/src/domains/customer.js @@ -4,23 +4,43 @@ 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 +const createCustomerDb = async (name, phone, email) => { + const registerdCustomer = 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 } - }, - // 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 - } -}) + }) + return registerdCustomer +} + +const updateCustomerById = async (customerId, name) => { + + const updateCustomer = await prisma.customer.update({ + where: { + id: parseInt(customerId) + }, + data: { + name + }, + include: { + contact: true + } + }) + return updateCustomer + +} module.exports = { - createCustomerDb + createCustomerDb, updateCustomerById } diff --git a/src/domains/movie.js b/src/domains/movie.js new file mode 100644 index 00000000..65d94f3f --- /dev/null +++ b/src/domains/movie.js @@ -0,0 +1,64 @@ +const prisma = require('../utils/prisma') + + +const getListMovies = async () => { + const movies = await prisma.movie.findMany({ + include: { + screenings: true + } + }) + return movies +} + +const postMovie = async (title, runtimeMins) => { + const movie = await prisma.movie.create({ + data: { + title, + runtimeMins, + screenings: {} + }, + include: { + screenings: true + } + }) + return movie +} + +const getMovieById = async (id) => { + const movie = await prisma.movie.findUnique({ + where: { + id: parseInt(id) + }, + include: { + screenings: true + } + }) + return movie +} + +const updateMovieById = async (movieId, title, runtimeMins, screenings) => { + + const updateData = await prisma.movie.update({ + where: { id: parseInt(movieId) }, + data: { + title, + runtimeMins, + screenings: { + update: screenings? screenings.map(screening => ({ + where: { id: screening.id }, + data: { + startsAt: screening.startsAt, + screenId: screening.screenId + } + })) : [] + } + }, + + include: { + screenings: true + } + }) + return updateData +} + +module.exports = { getListMovies, postMovie, getMovieById, updateMovieById } \ No newline at end of file diff --git a/src/domains/screen.js b/src/domains/screen.js new file mode 100644 index 00000000..15e9f305 --- /dev/null +++ b/src/domains/screen.js @@ -0,0 +1,15 @@ +const prisma = require('../utils/prisma') + +const createScreen = async (number) => { + const createdScreen = await prisma.screen.create({ + data: { + number, + }, + include: { + screenings: true + } + }) + return createdScreen + } + + module.exports = { createScreen } \ No newline at end of file diff --git a/src/routers/customer.js b/src/routers/customer.js index f14a87fc..d8c4facd 100644 --- a/src/routers/customer.js +++ b/src/routers/customer.js @@ -1,6 +1,6 @@ const express = require("express"); const { - createCustomer + createCustomer, updateCustomer } = require('../controllers/customer'); const router = express.Router(); @@ -10,4 +10,6 @@ const router = express.Router(); // that looks like http://localhost:4040/customer/register router.post("/register", createCustomer); +router.put("/:id", updateCustomer) + module.exports = router; diff --git a/src/routers/movie.js b/src/routers/movie.js new file mode 100644 index 00000000..3ce7eefb --- /dev/null +++ b/src/routers/movie.js @@ -0,0 +1,21 @@ +const express = require("express"); +const { + getMovies, + createMovie, + fetchMovieByID, + updateMovie +} = require('../controllers/movie'); + +const router = express.Router(); + + +router.get("/", getMovies); + +router.post("/", createMovie) + +router.get("/:id", fetchMovieByID) + +router.put("/:id", updateMovie) + + +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..c4a8e05b --- /dev/null +++ b/src/routers/screen.js @@ -0,0 +1,12 @@ +const express = require("express"); +const { + createNewScreen +} = require('../controllers/screen'); + +const router = express.Router(); + + +router.post("/", createNewScreen) + + +module.exports = router \ No newline at end of file diff --git a/src/server.js b/src/server.js index 93d47a16..cb6ccd4a 100644 --- a/src/server.js +++ b/src/server.js @@ -17,5 +17,11 @@ app.use(express.urlencoded({ extended: true })); const customerRouter = require('./routers/customer'); app.use('/customers', customerRouter); +const movieRouter = require('./routers/movie') +app.use('/movies', movieRouter) + +const screenRouter = require('./routers/screen') +app.use('/screens', screenRouter) + module.exports = app