Skip to content
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
64 changes: 57 additions & 7 deletions GUIDE.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,63 @@
**Note: Change any headings in this document**
# Cinema API Application Guide

# Project Guide
This document outlines the setup and usage of my Cinema API application, which leverages AWS services for the database, backend, and frontend.
Frontend url is [here](http://aws-jonas-halvorsen-day-5.s3-website.eu-north-1.amazonaws.com/).

## Setup
---

## Introduction
## Project Overview

## Technical Designs
This project consists of a backend API deployed on AWS Elastic Beanstalk, a database hosted on AWS RDS, and a frontend hosted on AWS S3 for static website hosting. The application is designed to manage customers, movies, screenings, and tickets.

## Technical Descriptions
---

## References
## Setup Instructions

### Database Setup

- **Service**: AWS RDS is used for persistent database storage.
- **Configuration**: The connection string is specified in the `appsettings.json` file. Database migrations are managed using Entity Framework.

### Backend Setup

- **Deployment**: The backend API is deployed using AWS Elastic Beanstalk.
- **Note**: The `Migrations` folder and `appsettings.json` file are excluded from the repository for security reasons.

### Frontend Setup

- **Hosting**: The frontend is hosted on AWS S3 as a static website.
- **Configuration**: Ensure the correct API URL is provided in the fetch requests. The `node_modules` folder is excluded from the repository.

---

## Running the Application Locally

To run the application locally after cloning the repository:

### Backend

1. Navigate to the `backend` folder.
2. Run the following commands:
```bash
dotnet restore
dotnet build
dotnet run

### Frontend

1. Navigate to the `frontend` folder.
2. Run the following commands:
```bash
npm install
npm audit fix
npm run dev

---

## API Documentation and endpoints

The backend API is structured according to the [API Documentation:](http://aws-day-5-jonas-api-env.eba-862qwvjc.eu-north-1.elasticbeanstalk.com/index.html)

**Example:**
To retrieve customer data:
```http://aws-day-5-jonas-api-env.eba-862qwvjc.eu-north-1.elasticbeanstalk.com/customers```
Binary file added Solution Documentation/Backend-swagger.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Solution Documentation/S3 Bucket Frontend.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added backend/CinemaERD.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions backend/api-cinema-challenge/api-cinema-challenge.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.33516.290
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "api-cinema-challenge", "api-cinema-challenge\api-cinema-challenge.csproj", "{E407EDC9-D711-4E04-84D0-98D84EBE42D1}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3C371BAA-344D-4C8A-AF08-7829816D726F}"
ProjectSection(SolutionItems) = preProject
..\.gitignore = ..\.gitignore
..\CinemaERD.png = ..\CinemaERD.png
..\README.md = ..\README.md
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E407EDC9-D711-4E04-84D0-98D84EBE42D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E407EDC9-D711-4E04-84D0-98D84EBE42D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E407EDC9-D711-4E04-84D0-98D84EBE42D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E407EDC9-D711-4E04-84D0-98D84EBE42D1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5BD9A95C-9AC8-4300-A9BD-FF464CACE65D}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using api_cinema_challenge.Models;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;

namespace api_cinema_challenge.DTOs
{
public class ResponseCustomerDTO
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
public List<ResponseTicketDTOCustomerLess> Tickets { get; set; } = new List<ResponseTicketDTOCustomerLess>();
}

public class PostCustomerDTO
{
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}

public class PutCustomerDTO
{
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
}
94 changes: 94 additions & 0 deletions backend/api-cinema-challenge/api-cinema-challenge/DTOs/Mapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using api_cinema_challenge.Models;

namespace api_cinema_challenge.DTOs
{
public static class Mapper
{
public static ResponseCustomerDTO MapToDTO(Customer customer)
{
ResponseCustomerDTO responseCustomer = new ResponseCustomerDTO();
responseCustomer.Id = customer.Id;
responseCustomer.Name = customer.Name;
responseCustomer.Email = customer.Email;
responseCustomer.Phone = customer.Phone;
responseCustomer.CreatedAt = customer.CreatedAt;
responseCustomer.UpdatedAt = customer.UpdatedAt;

foreach (Ticket t in customer.Tickets)
{
ResponseTicketDTOCustomerLess responseTicket = new ResponseTicketDTOCustomerLess();
responseTicket.Id = t.Id;
responseTicket.NumSeats = t.NumSeats;
responseTicket.ScreenNumber = t.Screening.ScreenNumber;
responseTicket.ScreeningStartsAt = t.Screening.StartsAt;
responseTicket.MovieTitle = t.Screening.Movie.Title;
responseTicket.CreatedAt = t.CreatedAt;
responseTicket.UpdatedAt = t.UpdatedAt;

responseCustomer.Tickets.Add(responseTicket);
}

return responseCustomer;
}

public static ResponseMovieDTO MapToDTO(Movie movie)
{
ResponseMovieDTO responseMovie = new ResponseMovieDTO();
responseMovie.Id = movie.Id;
responseMovie.Title = movie.Title;
responseMovie.Rating = movie.Rating;
responseMovie.Description = movie.Description;
responseMovie.RuntimeMins = movie.RuntimeMins;
responseMovie.CreatedAt = movie.CreatedAt;
responseMovie.UpdatedAt = movie.UpdatedAt;

foreach (Screening s in movie.Screenings)
{
ResponseScreeningDTOMovieLess responseSreening = new ResponseScreeningDTOMovieLess();
responseSreening.Id = s.Id;
responseSreening.ScreenNumber = s.ScreenNumber;
responseSreening.Capacity = s.Capacity;
responseSreening.StartsAt = s.StartsAt;
responseSreening.CreatedAt = s.CreatedAt;
responseSreening.UpdatedAt = s.UpdatedAt;

responseMovie.Screenings.Add(responseSreening);
}

return responseMovie;
}

public static ResponseScreeningDTO MapToDTO(Screening screening)
{
ResponseScreeningDTO responseScreening = new ResponseScreeningDTO();
responseScreening.Id = screening.Id;
responseScreening.ScreenNumber = screening.ScreenNumber;
responseScreening.Capacity = screening.Capacity;
responseScreening.MovieId = screening.MovieId;
responseScreening.MovieTitle = screening.Movie.Title;
responseScreening.StartsAt = screening.StartsAt;
responseScreening.CreatedAt = screening.CreatedAt;
responseScreening.UpdatedAt = screening.UpdatedAt;
responseScreening.NumOfTicketsSold = screening.Tickets.Count;

return responseScreening;
}

public static ResponseTicketDTO MapToDTO(Ticket ticket)
{
ResponseTicketDTO responseTicket = new ResponseTicketDTO();
responseTicket.Id = ticket.Id;
responseTicket.NumSeats = ticket.NumSeats;
responseTicket.CustomerId = ticket.CustomerId;
responseTicket.CustomerName = ticket.Customer.Name;
responseTicket.ScreeningId = ticket.ScreeningId;
responseTicket.ScreenNumber = ticket.Screening.ScreenNumber;
responseTicket.ScreeningStartsAt = ticket.Screening.StartsAt;
responseTicket.MovieName = ticket.Screening.Movie.Title;
responseTicket.CreatedAt = ticket.CreatedAt;
responseTicket.UpdatedAt = ticket.UpdatedAt;

return responseTicket;
}
}
}
31 changes: 31 additions & 0 deletions backend/api-cinema-challenge/api-cinema-challenge/DTOs/MovieDTO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
namespace api_cinema_challenge.DTOs
{
public class ResponseMovieDTO
{
public int Id { get; set; }
public string Title { get; set; }
public string Rating { get; set; }
public string Description { get; set; }
public int RuntimeMins { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
public List<ResponseScreeningDTOMovieLess> Screenings { get; set; } = new List<ResponseScreeningDTOMovieLess>();
}

public class PostMovieDTO
{
public string Title { get; set; }
public string Rating { get; set; }
public string Description { get; set; }
public int RuntimeMins { get; set; }
public List<PostScreeningDTOMovieLess> Screenings { get; set; }
}

public class PutMovieDTO
{
public string Title { get; set; }
public string Rating { get; set; }
public string Description { get; set; }
public int RuntimeMins { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
namespace api_cinema_challenge.DTOs
{
public class ResponseScreeningDTO
{
public int Id { get; set; }
public int ScreenNumber { get; set; }
public int Capacity { get; set; }
public int MovieId { get; set; }
public string MovieTitle { get; set; }
public int NumOfTicketsSold { get; set; }
public DateTime StartsAt { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}

public class ResponseScreeningDTOMovieLess
{
public int Id { get; set; }
public int ScreenNumber { get; set; }
public int Capacity { get; set; }
public DateTime StartsAt { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}

public class PostScreeningDTO
{
public int ScreenNumber { get; set; }
public int Capacity { get; set; }
public int MovieId { get; set; }
public DateTime StartsAt { get; set; }
}

public class PostScreeningDTOMovieLess
{
public int ScreenNumber { get; set; }
public int Capacity { get; set; }
public DateTime StartsAt { get; set; }
}

public class PutScreeningDTO
{
public int ScreenNumber { get; set; }
public int Capacity { get; set; }
public int MovieId { get; set; }
public DateTime StartsAt { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
namespace api_cinema_challenge.DTOs
{
public class ResponseTicketDTO
{
public int Id { get; set; }
public int NumSeats { get; set; }
public int CustomerId { get; set; }
public string CustomerName { get; set; }
public int ScreeningId { get; set; }
public int ScreenNumber { get; set; }
public DateTime ScreeningStartsAt { get; set; }
public string MovieName { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}

public class ResponseTicketDTOCustomerLess
{
public int Id { get; set; }
public int NumSeats { get; set; }
public int ScreeningId { get; set; }
public int ScreenNumber { get; set; }
public DateTime ScreeningStartsAt { get; set; }
public string MovieTitle { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}

public class PostTicketDTO
{
public int NumSeats { get; set; }
public int CustomerId { get; set; }
public int ScreeningId { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using api_cinema_challenge.Models;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json.Linq;

namespace api_cinema_challenge.Data
{
public class CinemaContext : DbContext
{
private string _connectionString;
public CinemaContext(DbContextOptions<CinemaContext> options) : base(options)
{
var configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
_connectionString = configuration.GetValue<string>("ConnectionStrings:DefaultConnectionString")!;
//this.Database.EnsureCreated();
}

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseNpgsql(_connectionString);
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
Seeder seeder = new Seeder();

modelBuilder.Entity<Customer>().HasData(seeder.Customers);
modelBuilder.Entity<Movie>().HasData(seeder.Movies);
modelBuilder.Entity<Screening>().HasData(seeder.Screenings);
modelBuilder.Entity<Ticket>().HasData(seeder.Tickets);
}

public DbSet<Customer> Customers { get; set; }
public DbSet<Movie> Movies { get; set; }
public DbSet<Screening> Screenings { get; set; }
public DbSet<Ticket> Tickets { get; set; }
}
}
Loading